diff --git a/3.0/client/PHP/Gallery3.php b/3.0/client/PHP/Gallery3.php index 83ed7b2d..fb97ddf8 100644 --- a/3.0/client/PHP/Gallery3.php +++ b/3.0/client/PHP/Gallery3.php @@ -1,7 +1,7 @@ + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. diff --git a/3.0/client/Python/pylibgal3/MANIFEST.in b/3.0/client/Python/pylibgal3/MANIFEST.in new file mode 100644 index 00000000..3ca15d46 --- /dev/null +++ b/3.0/client/Python/pylibgal3/MANIFEST.in @@ -0,0 +1,2 @@ +include KNOWN_ISSUES +include LICENSE diff --git a/3.0/client/Python/pylibgal3/README b/3.0/client/Python/pylibgal3/README new file mode 100644 index 00000000..57114ce3 --- /dev/null +++ b/3.0/client/Python/pylibgal3/README @@ -0,0 +1,21 @@ +======= +Install +======= + +To install this libary, just do the usual Python setup: + +# tar -xvzf libgal3-*.tar.gz +# cd libgal3-* +# python setup.py install + +That's it for install. You should be able to import the libg3 library after +that: + +(In your python script) +import libg3 + +============= +Documentation +============= + +See http://stuffivelearned.org/doku.php?id=programming:python:libgal3 for documentation info. diff --git a/3.0/client/Python/pylibgal3/libg3/Errors.py b/3.0/client/Python/pylibgal3/libg3/Errors.py new file mode 100644 index 00000000..399bc259 --- /dev/null +++ b/3.0/client/Python/pylibgal3/libg3/Errors.py @@ -0,0 +1,51 @@ +# +# Author: Jay Deiman +# Email: admin@splitstreams.com +# +# This file is part of pylibgal3. +# +# pylibgal3 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. +# +# pylibgal3 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 pylibgal3. If not, see . +# + +__all__ = ['G3Error' , 'G3RequestError' , 'G3InvalidRespError' , + 'G3UnknownTypeError' , 'G3AuthError' , 'G3UnknownError'] + +class G3Error(Exception): + pass + +class G3RequestError(G3Error): + def __init__(self , errDict): + self.errors = errDict + self._message = self._getMessage() + + def _getMessage(self): + ret = '' + for e in self.errors.items(): + ret += '%s: %r\n' % e + return ret + + def __str__(self): + return self._message + +class G3InvalidRespError(G3Error): + pass + +class G3UnknownTypeError(G3InvalidRespError): + pass + +class G3AuthError(G3Error): + pass + +class G3UnknownError(G3Error): + pass diff --git a/3.0/client/Python/pylibgal3/libg3/G3Items.py b/3.0/client/Python/pylibgal3/libg3/G3Items.py new file mode 100644 index 00000000..0fdae593 --- /dev/null +++ b/3.0/client/Python/pylibgal3/libg3/G3Items.py @@ -0,0 +1,502 @@ +# +# Author: Jay Deiman +# Email: admin@splitstreams.com +# +# This file is part of pylibgal3. +# +# pylibgal3 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. +# +# pylibgal3 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 pylibgal3. If not, see . +# + +__all__ = ['Album' , 'Image' , 'LocalImage' , 'RemoteImage' , 'LocalMovie' , + 'RemoteMovie' , 'getItemFromResp' , 'getItemsFromResp'] + +from datetime import datetime +import json , weakref , types , os , mimetypes , re + +class BaseRemote(object): + def __init__(self , respObj , weakGalObj , weakParent=None): + self._setAttrItems(respObj.items()) + if 'entity' in respObj: + self._setAttrItems(respObj['entity'].items()) + self._weakParent = None + if weakParent is not None: + self._weakParent = weakParent + self._weakGal = weakGalObj + self.fh = None + self._postInit() + + def __str__(self): + try: + return self.title + except: + pass + return self.name + + def __getattr__(self , name): + """ + A bit of magic to make the retrieval of member objects lazy + """ + # Process the specials + if name == 'members': + self.members = self._getMemberObjects() + return self.members + if name == 'tags': + self.tags = self._getTags() + return self.tags + if name == 'comments': + self.comments = self._getComments() + return self.comments + # Process the weak reference calls + if name == '_gal': + return self._weakGal() + if name == 'parent' and self._weakParent is not None: + return self._weakParent() + # Process the generic items + urlAttr = '_%s' % name + # Call __getattribute__ to prevent loops + attr = object.__getattribute__(self , urlAttr) + if attr is not None and attr.startswith('http'): + obj = self._getUrlObject(attr) + setattr(self , name , obj) + return obj + raise AttributeError(name) + + def _postInit(self): + """ + This can be overridden in subclasses to do any special initialization + at the end of the __init__ call + """ + pass + + def _setAttrItems(self , d): + for k , v in d: + if k == 'entity': + # Skip it + continue + if (type(v) in types.StringTypes and v.startswith('http') and + 'url' not in k) or k == 'members': + setattr(self , '_%s' % k , v) + else: + setattr(self , k , v) + + def _getMemberObjects(self): + """ + This returns the appropriate objects for each child of this object. + The default "members" attribute only contains the URLs for the + children of this object. This returns a list of the actual objects. + """ + memObjs = self._gal.getItemsForUrls(self._members , self) + return memObjs + + def _getTags(self): + """ + Returns the list of tag objects + + returns(list[Tag]) + """ + # First, I want just the actual tag itself, not the RESTy "tag_item", + # so I'm going to modify the urls to save a step + ret = [] + urls = [] + for url in self.relationships['tags']['members']: + m = re.match('^(.*?/tag)_item(/\d+),\d+$' , url) + urls.append('%s%s' % tuple(m.groups())) + if urls: + for url in urls: + resp = self._gal.getRespFromUrl(url) + ret.append(getItemFromResp(resp , self._gal , self)) + return ret + + def _getComments(self): + """ + Returns a list of the Comment items for this item + + returns(list[Comment]) : Returns a list of Comment objects + """ + ret = [] + # I can't use the shortcut I did for tags so I need to get the list + # of comments in the first call and then create the objects with + # the calls thereafter + commListUrl = self.relationships['comments']['url'] + resp = self._gal.getRespFromUrl(commListUrl) + tmpObj = json.loads(resp.read()) + for url in tmpObj['members']: + resp = self._gal.getRespFromUrl(url) + ret.append(getItemFromResp(resp , self._gal , self)) + return ret + + def _getUrlObject(self , url): + """ + This returns the album cover image + """ + resp = self._gal.getRespFromUrl(url) + return getItemFromResp(resp , self._gal , self) + + def getCrDT(self): + """ + Returns a datetime object for the time this item was created + """ + if hasattr(self , 'created'): + return datetime.fromtimestamp(int(self.created)) + return None + + def getUpdDT(self): + """ + Returns a datetime object for the time this item was last updated + """ + if hasattr(self , 'updated'): + return datetime.fromtimestamp(int(self.updated)) + return None + + def delete(self): + """ + Deletes this + + returns(tuple(status , msg)) : Returns a tuple of a boolean status + and a message if there is an error + """ + return self._gal.deleteItem(self) + + def update(self , title=None , description=None): + """ + Update either the title, the description or both + + title(str) : The new item title + description(str) : The new item description + + returns(tuple(status , msg)) : Returns a tuple of a boolean status + and a message if there is an error + """ + if title is not None: + self.title = title + if description is not None: + self.description = description + return self._gal.updateItem(self) + + def tag(self , tagName): + """ + Tag this item with the string "tagName" + + tagName(str) : The actual tag name + + returns(Tag) : The tag that was created + """ + return self._gal.tagItem(self , tagName) + +class Album(BaseRemote): + def addImage(self , image , title='' , description='' , name=''): + """ + Add a LocalImage object to the album + + image(LocalImage) : The image to upload + + returns(RemoteImage) : The RemoteImage object that was created + """ + if not isinstance(image , LocalImage): + raise TypeError('%r is not of type LocalImage' % image) + return self._gal.addImage(self , image , title , description , name) + + def addMovie(self , movie , name='' , title='' , description=''): + """ + Adds a LocalMovie object to the album + + movie(LocalMovie) : The movie to upload + + returns(RemoteMovie) : The RemoteMovie object that was created + """ + return self._gal.addMovie(self , movie , title , description , name) + + def addAlbum(self , albumName , title , description=''): + """ + Add a subalbum to this album + + albumName(str) : The name of the new album + title(str) : The album title + description(str): The album description + + returns(Album) : The Album object that was created + """ + return self._gal.addAlbum(self , albumName , title , description) + + def setCover(self , image): + """ + Sets the album cover to the RemoteImage + + image(RemoteImage) : The image to set as the album cover + + returns(tuple(status , msg)) : Returns a tuple of a boolean status + and a message if there is an error + """ + return self._gal.setAlbumCover(self , image) + + def getAlbums(self): + """ + Return a list of the sub-albums in this album + + returns(list[Album]) : A list of Album objects + """ + return self._getByType('album') + Albums = property(getAlbums) + + def getImages(self): + """ + Return a list of the images in this album + + returns(list[RemoteImage]) : A list of RemoteImages + """ + return self._getByType('photo') + Images = property(getImages) + + def getMovies(self): + """ + Return a list of the movies in this album + + returns(list[RemoteMovie]) : A list of RemoteMovie objects + """ + return self._getByType('movie') + Movies = property(getMovies) + + def getRandomImage(self , direct=True): + """ + Returns a random RemoteImage object for the album. If "direct" is + False, a random image can be pulled from nested albums. + + direct(bool) : If set to False, the image may be pulled from + a sub-album + + returns(RemoteImage) : Returns a RemoteImage instance + """ + return self._gal.getRandomImage(self , direct) + + def _getByType(self , t): + ret = [] + for m in self.members: + if m.type == t: + ret.append(m) + return ret + +class Image(object): + contentType = '' + +class LocalImage(Image): + def __init__(self , path , replaceSpaces=True): + if not os.path.isfile(path): + raise IOError('%s is not a file' % path) + self.path = path + self.replaceSpaces = replaceSpaces + self.Filename = os.path.basename(self.path) + self.fh = None + self.type = 'photo' + + def setContentType(self , ctype=None): + if ctype is not None: + self.contentType = ctype + self.contentType = mimetypes.guess_type(self.getFileContents())[0] or \ + 'application/octet-stream' + def getContentType(self): + if not self.contentType: + self.setContentType() + return self.contentType + ContentType = property(getContentType , setContentType) + + def setFilename(self , name): + self.filename = name + if self.replaceSpaces: + self.filename = self.filename.replace(' ' , '_') + def getFilename(self): + return self.filename + Filename = property(getFilename , setFilename) + + def getFileContents(self): + """ + Gets the entire contents of the file + + returns(str) : File contents + """ + if self.fh is None: + self.fh = open(self.path , 'rb') + self.fh.seek(0) + return self.fh.read() + + def getUploadContent(self): + """ + This will return a string containing the MIME headers and the actual + binary content to be uploaded + """ + ret = 'Content-Disposition: form-data; name="file"; ' + ret += 'filename="%s"\r\n' % self.filename + ret += 'Content-Type: %s\r\n' % self.ContentType + ret += 'Content-Transfer-Encoding: binary\r\n' + ret += '\r\n' + ret += self.getFileContents() + '\r\n' + return ret + + def close(self): + try: + self.fh.close() + except: + pass + +class RemoteImage(BaseRemote , Image): + def addComment(self , comment): + """ + Comment on this item with the string "comment" + + comment(str) : The comment + + returns(Comment) : The comment that was created + """ + return self._gal.addComment(self , comment) + + def read(self , length=None): + if not self.fh: + resp = self._gal.getRespFromUrl(self.file_url) + self.fh = resp + if length is None: + return self.fh.read() + return self.fh.read(int(length)) + + def close(self): + try: + self.fh.close() + except: + pass + + def getResizeHandle(self): + """ + Returns a file-like object (specifically a urllib2.addinfourl) handle + to the "resize" version of the image + + returns(urllib2.addinfourl) : A file-like object handle for retrieving + the resized image + """ + if hasattr(self , 'resize_url'): + resp = self._gal.getRespFromUrl(self.resize_url) + return resp + return None + + def getThumbHandle(self): + """ + Returns a file-like object (specifically a urllib2.addinfourl) handle + to the "thumbnail" version of the image + + returns(urllib2.addinfourl) : A file-like object handle for retrieving + the thumbnail image + """ + if hasattr(self , 'thumb_url'): + resp = self._gal.getRespFromUrl(self.thumb_url) + return resp + return None + +class LocalMovie(LocalImage): + def __init__(self , path , replaceSpaces=True): + LocalImage.__init__(self , path , replaceSpaces) + self.type = 'movie' + +class RemoteMovie(RemoteImage): + pass + +class Tag(BaseRemote): + """ + A simple class to represent a tag + """ + def __str__(self): + return self.name + + def _postInit(self): + if hasattr(self , 'count'): + self.count = int(self.count) + self.type = 'tag' + + def tag(self , tagName): + raise G3Error('You cannot tag a tag') + +class Comment(BaseRemote): + """ + A class to represent a comment + """ + def __str__(self): + return self.text + + def _postInit(self): + # Change the "item" attribute to "parent" since that's what it is + # I'm doing this to address overall consistency + self._parent = None + if hasattr(self , '_item'): + self._parent = getattr(self , '_item') + + def tag(self , tagName): + raise G3Error('You cannot tag a comment') + +def getItemFromResp(response , galObj , parent=None): + """ + Returns the appropriate item given the "addinfourl" response object from + the urllib2 request + + response(addinfourl|dict) : The response object from the urllib2 request + or a dict that has already been converted + (usually when called from getItemsFromResp) + galObj(Gallery3) : The gallery object this is associated with + parent(Album) : The parent object for this item + + returns(BaseRemote) : Returns an implemenation of BaseRemote + """ + galObj = weakref.ref(galObj) + if parent is not None: + parent = weakref.ref(parent) + if isinstance(response , dict): + respObj = response + else: + respObj = json.loads(response.read()) + if 'count' in respObj['entity']: + # This is a tag. It doesn't have the same items as regular objects + return Tag(respObj , galObj , parent) + if 'text' in respObj['entity']: + # This is a comment. It also does not have the same items as + # regular objects + return Comment(respObj , galObj , parent) + try: + t = respObj['entity']['type'] + except: + raise G3InvalidRespError('Response contains no "entity type": %r' % + response) + if t == 'album': + return Album(respObj , galObj , parent) + elif t == 'photo': + return RemoteImage(respObj , galObj , parent) + elif t == 'movie': + return RemoteMovie(respObj , galObj , parent) + else: + raise G3UnknownTypeError('Unknown entity type: %s' % t) + +def getItemsFromResp(response , galObj , parent=None): + """ + This takes the raw response with a list of items and returns a list of + the corresponding objects + + response(addinfourl|dict) : The response object from the urllib2 request + or a dict that has already been converted + (usually when called from getItemsFromResp) + galObj(Gallery3) : The gallery object this is associated with + parent(Album) : The parent object for this item + + returns(list[BaseRemote]) : Returns a list of BaseRemote objects + """ + ret = [] + lResp = json.loads(response.read()) + if not isinstance(lResp , list): + lResp = list(lResp) + for resp in lResp: + ret.append(getItemFromResp(resp , galObj , parent)) + return ret diff --git a/3.0/client/Python/pylibgal3/libg3/Gallery3.py b/3.0/client/Python/pylibgal3/libg3/Gallery3.py new file mode 100644 index 00000000..6345c1a8 --- /dev/null +++ b/3.0/client/Python/pylibgal3/libg3/Gallery3.py @@ -0,0 +1,464 @@ +# +# Author: Jay Deiman +# Email: admin@splitstreams.com +# +# This file is part of pylibgal3. +# +# pylibgal3 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. +# +# pylibgal3 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 pylibgal3. If not, see . +# + +__all__ = ['Gallery3' , 'login'] + +from Requests import * +from Errors import G3RequestError , G3UnknownError +from G3Items import getItemFromResp , getItemsFromResp , BaseRemote , Album , \ + RemoteImage , Tag +from urllib import quote , urlencode +from uuid import uuid4 +import urllib2 , os , json + +class Gallery3(object): + """ + This is the main utility class that should be instantiated and used for all + calls + """ + def __init__(self , host , apiKey , g3Base='/gallery3' , port=80 , + ssl=False): + """ + Initializes and sets up the gallery 3 object + + host(str) : The hostname of the gallery site + apiKey(str) : The api key to use for the connections + g3Base(str) : The remote url path to your gallery 3 install + (default: /gallery3) + port(int) : The port number to connect to (default: 80) + ssl(bool) : If true, use SSL for the connection (default: 80) + """ + self.host = host + self.apiKey = apiKey + self.port = int(port) + self.ssl = ssl + self.g3Base = g3Base.strip('/') + self.protocol = ('http' , 'https')[ssl] + self.root = None + self._rootUri = 'index.php/rest/item/1' + self._opener = None + self._buildOpener() + + def getRoot(self): + """ + Returns the root item (album) + """ + if self.root is None: + resp = self.getRespFromUri(self._rootUri) + self.root = getItemFromResp(resp , self) + return self.root + + def getRandomImage(self , album , direct=True): + """ + Returns a random RemoteImage object for the album. If "direct" is + False, a random image can be pulled from nested albums. + + album(Album) : The album object to pull the random image from + direct(bool) : If set to False, the image may be pulled from + a sub-album + + returns(RemoteImage) : Returns a RemoteImage instance + """ + scope = ('all' , 'direct')[direct] + data = { + 'type': 'photo' , + 'random': 'true' , + 'scope': scope , + } + url = '%s?%s' % (album.url , urlencode(data)) + resp = self.getRespFromUrl(url) + return getItemFromResp(resp , self) + + def getItemsForUrls(self , urls , parent=None): + """ + This retrieves an item for each url specified in the urls list + + urls(list[str]) : The list of urls to retrieve + + returns(list[BaseRemote]) : Returns a list of the corresponding + remote objects + """ + numUrls = len(urls) + start = 0 + increment = 25 + ret = [] + while start < numUrls: + data = { + 'urls': json.dumps(urls[start:start+increment]) , + 'num': str(increment) , + 'start': str(start) , + } + resp = self.getRespFromUri('index.php/rest/items' , data) + ret.extend(getItemsFromResp(resp , self , parent)) + start += increment + return ret + + def getRespFromUrl(self , url): + """ + This returns the response object given a full url rather than just a + uri defining the location on the server + + url(str) : The url to the resource + """ + req = GetRequest(url , self.apiKey) + resp = self._openReq(req) + return resp + + def getRespFromUri(self , uri , kwargs={}): + """ + Performs the request for the given uri and returns the "addinfourl" + response + + uri(str) : The uri string defining the resource on the defined host + """ + url = self._buildUrl(uri , kwargs) + print url + return self.getRespFromUrl(url) + + def addAlbum(self , parent , albumName , title , description=''): + """ + Adds an album to the given parent album + + parent(Album) : The parent Album object + albumName(str) : The name of the album + title(str) : The album title + description(str) : The album description + + returns(Album) : The Album object that was created + """ + if not parent.can_edit: + raise G3AuthError('You do not have permission to edit: %s' % + parent.title) + data = { + 'type': 'album' , + 'name': albumName , + 'title': title , + 'description': description , + } + req = PostRequest(parent.url , self.apiKey , data) + resp = self._openReq(req) + newObjUrl = self._getUrlFromResp(resp) + item = getItemFromResp(self.getRespFromUrl(newObjUrl) , self , parent) + parent._members.append(newObjUrl) + parent.members.append(item) + return item + + def addImage(self , parent , image , title='' , description='' , name=''): + """ + Add a LocalImage to the parent album. + + parent(Album) : The parent album to add the image to + image(LocalImage) : The local image to upload and add to the + parent + title(str) : The image title + description(str) : The image description + name(str) : The image file name + + returns(RemoteImage) : The RemoteImage instance for the item + uploaded + """ + if not parent.can_edit: + raise G3AuthError('You do not have permission to edit: %s' % + parent.title) + if name: + image.Filename = name + entity = { + 'name': image.filename , + 'type': image.type , + 'title': title , + 'description': description , + } + boundary = str(uuid4()) + headers = {'Content-Type': 'multipart/form-data; boundary=%s' % + boundary} + # this is more complicated than adding an album. We have to + # construct the upload MIME headers, including build the string + # data section + data = '--%s\r\n' % boundary + data += 'Content-Disposition: form-data; name="entity"\r\n' + data += 'Content-Type: text/plain; ' \ + 'charset=UTF-8\r\n' + data += 'Content-Transfer-Encoding: 8bit\r\n' + data += '\r\n' + data += '%s\r\n' % json.dumps(entity , separators=(',' , ':')) + data += '--%s\r\n' % boundary + data += image.getUploadContent() + data += '--%s--\r\n' % boundary + req = PostRequest(parent.url , self.apiKey , data , headers) + resp = self._openReq(req) + newObjUrl = self._getUrlFromResp(resp) + item = getItemFromResp(self.getRespFromUrl(newObjUrl) , self , parent) + parent._members.append(newObjUrl) + parent.members.append(item) + return item + + def addMovie(self , parent , movie , title='' , description='' , name=''): + """ + Add a LocalMovie to the parent album. + + parent(Album) : The parent album to add the movie to + image(LocalMovie) : The local movie to upload and add to the + parent + title(str) : The movie title + description(str) : The movie description + name(str) : The movie file name + + returns(RemoteMovie) : The RemoteMovie instance for the movie + uploaded + """ + return self.addImage(parent , movie , title , description , name) + + def setAlbumCover(self , album , image): + """ + Updates a remote item's title and description + + album(Album) : The album to set the cover on + image(RemoteImage) : The image to use as the cover + + returns(tuple(status , msg)) : Returns a tuple of a boolean status + and a message if there is an error + """ + if not album.can_edit: + raise G3AuthError('You do not have permission to edit: %s' % + album.title) + try: + self._isItemValid(album , Album) + self._isItemValid(image , RemoteImage) + except Exception , e: + return (False , str(e)) + data = { + 'album_cover': image.url , + } + req = PutRequest(album.url , self.apiKey , data) + try: + resp = self._openReq(req) + except G3RequestError , e: + return (False , str(e)) + album.album_cover = image + album._album_cover = image.url + return (True , '') + + def updateItem(self , item): + """ + Updates a remote item's title and description + + item(BaseRemote) : An item descended from BaseRemote + + returns(tuple(status , msg)) : Returns a tuple of a boolean status + and a message if there is an error + """ + if not item.can_edit: + raise G3AuthError('You do not have permission to edit: %s' % + item.title) + try: + self._isItemValid(item , BaseRemote) + except Exception , e: + return (False , str(e)) + data = { + 'title': item.title , + 'description': item.description , + } + req = PutRequest(item.url , self.apiKey , data) + try: + resp = self._openReq(req) + except G3RequestError , e: + return (False , str(e)) + return (True , '') + + def updateAlbum(self , album): + """ + Update the title and description for an album. + + image(Album) : Updates the title and/or description + for the Album + + returns(tuple(status , msg)) : Returns a tuple of a boolean status + and a message if there is an error + """ + return self.updateItem(album) + + def updateImage(self , image): + """ + Update the title and description for an image. + + image(RemoteImage) : Updates the title and/or description for the + RemoteImage + + returns(tuple(status , msg)) : Returns a tuple of a boolean status + and a message if there is an error + """ + return self.updateItem(image) + + def updateMovie(self , movie): + """ + Update the title and description for a movie. + + image(RemoteMovie) : Updates the title and/or description for the + RemoteMovie + + returns(tuple(status , msg)) : Returns a tuple of a boolean status + and a message if there is an error + """ + return self.updateItem(movie) + + def deleteItem(self , item): + """ + Deletes the given item. Item must be descended from BaseRemote. + + item(BaseRemote) : The item to delete + + returns(tuple(status , msg)) : Returns a tuple of a boolean status + and a message if there is an error + """ + if not item.can_edit: + raise G3AuthError('You do not have permission to edit: %s' % + item.title) + try: + self._isItemValid(item , BaseRemote) + except Exception , e: + return (False , e.message) + req = DeleteRequest(item.url , self.apiKey) + try: + resp = self._openReq(req) + except G3RequestError , e: + return (False , e.message) + return (True , '') + + def tagItem(self , item , tagName): + """ + Tag this item with the string "tagName" + + tagName(str) : The actual tag name + + returns(Tag) : The tag that was created + """ + # First we have to create the tag itself, if necessary + data = { + 'name': str(tagName) , + } + url = self._buildUrl('index.php/rest/tags') + req = PostRequest(url , self.apiKey , data) + resp = self._openReq(req) + r = json.loads(resp.read()) + tagUrl = r['url'] + # And now that we have our (possibly) newly created tag, we can + # use that to tag our item + data = { + 'tag': tagUrl , + 'item': item.url , + } + url = self._buildUrl('index.php/rest/item_tags/%s' % item.id) + req = PostRequest(url , self.apiKey , data) + resp = self._openReq(req) + respObj = json.loads(resp.read()) + item.relationships['tags']['members'].append(respObj['url']) + tag = Tag(respObj , self , item) + if hasattr(item , 'tags'): + item.tags.append(tag) + return tag + + def addComment(self , image , comment): + """ + Comment on this item with the string "comment" + + comment(str) : The comment + + returns(Comment) : The comment that was created + """ + data = { + 'item': image.url , + 'text': comment , + } + url = self._buildUrl('index.php/rest/comments') + req = PostRequest(url , self.apiKey , data) + resp = self._openReq(req) + commUrl = json.loads(resp.read())['url'] + resp = self.getRespFromUrl(commUrl) + comm = getItemFromResp(resp , self , image) + if hasattr(image , 'comments'): + image.comments.append(comm) + return comm + + def _buildOpener(self): + cp = urllib2.HTTPCookieProcessor() + self._opener = urllib2.build_opener(cp) + if self.ssl: + self._opener.add_handler(urllib2.HTTPSHandler()) + + def _buildUrl(self , resource , kwargs={}): + url = '%s://%s:%d/%s/%s' % (self.protocol , self.host , self.port , + quote(self.g3Base) , quote(resource)) + if kwargs: + url += '?%s' % urlencode(kwargs) + return url + + def _getUrlFromResp(self , resp): + d = json.loads(resp.read()) + return d['url'] + + def _openReq(self , req): + try: + resp = self._opener.open(req) + except urllib2.HTTPError , e: + err = json.loads(e.read()) + if isinstance(err , dict) and 'errors' in err: + raise G3RequestError(err['errors']) + else: + raise G3UnknownError('Unknown request error: %s' % e) + return resp + + def _isItemValid(self , item , cls): + if not isinstance(item , cls): + raise TypeError('Items to be modified must be descended from ' + '%s: %s' % (cls , type(item))) + if not 'url' in item.__dict__: + raise G3UnknownError('The object, %s, has no "url"' % item) + +def login(host , username , passwd , g3Base='/gallery3' , port=80 , + ssl=False): + """ + This will log you in and return a Gallery3 object on success, None + otherwise + + host(str) : The hostname of the gallery site + username(str) : The username to login with + passwd(str) : The password to login with + g3Base(str) : The remote url path to your gallery 3 install + (default: /gallery3) + port(int) : The port number to connect to (default: 80) + ssl(bool) : If true, use SSL for the connection (default: 80) + """ + data = { + 'user': username , + 'password': passwd , + } + protocol = ('http' , 'https')[ssl] + url = '%s://%s:%d/%s/index.php/rest' % (protocol , host , port , + quote(g3Base)) + req = PostRequest(url , None , urlencode(data)) + opener = urllib2.build_opener() + if ssl: + opener.add_handler(urllib2.HTTPSHandler()) + try: + resp = opener.open(req) + except urllib2.HTTPError , e: + return None + apiKey = resp.read().strip('\'"') + return Gallery3(host , apiKey , g3Base , port , ssl) diff --git a/3.0/client/Python/pylibgal3/libg3/Requests.py b/3.0/client/Python/pylibgal3/libg3/Requests.py new file mode 100644 index 00000000..7b0fedb6 --- /dev/null +++ b/3.0/client/Python/pylibgal3/libg3/Requests.py @@ -0,0 +1,72 @@ +# +# Author: Jay Deiman +# Email: admin@splitstreams.com +# +# This file is part of pylibgal3. +# +# pylibgal3 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. +# +# pylibgal3 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 pylibgal3. If not, see . +# + +__all__ = ['BaseRequest' , 'GetRequest' , 'PostRequest' , 'PutRequest' , + 'DeleteRequest'] + +from urllib2 import Request +from urllib import quote +import os , json , types + +class BaseRequest(Request): + def __init__(self , url , apiKey , data=None , headers={} , + origin_req_host=None , unverifiable=False): + if apiKey is not None: + headers['X-Gallery-Request-Key'] = apiKey + if data is not None: + if isinstance(data , dict): + data = 'entity=%s' % quote(json.dumps(data , + separators=(',' , ':'))) + elif type(data) not in types.StringTypes: + raise TypeError('Invalid type for data. It should be ' + 'a "dict" or "str", not %s' % type(data)) + headers['Content-Length'] = str(len(data)) + Request.__init__(self , url , data , headers , origin_req_host , + unverifiable) + +class GetRequest(BaseRequest): + def __init__(self , url , apiKey , data=None , headers={} , + origin_req_host=None , unverifiable=False): + headers['X-Gallery-Request-Method'] = 'get' + BaseRequest.__init__(self , url , apiKey , data , headers , + origin_req_host , unverifiable) + +class PostRequest(BaseRequest): + def __init__(self , url , apiKey , data , headers={} , + origin_req_host=None , unverifiable=False): + headers['X-Gallery-Request-Method'] = 'post' + if 'Content-Type' not in headers: + headers['Content-Type'] = 'application/x-www-form-urlencoded' + BaseRequest.__init__(self , url , apiKey , data , headers , + origin_req_host , unverifiable) + +class PutRequest(BaseRequest): + def __init__(self , url , apiKey , data=None , headers={} , + origin_req_host=None , unverifiable=False): + headers['X-Gallery-Request-Method'] = 'put' + BaseRequest.__init__(self , url , apiKey , data , headers , + origin_req_host , unverifiable) + +class DeleteRequest(BaseRequest): + def __init__(self , url , apiKey , data=None , headers={} , + origin_req_host=None , unverifiable=False): + headers['X-Gallery-Request-Method'] = 'delete' + BaseRequest.__init__(self , url , apiKey , data , headers , + origin_req_host , unverifiable) diff --git a/3.0/client/Python/pylibgal3/libg3/__init__.py b/3.0/client/Python/pylibgal3/libg3/__init__.py new file mode 100644 index 00000000..eec91668 --- /dev/null +++ b/3.0/client/Python/pylibgal3/libg3/__init__.py @@ -0,0 +1,24 @@ +# +# Author: Jay Deiman +# Email: admin@splitstreams.com +# +# This file is part of pylibgal3. +# +# pylibgal3 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. +# +# pylibgal3 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 pylibgal3. If not, see . +# + +from G3Items import * +from Gallery3 import * + +__version__ = '0.1.4' diff --git a/3.0/client/Python/pylibgal3/setup.py b/3.0/client/Python/pylibgal3/setup.py new file mode 100644 index 00000000..ba9d1d82 --- /dev/null +++ b/3.0/client/Python/pylibgal3/setup.py @@ -0,0 +1,36 @@ +#!/usr/bin/env python + +# +# Author: Jay Deiman +# Email: admin@splitstreams.com +# +# This file is part of pylibgal3. +# +# pylibgal3 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. +# +# pylibgal3 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 pylibgal3. If not, see . +# + + +from distutils.core import setup +from libg3 import __version__ as version +import sys + +setup(name='pylibgal3' , + version=version , + author='Jay Deiman' , + author_email='admin@splitstreams.com' , + url='http://stuffivelearned.org' , + description='A library for accessing/manipulating a Gallery 3 install' , + packages=['libg3'] , + package_dir={'libg3': 'libg3'} , +) diff --git a/3.0/modules/about/controllers/about.php b/3.0/modules/about/controllers/about.php new file mode 100644 index 00000000..473c99a9 --- /dev/null +++ b/3.0/modules/about/controllers/about.php @@ -0,0 +1,28 @@ +css("about.css"); + $template->page_title = t("Gallery :: About"); + $template->content = new View("about.html"); + print $template; + } +} \ No newline at end of file diff --git a/3.0/modules/about/controllers/admin_about.php b/3.0/modules/about/controllers/admin_about.php new file mode 100644 index 00000000..b476c925 --- /dev/null +++ b/3.0/modules/about/controllers/admin_about.php @@ -0,0 +1,61 @@ +_get_view(); + } + + public function handler() { + access::verify_csrf(); + + $form = $this->_get_form(); + if ($form->validate()) { + module::set_var( + "about", "code", $form->about->about_code->value); + module::set_var( + "about", "title", $form->about->about_title->value); + module::set_var ( + "about", "hidden", $form->about->about_hidden->value); + message::success(t("Your settings have been saved.")); + url::redirect("admin/about"); + } + + print $this->_get_view($form); + } + + private function _get_view($form=null) { + $v = new Admin_View("admin.html"); + $v->content = new View("admin_about.html"); + $v->content->form = empty($form) ? $this->_get_form() : $form; + return $v; + } + + private function _get_form() { + $form = new Forge("admin/about/handler", "", "post", array("id" => "g-admin-form")); + $group = $form->group("about"); + $group->input("about_title")->label(t('Enter the headline.'))->value(module::get_var("about", "title")); + $group->textarea("about_code")->label(t('Enter the standard HTML code you want on the page.'))->value(module::get_var("about", "code")); + $group->checkbox("about_hidden")->label(t("Hide link")) + ->checked(module::get_var("about", "hidden", false) == 1); + $group->submit("submit")->value(t("Save")); + + return $form; + } +} \ No newline at end of file diff --git a/3.0/modules/about/css/about.css b/3.0/modules/about/css/about.css new file mode 100644 index 00000000..17903b24 --- /dev/null +++ b/3.0/modules/about/css/about.css @@ -0,0 +1,2 @@ +table.about { text-align: center; width:500px; } +table.about caption { font-size: 1.5em; padding: 0.2em; } \ No newline at end of file diff --git a/3.0/themes/greydragon/helpers/exif_event.php b/3.0/modules/about/helpers/about_block.php similarity index 62% rename from 3.0/themes/greydragon/helpers/exif_event.php rename to 3.0/modules/about/helpers/about_block.php index 27b617a6..9dc85457 100644 --- a/3.0/themes/greydragon/helpers/exif_event.php +++ b/3.0/modules/about/helpers/about_block.php @@ -17,27 +17,23 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ -class exif_event_Core { - static function item_created($item) { - if (!$item->is_album()) { - exif::extract($item); +class about_block_Core { + static function get_site_list() { + return array("about" => t("About page")); + } + + static function get($block_id, $theme) { + $block = ""; + switch ($block_id) { + case "about": + if ($theme->item()) { + $block = new Block(); + $block->css_id = "g-metadata"; + $block->title = module::get_var("about", "title"); + $block->content = new View("about_block.html"); + } + break; } + return $block; } - - static function item_deleted($item) { - db::build() - ->delete("exif_records") - ->where("item_id", "=", $item->id) - ->execute(); - } - - static function photo_menu($menu, $theme) { - $item = $theme->item(); - $menu->append( - Menu::factory("link") - ->id("exifdata-link") - ->label(t("Photo Details")) - ->url(url::site("exif/show/$item->id")) - ->css_id("g-exifdata-link")); - } -} +} \ No newline at end of file diff --git a/3.0/modules/about/helpers/about_event.php b/3.0/modules/about/helpers/about_event.php new file mode 100644 index 00000000..e63aeb97 --- /dev/null +++ b/3.0/modules/about/helpers/about_event.php @@ -0,0 +1,37 @@ +get("settings_menu") + ->append(Menu::factory("link") + ->id("about_menu") + ->label(t("About page")) + ->url(url::site("admin/about"))); + } + + static function site_menu($menu, $theme) { + if (module::get_var("about", "hidden") != true) { + $menu->add_after("home", Menu::factory("link") + ->id("about") + ->label(t("About")) + ->url(url::site("about/"))); + } + } +} \ No newline at end of file diff --git a/3.0/modules/about/helpers/about_installer.php b/3.0/modules/about/helpers/about_installer.php new file mode 100644 index 00000000..9725986e --- /dev/null +++ b/3.0/modules/about/helpers/about_installer.php @@ -0,0 +1,26 @@ + +

+ \ No newline at end of file diff --git a/3.0/themes/greydragon/views/exif_sidebar.html.php b/3.0/modules/about/views/about_block.html.php similarity index 61% rename from 3.0/themes/greydragon/views/exif_sidebar.html.php rename to 3.0/modules/about/views/about_block.html.php index 115bfc86..3fecf5cc 100644 --- a/3.0/themes/greydragon/views/exif_sidebar.html.php +++ b/3.0/modules/about/views/about_block.html.php @@ -1 +1,2 @@ + \ No newline at end of file diff --git a/3.0/modules/about/views/admin_about.html.php b/3.0/modules/about/views/admin_about.html.php new file mode 100644 index 00000000..c341bdc4 --- /dev/null +++ b/3.0/modules/about/views/admin_about.html.php @@ -0,0 +1,5 @@ + +
+

+ +
diff --git a/3.0/modules/about_this_album/helpers/about_this_album_block.php b/3.0/modules/about_this_album/helpers/about_this_album_block.php new file mode 100644 index 00000000..aefafff5 --- /dev/null +++ b/3.0/modules/about_this_album/helpers/about_this_album_block.php @@ -0,0 +1,76 @@ + t("About This Album")); + } + + static function get($block_id, $theme) { + switch ($block_id) { + case "aboutthisalbum": + $item = $theme->item; + if ((!$item) or (!$theme->item->is_album())) { + return ""; + } + if ($theme->item->is_album()) { + $block = new Block(); + $block->css_id = "g-about-this-album"; + $block->content = new View("about_this_album.html"); + + if ($theme->item()->id == item::root()->id) { + $block->title = t("About this Site"); + $block->content->album_count = ORM::factory("item")->where("type", "=", "album")->where("id", "<>", 1)->count_all(); + $block->content->photo_count = ORM::factory("item")->where("type", "=", "photo")->count_all(); + $block->content->vcount = Database::instance()->query("SELECT SUM({items}.view_count) as c FROM {items} WHERE type=\"photo\"")->current()->c; + } Else { + $block->title = t("About this Album"); + $block->content->album_count = $item->descendants_count(array(array("type", "=", "album"))); + $block->content->photo_count = $item->descendants_count(array(array("type", "=", "photo"))); + // $block->content->vcount= $theme->item()->view_count; + $descds = $item->descendants(); + $descds_view = 0; + foreach ($descds as $descd) { + if ($descd->is_photo()) { + $descds_view += $descd->view_count; + } + } + $block->content->vcount = $descds_view; + if ($item->description) { + $block->content->description = html::clean($item->description); + } + } + + + $all_tags = ORM::factory("tag") + ->join("items_tags", "items_tags.tag_id", "tags.id") + ->join("items", "items.id", "items_tags.item_id", "LEFT") + ->where("items.parent_id", "=", $item->id) + ->order_by("tags.id", "ASC") + ->find_all(); + if (count($all_tags) > 0) { + $block->content->all_tags = $all_tags; + } + } + break; + } + return $block; + } +} diff --git a/3.0/modules/about_this_album/module.info b/3.0/modules/about_this_album/module.info new file mode 100644 index 00000000..19a0e6f1 --- /dev/null +++ b/3.0/modules/about_this_album/module.info @@ -0,0 +1,7 @@ +name = "About this Album" +description = "Show some simple, specific and useful info about a given album" +version = 1 +author_name = "" +author_url = "" +info_url = "http://codex.gallery2.org/Gallery3:Modules:about_this_album" +discuss_url = "http://gallery.menalto.com/forum_module_about_this_album" diff --git a/3.0/modules/about_this_album/views/about_this_album.html.php b/3.0/modules/about_this_album/views/about_this_album.html.php new file mode 100644 index 00000000..01dee4f7 --- /dev/null +++ b/3.0/modules/about_this_album/views/about_this_album.html.php @@ -0,0 +1,68 @@ + + + diff --git a/3.0/modules/about_this_photo/helpers/about_this_photo_block.php b/3.0/modules/about_this_photo/helpers/about_this_photo_block.php new file mode 100644 index 00000000..267f3904 --- /dev/null +++ b/3.0/modules/about_this_photo/helpers/about_this_photo_block.php @@ -0,0 +1,71 @@ + t("About This Photo")); + } + + static function get($block_id, $theme) { + $block = new Block(); + switch ($block_id) { + case "simple": + $item = $theme->item; + if ((!$item) or (!$item->is_photo())) { + return ""; + } + $block->css_id = "g-about-this-photo"; + $block->title = t("About this photo"); + $block->content = new View("about_this_photo.html"); + + // exif API doesn't give easy access to individual keys, so do this the hard way + if (module::is_active("exif")) { + $exif = ORM::factory("exif_record")->where("item_id", "=", $theme->item()->id)->find(); + if ($exif->loaded()) { + $exif = unserialize($exif->data); + $timestamp = strtotime($exif["DateTime"]); + //$block->content->date = gallery::date($timestamp); + $block->content->date = date('D j M Y', $timestamp); + $block->content->time = gallery::time($timestamp); + } + } + + $block->content->vcount = $theme->item()->view_count; + + // IPTC - copied more or less from iptc.php + if (module::is_active("iptc")) { + $record = ORM::factory("iptc_record")->where("item_id", "=", $theme->item()->id)->find(); + if ($record->loaded()) { + $record = unserialize($record->data); + $block->content->name = $record["ObjectName"]; + $block->content->caption = $record["Caption"]; + + } + } + + if (module::is_active("tag")) { + $block->content->tags = tag::item_tags($theme->item()); + } + break; + } + return $block; + } +} + diff --git a/3.0/modules/about_this_photo/module.info b/3.0/modules/about_this_photo/module.info new file mode 100644 index 00000000..876b111b --- /dev/null +++ b/3.0/modules/about_this_photo/module.info @@ -0,0 +1,7 @@ +name = "About this Photo" +description = "Show some simple, specific and useful info about a given photo" +version = 3 +author_name = "" +author_url = "" +info_url = "http://codex.gallery2.org/Gallery3:Modules:about_this_photo" +discuss_url = "http://gallery.menalto.com/forum_module_about_this_photo" diff --git a/3.0/modules/about_this_photo/views/about_this_photo.html.php b/3.0/modules/about_this_photo/views/about_this_photo.html.php new file mode 100644 index 00000000..f0ef130a --- /dev/null +++ b/3.0/modules/about_this_photo/views/about_this_photo.html.php @@ -0,0 +1,34 @@ + + + diff --git a/3.0/modules/addthis/config/addthis.php b/3.0/modules/addthis/config/addthis.php new file mode 100644 index 00000000..04e314c9 --- /dev/null +++ b/3.0/modules/addthis/config/addthis.php @@ -0,0 +1,29 @@ + email address that appears as the from address + * line-length => word wrap length (PHP documentations suggest no larger tha 70 characters + * reply-to => what goes into the reply to header + */ +$config["ranges"] = array( + "Addthis1" => array("low" => "65.249.152.0", "high" => "65.249.159.255"), + "Addthis2" => array("low" => "208.122.55.0", "high" => "208.122.55.255") +); diff --git a/3.0/modules/addthis/controllers/addthis.php b/3.0/modules/addthis/controllers/addthis.php new file mode 100644 index 00000000..6e55a17b --- /dev/null +++ b/3.0/modules/addthis/controllers/addthis.php @@ -0,0 +1,123 @@ +file_url(true); + $thumb_url = $item->thumb_url(true); + } else { + $proxy = ORM::factory("addthis_proxy"); + $proxy->uuid = md5(rand()); + $proxy->item_id = $item->id; + $proxy->save(); + $full_url = url::abs_site("addthis/print_proxy/full/$proxy->uuid"); + $thumb_url = url::abs_site("addthis/print_proxy/thumb/$proxy->uuid"); + } + + $v = new View("addthis_form.html"); + $v->order_parms = array( + "addthis_api_version" => "100", + "company_id" => module::get_var("addthis", "company_id"), + "event_id" => module::get_var("addthis", "event_id"), + "cmd" => "addimg", + "partner_code" => "69", + "return_url" => url::abs_site("addthis/close_window"), + "num_images" => "1", + "image_1" => $full_url, + "thumb_1" => $thumb_url, + "image_height_1" => $item->height, + "image_width_1" => $item->width, + "thumb_height_1" => $item->thumb_height, + "thumb_width_1" => $item->thumb_width, + "title_1" => html::purify($item->title)); + + print $v; + } + + public function print_proxy($type, $id) { + // If its a request for the full size then make sure we are coming from an + // authorized address + if ($type == "full") { + $remote_addr = ip2long($this->input->server("REMOTE_ADDR")); + if ($remote_addr === false) { + Kohana::show_404(); + } + $config = Kohana::config("addthis"); + + $authorized = false; + foreach ($config["ranges"] as $ip_range) { + $low = ip2long($ip_range["low"]); + $high = ip2long($ip_range["high"]); + $authorized = $low !== false && $high !== false && + $low <= $remote_addr && $remote_addr <= $high; + if ($authorized) { + break; + } + } + if (!$authorized) { + Kohana::show_404(); + } + } + + $proxy = ORM::factory("addthis_proxy", array("uuid" => $id)); + if (!$proxy->loaded || !$proxy->item->loaded) { + Kohana::show_404(); + } + + $file = $type == "full" ? $proxy->item->file_path() : $proxy->item->thumb_path(); + if (!file_exists($file)) { + kohana::show_404(); + } + + // We don't need to save the session for this request + Session::abort_save(); + + if (!TEST_MODE) { + // Dump out the image + header("Content-Type: $proxy->item->mime_type"); + Kohana::close_buffers(false); + $fd = fopen($file, "rb"); + fpassthru($fd); + fclose($fd); + + // If the request was for the image and not the thumb, then delete the proxy. + if ($type == "full") { + $proxy->delete(); + } + } + + $this->_clean_expired(); + } + + public function close_window() { + print ""; + } + + private function _clean_expired() { + Database::instance()->query( + "DELETE FROM {addthis_proxies} " . + "WHERE request_date <= (CURDATE() - INTERVAL 10 DAY) " . + "LIMIT 20"); + } +} \ No newline at end of file diff --git a/3.0/modules/addthis/controllers/admin_addthis.php b/3.0/modules/addthis/controllers/admin_addthis.php new file mode 100644 index 00000000..9c537b00 --- /dev/null +++ b/3.0/modules/addthis/controllers/admin_addthis.php @@ -0,0 +1,26 @@ +content = new View("admin_addthis.html"); + print $v; + } +} \ No newline at end of file diff --git a/3.0/modules/addthis/css/addthis_menu.css b/3.0/modules/addthis/css/addthis_menu.css new file mode 100644 index 00000000..b1deae01 --- /dev/null +++ b/3.0/modules/addthis/css/addthis_menu.css @@ -0,0 +1,3 @@ +#g-view-menu #g-addthis-link { + background-image: url('../images/addthis_logo.png'); +} diff --git a/3.0/modules/addthis/helpers/addthis_event.php b/3.0/modules/addthis/helpers/addthis_event.php new file mode 100644 index 00000000..c0415564 --- /dev/null +++ b/3.0/modules/addthis/helpers/addthis_event.php @@ -0,0 +1,48 @@ +get("settings_menu") + ->append(Menu::factory("link") + ->id("addthis_menu") + ->label(t("AddThis")) + ->url(url::site("admin/addthis"))); + } + + static function photo_menu($menu, $theme) { + $item = $theme->item(); + $menu->append(Menu::factory("link") + ->id("addthis") + ->label(t("Bookmark and Share: $item->title")) + ->url("") + ->css_id("g-addthis-link") + ->css_class("addthis_button")); + } + + static function album_menu($menu, $theme) { + $item = $theme->item(); + $menu->append(Menu::factory("link") + ->id("addthis") + ->label(t("Bookmark and Share: $item->title")) + ->url("") + ->css_id("g-addthis-link") + ->css_class("addthis_button")); + } +} diff --git a/3.1/themes/greydragon/helpers/greydragon_event.php b/3.0/modules/addthis/helpers/addthis_installer.php similarity index 54% rename from 3.1/themes/greydragon/helpers/greydragon_event.php rename to 3.0/modules/addthis/helpers/addthis_installer.php index 6f84512d..ac401eb6 100644 --- a/3.1/themes/greydragon/helpers/greydragon_event.php +++ b/3.0/modules/addthis/helpers/addthis_installer.php @@ -17,25 +17,29 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ -class greydragon_event_Core { +class addthis_installer { + static function install() { + Database::instance() + ->query("CREATE TABLE {addthis_proxies} ( + `id` int(9) NOT NULL AUTO_INCREMENT, + `uuid` char(32) NOT NULL, + `request_date` TIMESTAMP NOT NULL DEFAULT current_timestamp, + `item_id` int(9) NOT NULL, + PRIMARY KEY (`id`)) + DEFAULT CHARSET=utf8;"); - static function site_menu($menu, $theme) { - $submenu = $menu->get("add_menu"); - if (!empty($submenu)) { - $item = $submenu->get("add_photos_item"); - if (!empty($item)) { $item->css_class("ui-icon-plus"); } + module::set_var("addthis", "username", ""); + module::set_version("addthis", 1); + } - $item = $submenu->get("add_album_item"); - if (!empty($item)) { $item->css_class("ui-icon-note"); } - } - - $submenu = $menu->get("options_menu"); - if (!empty($submenu)) { - $item = $submenu->get("edit_item"); - if (!empty($item)) { $item->css_class("ui-icon-pencil"); } - - $item = $submenu->get("edit_permissions"); - if (!empty($item)) { $item->css_class("ui-icon-key"); } + static function upgrade($version) { + if ($version == 1) { + module::set_version("addthis", $version = 1); } } + + static function uninstall() { + Database::instance()->query("DROP TABLE IF EXISTS {addthis_proxies}"); + module::delete("addthis"); + } } diff --git a/3.0/modules/addthis/helpers/addthis_theme.php b/3.0/modules/addthis/helpers/addthis_theme.php new file mode 100644 index 00000000..7308954e --- /dev/null +++ b/3.0/modules/addthis/helpers/addthis_theme.php @@ -0,0 +1,29 @@ +css("addthis_menu.css"); + return "\n" . + ""; + } +} diff --git a/3.0/modules/addthis/images/addthis_logo.png b/3.0/modules/addthis/images/addthis_logo.png new file mode 100644 index 00000000..39372a0c Binary files /dev/null and b/3.0/modules/addthis/images/addthis_logo.png differ diff --git a/3.0/modules/addthis/models/addthis_proxy.php b/3.0/modules/addthis/models/addthis_proxy.php new file mode 100644 index 00000000..dd7ff120 --- /dev/null +++ b/3.0/modules/addthis/models/addthis_proxy.php @@ -0,0 +1,22 @@ + +
+ " alt="Add This logo" class="g-right"/> +

+
+

+ +AddThis uses services to provide an intelligent, optimized sharing menu that is designed to offer the right options at the right time and maximize distribution of your content - everywhere.") ?> +

+
    +
  • + +
  • +
+

+ register with Add This and enter your addthis username in the Advanced Settings page you can get Analytics. Example data below.", + array("signup_url" => "http://www.addthis.com/register", + "advanced_settings_url" => html::mark_clean(url::site("admin/advanced_settings")))) ?> +

+
+
+
diff --git a/3.0/modules/adsense/controllers/admin_adsense.php b/3.0/modules/adsense/controllers/admin_adsense.php index 13be83d8..05f0c6ad 100644 --- a/3.0/modules/adsense/controllers/admin_adsense.php +++ b/3.0/modules/adsense/controllers/admin_adsense.php @@ -1,7 +1,7 @@ content = new View("admin_albumpassword.html"); + + // Generate a form for controlling the admin section. + $view->content->albumpassword_form = $this->_get_admin_form(); + + // Display the page. + print $view; + } + + private function _get_admin_form() { + // Make a new form for changing admin settings for this module. + $form = new Forge("admin/albumpassword/saveprefs", "", "post", + array("id" => "g-album-password-admin-form")); + + // Should protected items be hidden, or completely in-accessable? + $albumpassword_group = $form->group("album_password_group"); + $albumpassword_group->checkbox("hideonly") + ->label(t("Do not require passwords")) + ->checked(module::get_var("albumpassword", "hideonly")); + + // Add a save button to the form. + $albumpassword_group->submit("save_settings")->value(t("Save")); + + // Return the newly generated form. + return $form; + } + + public function saveprefs() { + // Save user specified preferences. + + // Prevent Cross Site Request Forgery + access::verify_csrf(); + + // Retrieve submitted form data. + if (Input::instance()->post("hideonly") == false) { + module::set_var("albumpassword", "hideonly", false); + } else { + module::set_var("albumpassword", "hideonly", true); + } + // Display a success message and redirect back to the TagsMap admin page. + message::success(t("Your settings have been saved.")); + url::redirect("admin/albumpassword"); + } +} diff --git a/3.0/modules/albumpassword/controllers/albumpassword.php b/3.0/modules/albumpassword/controllers/albumpassword.php index b014b749..bf79698d 100644 --- a/3.0/modules/albumpassword/controllers/albumpassword.php +++ b/3.0/modules/albumpassword/controllers/albumpassword.php @@ -1,7 +1,7 @@ where("album_id", "=", $id)->find(); - if ($existing_password->loaded()) { + // Check for and delete the password and any cached ids assigned to it. + $existing_password = ORM::factory("items_albumpassword")->where("album_id", "=", $id)->find_all(); + if (count($existing_password) > 0) { + foreach ($existing_password as $one_password) { + db::build()->delete("albumpassword_idcaches")->where("password_id", "=", $one_password->id)->execute(); + } db::build()->delete("items_albumpasswords")->where("album_id", "=", $id)->execute(); message::success(t("Password Removed.")); } @@ -68,11 +71,14 @@ class albumpassword_Controller extends Controller { // Convert submitted data to local variables. $album_id = Input::instance()->post("item_id"); - $album_password = Input::instance()->post("assignpassword_password"); + $album_password = strtolower(Input::instance()->post("assignpassword_password")); - // Check for, and remove, any existing passwords. - $existing_password = ORM::factory("items_albumpassword")->where("album_id", "=", $album_id)->find(); - if ($existing_password->loaded()) { + // Check for, and remove, any existing passwords and cached ids. + $existing_password = ORM::factory("items_albumpassword")->where("album_id", "=", $album_id)->find_all(); + if (count($existing_password) > 0) { + foreach ($existing_password as $one_password) { + db::build()->delete("albumpassword_idcaches")->where("password_id", "=", $one_password->id)->execute(); + } db::build()->delete("items_albumpasswords")->where("album_id", "=", $album_id)->execute(); } @@ -82,6 +88,25 @@ class albumpassword_Controller extends Controller { $new_password->password = $album_password; $new_password->save(); + // Add the album to the id cache. + $cached_album = ORM::factory("albumpassword_idcache"); + $cached_album->password_id = $new_password->id; + $cached_album->item_id = $album_id; + $cached_album->save(); + + // Check for any sub-items within the album, add all of them to the id cache. + $items = ORM::factory("item", $album_id) + ->viewable() + ->descendants(); + if (count($items) > 0) { + foreach ($items as $one_item) { + $cached_item = ORM::factory("albumpassword_idcache"); + $cached_item->password_id = $new_password->id; + $cached_item->item_id = $one_item->id; + $cached_item->save(); + } + } + // Display a success message and close the dialog. message::success(t("Password saved.")); json::reply(array("result" => "success")); @@ -90,6 +115,7 @@ class albumpassword_Controller extends Controller { public function logout() { // Delete a stored password cookie. cookie::delete("g3_albumpassword"); + cookie::delete("g3_albumpassword_id"); url::redirect(url::abs_site("albums/1")); } @@ -100,7 +126,7 @@ class albumpassword_Controller extends Controller { access::verify_csrf(); // Convert submitted data to local variables. - $album_password = Input::instance()->post("albumpassword_password"); + $album_password = strtolower(Input::instance()->post("albumpassword_password")); // See if the submitted password matches any in the database. $existing_password = ORM::factory("items_albumpassword") @@ -110,6 +136,7 @@ class albumpassword_Controller extends Controller { if (count($existing_password) > 0) { // If the password if valid, then store it, and display a success message. // If not, close the dialog and display a rejected message. + cookie::delete("g3_albumpassword_id"); cookie::set("g3_albumpassword", $album_password); message::success(t("Password Accepted.")); json::reply(array("result" => "success")); @@ -129,7 +156,7 @@ class albumpassword_Controller extends Controller { $assignpassword_group->input("assignpassword_password") ->id('assignpassword_password') ->label(t("Password:")); - $form->submit("save_password")->value(t("Save")); + $assignpassword_group->submit("save_password")->value(t("Save")); // Return the newly generated form. return $form; @@ -139,12 +166,14 @@ class albumpassword_Controller extends Controller { // Generate a form for allowing visitors to enter in their passwords. $form = new Forge("albumpassword/checkpassword", "", "post", array("id" => "g-login-password-form")); + $assignpassword_group = $form->group("Enter Password") ->label(t("Enter Password:")); - $assignpassword_group->input("albumpassword_password") + $assignpassword_group->password("albumpassword_password") ->id('albumpassword_password') ->label(t("Password:")); - $form->submit("login_password")->value(t("Login")); + + $assignpassword_group->submit("")->value(t("Login")); // Return the newly generated form. return $form; diff --git a/3.0/modules/albumpassword/helpers/MY_access.php b/3.0/modules/albumpassword/helpers/MY_access.php new file mode 100644 index 00000000..bda1db32 --- /dev/null +++ b/3.0/modules/albumpassword/helpers/MY_access.php @@ -0,0 +1,49 @@ +where("item_id", "=", $item->id)->order_by("cache_id")->find_all(); + if (count($item_protected) > 0) { + $existing_password = ORM::factory("items_albumpassword")->where("id", "=", $item_protected[0]->password_id)->find(); + if ($existing_password->loaded()) { + if ((cookie::get("g3_albumpassword") != $existing_password->password) && + (identity::active_user()->id != $item->owner_id) && + (!identity::active_user()->admin)) { + throw new Kohana_404_Exception(); + } + } + } + } + } +} diff --git a/3.0/modules/albumpassword/helpers/MY_item.php b/3.0/modules/albumpassword/helpers/MY_item.php index 3e09a64d..07f81906 100644 --- a/3.0/modules/albumpassword/helpers/MY_item.php +++ b/3.0/modules/albumpassword/helpers/MY_item.php @@ -1,7 +1,7 @@ where("id", "=", $model->id)->find(); - // Figure out if the user can access this album. - $deny_access = false; - $existing_password = ORM::factory("items_albumpassword")->where("album_id", "=", $model->id)->find(); - if ($existing_password->loaded()) { - if ((cookie::get("g3_albumpassword") != $existing_password->password) && - (identity::active_user()->id != $album_item->owner_id)) - $deny_access = true; - } + // If the user is an admin, don't hide anything anything. + // If not, hide whatever is restricted by an album password + // that the current user is not the owner of. + if (!identity::active_user()->admin) { - // set access::DENY if necessary. - if ($deny_access == true) { - $view_restrictions = array(); - if (!identity::active_user()->admin) { - foreach (identity::group_ids_for_active_user() as $id) { - $view_restrictions[] = array("items.view_$id", "=", access::DENY); + // Display items that are not in idcaches. + $model->and_open()->join("albumpassword_idcaches", "items.id", "albumpassword_idcaches.item_id", "LEFT OUTER") + ->and_where("albumpassword_idcaches.item_id", "IS", NULL); + + // If in hide only mode, check and see if the current item is protected. + // If it is, log the user in with the password to view it. + if (module::get_var("albumpassword", "hideonly") == true) { + $existing_cacheditem = ORM::factory("albumpassword_idcache")->where("item_id", "=", $model->id)->order_by("cache_id")->find_all(); + if (count($existing_cacheditem) > 0) { + $existing_cacheditem_password = ORM::factory("items_albumpassword")->where("id", "=", $existing_cacheditem[0]->password_id)->find_all(); + if (cookie::get("g3_albumpassword") != $existing_cacheditem_password[0]->password) { + cookie::set("g3_albumpassword", $existing_cacheditem_password[0]->password); + cookie::set("g3_albumpassword_id", $existing_cacheditem_password[0]->id); + $model->or_where("albumpassword_idcaches.password_id", "=", $existing_cacheditem_password[0]->id); + } } } - } - if (count($view_restrictions)) { - $model->and_open()->merge_or_where($view_restrictions)->close(); + + // ... Unless their password id corresponds with a valid password. + $existing_password = ORM::factory("items_albumpassword")->where("password", "=", cookie::get("g3_albumpassword"))->find_all(); + if (count($existing_password) > 0) { + foreach ($existing_password as $one_password) { + if (cookie::get("g3_albumpassword_id") != "") { + if (cookie::get("g3_albumpassword_id") == $one_password->id) { + $model->or_where("albumpassword_idcaches.password_id", "=", $one_password->id); + } + } else { + $model->or_where("albumpassword_idcaches.password_id", "=", $one_password->id); + } + } + } + + // Or the current user is the owner of the item. + $model->or_where("items.owner_id", "=", identity::active_user()->id)->close(); } return $model; diff --git a/3.0/modules/albumpassword/helpers/albumpassword_event.php b/3.0/modules/albumpassword/helpers/albumpassword_event.php index dd83c4d9..b6b93e81 100644 --- a/3.0/modules/albumpassword/helpers/albumpassword_event.php +++ b/3.0/modules/albumpassword/helpers/albumpassword_event.php @@ -1,7 +1,7 @@ id("albumpassword_login") ->css_id("g-album-password-login") ->url(url::site("albumpassword/login")) - ->label(t("Enter password"))); + ->label(t("Unlock albums"))); } else { // If a password has been entered already // display the log out link, and links to the protected albums @@ -48,9 +48,17 @@ class albumpassword_event_Core { ->css_id("g-album-password-logout") ->url(url::site("albumpassword/logout")) ->label(t("Clear password"))); - $existing_password = ORM::factory("items_albumpassword") + $existing_password = ""; + if (cookie::get("g3_albumpassword_id") != "") { + $existing_password = ORM::factory("items_albumpassword") + ->where("password", "=", cookie::get("g3_albumpassword")) + ->where("id", "=", cookie::get("g3_albumpassword_id")) + ->find_all(); + } else { + $existing_password = ORM::factory("items_albumpassword") ->where("password", "=", cookie::get("g3_albumpassword")) ->find_all(); + } if (count($existing_password) > 0) { $counter = 0; while ($counter < count($existing_password)) { @@ -80,25 +88,71 @@ class albumpassword_event_Core { ->label(t("Remove password")) ->css_id("g-album-password-remove") ->url(url::site("albumpassword/remove/" . $item->id))); - } else { - $menu->get("options_menu") - ->append(Menu::factory("dialog") - ->id("albumpassword_assign") - ->label(t("Assign password")) - ->css_id("g-album-password-assign") - ->url(url::site("albumpassword/assign/" . $item->id))); + } elseif ($item->id != 1) { + $passworded_subitems = ORM::factory("item", $item->id) + ->and_open()->join("albumpassword_idcaches", "items.id", "albumpassword_idcaches.item_id", "LEFT OUTER") + ->where("albumpassword_idcaches.item_id", "IS NOT", NULL)->close() + ->descendants(); + + $existing_cacheditem = ORM::factory("albumpassword_idcache")->where("item_id", "=", $item->id)->order_by("cache_id")->find_all(); + if ((count($existing_cacheditem) == 0) && count($passworded_subitems) == 0) { + $menu->get("options_menu") + ->append(Menu::factory("dialog") + ->id("albumpassword_assign") + ->label(t("Assign password")) + ->css_id("g-album-password-assign") + ->url(url::site("albumpassword/assign/" . $item->id))); + } } } } } static function item_deleted($item) { - // If an album is deleted, remove any associated passwords. - $existingPasswords = ORM::factory("items_albumpassword") - ->where("album_id", "=", $item->id) - ->find_all(); - if (count($existingPasswords) > 0) { - db::build()->delete("items_albumpassword")->where("album_id", "=", $item->id)->execute(); + // Check for and delete the password and any cached ids assigned to it. + $existing_password = ORM::factory("items_albumpassword")->where("album_id", "=", $item->id)->find_all(); + if (count($existing_password) > 0) { + foreach ($existing_password as $one_password) { + db::build()->delete("albumpassword_idcaches")->where("password_id", "=", $one_password->id)->execute(); + } + db::build()->delete("items_albumpasswords")->where("album_id", "=", $item->id)->execute(); + message::success(t("Password Removed.")); + } else { + db::build()->delete("albumpassword_idcaches")->where("item_id", "=", $item->id)->execute(); } } + + static function item_created($item) { + // Check for any already existing password on parent album(s), if found, generate cache data for the new item. + $existing_password = ORM::factory("albumpassword_idcache")->where("item_id", "=", $item->parent_id)->order_by("cache_id")->find_all(); + if (count($existing_password) > 0) { + $new_cachedid = ORM::factory("albumpassword_idcache"); + $new_cachedid->password_id = $existing_password[0]->password_id; + $new_cachedid->item_id = $item->id; + $new_cachedid->save(); + } + } + + static function item_moved($item, $old_parent) { + // Delete any existing cache data. + db::build()->delete("albumpassword_idcaches")->where("item_id", "=", $item->id)->execute(); + + // Check for a password on the new parent, generate cache data if necessary. + $existing_password = ORM::factory("albumpassword_idcache")->where("item_id", "=", $item->parent_id)->order_by("cache_id")->find_all(); + if (count($existing_password) > 0) { + $new_cachedid = ORM::factory("albumpassword_idcache"); + $new_cachedid->password_id = $existing_password[0]->password_id; + $new_cachedid->item_id = $item->id; + $new_cachedid->save(); + } + } + + static function admin_menu($menu, $theme) { + // Add a link to the Album Password admin page to the Content menu. + $menu->get("settings_menu") + ->append(Menu::factory("link") + ->id("albumpassword") + ->label(t("Album Password Settings")) + ->url(url::site("admin/albumpassword"))); + } } diff --git a/3.0/modules/albumpassword/helpers/albumpassword_installer.php b/3.0/modules/albumpassword/helpers/albumpassword_installer.php index e59faffb..93a6d0c0 100644 --- a/3.0/modules/albumpassword/helpers/albumpassword_installer.php +++ b/3.0/modules/albumpassword/helpers/albumpassword_installer.php @@ -1,7 +1,7 @@ query("CREATE TABLE IF NOT EXISTS {albumpassword_idcaches} ( + `cache_id` int(9) NOT NULL auto_increment, + `password_id` int(9) NOT NULL, + `item_id` int(9) NOT NULL, + PRIMARY KEY (`cache_id`)) + DEFAULT CHARSET=utf8;"); + + // Set the default value for this module's behavior. + module::set_var("albumpassword", "hideonly", true); // Set the module's version number. - module::set_version("albumpassword", 1); + module::set_version("albumpassword", 3); + } + + static function upgrade($version) { + $db = Database::instance(); + if ($version == 1) { + // Set the default value for this module's behavior. + module::set_var("albumpassword", "hideonly", true); + module::set_version("albumpassword", $version = 2); + } + if ($version == 2) { + // Create a table to store a list of all protected items in. + $db->query("CREATE TABLE IF NOT EXISTS {albumpassword_idcaches} ( + `cache_id` int(9) NOT NULL auto_increment, + `password_id` int(9) NOT NULL, + `item_id` int(9) NOT NULL, + PRIMARY KEY (`cache_id`)) + DEFAULT CHARSET=utf8;"); + module::set_version("albumpassword", $version = 3); + } } static function uninstall() { // Delete the password table before uninstalling. $db = Database::instance(); - $db->query("DROP TABLE IF EXISTS {items_albumpassword};"); + $db->query("DROP TABLE IF EXISTS {items_albumpasswords};"); + $db->query("DROP TABLE IF EXISTS {albumpassword_idcaches};"); module::delete("albumpassword"); } } diff --git a/3.0/modules/albumpassword/helpers/albumpassword_task.php b/3.0/modules/albumpassword/helpers/albumpassword_task.php new file mode 100644 index 00000000..07f620e1 --- /dev/null +++ b/3.0/modules/albumpassword/helpers/albumpassword_task.php @@ -0,0 +1,197 @@ +join("albumpassword_idcaches", "items_albumpasswords.id", "albumpassword_idcaches.password_id", "LEFT OUTER") + ->and_where("albumpassword_idcaches.password_id", "IS", NULL)->count_all(); + + $tasks = array(); + + $tasks[] = Task_Definition::factory() + ->callback("albumpassword_task::update_idcaches") + ->name(t("Rebuild Album Password ID Caches DB")) + ->description(t("Logs the contents of all protected albums into the db.")) + ->severity($bad_albums ? log::WARNING : log::SUCCESS); + + $tasks[] = Task_Definition::factory() + ->callback("albumpassword_task::lowercase_passwords") + ->name(t("Fix Password DB Casing")) + ->description(t("Fixes case sensitivity issues.")) + ->severity(log::SUCCESS); + + return $tasks; + } + + static function lowercase_passwords($task) { + // Converts all passwords to lower case. + + $start = microtime(true); + $total = $task->get("total"); + $existing_passwords = ORM::factory("items_albumpassword")->find_all(); + + if (empty($total)) { + // Set the initial values for all variables. + $task->set("total", count($existing_passwords)); + $total = $task->get("total"); + $task->set("last_password_id", 0); + $task->set("completed_passwords", 0); + } + + // Retrieve the values for variables from the last time this + // function was run. + $last_password_id = $task->get("last_password_id"); + $completed_passwords = $task->get("completed_passwords"); + + foreach (ORM::factory("items_albumpassword") + ->where("id", ">", $last_password_id) + ->order_by("id") + ->find_all(100) as $one_password) { + $one_password->password = strtolower($one_password->password); + $one_password->save(); + + $last_password_id = $one_password->id; + $completed_passwords++; + + if ($completed_passwords == count($existing_passwords) || microtime(true) - $start > 1.5) { + break; + } + } + + $task->set("last_password_id", $last_password_id); + $task->set("completed_passwords", $completed_passwords); + + if ($completed_passwords == count($existing_passwords)) { + $task->done = true; + $task->state = "success"; + $task->percent_complete = 100; + } else { + $task->percent_complete = round(100 * $completed_passwords / count($existing_passwords)); + } + $task->status = t2("One password fixed", "%count / %total passwords fixed", $completed_passwords, + array("total" => count($existing_passwords))); + } + + static function update_idcaches($task) { + // Populate the idcaches table with the contents of all protected albums. + + $start = microtime(true); + $total = $task->get("total"); + $existing_passwords = ORM::factory("items_albumpassword")->find_all(); + // If this is the first time this function has been run, + // delete and re-create the idcaches table, and set up + // some initial variables. + if (empty($total)) { + // Delete the idcache table and make a new one. + $db = Database::instance(); + $db->query("DROP TABLE IF EXISTS {albumpassword_idcaches};"); + $db->query("CREATE TABLE IF NOT EXISTS {albumpassword_idcaches} ( + `cache_id` int(9) NOT NULL auto_increment, + `password_id` int(9) NOT NULL, + `item_id` int(9) NOT NULL, + PRIMARY KEY (`cache_id`)) + DEFAULT CHARSET=utf8;"); + + // Set the initial values for all variables. + $task->set("total", count($existing_passwords)); + $total = $task->get("total"); + $task->set("last_album_counter", 0); + $task->set("last_id", 0); + $task->set("completed_albums", 0); + $task->set("completed_items", 0); + $task->set("total_items", 0); + } + + // Retrieve the values for variables from the last time this + // function was run. + $last_album_counter = $task->get("last_album_counter"); + $completed_albums = $task->get("completed_albums"); + $completed_items = $task->get("completed_items"); + $total_items = $task->get("total_items"); + $last_id = $task->get("last_id"); + + // If completed_items is 0, then we're just starting to process this + // album. Add the album to idcaches before adding it's contents. + if ($completed_items == 0) { + // Add the album to the id cache. + $cached_album = ORM::factory("albumpassword_idcache"); + $cached_album->password_id = $existing_passwords[$last_album_counter]->id; + $cached_album->item_id = $existing_passwords[$last_album_counter]->album_id; + $cached_album->save(); + + // Set total_items to the number of items in this album. + $total_items = ORM::factory("item", $existing_passwords[$last_album_counter]->album_id) + ->descendants_count(); + $task->set("total_items", $total_items); + } + + // Add each item in the album to idcaches. + foreach (ORM::factory("item", $existing_passwords[$last_album_counter]->album_id) + ->where("id", ">", $last_id) + ->order_by("id") + ->descendants(100) as $item) { + + $cached_item = ORM::factory("albumpassword_idcache"); + $cached_item->password_id =$existing_passwords[$last_album_counter]->id; + $cached_item->item_id = $item->id; + $cached_item->save(); + + $last_id = $item->id; + $completed_items++; + + // Set a time limit so the script doesn't time out. + if (microtime(true) - $start > 1.5) { + break; + } + } // end foreach + + // If completed_items equals total_items, then we've + // processed everything in the current album. + // Increase variables and set everything up for the + // next album. + if ($completed_items == $total_items) { + $completed_items = 0; + $last_album_counter++; + $completed_albums++; + $last_id = 0; + } + + // Store the current values of the variables for the next + // time this function is called. + $task->set("last_album_counter", $last_album_counter); + $task->set("last_id", $last_id); + $task->set("completed_albums", $completed_albums); + $task->set("completed_items", $completed_items); + + // Display the number of albums that have been completed before exiting. + if ($total == $completed_albums) { + $task->done = true; + $task->state = "success"; + $task->percent_complete = 100; + $task->status = t("Scanning Protected Album $completed_albums of $total"); + } else { + $task->percent_complete = round(100 * $completed / $total); + $task->status = t("Scanning Protected Album $completed_albums of $total -- $completed_items / $total_items files"); + } + } +} diff --git a/3.0/modules/albumpassword/models/albumpassword_idcache.php b/3.0/modules/albumpassword/models/albumpassword_idcache.php new file mode 100644 index 00000000..e3d80667 --- /dev/null +++ b/3.0/modules/albumpassword/models/albumpassword_idcache.php @@ -0,0 +1,21 @@ + +

+ +

+
+
+ +

+
diff --git a/3.0/modules/albumpassword/views/assignpassword.html.php b/3.0/modules/albumpassword/views/assignpassword.html.php index 14cd2767..c1a60b8d 100644 --- a/3.0/modules/albumpassword/views/assignpassword.html.php +++ b/3.0/modules/albumpassword/views/assignpassword.html.php @@ -1,20 +1,3 @@ -
  • diff --git a/3.0/modules/albumpassword/views/loginpassword.html.php b/3.0/modules/albumpassword/views/loginpassword.html.php index 9ebb47fd..750ffbed 100644 --- a/3.0/modules/albumpassword/views/loginpassword.html.php +++ b/3.0/modules/albumpassword/views/loginpassword.html.php @@ -1,20 +1,3 @@ -
    • diff --git a/3.0/modules/albumtree/helpers/albumtree_block.php b/3.0/modules/albumtree/helpers/albumtree_block.php index 8d184f51..f812ab17 100644 --- a/3.0/modules/albumtree/helpers/albumtree_block.php +++ b/3.0/modules/albumtree/helpers/albumtree_block.php @@ -1,7 +1,7 @@ css_id = "g-albumtree"; $block->title = t("Album Tree"); - $block->content = new View("albumtree_block.html"); + $block->content = new View("albumtree_block_{$style}.html"); $block->content->root = item::root(); break; } diff --git a/3.0/modules/albumtree/helpers/albumtree_installer.php b/3.0/modules/albumtree/helpers/albumtree_installer.php new file mode 100644 index 00000000..77c7066f --- /dev/null +++ b/3.0/modules/albumtree/helpers/albumtree_installer.php @@ -0,0 +1,33 @@ + - diff --git a/3.0/modules/albumtree/views/albumtree_block_dtree.html.php b/3.0/modules/albumtree/views/albumtree_block_dtree.html.php new file mode 100644 index 00000000..257181f1 --- /dev/null +++ b/3.0/modules/albumtree/views/albumtree_block_dtree.html.php @@ -0,0 +1,414 @@ + + + + +
      +
      + +
      +
      diff --git a/3.0/modules/albumtree/views/albumtree_block_list.html.php b/3.0/modules/albumtree/views/albumtree_block_list.html.php new file mode 100644 index 00000000..62d8c0ad --- /dev/null +++ b/3.0/modules/albumtree/views/albumtree_block_list.html.php @@ -0,0 +1,30 @@ + + + +
        + +
      • + title ?> +
      • +viewable()->children(null, null, array(array("type", "=", "album"))) as $child){ + makelist($child,$level+1); + } +} +makelist($root,0); +?> +
      + + diff --git a/3.0/modules/albumtree/views/albumtree_block_select.html.php b/3.0/modules/albumtree/views/albumtree_block_select.html.php new file mode 100644 index 00000000..c4633d27 --- /dev/null +++ b/3.0/modules/albumtree/views/albumtree_block_select.html.php @@ -0,0 +1,16 @@ + + diff --git a/3.0/modules/all_tags/controllers/all_tags.php b/3.0/modules/all_tags/controllers/all_tags.php new file mode 100644 index 00000000..e0e1c344 --- /dev/null +++ b/3.0/modules/all_tags/controllers/all_tags.php @@ -0,0 +1,56 @@ +css("all_tags.css"); + $template->page_title = t("Gallery :: All Tags"); + $template->content = new View("all_tags.html"); + + $filter = Input::instance()->get("filter"); + $template->content->filter = $filter; + $query = ORM::factory("tag"); + if ($filter) { + $query->like("name", $filter); + } + $template->content->tags = $query->order_by("name", "ASC")->find_all(); + + print $template; + } +} + +/* + public function index() { + $filter = Input::instance()->get("filter"); + + $view = new Admin_View("admin.html"); + $view->page_title = t("Manage tags"); + $view->content = new View("admin_tags.html"); + $view->content->filter = $filter; + + $query = ORM::factory("tag"); + if ($filter) { + $query->like("name", $filter); + } + $view->content->tags = $query->order_by("name", "ASC")->find_all(); + print $view; + } + */ diff --git a/3.0/modules/all_tags/css/all_tags.css b/3.0/modules/all_tags/css/all_tags.css new file mode 100644 index 00000000..3dc93836 --- /dev/null +++ b/3.0/modules/all_tags/css/all_tags.css @@ -0,0 +1,2 @@ +table.all_tags { text-align: center; width:500px; } +table.all_tags caption { font-size: 1.5em; padding: 0.2em; } \ No newline at end of file diff --git a/3.0/modules/all_tags/helpers/all_tags_event.php b/3.0/modules/all_tags/helpers/all_tags_event.php new file mode 100644 index 00000000..3007f434 --- /dev/null +++ b/3.0/modules/all_tags/helpers/all_tags_event.php @@ -0,0 +1,29 @@ +add_after("home", Menu::factory("link") + ->id("all_tags") + ->label(t("All Tags")) + ->url(url::site("all_tags/"))); + } + } +} \ No newline at end of file diff --git a/3.0/modules/all_tags/helpers/all_tags_theme.php b/3.0/modules/all_tags/helpers/all_tags_theme.php new file mode 100644 index 00000000..89b91e70 --- /dev/null +++ b/3.0/modules/all_tags/helpers/all_tags_theme.php @@ -0,0 +1,24 @@ +css("all_tags.css"); + } +} diff --git a/3.0/modules/all_tags/module.info b/3.0/modules/all_tags/module.info new file mode 100644 index 00000000..10862900 --- /dev/null +++ b/3.0/modules/all_tags/module.info @@ -0,0 +1,7 @@ +name = "All Tags" +description = "All Tags page and menu item." +version = 2 +author_name = "Undagiga" +author_url = "http://codex.gallery2.org/User:Undagiga" +info_url = "http://codex.gallery2.org/Gallery3:Modules:all_tags" +discuss_url = "http://gallery.menalto.com/forum_module_all_tags" \ No newline at end of file diff --git a/3.0/modules/all_tags/views/all_tags.html.php b/3.0/modules/all_tags/views/all_tags.html.php new file mode 100644 index 00000000..381ee6b6 --- /dev/null +++ b/3.0/modules/all_tags/views/all_tags.html.php @@ -0,0 +1,44 @@ + + +count()/5 ?> + + +
      +

      + +
      + + + + + + +
      + count()) ?> +
      + $tag): ?> + name, 0, 1)) ?> + + + +
        + +
      + $tags_per_column): /* new column */ ?> + +
      + + + +
      +
      +
      diff --git a/3.0/modules/atom/module.info b/3.0/modules/atom/module.info new file mode 100644 index 00000000..77f5c0b8 --- /dev/null +++ b/3.0/modules/atom/module.info @@ -0,0 +1,7 @@ +name = "Atom" +description = "Enable Atom feeds in your Gallery" +version = 1 +author_name = "" +author_url = "" +info_url = "http://codex.gallery2.org/Gallery3:Modules:atom" +discuss_url = "http://gallery.menalto.com/forum_module_atom" diff --git a/3.0/modules/author/helpers/author.php b/3.0/modules/author/helpers/author.php new file mode 100644 index 00000000..ae259ec8 --- /dev/null +++ b/3.0/modules/author/helpers/author.php @@ -0,0 +1,121 @@ +is_album()) { return false; } + + $mime = $item->mime_type; + if ($mime == 'image/jpeg' || $mime == 'image/png' || $mime == 'image/gif') {} + else { return false; } + + $owner = ORM::factory("user")->where("id", "=", $item->owner_id)->find(); + $user_name = $owner->full_name; + + $exiv = module::get_var('author', 'exiv_path'); + $version = module::get_var('author', 'exiv_version'); + + /* + Debian stable ships with exiv2 0.16 at the time of writing. You get + roughly the same output out of the utility as with 0.20, but you have + to invoke it several times. + + The real threshhold for this might be somewhere between 0.16 and 0.20, + but the 0.16 way of doing things is forward compatible. + */ + $exivData = array(); + if ($version < 0.20) { + exec("$exiv -p x " . escapeshellarg($item->file_path()), $exivData); + exec("$exiv -p i " . escapeshellarg($item->file_path()), $exivData); + exec("$exiv -p t " . escapeshellarg($item->file_path()), $exivData); + } else { + exec("$exiv -p a " . escapeshellarg($item->file_path()), $exivData); + } + + $has = array(); + $mod = array(); + foreach ($exivData as $line) + { + $tokens = preg_split('/\s+/', $line, 4); + $has[ $tokens[0] ] = $tokens[3]; + } + + $candidates = array( + $has['Xmp.dc.creator'], + $has['Iptc.Application2.Byline'], + $has['Exif.Image.Artist'], + $user_name, + 'Unknown'); + + foreach ($candidates as $cand) { + if ($cand != '') { $byline = $cand; break; } + } + + if (!array_key_exists('Exif.Image.Artist', $has)) { $mod['Exif.Image.Artist'] = $byline; } + if (!array_key_exists('Iptc.Application2.Byline', $has)) { $mod['Iptc.Application2.Byline'] = $byline; } + + /* Apply the credit block */ + $credit = module::get_var("author", "credit"); + if ($credit != '') { + $mod['Iptc.Application2.Credit'] = $credit; + } + + /* + Older versions doesn't support XMP writing. + */ + if ($version >= 0.20) { + if (!array_key_exists('Xmp.dc.creator', $has)) { $mod['Xmp.dc.creator'] = $byline; } + + /* Apply our own image terms URL */ + $terms = module::get_var("author", "usage_terms"); + if ($terms != '') { + $mod['Xmp.xmpRights.UsageTerms'] = 'http://wiki.sverok.se/wiki/Bildbank-Bilder'; + } + } + + $line = $exiv . ' '; + foreach ($mod as $key => $value) { + $line .= "-M \"set $key " . escapeshellarg($value) . "\" "; + } + + $files = array( + $item->file_path(), + $item->thumb_path(), + $item->resize_path() + ); + + foreach ($files as $file) { + system("$line " . escapeshellarg($file)); + } + + $record = ORM::factory("author_record")->where("item_id", "=", $item->id)->find(); + if (!$record->loaded()) { + $record->item_id = $item->id; + } + $record->author = $byline; + $record->dirty = 0; + $record->save(); + return $byline; + } + +} diff --git a/3.0/modules/author/helpers/author_block.php b/3.0/modules/author/helpers/author_block.php new file mode 100644 index 00000000..9b571ba3 --- /dev/null +++ b/3.0/modules/author/helpers/author_block.php @@ -0,0 +1,48 @@ + t("Author")); + } + + static function get($block_id, $theme) { + $item = $theme->item; + if ($block_id != 'author' || $item->is_album() ) { + return ''; + } + $record = db::build() + ->select("author") + ->from("author_records") + ->where("item_id", "=", $item->id) + ->execute() + ->current(); + + $byline = $record->author; + if ($byline == '') { + $byline = author::fix($item); + } + + $block = new Block(); + $block->content = new View("author_block.html"); + $block->content->author = $byline; + + return $block; + } +} diff --git a/3.0/modules/author/helpers/author_event.php b/3.0/modules/author/helpers/author_event.php new file mode 100644 index 00000000..b9c31c8c --- /dev/null +++ b/3.0/modules/author/helpers/author_event.php @@ -0,0 +1,32 @@ +delete("author_records") + ->where("item_id", "=", $item->id) + ->execute(); + } +} diff --git a/3.0/modules/author/helpers/author_installer.php b/3.0/modules/author/helpers/author_installer.php new file mode 100644 index 00000000..1186f1f0 --- /dev/null +++ b/3.0/modules/author/helpers/author_installer.php @@ -0,0 +1,64 @@ +query("CREATE TABLE IF NOT EXISTS {author_records} ( + `id` int(9) NOT NULL auto_increment, + `item_id` INTEGER(9) NOT NULL, + `author` TEXT, + `dirty` BOOLEAN default 1, + PRIMARY KEY (`id`), + KEY(`item_id`)) + DEFAULT CHARSET=utf8;"); + module::set_version("author", 1); + module::set_var("author", "usage_terms", ''); + module::set_var("author", "credit", ''); + + return true; + } + + static function activate() { + gallery::set_path_env( + array( + getenv("PATH"), + module::get_var("gallery", "extra_binary_paths") + )); + + $exiv = exec('which exiv2'); + if ($exiv == '') { + # Proper warning + } + else { + module::set_var("author", "exiv_path", $exiv); + $out = array(); + exec("$exiv -V", $out); + $parts = split(' ', $out[0]); + module::set_var("author", "exiv_version", $parts[1]); + } + } + + static function deactivate() { + } + + static function uninstall() { + Database::instance()->query("DROP TABLE IF EXISTS {author_records};"); + } +} diff --git a/3.0/modules/author/models/author_record.php b/3.0/modules/author/models/author_record.php new file mode 100644 index 00000000..bd6eeb03 --- /dev/null +++ b/3.0/modules/author/models/author_record.php @@ -0,0 +1,21 @@ + + +
      +: +
      + diff --git a/3.0/modules/autorotate/helpers/autorotate.php b/3.0/modules/autorotate/helpers/autorotate.php index 5bfe1afe..bf531d01 100644 --- a/3.0/modules/autorotate/helpers/autorotate.php +++ b/3.0/modules/autorotate/helpers/autorotate.php @@ -1,7 +1,7 @@ _get_s3_form(); + + if (request::method() == "post") { + access::verify_csrf(); + + if (($valid_form = $form->validate()) && + ($s3_axs_correct = aws_s3::validate_access_details($_POST['access_key'], $_POST['secret_key'], $_POST['bucket_name']))) { + + // get variable values before changes so we can act on certain changes later + $vars = array(); + foreach (ORM::factory("var")->where("module_name", "=", "aws_s3")->find_all() as $var) { + $vars[$var->name] = $var->value; + } + + // set variables from $_POST into module::set_var() to save + module::set_var("aws_s3", "enabled", (isset($_POST['enabled']) ? true : false)); + module::set_var("aws_s3", "access_key", $_POST['access_key']); + module::set_var("aws_s3", "secret_key", $_POST['secret_key']); + module::set_var("aws_s3", "bucket_name", $_POST['bucket_name']); + site_status::clear("aws_s3_not_configured"); + + module::set_var("aws_s3", "g3id", $_POST['g3id']); + + module::set_var("aws_s3", "url_str", $_POST['url_str']); + module::set_var("aws_s3", "sig_exp", $_POST['sig_exp']); + + module::set_var("aws_s3", "use_ssl", (isset($_POST['use_ssl']) ? true : false)); + + module::set_var("aws_s3", "upload_thumbs", (isset($_POST['upload_thumbs']) ? true : false)); + module::set_var("aws_s3", "upload_resizes", (isset($_POST['upload_resizes']) ? true : false)); + module::set_var("aws_s3", "upload_fullsizes", (isset($_POST['upload_fullsizes']) ? true : false)); + + module::set_var("aws_s3", "s3_storage_only", (isset($_POST['s3_storage_only']) ? true : false)); + + // post option processing +// if (module::get_var("aws_s3", "s3_storage_only") && !module::get_var("aws_s3", "enabled")) { +// module::set_var("aws_s3", "enabled", true); +// module::set_var("aws_s3", "upload_thumbs", true); +// module::set_var("aws_s3", "upload_resizes", true); +// module::set_var("aws_s3", "upload_fullsizes", true); +// } +// if (module::get_var("aws_s3", "s3_storage_only") && !$vars['s3_storage_only']) { +// // content needs remove from local storage as it wasn't switched on before this point. +// if (!module::get_var("aws_s3", "synced")) { +// // force a sync between local storage and S3, as we're about to remove content from local storage. +// } +// } +// else if (!module::get_var("aws_s3", "s3_storage_only") && $vars['s3_storage_only']) { +// // content needs to be downloaded from s3 as it was just switched off. at this point, +// // we shouldn't actually have a copy of the gallery content locally. +// } + + if (module::get_var("aws_s3", "enabled") && !module::get_var("aws_s3", "synced", false)) { + if (aws_s3::can_schedule()) { + // i can schedule this task + aws_s3::schedule_full_sync2(); + site_status::warning( + "Your site has been scheduled for full Amazon S3 re-synchronisation. This message will clear when this has been completed.", + "aws_s3_not_synced" + ); + } + else { + // i CAN'T schedule it.. + site_status::warning( + t('Your site has not been synchronised to Amazon S3. Until it has, your server will continue to serve image content to your visitors. Click here to start the synchronisation task.', + array("url" => html::mark_clean(url::site("admin/maintenance/start/aws_s3_task::manual_sync?csrf=__CSRF__"))) + ), + "aws_s3_not_synced" + ); + } + } + + message::success(t("Settings have been saved")); + url::redirect("admin/aws_s3"); + } + else { + if (!$valid_form) + message::error(t("There was a problem with the submitted form. Please check your values and try again.")); + if (!$s3_axs_correct) { + message::error(t("The Amazon S3 access details provided appear to be incorrect. Please check your values and try again.")); + $form->aws_s3->access_key->add_error("invalid", true); + $form->aws_s3->secret_key->add_error("invalid", true); + $form->aws_s3->bucket_name->add_error("invalid", true); + } + } + } + + $v = new Admin_View("admin.html"); + $v->page_title = t("Amazon S3 Configuration"); + $v->content = new View("admin_aws_s3.html"); + $v->content->form = $form; + $v->content->end = ""; + + echo $v; + } + + private function _get_s3_form() { + $form = new Forge("admin/aws_s3", "", "post", array("id" => "g-admin-s3-form")); + + $group = $form->group("aws_s3")->label(t("Amazon S3 Settings")); + + $chkbox = + $group ->checkbox("enabled") + ->id("s3-enabled") + ->checked(module::get_var("aws_s3", "enabled", true)) + ->label("S3 enabled"); + + if (module::get_var("aws_s3", "s3_storage_only")) + $chkbox->disabled(true) + ->message("Warning:You may not turn this option off as S3 Storage Only is enabled. In order to disable using S3, you must first disable S3 Storage Only to re-download your content from Amazon S3, since it does not yet exist on the local server."); + + $group ->input("access_key") + ->id("s3-access-key") + ->label("Access Key ID") + ->value(module::get_var("aws_s3", "access_key")) + ->rules("required") + ->error_messages("required", "This field is required") + ->error_messages("invalid", "Access Key is invalid") + ->message('Click here to sign up to Amazon Web Services.'); + + $group ->input("secret_key") + ->id("s3-secret-key") + ->label("Secret Access Key") + ->value(module::get_var("aws_s3", "secret_key")) + ->rules("required") + ->error_messages("required", "This field is required") + ->error_messages("invalid", "Secret Key is invalid"); + + $group ->input("bucket_name") + ->id("s3-bucket") + ->label("Bucket Name") + ->value(module::get_var("aws_s3", "bucket_name")) + ->rules("required") + ->callback("aws_s3::validate_bucket") + ->error_messages("required", "This field is required") + ->error_messages("invalid", "Bucket name is invalid") + ->message('Note: This module will not create a bucket if it does not already exist. Please ensure you have already created the bucket using the AWS Console before continuing.
      +Click here for information on Amazon S3 bucket naming conventions/restrictions.'); + + $group ->input("g3id") + ->id("s3-g3id") + ->label("G3 ID") + ->value(module::get_var("aws_s3", "g3id", md5(time()))) + ->rules("required") + ->error_messages("required", "This field is required") + ->message("Utilising this field allows for multiple G3 file repositories stored inside the same S3 bucket."); + + $group ->checkbox("use_ssl") + ->id("s3-use-ssl") + ->checked(module::get_var("aws_s3", "use_ssl")) + ->label("Use SSL for S3 transfers") + ->message("You may have problems when uploading content to S3 if this option is enabled. If so, turn off this option."); + + $group = $form->group("cdn_settings")->label(t("CDN Settings")); + + $group ->input("url_str") + ->id("s3-url-str") + ->label("URL String") + ->value(module::get_var("aws_s3", "url_str", "http://{bucket}.s3.amazonaws.com/g3/{guid}/{resource}")) + ->rules("required") + ->message("Configure the URL to access uploaded resources on the CDN. Use the following variables to define and build up the URL:
      +• {bucket} - Bucket Name
      +• {guid} - Unique identifier for this gallery installation
      +• {resource} - The end path to the resource/object"); + + $group ->input("sig_exp") + ->id("s3-sig_exp") + ->label("Private Content Signature Duration") + ->value(module::get_var("aws_s3", "sig_exp", 60)) + ->rules("required") + ->callback("aws_s3::validate_number") + ->error_messages("not_numeric", "The value provided is not numeric. Please enter a number in this field.") + ->message("Set the time in seconds until the generated signature expires access to permission-restricted S3 objects (private content on G3 is where the user group 'Everybody' does not have access).

      +Note: this module does not yet support the creation of signatures to access private objects on S3 via CloudFront CDN."); + + $group = $form->group("general_settings")->label(t("General Settings")); + + $chkbox = + $group ->checkbox("upload_thumbs") + ->id("s3-upload_thumbs") + ->label("Upload Thumbnails") + ->checked(module::get_var("aws_s3", "upload_thumbs", true)); + if (module::get_var("aws_s3", "s3_storage_only")) + $chkbox->disabled(true); + + $chkbox = + $group ->checkbox("upload_resizes") + ->id("s3-upload_resizes") + ->label("Upload Resized Images") + ->checked(module::get_var("aws_s3", "upload_resizes", true)); + if (module::get_var("aws_s3", "s3_storage_only")) + $chkbox->disabled(true); + + $chkbox = + $group ->checkbox("upload_fullsizes") + ->id("s3-upload_fullsizes") + ->label("Upload Fullsize Images") + ->checked(module::get_var("aws_s3", "upload_fullsizes", true)); + if (module::get_var("aws_s3", "s3_storage_only")) + $chkbox->disabled(true); + + $chkbox = + $group ->checkbox("s3_storage_only") + ->id("s3-storage-only") + ->label("Use S3 for primary storage of Gallery content (Not yet available)") + ->checked(module::get_var("aws_s3", "s3_storage_only", false)) + ->message("Use this option if your webhost has limited space available on your account. This module will remove content from the local server after it has been uploaded to S3.

      +Note: You must have enough storage on your webhost account to store the images temporarily until they have been uploaded to S3.
      ") + ->disabled(true); + + if (!module::get_var("aws_s3", "enabled")) + $chkbox->disabled(true); + + // done creating form. + $form ->submit("save") + ->value("Save Settings"); + + + return $form; + } + +} \ No newline at end of file diff --git a/3.0/modules/aws_s3/controllers/aws_s3.php b/3.0/modules/aws_s3/controllers/aws_s3.php new file mode 100644 index 00000000..a5d092b2 --- /dev/null +++ b/3.0/modules/aws_s3/controllers/aws_s3.php @@ -0,0 +1,9 @@ +item && $theme->item->view_1 == 1) + parent::get($block_id, $theme); + } + +} \ No newline at end of file diff --git a/3.0/modules/aws_s3/helpers/MY_embedlinks_theme.php b/3.0/modules/aws_s3/helpers/MY_embedlinks_theme.php new file mode 100644 index 00000000..87434ca8 --- /dev/null +++ b/3.0/modules/aws_s3/helpers/MY_embedlinks_theme.php @@ -0,0 +1,31 @@ +item; + if ($item->view_1 == 1) + return parent::photo_bottom($theme); + } + } + +} \ No newline at end of file diff --git a/3.0/modules/aws_s3/helpers/MY_item.php b/3.0/modules/aws_s3/helpers/MY_item.php new file mode 100644 index 00000000..e7031c27 --- /dev/null +++ b/3.0/modules/aws_s3/helpers/MY_item.php @@ -0,0 +1,41 @@ +parent(); + if ($parent->id > 1) { + aws_s3::upload_item($parent); + } + } + + static function remove_album_cover($album) { + parent::remove_album_cover($album); + + if ($album->id > 1) { + aws_s3::remove_item($album); + } + } + +} \ No newline at end of file diff --git a/3.0/modules/aws_s3/helpers/aws_s3.php b/3.0/modules/aws_s3/helpers/aws_s3.php new file mode 100644 index 00000000..eafdaf62 --- /dev/null +++ b/3.0/modules/aws_s3/helpers/aws_s3.php @@ -0,0 +1,330 @@ + 0) + return $matches[1]; + return false; + } + + static function log($item) { + if (is_string($item) || is_numeric($item)) {} + else + $item = print_r($item, true); + + $fh = fopen(VARPATH . "modules/aws_s3/log/aws_s3-" . date("Y-m-d") . ".log", "a"); + fwrite($fh, date("Y-m-d H:i:s") . ": " . $item . "\n"); + fclose($fh); + } + + static function get_upload_flags() { + $flags = 0; + if (module::get_var("aws_s3", "upload_thumbs") == 1) + $flags += self::UPLOAD_THUMB; + if (module::get_var("aws_s3", "upload_resizes") == 1) + $flags += self::UPLOAD_RESIZE; + if (module::get_var("aws_s3", "upload_fullsizes") == 1) + $flags += self::UPLOAD_FULLSIZE; + return $flags; + } + + static function upload_item($item, $flags = 7) { + self::get_s3(); + + $filename = urldecode($item->relative_path()); + $itype = "I"; + if ($item->is_album()) { + $filename .= "/.album.jpg"; + $itype = "A"; + } + + if (!$item->s3_fullsize_uploaded && $flags & aws_s3::UPLOAD_FULLSIZE && !$item->is_album()) { + aws_s3::log("[" . $itype . ":" . $item->id . "] Uploading fullsize object"); + $success_fs = S3::putObjectFile(VARPATH . "albums/" . $filename, + module::get_var("aws_s3", "bucket_name"), + self::get_resource_url("fs/" . $filename), + ($item->view_1 ? S3::ACL_PUBLIC_READ : S3::ACL_PRIVATE)); + $item->s3_fullsize_uploaded = $success_fs; + } + else + $success_fs = true; + + if (!$item->s3_resize_uploaded && $flags & aws_s3::UPLOAD_RESIZE && !$item->is_album()) { + aws_s3::log("[" . $itype . ":" . $item->id . "] Uploading resize object"); + $success_rs = S3::putObjectFile(VARPATH . "resizes/" . $filename, + module::get_var("aws_s3", "bucket_name"), + self::get_resource_url("rs/" . $filename), + ($item->view_1 ? S3::ACL_PUBLIC_READ : S3::ACL_PRIVATE)); + $item->s3_resize_uploaded = $success_rs; + } + else + $success_rs = true; + + if (!$item->s3_thumb_uploaded && $flags & aws_s3::UPLOAD_THUMB) { + aws_s3::log("[" . $itype . ":" . $item->id . "] Uploading thumbnail object"); + $success_th = S3::putObjectFile(VARPATH . "thumbs/" . $filename, + module::get_var("aws_s3", "bucket_name"), + self::get_resource_url("th/" . $filename), + ($item->view_1 ? S3::ACL_PUBLIC_READ : S3::ACL_PRIVATE)); + $item->s3_thumb_uploaded = $success_th; + } + else + $success_th = true; + + $item->s3_item_hash = md5($item->relative_path()); + + $item->save(); + + $success = $success_fs && $success_th && $success_rs; + aws_s3::log("item upload success: " . $success); + return $success; + } + + static function move_item($old_item, $new_item) { + self::get_s3(); + + $old_filename = urldecode($old_item->relative_path()); + $new_filename = urldecode($new_item->relative_path()); + + aws_s3::log("old filename: " . self::get_resource_url("fs/" . $old_filename) . ", " . + "new filename: " . self::get_resource_url("fs/" . $new_filename)); + + //aws_s3::log($old_item->get_aws_s3_meta()); + + if ($old_item->s3_fullsize_uploaded) { + aws_s3::log("Copying fullsize " . $old_filename . " to " . $new_filename); + S3::copyObject(module::get_var("aws_s3", "bucket_name"), self::get_resource_url("fs/" . $old_filename), + module::get_var("aws_s3", "bucket_name"), self::get_resource_url("fs/" . $new_filename), + ($new_item->view_1 ? S3::ACL_PUBLIC_READ : S3::ACL_PRIVATE)); + S3::deleteObject(module::get_var("aws_s3", "bucket_name"), self::get_resource_url("fs/" . $old_filename)); + } + else + aws_s3::upload_item($new_item, aws_s3::UPLOAD_FULLSIZE); + + if ($old_item->s3_resize_uploaded) { + aws_s3::log("Copying resized " . $old_filename . " to " . $new_filename); + S3::copyObject(module::get_var("aws_s3", "bucket_name"), self::get_resource_url("rs/" . $old_filename), + module::get_var("aws_s3", "bucket_name"), self::get_resource_url("rs/" . $new_filename), + ($new_item->view_1 ? S3::ACL_PUBLIC_READ : S3::ACL_PRIVATE)); + S3::deleteObject(module::get_var("aws_s3", "bucket_name"), self::get_resource_url("rs/" . $old_filename)); + } + else + aws_s3::upload_item($new_item, aws_s3::UPLOAD_RESIZE); + + if ($old_item->s3_thumb_uploaded) { + aws_s3::log("Copying thumbnail " . $old_filename . " to " . $new_filename); + S3::copyObject(module::get_var("aws_s3", "bucket_name"), self::get_resource_url("th/" . $old_filename), + module::get_var("aws_s3", "bucket_name"), self::get_resource_url("th/" . $new_filename), + ($new_item->view_1 ? S3::ACL_PUBLIC_READ : S3::ACL_PRIVATE)); + S3::deleteObject(module::get_var("aws_s3", "bucket_name"), self::get_resource_url("th/" . $old_filename)); + } + else + aws_s3::upload_item($new_item, aws_s3::UPLOAD_THUMB); + } + + static function remove_item($item) { + self::get_s3(); + + $filename = urldecode($item->relative_path()); + $itype = "I"; + if ($item->is_album()) { + $filename .= "/.album.jpg"; + $itype = "A"; + } + + if ($item->s3_fullsize_uploaded && !$item->is_album()) { + aws_s3::log("[" . $itype . ":" . $item->id . "] Deleting fullsize object"); + $success_fs = S3::deleteObject(module::get_var("aws_s3", "bucket_name"), + self::get_resource_url("fs/" . $filename)); + $item->s3_fullsize_uploaded = !$success_fs; + } + else + $success_fs = true; + + if ($item->s3_resize_uploaded && !$item->is_album()) { + aws_s3::log("[" . $itype . ":" . $item->id . "] Deleting resize object"); + $success_rs = S3::deleteObject(module::get_var("aws_s3", "bucket_name"), + self::get_resource_url("rs/" . $filename)); + $item->s3_resize_uploaded = !$success_rs; + } + else + $success_rs = true; + + if ($item->s3_thumb_uploaded) { + aws_s3::log("[" . $itype . ":" . $item->id . "] Deleting thumbnail object"); + $success_th = S3::deleteObject(module::get_var("aws_s3", "bucket_name"), + self::get_resource_url("th/" . $filename)); + $item->s3_thumb_uploaded = !$success_th; + } + else + $success_th = true; + + $item->save_s3_meta(); + + $success = $success_fs && $success_th && $success_rs; + aws_s3::log("S3 delete success: " . $success); + return $success; + } + + static function getAuthenticatedURL($bucket, $uri) { + self::get_s3(); + + return S3::getAuthenticatedURL($bucket, $uri, 60); + } + + static function validate_number($field) { + if (preg_match("/\D/", $field->value)) + $field->add_error("not_numeric", 1); + } + + static function validate_bucket($field) { + if (preg_match("/[^a-zA-Z0-9\-\.]/", $field->value)) + $field->add_error("invalid", 1); + } + + // @TODO: Write validation function (check with S3) + static function validate_access_details($access_key, $secret_key, $bucket_name) { + require_once(MODPATH . "aws_s3/lib/s3.php"); + S3::setAuth($access_key, $secret_key); + S3::$useSSL = false; + + $success_test = S3::putObjectString((string)time(), $bucket_name, ".s3_test"); + if ($success_test) + S3::deleteObject($bucket_name, ".s3_test"); + + return $success_test; + } + + static function base64_filename(Item_Model $item) { + $file_path = explode("/", $item->relative_path()); + return base64_encode(end($file_path)); + } + + static function can_schedule() { + if (!module::is_active("scheduler")) { + return false; + } + + return true; + } + + static function schedule_task($task) { + $schedule = ORM::factory("schedule"); + $schedule->add_task($task); + } + + static function schedule_full_sync2() { + $task_def = + Task_Definition::factory() + ->callback("aws_s3_task::sync") + ->name("Amazon S3 bucket synchronisation") + ->severity(log::SUCCESS); + + $task = task::create($task_def, array()); + self::schedule_task($task); + } + + static function schedule_full_sync($this_task) { + if (!self::can_schedule()) + throw new Exception("Unable to initialize schedule"); + + try { + self::schedule_full_sync2(); + + $this_task->status = "Scheduled re-sync task"; + $this_task->done = true; + $this_task->state = "success"; + $this_task->percent_complete = 100; + } + catch (Exception $err) { + $task->done = true; + $thisSynchronise_task->state = "error"; + $this_task->status = $err->getMessage(); + $this_task->log((string)$err); + } + + $this_task->save(); + + if (!module::get_var("aws_s3", "synced", false)) { + site_status::warning( + "Your site has been scheduled for full Amazon S3 re-synchronisation. This message will clear when this has been completed.", + "aws_s3_not_synced" + ); + } + + return true; + } + + static function schedule_item_sync($item) { + if (!self::can_schedule()) + throw new Exception("Unable to initialize schedule"); + + $item_id = null; + if (is_object($item) && $item instanceof Item_Model) + $item_id = $item->id; + else if (is_numeric($item)) + $item_id = $item; + else + throw new Exception("Un-intelligible item reference passed."); + + $task_def = + Task_Definition::factory() + ->callback("aws_s3_task::upload_item") + ->name("Amazon S3 item upload (ID: " . $item_id . ")") + ->severity(log::SUCCESS); + + $task = task::create($task_def, array("item_id" => $item_id)); + + self::schedule_task($task); + } + + +} \ No newline at end of file diff --git a/3.0/modules/aws_s3/helpers/aws_s3_event.php b/3.0/modules/aws_s3/helpers/aws_s3_event.php new file mode 100644 index 00000000..29a9477a --- /dev/null +++ b/3.0/modules/aws_s3/helpers/aws_s3_event.php @@ -0,0 +1,56 @@ +get("settings_menu") + ->append( + Menu::factory("link") + ->id("aws_s3_link") + ->label(t("Amazon S3")) + ->url(url::site("admin/aws_s3")) + ); + } + + static function item_created($item) { + if ($item->id == 1) + return true; + + aws_s3::log("Item created - " . $item->id); + aws_s3::schedule_item_sync($item); + } + + static function item_deleted($item) { + if ($item->id == 1) + return true; + + aws_s3::log("Item deleted - " . $item->id); + aws_s3::remove_item($item); + + ORM::factory("aws_s3_meta", $item->id)->delete(); + } + + static function item_updated($old_item, $new_item) { + if ($new_item->id == 1) + return true; + + if ($new_item->has_aws_s3_meta()) { + aws_s3::log("Item updated - " . $new_item->id); + + if ($old_item->relative_path() == $new_item->relative_path() && $old_item->s3_item_hash == $new_item->s3_item_hash) { + aws_s3::log("nothing changed?!"); + } + else if ($old_item->relative_path() != $new_item->relative_path()) { + aws_s3::log("Item moved..."); + aws_s3::move_item($old_item, $new_item); + } + else { + aws_s3::log("Item hasn't moved. Image updated?"); + aws_s3::remove_item($old_item); + aws_s3::schedule_item_sync($new_item); + } + } + } + +} \ No newline at end of file diff --git a/3.0/modules/aws_s3/helpers/aws_s3_installer.php b/3.0/modules/aws_s3/helpers/aws_s3_installer.php new file mode 100644 index 00000000..0a297dbb --- /dev/null +++ b/3.0/modules/aws_s3/helpers/aws_s3_installer.php @@ -0,0 +1,126 @@ +query("DROP TABLE {aws_s3_meta}"); + } + + static function upgrade($version) { + log::info("aws_s3", "Commencing module upgrade (" . $version . ")"); + switch ($version) { + case 0: { + log::info("aws_s3", "Installing version 1"); + + @mkdir(VARPATH . "modules/aws_s3"); + @mkdir(VARPATH . "modules/aws_s3/log"); + + // installation's unique identifier - allows multiple g3's pointing to the same s3 bucket. + if (!module::get_var("aws_s3", "g3id")) + module::set_var("aws_s3", "g3id", md5(time())); + + module::set_var("aws_s3", "synced", false); + module::set_var("aws_s3", "enabled", false); + module::set_var("aws_s3", "access_key", ""); + module::set_var("aws_s3", "secret_key", ""); + module::set_var("aws_s3", "bucket_name", ""); + + module::set_version("aws_s3", 1); + } + case 1: { + log::info("aws_s3", "Upgrading to version 2"); + $db = Database::instance(); + $db->query("CREATE TABLE {aws_s3_meta} ( + `item_id` int(9) NOT NULL, + `item_hash` varchar(32) NOT NULL DEFAULT '', + `thumb_uploaded` smallint(1) NOT NULL DEFAULT 0, + `resize_uploaded` smallint(1) NOT NULL DEFAULT 0, + `fullsize_uploaded` smallint(1) NOT NULL DEFAULT 0, + `local_deleted` smallint(1) NOT NULL DEFAULT 0, + PRIMARY KEY (`item_id`) + ) DEFAULT CHARSET=utf8;"); + + module::set_var("aws_s3", "upload_thumbs", true); + module::set_var("aws_s3", "upload_resizes", true); + module::set_var("aws_s3", "upload_fullsizes", true); + module::set_var("aws_s3", "s3_storage_only", false); + + if (module::get_var("aws_s3", "synced")) { + // v1 has already synced this installation to s3. mark all the items with the relevant meta data + $items = ORM::factory("item")->find_all(); + foreach ($items as $item) { + aws_s3::log("Updating S3 meta for item ID: " . $item->id); + $item->s3_thumb_uploaded = true; + if (!$item->is_album()) { + $item->s3_resize_uploaded = true; + $item->s3_fullsize_uploaded = true; + } + $item->s3_local_deleted = false; + $item->s3_item_hash = md5($item->relative_path()); + $item->save_s3_meta(); + } + } + else { + // check various states after upgrade from v1.. + + if (module::get_var("aws_s3", "access_key") != "" && + module::get_var("aws_s3", "secret_key") != "" && + module::get_var("aws_s3", "bucket_name") != "" && + aws_s3::validate_access_details(module::get_var("aws_s3", "access_key"), + module::get_var("aws_s3", "secret_key"), + module::get_var("aws_s3", "bucket_name")) + ) { + // details are correct but hasn't been synced. + if (aws_s3::can_schedule()) { + // i can schedule this task + aws_s3::schedule_full_sync2(); + site_status::warning( + "Your site has been scheduled for full Amazon S3 re-synchronisation. This message will clear when this has been completed.", + "aws_s3_not_synced" + ); + } + else { + // i CAN'T schedule it.. + site_status::warning( + t('Your site has not been synchronised to Amazon S3. Until it has, your server will continue to serve image content to your visitors.
      Click here to start the synchronisation task.', + array("url" => html::mark_clean(url::site("admin/maintenance/start/aws_s3_task::manual_sync?csrf=__CSRF__"))) + ), + "aws_s3_not_synced" + ); + } + } + else { + site_status::warning( + t('Amazon S3 module needs configuration. Click here to go to the configuration page.', + array("url" => html::mark_clean(url::site("admin/aws_s3"))) + ), + "aws_s3_not_configured" + ); + } + } + + module::set_version("aws_s3", 2); + } + } + log::info("aws_s3", "Module upgrade complete"); + } + + static function deactivate() {} + static function activate() {} + static function can_activate() { + $messages = array(); + if (!function_exists("curl_init")) { + $messages['error'][] = "The S3 library (and this module) depend on the php5-curl extension. Please install this extension and try again."; + } + if (!module::is_active("scheduler")) { + $messages['warn'][] = "The 'Scheduler' module is not installed/active. Scheduled maintenance tasks such as synchronisation will not be available."; + } + return $messages; + } + +} \ No newline at end of file diff --git a/3.0/modules/aws_s3/helpers/aws_s3_task.php b/3.0/modules/aws_s3/helpers/aws_s3_task.php new file mode 100644 index 00000000..f0dcb701 --- /dev/null +++ b/3.0/modules/aws_s3/helpers/aws_s3_task.php @@ -0,0 +1,193 @@ +callback("aws_s3::schedule_full_sync") + ->name(t("Synchronise with Amazon S3")) + ->description(t("Schedule a task to synchronise your Gallery 3 data/images with your Amazon S3 bucket")) + ->severity(log::SUCCESS) + ->set_flags(Task_Definition::CAN_RUN_NOW)); + else + return array(Task_Definition::factory() + ->callback("aws_s3_task::manual_sync") + ->name(t("Synchronise with Amazon S3")) + ->description(t("Synchronise your Gallery 3 data/images with your Amazon S3 bucket")) + ->severity(log::SUCCESS)); + + } + + static function upload_item($task) { + aws_s3::log("aws_s3_task::upload_item called"); + + $item = ORM::factory("item", $task->get("item_id")); + + aws_s3::log("Commencing upload task for item " . $item->id); + + $task->status = "Commencing upload"; + $task->percent_complete = 0; + $task->save(); + if (aws_s3::upload_item($item, aws_s3::get_upload_flags())) { + $task->percent_complete = 100; + $task->done = true; + $task->state = "success"; + $task->status = "Upload complete"; + } + else { + $task->done = false; + $task->state = "error"; + $task->status = "Upload failed"; + } + $task->save(); + } + + static function manual_sync($task) { + aws_s3::log("Amazon S3 manual re-sync started."); + + if (!$task->get("mode")) { + $task->set("mode", "init"); + } + + aws_s3::log("mode: " . $task->get("mode")); + switch ($task->get("mode")) { + case "init": { + batch::start(); + $items = ORM::factory("item")->find_all(); + $task->set("total_count", count($items)); + + if (count($items) <= 50) + $task->set("batch", 1); + else if (count($items) > 50 && count($items) <= 500) + $task->set("batch", 5); + else if (count($items) > 500 && count($items) <= 5000) + $task->set("batch", 10); + else if (count($items) > 5000) + $task->set("batch", 25); + + $task->set("completed", 0); + $task->state = "running"; + + if (!module::get_var("aws_s3", "synced", false)) { + $task->set("mode", "clean"); + $task->status = "Emptying contents of bucket"; + } + else { + $task->status = "Uploading items..."; + $task->percent_complete = 10; + $task->set("mode", "upload"); + } + } break; + case "clean": { + aws_s3::log("Emptying contents of bucket"); + + require_once(MODPATH . "aws_s3/lib/s3.php"); + $s3 = new S3(module::get_var("aws_s3", "access_key"), module::get_var("aws_s3", "secret_key")); + + $bucket = module::get_var("aws_s3", "bucket_name"); + $resource = aws_s3::get_resource_url(""); + $stuff = array_reverse(S3::getBucket($bucket, $resource)); + $i = 0; + foreach ($stuff as $uri => $item) { + $i++; + aws_s3::log("Removing " . $uri . " from S3"); + S3::deleteObject($bucket, $uri); + $task->percent_complete = round(20 * ($i / count($stuff))); + $task->save(); + } + $task->set("mode", "upload"); + $task->status = "Uploading items..."; + } break; + case "upload": { + $items = ORM::factory("item")->find_all($task->get("batch"), $task->get("completed")); + foreach ($items as $item) { + aws_s3::upload_item($item, aws_s3::get_upload_flags()); + $task->set("completed", $task->get("completed") + 1); + } + $task->percent_complete = (90 * ($task->get("completed") / $task->get("total_count"))) + 10; + $task->status = "Uploaded " . $task->get("completed") . " of " . $task->get("total_count") . " items..."; + + if ($task->get("completed") == $task->get("total_count")) { + $task->set("mode", "complete"); + } + } break; + case "complete": { + $task->done = true; + $task->state = "success"; + $task->percent_complete = 100; + $task->status = "Completed."; + module::set_var("aws_s3", "synced", true); + site_status::clear("aws_s3_not_synced"); + batch::stop(); + } break; + } + aws_s3::log("End of function.."); + $task->save(); + } + + static function sync($task) { + aws_s3::log("Amazon S3 Re-sync task started.."); + + batch::start(); + $items = ORM::factory("item")->find_all(); + + $task->set("total_count", count($items)); + $task->set("completed", 0); + + if (!module::get_var("aws_s3", "synced", false)) { + aws_s3::log("Emptying contents of bucket"); + $task->status = "Emptying contents of bucket"; + $task->save(); + + require_once(MODPATH . "aws_s3/lib/s3.php"); + $s3 = new S3(module::get_var("aws_s3", "access_key"), module::get_var("aws_s3", "secret_key")); + + $bucket = module::get_var("aws_s3", "bucket_name"); + $resource = aws_s3::get_resource_url(""); + $stuff = array_reverse(S3::getBucket($bucket, $resource)); + $i = 0; + foreach ($stuff as $uri => $item) { + $i++; + aws_s3::log("Removing " . $uri . " from S3"); + S3::deleteObject($bucket, $uri); + $task->percent_complete = round(20 * ($i / count($stuff))); + $task->save(); + } + } + + $task->percent_complete = 20; + aws_s3::log("Commencing upload tasks"); + $task->state = "Commencing upload..."; + $task->save(); + + $completed = $task->get("completed", 0); + + $items = ORM::factory("item")->find_all(); + foreach ($items as $item) { + try { + if ($item->id > 1) + aws_s3::upload_item($item, aws_s3::get_upload_flags()); + } + catch (Exception $err) {} + $completed++; + + $task->set("completed", $completed); + $task->percent_complete = round(80 * ($completed / $task->get("total_count"))) + 20; + $task->status = $completed . " of " . $task->get("total_count"). " uploaded."; + $task->save(); + } + + $task->percent_complete = 100; + $task->state = "success"; + $task->done = true; + aws_s3::log("Sync task completed successfully"); + $task->status = "Sync task completed successfully"; + module::set_var("aws_s3", "synced", true); + site_status::clear("aws_s3_not_synced"); + batch::stop(); + + $task->save(); + } + +} \ No newline at end of file diff --git a/3.0/modules/aws_s3/lib/s3.php b/3.0/modules/aws_s3/lib/s3.php new file mode 100644 index 00000000..b2ce6cec --- /dev/null +++ b/3.0/modules/aws_s3/lib/s3.php @@ -0,0 +1,1367 @@ +getResponse(); + if ($rest->error === false && $rest->code !== 200) + $rest->error = array('code' => $rest->code, 'message' => 'Unexpected HTTP status'); + if ($rest->error !== false) { + trigger_error(sprintf("S3::listBuckets(): [%s] %s", $rest->error['code'], $rest->error['message']), E_USER_WARNING); + return false; + } + $results = array(); + if (!isset($rest->body->Buckets)) return $results; + + if ($detailed) { + if (isset($rest->body->Owner, $rest->body->Owner->ID, $rest->body->Owner->DisplayName)) + $results['owner'] = array( + 'id' => (string)$rest->body->Owner->ID, 'name' => (string)$rest->body->Owner->ID + ); + $results['buckets'] = array(); + foreach ($rest->body->Buckets->Bucket as $b) + $results['buckets'][] = array( + 'name' => (string)$b->Name, 'time' => strtotime((string)$b->CreationDate) + ); + } else + foreach ($rest->body->Buckets->Bucket as $b) $results[] = (string)$b->Name; + + return $results; + } + + + /* + * Get contents for a bucket + * + * If maxKeys is null this method will loop through truncated result sets + * + * @param string $bucket Bucket name + * @param string $prefix Prefix + * @param string $marker Marker (last file listed) + * @param string $maxKeys Max keys (maximum number of keys to return) + * @param string $delimiter Delimiter + * @param boolean $returnCommonPrefixes Set to true to return CommonPrefixes + * @return array | false + */ + public static function getBucket($bucket, $prefix = null, $marker = null, $maxKeys = null, $delimiter = null, $returnCommonPrefixes = false) { + $rest = new S3Request('GET', $bucket, ''); + if ($prefix !== null && $prefix !== '') $rest->setParameter('prefix', $prefix); + if ($marker !== null && $marker !== '') $rest->setParameter('marker', $marker); + if ($maxKeys !== null && $maxKeys !== '') $rest->setParameter('max-keys', $maxKeys); + if ($delimiter !== null && $delimiter !== '') $rest->setParameter('delimiter', $delimiter); + $response = $rest->getResponse(); + if ($response->error === false && $response->code !== 200) + $response->error = array('code' => $response->code, 'message' => 'Unexpected HTTP status'); + if ($response->error !== false) { + trigger_error(sprintf("S3::getBucket(): [%s] %s", $response->error['code'], $response->error['message']), E_USER_WARNING); + return false; + } + + $results = array(); + + $nextMarker = null; + if (isset($response->body, $response->body->Contents)) + foreach ($response->body->Contents as $c) { + $results[(string)$c->Key] = array( + 'name' => (string)$c->Key, + 'time' => strtotime((string)$c->LastModified), + 'size' => (int)$c->Size, + 'hash' => substr((string)$c->ETag, 1, -1) + ); + $nextMarker = (string)$c->Key; + } + + if ($returnCommonPrefixes && isset($response->body, $response->body->CommonPrefixes)) + foreach ($response->body->CommonPrefixes as $c) + $results[(string)$c->Prefix] = array('prefix' => (string)$c->Prefix); + + if (isset($response->body, $response->body->IsTruncated) && + (string)$response->body->IsTruncated == 'false') return $results; + + if (isset($response->body, $response->body->NextMarker)) + $nextMarker = (string)$response->body->NextMarker; + + // Loop through truncated results if maxKeys isn't specified + if ($maxKeys == null && $nextMarker !== null && (string)$response->body->IsTruncated == 'true') + do { + $rest = new S3Request('GET', $bucket, ''); + if ($prefix !== null && $prefix !== '') $rest->setParameter('prefix', $prefix); + $rest->setParameter('marker', $nextMarker); + if ($delimiter !== null && $delimiter !== '') $rest->setParameter('delimiter', $delimiter); + + if (($response = $rest->getResponse(true)) == false || $response->code !== 200) break; + + if (isset($response->body, $response->body->Contents)) + foreach ($response->body->Contents as $c) { + $results[(string)$c->Key] = array( + 'name' => (string)$c->Key, + 'time' => strtotime((string)$c->LastModified), + 'size' => (int)$c->Size, + 'hash' => substr((string)$c->ETag, 1, -1) + ); + $nextMarker = (string)$c->Key; + } + + if ($returnCommonPrefixes && isset($response->body, $response->body->CommonPrefixes)) + foreach ($response->body->CommonPrefixes as $c) + $results[(string)$c->Prefix] = array('prefix' => (string)$c->Prefix); + + if (isset($response->body, $response->body->NextMarker)) + $nextMarker = (string)$response->body->NextMarker; + + } while ($response !== false && (string)$response->body->IsTruncated == 'true'); + + return $results; + } + + + /** + * Put a bucket + * + * @param string $bucket Bucket name + * @param constant $acl ACL flag + * @param string $location Set as "EU" to create buckets hosted in Europe + * @return boolean + */ + public static function putBucket($bucket, $acl = self::ACL_PRIVATE, $location = false) { + $rest = new S3Request('PUT', $bucket, ''); + $rest->setAmzHeader('x-amz-acl', $acl); + + if ($location !== false) { + $dom = new DOMDocument; + $createBucketConfiguration = $dom->createElement('CreateBucketConfiguration'); + $locationConstraint = $dom->createElement('LocationConstraint', strtoupper($location)); + $createBucketConfiguration->appendChild($locationConstraint); + $dom->appendChild($createBucketConfiguration); + $rest->data = $dom->saveXML(); + $rest->size = strlen($rest->data); + $rest->setHeader('Content-Type', 'application/xml'); + } + $rest = $rest->getResponse(); + + if ($rest->error === false && $rest->code !== 200) + $rest->error = array('code' => $rest->code, 'message' => 'Unexpected HTTP status'); + if ($rest->error !== false) { + trigger_error(sprintf("S3::putBucket({$bucket}, {$acl}, {$location}): [%s] %s", + $rest->error['code'], $rest->error['message']), E_USER_WARNING); + return false; + } + return true; + } + + + /** + * Delete an empty bucket + * + * @param string $bucket Bucket name + * @return boolean + */ + public static function deleteBucket($bucket) { + $rest = new S3Request('DELETE', $bucket); + $rest = $rest->getResponse(); + if ($rest->error === false && $rest->code !== 204) + $rest->error = array('code' => $rest->code, 'message' => 'Unexpected HTTP status'); + if ($rest->error !== false) { + trigger_error(sprintf("S3::deleteBucket({$bucket}): [%s] %s", + $rest->error['code'], $rest->error['message']), E_USER_WARNING); + return false; + } + return true; + } + + + /** + * Create input info array for putObject() + * + * @param string $file Input file + * @param mixed $md5sum Use MD5 hash (supply a string if you want to use your own) + * @return array | false + */ + public static function inputFile($file, $md5sum = true) { + if (!file_exists($file) || !is_file($file) || !is_readable($file)) { + trigger_error('S3::inputFile(): Unable to open input file: '.$file, E_USER_WARNING); + return false; + } + return array('file' => $file, 'size' => filesize($file), + 'md5sum' => $md5sum !== false ? (is_string($md5sum) ? $md5sum : + base64_encode(md5_file($file, true))) : ''); + } + + + /** + * Create input array info for putObject() with a resource + * + * @param string $resource Input resource to read from + * @param integer $bufferSize Input byte size + * @param string $md5sum MD5 hash to send (optional) + * @return array | false + */ + public static function inputResource(&$resource, $bufferSize, $md5sum = '') { + if (!is_resource($resource) || $bufferSize < 0) { + trigger_error('S3::inputResource(): Invalid resource or buffer size', E_USER_WARNING); + return false; + } + $input = array('size' => $bufferSize, 'md5sum' => $md5sum); + $input['fp'] =& $resource; + return $input; + } + + + /** + * Put an object + * + * @param mixed $input Input data + * @param string $bucket Bucket name + * @param string $uri Object URI + * @param constant $acl ACL constant + * @param array $metaHeaders Array of x-amz-meta-* headers + * @param array $requestHeaders Array of request headers or content type as a string + * @return boolean + */ + public static function putObject($input, $bucket, $uri, $acl = self::ACL_PRIVATE, $metaHeaders = array(), $requestHeaders = array()) { + if ($input === false) return false; + $rest = new S3Request('PUT', $bucket, $uri); + + if (is_string($input) || is_numeric($input)) $input = array( + 'data' => $input, 'size' => strlen($input), + 'md5sum' => base64_encode(md5($input, true)) + ); + + // Data + if (isset($input['fp'])) + $rest->fp =& $input['fp']; + elseif (isset($input['file'])) + $rest->fp = @fopen($input['file'], 'rb'); + elseif (isset($input['data'])) + $rest->data = $input['data']; + + // Content-Length (required) + if (isset($input['size']) && $input['size'] >= 0) + $rest->size = $input['size']; + else { + if (isset($input['file'])) + $rest->size = filesize($input['file']); + elseif (isset($input['data'])) + $rest->size = strlen($input['data']); + } + + // Custom request headers (Content-Type, Content-Disposition, Content-Encoding) + if (is_array($requestHeaders)) + foreach ($requestHeaders as $h => $v) $rest->setHeader($h, $v); + elseif (is_string($requestHeaders)) // Support for legacy contentType parameter + $input['type'] = $requestHeaders; + + // Content-Type + if (!isset($input['type'])) { + if (isset($requestHeaders['Content-Type'])) + $input['type'] =& $requestHeaders['Content-Type']; + elseif (isset($input['file'])) + $input['type'] = self::__getMimeType($input['file']); + else + $input['type'] = 'application/octet-stream'; + } + + // We need to post with Content-Length and Content-Type, MD5 is optional + if ($rest->size >= 0 && ($rest->fp !== false || $rest->data !== false)) { + $rest->setHeader('Content-Type', $input['type']); + if (isset($input['md5sum'])) $rest->setHeader('Content-MD5', $input['md5sum']); + + $rest->setAmzHeader('x-amz-acl', $acl); + foreach ($metaHeaders as $h => $v) $rest->setAmzHeader('x-amz-meta-'.$h, $v); + $rest->getResponse(); + } else + $rest->response->error = array('code' => 0, 'message' => 'Missing input parameters'); + + if ($rest->response->error === false && $rest->response->code !== 200) + $rest->response->error = array('code' => $rest->response->code, 'message' => 'Unexpected HTTP status'); + if ($rest->response->error !== false) { + trigger_error(sprintf("S3::putObject(): [%s] %s", $rest->response->error['code'], $rest->response->error['message']), E_USER_WARNING); + return false; + } + return true; + } + + + /** + * Put an object from a file (legacy function) + * + * @param string $file Input file path + * @param string $bucket Bucket name + * @param string $uri Object URI + * @param constant $acl ACL constant + * @param array $metaHeaders Array of x-amz-meta-* headers + * @param string $contentType Content type + * @return boolean + */ + public static function putObjectFile($file, $bucket, $uri, $acl = self::ACL_PRIVATE, $metaHeaders = array(), $contentType = null) { + return self::putObject(self::inputFile($file), $bucket, $uri, $acl, $metaHeaders, $contentType); + } + + + /** + * Put an object from a string (legacy function) + * + * @param string $string Input data + * @param string $bucket Bucket name + * @param string $uri Object URI + * @param constant $acl ACL constant + * @param array $metaHeaders Array of x-amz-meta-* headers + * @param string $contentType Content type + * @return boolean + */ + public static function putObjectString($string, $bucket, $uri, $acl = self::ACL_PRIVATE, $metaHeaders = array(), $contentType = 'text/plain') { + return self::putObject($string, $bucket, $uri, $acl, $metaHeaders, $contentType); + } + + + /** + * Get an object + * + * @param string $bucket Bucket name + * @param string $uri Object URI + * @param mixed $saveTo Filename or resource to write to + * @return mixed + */ + public static function getObject($bucket, $uri, $saveTo = false) { + $rest = new S3Request('GET', $bucket, $uri); + if ($saveTo !== false) { + if (is_resource($saveTo)) + $rest->fp =& $saveTo; + else + if (($rest->fp = @fopen($saveTo, 'wb')) !== false) + $rest->file = realpath($saveTo); + else + $rest->response->error = array('code' => 0, 'message' => 'Unable to open save file for writing: '.$saveTo); + } + if ($rest->response->error === false) $rest->getResponse(); + + if ($rest->response->error === false && $rest->response->code !== 200) + $rest->response->error = array('code' => $rest->response->code, 'message' => 'Unexpected HTTP status'); + if ($rest->response->error !== false) { + trigger_error(sprintf("S3::getObject({$bucket}, {$uri}): [%s] %s", + $rest->response->error['code'], $rest->response->error['message']), E_USER_WARNING); + return false; + } + return $rest->response; + } + + + /** + * Get object information + * + * @param string $bucket Bucket name + * @param string $uri Object URI + * @param boolean $returnInfo Return response information + * @return mixed | false + */ + public static function getObjectInfo($bucket, $uri, $returnInfo = true) { + $rest = new S3Request('HEAD', $bucket, $uri); + $rest = $rest->getResponse(); + if ($rest->error === false && ($rest->code !== 200 && $rest->code !== 404)) + $rest->error = array('code' => $rest->code, 'message' => 'Unexpected HTTP status'); + if ($rest->error !== false) { + trigger_error(sprintf("S3::getObjectInfo({$bucket}, {$uri}): [%s] %s", + $rest->error['code'], $rest->error['message']), E_USER_WARNING); + return false; + } + return $rest->code == 200 ? $returnInfo ? $rest->headers : true : false; + } + + + /** + * Copy an object + * + * @param string $bucket Source bucket name + * @param string $uri Source object URI + * @param string $bucket Destination bucket name + * @param string $uri Destination object URI + * @param constant $acl ACL constant + * @param array $metaHeaders Optional array of x-amz-meta-* headers + * @param array $requestHeaders Optional array of request headers (content type, disposition, etc.) + * @return mixed | false + */ + public static function copyObject($srcBucket, $srcUri, $bucket, $uri, $acl = self::ACL_PRIVATE, $metaHeaders = array(), $requestHeaders = array()) { + $rest = new S3Request('PUT', $bucket, $uri); + $rest->setHeader('Content-Length', 0); + foreach ($requestHeaders as $h => $v) $rest->setHeader($h, $v); + foreach ($metaHeaders as $h => $v) $rest->setAmzHeader('x-amz-meta-'.$h, $v); + $rest->setAmzHeader('x-amz-acl', $acl); + $rest->setAmzHeader('x-amz-copy-source', sprintf('/%s/%s', $srcBucket, $srcUri)); + if (sizeof($requestHeaders) > 0 || sizeof($metaHeaders) > 0) + $rest->setAmzHeader('x-amz-metadata-directive', 'REPLACE'); + $rest = $rest->getResponse(); + if ($rest->error === false && $rest->code !== 200) + $rest->error = array('code' => $rest->code, 'message' => 'Unexpected HTTP status'); + if ($rest->error !== false) { + trigger_error(sprintf("S3::copyObject({$srcBucket}, {$srcUri}, {$bucket}, {$uri}): [%s] %s", + $rest->error['code'], $rest->error['message']), E_USER_WARNING); + return false; + } + return isset($rest->body->LastModified, $rest->body->ETag) ? array( + 'time' => strtotime((string)$rest->body->LastModified), + 'hash' => substr((string)$rest->body->ETag, 1, -1) + ) : false; + } + + + /** + * Set logging for a bucket + * + * @param string $bucket Bucket name + * @param string $targetBucket Target bucket (where logs are stored) + * @param string $targetPrefix Log prefix (e,g; domain.com-) + * @return boolean + */ + public static function setBucketLogging($bucket, $targetBucket, $targetPrefix = null) { + // The S3 log delivery group has to be added to the target bucket's ACP + if ($targetBucket !== null && ($acp = self::getAccessControlPolicy($targetBucket, '')) !== false) { + // Only add permissions to the target bucket when they do not exist + $aclWriteSet = false; + $aclReadSet = false; + foreach ($acp['acl'] as $acl) + if ($acl['type'] == 'Group' && $acl['uri'] == 'http://acs.amazonaws.com/groups/s3/LogDelivery') { + if ($acl['permission'] == 'WRITE') $aclWriteSet = true; + elseif ($acl['permission'] == 'READ_ACP') $aclReadSet = true; + } + if (!$aclWriteSet) $acp['acl'][] = array( + 'type' => 'Group', 'uri' => 'http://acs.amazonaws.com/groups/s3/LogDelivery', 'permission' => 'WRITE' + ); + if (!$aclReadSet) $acp['acl'][] = array( + 'type' => 'Group', 'uri' => 'http://acs.amazonaws.com/groups/s3/LogDelivery', 'permission' => 'READ_ACP' + ); + if (!$aclReadSet || !$aclWriteSet) self::setAccessControlPolicy($targetBucket, '', $acp); + } + + $dom = new DOMDocument; + $bucketLoggingStatus = $dom->createElement('BucketLoggingStatus'); + $bucketLoggingStatus->setAttribute('xmlns', 'http://s3.amazonaws.com/doc/2006-03-01/'); + if ($targetBucket !== null) { + if ($targetPrefix == null) $targetPrefix = $bucket . '-'; + $loggingEnabled = $dom->createElement('LoggingEnabled'); + $loggingEnabled->appendChild($dom->createElement('TargetBucket', $targetBucket)); + $loggingEnabled->appendChild($dom->createElement('TargetPrefix', $targetPrefix)); + // TODO: Add TargetGrants? + $bucketLoggingStatus->appendChild($loggingEnabled); + } + $dom->appendChild($bucketLoggingStatus); + + $rest = new S3Request('PUT', $bucket, ''); + $rest->setParameter('logging', null); + $rest->data = $dom->saveXML(); + $rest->size = strlen($rest->data); + $rest->setHeader('Content-Type', 'application/xml'); + $rest = $rest->getResponse(); + if ($rest->error === false && $rest->code !== 200) + $rest->error = array('code' => $rest->code, 'message' => 'Unexpected HTTP status'); + if ($rest->error !== false) { + trigger_error(sprintf("S3::setBucketLogging({$bucket}, {$uri}): [%s] %s", + $rest->error['code'], $rest->error['message']), E_USER_WARNING); + return false; + } + return true; + } + + + /** + * Get logging status for a bucket + * + * This will return false if logging is not enabled. + * Note: To enable logging, you also need to grant write access to the log group + * + * @param string $bucket Bucket name + * @return array | false + */ + public static function getBucketLogging($bucket) { + $rest = new S3Request('GET', $bucket, ''); + $rest->setParameter('logging', null); + $rest = $rest->getResponse(); + if ($rest->error === false && $rest->code !== 200) + $rest->error = array('code' => $rest->code, 'message' => 'Unexpected HTTP status'); + if ($rest->error !== false) { + trigger_error(sprintf("S3::getBucketLogging({$bucket}): [%s] %s", + $rest->error['code'], $rest->error['message']), E_USER_WARNING); + return false; + } + if (!isset($rest->body->LoggingEnabled)) return false; // No logging + return array( + 'targetBucket' => (string)$rest->body->LoggingEnabled->TargetBucket, + 'targetPrefix' => (string)$rest->body->LoggingEnabled->TargetPrefix, + ); + } + + + /** + * Disable bucket logging + * + * @param string $bucket Bucket name + * @return boolean + */ + public static function disableBucketLogging($bucket) { + return self::setBucketLogging($bucket, null); + } + + + /** + * Get a bucket's location + * + * @param string $bucket Bucket name + * @return string | false + */ + public static function getBucketLocation($bucket) { + $rest = new S3Request('GET', $bucket, ''); + $rest->setParameter('location', null); + $rest = $rest->getResponse(); + if ($rest->error === false && $rest->code !== 200) + $rest->error = array('code' => $rest->code, 'message' => 'Unexpected HTTP status'); + if ($rest->error !== false) { + trigger_error(sprintf("S3::getBucketLocation({$bucket}): [%s] %s", + $rest->error['code'], $rest->error['message']), E_USER_WARNING); + return false; + } + return (isset($rest->body[0]) && (string)$rest->body[0] !== '') ? (string)$rest->body[0] : 'US'; + } + + + /** + * Set object or bucket Access Control Policy + * + * @param string $bucket Bucket name + * @param string $uri Object URI + * @param array $acp Access Control Policy Data (same as the data returned from getAccessControlPolicy) + * @return boolean + */ + public static function setAccessControlPolicy($bucket, $uri = '', $acp = array()) { + $dom = new DOMDocument; + $dom->formatOutput = true; + $accessControlPolicy = $dom->createElement('AccessControlPolicy'); + $accessControlList = $dom->createElement('AccessControlList'); + + // It seems the owner has to be passed along too + $owner = $dom->createElement('Owner'); + $owner->appendChild($dom->createElement('ID', $acp['owner']['id'])); + $owner->appendChild($dom->createElement('DisplayName', $acp['owner']['name'])); + $accessControlPolicy->appendChild($owner); + + foreach ($acp['acl'] as $g) { + $grant = $dom->createElement('Grant'); + $grantee = $dom->createElement('Grantee'); + $grantee->setAttribute('xmlns:xsi', 'http://www.w3.org/2001/XMLSchema-instance'); + if (isset($g['id'])) { // CanonicalUser (DisplayName is omitted) + $grantee->setAttribute('xsi:type', 'CanonicalUser'); + $grantee->appendChild($dom->createElement('ID', $g['id'])); + } elseif (isset($g['email'])) { // AmazonCustomerByEmail + $grantee->setAttribute('xsi:type', 'AmazonCustomerByEmail'); + $grantee->appendChild($dom->createElement('EmailAddress', $g['email'])); + } elseif ($g['type'] == 'Group') { // Group + $grantee->setAttribute('xsi:type', 'Group'); + $grantee->appendChild($dom->createElement('URI', $g['uri'])); + } + $grant->appendChild($grantee); + $grant->appendChild($dom->createElement('Permission', $g['permission'])); + $accessControlList->appendChild($grant); + } + + $accessControlPolicy->appendChild($accessControlList); + $dom->appendChild($accessControlPolicy); + + $rest = new S3Request('PUT', $bucket, $uri); + $rest->setParameter('acl', null); + $rest->data = $dom->saveXML(); + $rest->size = strlen($rest->data); + $rest->setHeader('Content-Type', 'application/xml'); + $rest = $rest->getResponse(); + if ($rest->error === false && $rest->code !== 200) + $rest->error = array('code' => $rest->code, 'message' => 'Unexpected HTTP status'); + if ($rest->error !== false) { + trigger_error(sprintf("S3::setAccessControlPolicy({$bucket}, {$uri}): [%s] %s", + $rest->error['code'], $rest->error['message']), E_USER_WARNING); + return false; + } + return true; + } + + + /** + * Get object or bucket Access Control Policy + * + * @param string $bucket Bucket name + * @param string $uri Object URI + * @return mixed | false + */ + public static function getAccessControlPolicy($bucket, $uri = '') { + $rest = new S3Request('GET', $bucket, $uri); + $rest->setParameter('acl', null); + $rest = $rest->getResponse(); + if ($rest->error === false && $rest->code !== 200) + $rest->error = array('code' => $rest->code, 'message' => 'Unexpected HTTP status'); + if ($rest->error !== false) { + trigger_error(sprintf("S3::getAccessControlPolicy({$bucket}, {$uri}): [%s] %s", + $rest->error['code'], $rest->error['message']), E_USER_WARNING); + return false; + } + + $acp = array(); + if (isset($rest->body->Owner, $rest->body->Owner->ID, $rest->body->Owner->DisplayName)) { + $acp['owner'] = array( + 'id' => (string)$rest->body->Owner->ID, 'name' => (string)$rest->body->Owner->DisplayName + ); + } + if (isset($rest->body->AccessControlList)) { + $acp['acl'] = array(); + foreach ($rest->body->AccessControlList->Grant as $grant) { + foreach ($grant->Grantee as $grantee) { + if (isset($grantee->ID, $grantee->DisplayName)) // CanonicalUser + $acp['acl'][] = array( + 'type' => 'CanonicalUser', + 'id' => (string)$grantee->ID, + 'name' => (string)$grantee->DisplayName, + 'permission' => (string)$grant->Permission + ); + elseif (isset($grantee->EmailAddress)) // AmazonCustomerByEmail + $acp['acl'][] = array( + 'type' => 'AmazonCustomerByEmail', + 'email' => (string)$grantee->EmailAddress, + 'permission' => (string)$grant->Permission + ); + elseif (isset($grantee->URI)) // Group + $acp['acl'][] = array( + 'type' => 'Group', + 'uri' => (string)$grantee->URI, + 'permission' => (string)$grant->Permission + ); + else continue; + } + } + } + return $acp; + } + + + /** + * Delete an object + * + * @param string $bucket Bucket name + * @param string $uri Object URI + * @return boolean + */ + public static function deleteObject($bucket, $uri) { + $rest = new S3Request('DELETE', $bucket, $uri); + $rest = $rest->getResponse(); + if ($rest->error === false && $rest->code !== 204) + $rest->error = array('code' => $rest->code, 'message' => 'Unexpected HTTP status'); + if ($rest->error !== false) { + trigger_error(sprintf("S3::deleteObject(): [%s] %s", + $rest->error['code'], $rest->error['message']), E_USER_WARNING); + return false; + } + return true; + } + + + /** + * Get a query string authenticated URL + * + * @param string $bucket Bucket name + * @param string $uri Object URI + * @param integer $lifetime Lifetime in seconds + * @param boolean $hostBucket Use the bucket name as the hostname + * @param boolean $https Use HTTPS ($hostBucket should be false for SSL verification) + * @return string + */ + public static function getAuthenticatedURL($bucket, $uri, $lifetime, $hostBucket = false, $https = false) { + $expires = time() + $lifetime; + $uri = str_replace('%2F', '/', rawurlencode($uri)); // URI should be encoded (thanks Sean O'Dea) + return sprintf(($https ? 'https' : 'http').'://%s/%s?AWSAccessKeyId=%s&Expires=%u&Signature=%s', + $hostBucket ? $bucket : $bucket.'.s3.amazonaws.com', $uri, self::$__accessKey, $expires, + urlencode(self::__getHash("GET\n\n\n{$expires}\n/{$bucket}/{$uri}"))); + } + + /** + * Get upload POST parameters for form uploads + * + * @param string $bucket Bucket name + * @param string $uriPrefix Object URI prefix + * @param constant $acl ACL constant + * @param integer $lifetime Lifetime in seconds + * @param integer $maxFileSize Maximum filesize in bytes (default 5MB) + * @param string $successRedirect Redirect URL or 200 / 201 status code + * @param array $amzHeaders Array of x-amz-meta-* headers + * @param array $headers Array of request headers or content type as a string + * @param boolean $flashVars Includes additional "Filename" variable posted by Flash + * @return object + */ + public static function getHttpUploadPostParams($bucket, $uriPrefix = '', $acl = self::ACL_PRIVATE, $lifetime = 3600, $maxFileSize = 5242880, $successRedirect = "201", $amzHeaders = array(), $headers = array(), $flashVars = false) { + // Create policy object + $policy = new stdClass; + $policy->expiration = gmdate('Y-m-d\TH:i:s\Z', (time() + $lifetime)); + $policy->conditions = array(); + $obj = new stdClass; $obj->bucket = $bucket; array_push($policy->conditions, $obj); + $obj = new stdClass; $obj->acl = $acl; array_push($policy->conditions, $obj); + + $obj = new stdClass; // 200 for non-redirect uploads + if (is_numeric($successRedirect) && in_array((int)$successRedirect, array(200, 201))) + $obj->success_action_status = (string)$successRedirect; + else // URL + $obj->success_action_redirect = $successRedirect; + array_push($policy->conditions, $obj); + + array_push($policy->conditions, array('starts-with', '$key', $uriPrefix)); + if ($flashVars) array_push($policy->conditions, array('starts-with', '$Filename', '')); + foreach (array_keys($headers) as $headerKey) + array_push($policy->conditions, array('starts-with', '$'.$headerKey, '')); + foreach ($amzHeaders as $headerKey => $headerVal) { + $obj = new stdClass; $obj->{$headerKey} = (string)$headerVal; array_push($policy->conditions, $obj); + } + array_push($policy->conditions, array('content-length-range', 0, $maxFileSize)); + $policy = base64_encode(str_replace('\/', '/', json_encode($policy))); + + // Create parameters + $params = new stdClass; + $params->AWSAccessKeyId = self::$__accessKey; + $params->key = $uriPrefix.'${filename}'; + $params->acl = $acl; + $params->policy = $policy; unset($policy); + $params->signature = self::__getHash($params->policy); + if (is_numeric($successRedirect) && in_array((int)$successRedirect, array(200, 201))) + $params->success_action_status = (string)$successRedirect; + else + $params->success_action_redirect = $successRedirect; + foreach ($headers as $headerKey => $headerVal) $params->{$headerKey} = (string)$headerVal; + foreach ($amzHeaders as $headerKey => $headerVal) $params->{$headerKey} = (string)$headerVal; + return $params; + } + + /** + * Create a CloudFront distribution + * + * @param string $bucket Bucket name + * @param boolean $enabled Enabled (true/false) + * @param array $cnames Array containing CNAME aliases + * @param string $comment Use the bucket name as the hostname + * @return array | false + */ + public static function createDistribution($bucket, $enabled = true, $cnames = array(), $comment = '') { + self::$useSSL = true; // CloudFront requires SSL + $rest = new S3Request('POST', '', '2008-06-30/distribution', 'cloudfront.amazonaws.com'); + $rest->data = self::__getCloudFrontDistributionConfigXML($bucket.'.s3.amazonaws.com', $enabled, $comment, (string)microtime(true), $cnames); + $rest->size = strlen($rest->data); + $rest->setHeader('Content-Type', 'application/xml'); + $rest = self::__getCloudFrontResponse($rest); + + if ($rest->error === false && $rest->code !== 201) + $rest->error = array('code' => $rest->code, 'message' => 'Unexpected HTTP status'); + if ($rest->error !== false) { + trigger_error(sprintf("S3::createDistribution({$bucket}, ".(int)$enabled.", '$comment'): [%s] %s", + $rest->error['code'], $rest->error['message']), E_USER_WARNING); + return false; + } elseif ($rest->body instanceof SimpleXMLElement) + return self::__parseCloudFrontDistributionConfig($rest->body); + return false; + } + + + /** + * Get CloudFront distribution info + * + * @param string $distributionId Distribution ID from listDistributions() + * @return array | false + */ + public static function getDistribution($distributionId) { + self::$useSSL = true; // CloudFront requires SSL + $rest = new S3Request('GET', '', '2008-06-30/distribution/'.$distributionId, 'cloudfront.amazonaws.com'); + $rest = self::__getCloudFrontResponse($rest); + + if ($rest->error === false && $rest->code !== 200) + $rest->error = array('code' => $rest->code, 'message' => 'Unexpected HTTP status'); + if ($rest->error !== false) { + trigger_error(sprintf("S3::getDistribution($distributionId): [%s] %s", + $rest->error['code'], $rest->error['message']), E_USER_WARNING); + return false; + } elseif ($rest->body instanceof SimpleXMLElement) { + $dist = self::__parseCloudFrontDistributionConfig($rest->body); + $dist['hash'] = $rest->headers['hash']; + return $dist; + } + return false; + } + + + /** + * Update a CloudFront distribution + * + * @param array $dist Distribution array info identical to output of getDistribution() + * @return array | false + */ + public static function updateDistribution($dist) { + self::$useSSL = true; // CloudFront requires SSL + $rest = new S3Request('PUT', '', '2008-06-30/distribution/'.$dist['id'].'/config', 'cloudfront.amazonaws.com'); + $rest->data = self::__getCloudFrontDistributionConfigXML($dist['origin'], $dist['enabled'], $dist['comment'], $dist['callerReference'], $dist['cnames']); + $rest->size = strlen($rest->data); + $rest->setHeader('If-Match', $dist['hash']); + $rest = self::__getCloudFrontResponse($rest); + + if ($rest->error === false && $rest->code !== 200) + $rest->error = array('code' => $rest->code, 'message' => 'Unexpected HTTP status'); + if ($rest->error !== false) { + trigger_error(sprintf("S3::updateDistribution({$dist['id']}, ".(int)$enabled.", '$comment'): [%s] %s", + $rest->error['code'], $rest->error['message']), E_USER_WARNING); + return false; + } else { + $dist = self::__parseCloudFrontDistributionConfig($rest->body); + $dist['hash'] = $rest->headers['hash']; + return $dist; + } + return false; + } + + + /** + * Delete a CloudFront distribution + * + * @param array $dist Distribution array info identical to output of getDistribution() + * @return boolean + */ + public static function deleteDistribution($dist) { + self::$useSSL = true; // CloudFront requires SSL + $rest = new S3Request('DELETE', '', '2008-06-30/distribution/'.$dist['id'], 'cloudfront.amazonaws.com'); + $rest->setHeader('If-Match', $dist['hash']); + $rest = self::__getCloudFrontResponse($rest); + + if ($rest->error === false && $rest->code !== 204) + $rest->error = array('code' => $rest->code, 'message' => 'Unexpected HTTP status'); + if ($rest->error !== false) { + trigger_error(sprintf("S3::deleteDistribution({$dist['id']}): [%s] %s", + $rest->error['code'], $rest->error['message']), E_USER_WARNING); + return false; + } + return true; + } + + + /** + * Get a list of CloudFront distributions + * + * @return array + */ + public static function listDistributions() { + self::$useSSL = true; // CloudFront requires SSL + $rest = new S3Request('GET', '', '2008-06-30/distribution', 'cloudfront.amazonaws.com'); + $rest = self::__getCloudFrontResponse($rest); + + if ($rest->error === false && $rest->code !== 200) + $rest->error = array('code' => $rest->code, 'message' => 'Unexpected HTTP status'); + if ($rest->error !== false) { + trigger_error(sprintf("S3::listDistributions(): [%s] %s", + $rest->error['code'], $rest->error['message']), E_USER_WARNING); + return false; + } elseif ($rest->body instanceof SimpleXMLElement && isset($rest->body->DistributionSummary)) { + $list = array(); + if (isset($rest->body->Marker, $rest->body->MaxItems, $rest->body->IsTruncated)) { + //$info['marker'] = (string)$rest->body->Marker; + //$info['maxItems'] = (int)$rest->body->MaxItems; + //$info['isTruncated'] = (string)$rest->body->IsTruncated == 'true' ? true : false; + } + foreach ($rest->body->DistributionSummary as $summary) { + $list[(string)$summary->Id] = self::__parseCloudFrontDistributionConfig($summary); + } + return $list; + } + return array(); + } + + + /** + * Get a DistributionConfig DOMDocument + * + * @internal Used to create XML in createDistribution() and updateDistribution() + * @param string $bucket Origin bucket + * @param boolean $enabled Enabled (true/false) + * @param string $comment Comment to append + * @param string $callerReference Caller reference + * @param array $cnames Array of CNAME aliases + * @return string + */ + private static function __getCloudFrontDistributionConfigXML($bucket, $enabled, $comment, $callerReference = '0', $cnames = array()) { + $dom = new DOMDocument('1.0', 'UTF-8'); + $dom->formatOutput = true; + $distributionConfig = $dom->createElement('DistributionConfig'); + $distributionConfig->setAttribute('xmlns', 'http://cloudfront.amazonaws.com/doc/2008-06-30/'); + $distributionConfig->appendChild($dom->createElement('Origin', $bucket)); + $distributionConfig->appendChild($dom->createElement('CallerReference', $callerReference)); + foreach ($cnames as $cname) + $distributionConfig->appendChild($dom->createElement('CNAME', $cname)); + if ($comment !== '') $distributionConfig->appendChild($dom->createElement('Comment', $comment)); + $distributionConfig->appendChild($dom->createElement('Enabled', $enabled ? 'true' : 'false')); + $dom->appendChild($distributionConfig); + return $dom->saveXML(); + } + + + /** + * Parse a CloudFront distribution config + * + * @internal Used to parse the CloudFront DistributionConfig node to an array + * @param object &$node DOMNode + * @return array + */ + private static function __parseCloudFrontDistributionConfig(&$node) { + $dist = array(); + if (isset($node->Id, $node->Status, $node->LastModifiedTime, $node->DomainName)) { + $dist['id'] = (string)$node->Id; + $dist['status'] = (string)$node->Status; + $dist['time'] = strtotime((string)$node->LastModifiedTime); + $dist['domain'] = (string)$node->DomainName; + } + if (isset($node->CallerReference)) + $dist['callerReference'] = (string)$node->CallerReference; + if (isset($node->Comment)) + $dist['comment'] = (string)$node->Comment; + if (isset($node->Enabled, $node->Origin)) { + $dist['origin'] = (string)$node->Origin; + $dist['enabled'] = (string)$node->Enabled == 'true' ? true : false; + } elseif (isset($node->DistributionConfig)) { + $dist = array_merge($dist, self::__parseCloudFrontDistributionConfig($node->DistributionConfig)); + } + if (isset($node->CNAME)) { + $dist['cnames'] = array(); + foreach ($node->CNAME as $cname) $dist['cnames'][(string)$cname] = (string)$cname; + } + return $dist; + } + + + /** + * Grab CloudFront response + * + * @internal Used to parse the CloudFront S3Request::getResponse() output + * @param object &$rest S3Request instance + * @return object + */ + private static function __getCloudFrontResponse(&$rest) { + $rest->getResponse(); + if ($rest->response->error === false && isset($rest->response->body) && + is_string($rest->response->body) && substr($rest->response->body, 0, 5) == 'response->body = simplexml_load_string($rest->response->body); + // Grab CloudFront errors + if (isset($rest->response->body->Error, $rest->response->body->Error->Code, + $rest->response->body->Error->Message)) { + $rest->response->error = array( + 'code' => (string)$rest->response->body->Error->Code, + 'message' => (string)$rest->response->body->Error->Message + ); + unset($rest->response->body); + } + } + return $rest->response; + } + + + /** + * Get MIME type for file + * + * @internal Used to get mime types + * @param string &$file File path + * @return string + */ + public static function __getMimeType(&$file) { + $type = false; + // Fileinfo documentation says fileinfo_open() will use the + // MAGIC env var for the magic file + if (extension_loaded('fileinfo') && isset($_ENV['MAGIC']) && + ($finfo = finfo_open(FILEINFO_MIME, $_ENV['MAGIC'])) !== false) { + if (($type = finfo_file($finfo, $file)) !== false) { + // Remove the charset and grab the last content-type + $type = explode(' ', str_replace('; charset=', ';charset=', $type)); + $type = array_pop($type); + $type = explode(';', $type); + $type = trim(array_shift($type)); + } + finfo_close($finfo); + + // If anyone is still using mime_content_type() + } elseif (function_exists('mime_content_type')) + $type = trim(mime_content_type($file)); + + if ($type !== false && strlen($type) > 0) return $type; + + // Otherwise do it the old fashioned way + static $exts = array( + 'jpg' => 'image/jpeg', 'gif' => 'image/gif', 'png' => 'image/png', + 'tif' => 'image/tiff', 'tiff' => 'image/tiff', 'ico' => 'image/x-icon', + 'swf' => 'application/x-shockwave-flash', 'pdf' => 'application/pdf', + 'zip' => 'application/zip', 'gz' => 'application/x-gzip', + 'tar' => 'application/x-tar', 'bz' => 'application/x-bzip', + 'bz2' => 'application/x-bzip2', 'txt' => 'text/plain', + 'asc' => 'text/plain', 'htm' => 'text/html', 'html' => 'text/html', + 'css' => 'text/css', 'js' => 'text/javascript', + 'xml' => 'text/xml', 'xsl' => 'application/xsl+xml', + 'ogg' => 'application/ogg', 'mp3' => 'audio/mpeg', 'wav' => 'audio/x-wav', + 'avi' => 'video/x-msvideo', 'mpg' => 'video/mpeg', 'mpeg' => 'video/mpeg', + 'mov' => 'video/quicktime', 'flv' => 'video/x-flv', 'php' => 'text/x-php' + ); + $ext = strtolower(pathInfo($file, PATHINFO_EXTENSION)); + return isset($exts[$ext]) ? $exts[$ext] : 'application/octet-stream'; + } + + + /** + * Generate the auth string: "AWS AccessKey:Signature" + * + * @internal Used by S3Request::getResponse() + * @param string $string String to sign + * @return string + */ + public static function __getSignature($string) { + return 'AWS '.self::$__accessKey.':'.self::__getHash($string); + } + + + /** + * Creates a HMAC-SHA1 hash + * + * This uses the hash extension if loaded + * + * @internal Used by __getSignature() + * @param string $string String to sign + * @return string + */ + private static function __getHash($string) { + return base64_encode(extension_loaded('hash') ? + hash_hmac('sha1', $string, self::$__secretKey, true) : pack('H*', sha1( + (str_pad(self::$__secretKey, 64, chr(0x00)) ^ (str_repeat(chr(0x5c), 64))) . + pack('H*', sha1((str_pad(self::$__secretKey, 64, chr(0x00)) ^ + (str_repeat(chr(0x36), 64))) . $string))))); + } + +} + +final class S3Request { + private $verb, $bucket, $uri, $resource = '', $parameters = array(), + $amzHeaders = array(), $headers = array( + 'Host' => '', 'Date' => '', 'Content-MD5' => '', 'Content-Type' => '' + ); + public $fp = false, $size = 0, $data = false, $response; + + + /** + * Constructor + * + * @param string $verb Verb + * @param string $bucket Bucket name + * @param string $uri Object URI + * @return mixed + */ + function __construct($verb, $bucket = '', $uri = '', $defaultHost = 's3.amazonaws.com') { + $this->verb = $verb; + $this->bucket = strtolower($bucket); + $this->uri = $uri !== '' ? '/'.str_replace('%2F', '/', rawurlencode($uri)) : '/'; + + if ($this->bucket !== '') { + $this->headers['Host'] = $this->bucket.'.'.$defaultHost; + $this->resource = '/'.$this->bucket.$this->uri; + } else { + $this->headers['Host'] = $defaultHost; + //$this->resource = strlen($this->uri) > 1 ? '/'.$this->bucket.$this->uri : $this->uri; + $this->resource = $this->uri; + } + $this->headers['Date'] = gmdate('D, d M Y H:i:s T'); + + $this->response = new STDClass; + $this->response->error = false; + } + + + /** + * Set request parameter + * + * @param string $key Key + * @param string $value Value + * @return void + */ + public function setParameter($key, $value) { + $this->parameters[$key] = $value; + } + + + /** + * Set request header + * + * @param string $key Key + * @param string $value Value + * @return void + */ + public function setHeader($key, $value) { + $this->headers[$key] = $value; + } + + + /** + * Set x-amz-meta-* header + * + * @param string $key Key + * @param string $value Value + * @return void + */ + public function setAmzHeader($key, $value) { + $this->amzHeaders[$key] = $value; + } + + + /** + * Get the S3 response + * + * @return object | false + */ + public function getResponse() { + $query = ''; + if (sizeof($this->parameters) > 0) { + $query = substr($this->uri, -1) !== '?' ? '?' : '&'; + foreach ($this->parameters as $var => $value) + if ($value == null || $value == '') $query .= $var.'&'; + // Parameters should be encoded (thanks Sean O'Dea) + else $query .= $var.'='.rawurlencode($value).'&'; + $query = substr($query, 0, -1); + $this->uri .= $query; + + if (array_key_exists('acl', $this->parameters) || + array_key_exists('location', $this->parameters) || + array_key_exists('torrent', $this->parameters) || + array_key_exists('logging', $this->parameters)) + $this->resource .= $query; + } + $url = ((S3::$useSSL && extension_loaded('openssl')) ? + 'https://':'http://').$this->headers['Host'].$this->uri; + //var_dump($this->bucket, $this->uri, $this->resource, $url); + + // Basic setup + $curl = curl_init(); + curl_setopt($curl, CURLOPT_USERAGENT, 'S3/php'); + + if (S3::$useSSL) { + curl_setopt($curl, CURLOPT_SSL_VERIFYPEER , false ); + curl_setopt($curl, CURLOPT_SSL_VERIFYHOST , false ); +// curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 1); +// curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, 1); + } + + curl_setopt($curl, CURLOPT_URL, $url); + + // Headers + $headers = array(); $amz = array(); + foreach ($this->amzHeaders as $header => $value) + if (strlen($value) > 0) $headers[] = $header.': '.$value; + foreach ($this->headers as $header => $value) + if (strlen($value) > 0) $headers[] = $header.': '.$value; + + // Collect AMZ headers for signature + foreach ($this->amzHeaders as $header => $value) + if (strlen($value) > 0) $amz[] = strtolower($header).':'.$value; + + // AMZ headers must be sorted + if (sizeof($amz) > 0) { + sort($amz); + $amz = "\n".implode("\n", $amz); + } else $amz = ''; + + // Authorization string (CloudFront stringToSign should only contain a date) + $headers[] = 'Authorization: ' . S3::__getSignature( + $this->headers['Host'] == 'cloudfront.amazonaws.com' ? $this->headers['Date'] : + $this->verb."\n".$this->headers['Content-MD5']."\n". + $this->headers['Content-Type']."\n".$this->headers['Date'].$amz."\n".$this->resource + ); + + curl_setopt($curl, CURLOPT_HTTPHEADER, $headers); + curl_setopt($curl, CURLOPT_HEADER, false); + curl_setopt($curl, CURLOPT_RETURNTRANSFER, false); + curl_setopt($curl, CURLOPT_WRITEFUNCTION, array(&$this, '__responseWriteCallback')); + curl_setopt($curl, CURLOPT_HEADERFUNCTION, array(&$this, '__responseHeaderCallback')); + curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true); + + // Request types + switch ($this->verb) { + case 'GET': break; + case 'PUT': case 'POST': // POST only used for CloudFront + if ($this->fp !== false) { + curl_setopt($curl, CURLOPT_PUT, true); + curl_setopt($curl, CURLOPT_INFILE, $this->fp); + if ($this->size >= 0) + curl_setopt($curl, CURLOPT_INFILESIZE, $this->size); + } elseif ($this->data !== false) { + curl_setopt($curl, CURLOPT_CUSTOMREQUEST, $this->verb); + curl_setopt($curl, CURLOPT_POSTFIELDS, $this->data); + if ($this->size >= 0) + curl_setopt($curl, CURLOPT_BUFFERSIZE, $this->size); + } else + curl_setopt($curl, CURLOPT_CUSTOMREQUEST, $this->verb); + break; + case 'HEAD': + curl_setopt($curl, CURLOPT_CUSTOMREQUEST, 'HEAD'); + curl_setopt($curl, CURLOPT_NOBODY, true); + break; + case 'DELETE': + curl_setopt($curl, CURLOPT_CUSTOMREQUEST, 'DELETE'); + break; + default: break; + } + + // Execute, grab errors + if (curl_exec($curl)) + $this->response->code = curl_getinfo($curl, CURLINFO_HTTP_CODE); + else + $this->response->error = array( + 'code' => curl_errno($curl), + 'message' => curl_error($curl), + 'resource' => $this->resource + ); + + @curl_close($curl); + + // Parse body into XML + if ($this->response->error === false && isset($this->response->headers['type']) && + $this->response->headers['type'] == 'application/xml' && isset($this->response->body)) { + $this->response->body = simplexml_load_string($this->response->body); + + // Grab S3 errors + if (!in_array($this->response->code, array(200, 204)) && + isset($this->response->body->Code, $this->response->body->Message)) { + $this->response->error = array( + 'code' => (string)$this->response->body->Code, + 'message' => (string)$this->response->body->Message + ); + if (isset($this->response->body->Resource)) + $this->response->error['resource'] = (string)$this->response->body->Resource; + unset($this->response->body); + } + } + + // Clean up file resources + if ($this->fp !== false && is_resource($this->fp)) fclose($this->fp); + + return $this->response; + } + + + /** + * CURL write callback + * + * @param resource &$curl CURL resource + * @param string &$data Data + * @return integer + */ + private function __responseWriteCallback(&$curl, &$data) { + if ($this->response->code == 200 && $this->fp !== false) + return fwrite($this->fp, $data); + else + $this->response->body .= $data; + return strlen($data); + } + + + /** + * CURL header callback + * + * @param resource &$curl CURL resource + * @param string &$data Data + * @return integer + */ + private function __responseHeaderCallback(&$curl, &$data) { + if (($strlen = strlen($data)) <= 2) return $strlen; + if (substr($data, 0, 4) == 'HTTP') + $this->response->code = (int)substr($data, 9, 3); + else { + list($header, $value) = explode(': ', trim($data), 2); + if ($header == 'Last-Modified') + $this->response->headers['time'] = strtotime($value); + elseif ($header == 'Content-Length') + $this->response->headers['size'] = (int)$value; + elseif ($header == 'Content-Type') + $this->response->headers['type'] = $value; + elseif ($header == 'ETag') + $this->response->headers['hash'] = $value{0} == '"' ? substr($value, 1, -1) : $value; + elseif (preg_match('/^x-amz-meta-.*$/', $header)) + $this->response->headers[$header] = is_numeric($value) ? (int)$value : $value; + } + return $strlen; + } + +} diff --git a/3.0/modules/aws_s3/models/MY_Item_Model.php b/3.0/modules/aws_s3/models/MY_Item_Model.php new file mode 100644 index 00000000..1ef443f2 --- /dev/null +++ b/3.0/modules/aws_s3/models/MY_Item_Model.php @@ -0,0 +1,90 @@ +s3_thumb_uploaded) + return parent::thumb_url($full_uri); + + if ($this->is_photo()) + return aws_s3::generate_url("th/" . $this->relative_path(), ($this->view_1 == 1 ? false : true), $this->updated); + else if ($this->is_album() && $this->id > 1) + return aws_s3::generate_url("th/" . $this->relative_path() . "/.album.jpg", ($this->view_1 == 1 ? false : true), $this->updated); + else if ($this->is_movie()) + return aws_s3::generate_url("th/" . preg_replace("/...$/", "jpg", $this->relative_path()), ($this->view_1 == 1 ? false : true), $this->updated); + } + + public function file_url($full_uri=false) { + if (!module::get_var("aws_s3", "enabled") || Router::$controller == "rest" || !$this->s3_fullsize_uploaded) + return parent::file_url($full_uri); + + return aws_s3::generate_url("fs/" . $this->relative_path(), ($this->view_1 == 1 ? false : true), $this->updated); + } + + public function resize_url($full_uri=false) { + if (!module::get_var("aws_s3", "enabled") || Router::$controller == "rest" || !$this->s3_resize_uploaded) + return parent::resize_url($full_uri); + + if ($this->is_album() && $this->id > 1) + return aws_s3::generate_url("rs/" . $this->relative_path() . "/.album.jpg", ($this->view_1 == 1 ? false : true), $this->updated); + else + return aws_s3::generate_url("rs/" . $this->relative_path(), ($this->view_1 == 1 ? false : true), $this->updated); + } + + private function _load_aws_s3_meta($create_if_not_exists = true) { + $this->_aws_s3_meta = ORM::factory("aws_s3_meta")->find($this->id); + if (!$this->_aws_s3_meta->item_id) { + if ($create_if_not_exists) { + $this->_aws_s3_meta->item_id = $this->id; + $this->_aws_s3_meta->save(); + } + else + return false; + } + return $this; + } + + public function has_aws_s3_meta() { + if (!$this->_load_aws_s3_meta(false)) + return false; + return true; + } + + public function get_aws_s3_meta() { + if (!$this->_aws_s3_meta) + $this->_load_aws_s3_meta(); + + return $this->_aws_s3_meta; + } + + public function save_s3_meta() { + if ($this->_aws_s3_meta) + $this->_aws_s3_meta->save(); + } + + public function save() { + $this->save_s3_meta(); + return parent::save(); + } + + public function __get($column) { + if (substr($column, 0, 3) == "s3_") { + $var = substr($column, 3); + return $this->get_aws_s3_meta()->$var; + } + return parent::__get($column); + } + + public function __set($column, $value) { + if (substr($column, 0, 3) == "s3_") { + $var = substr($column, 3); + $this->get_aws_s3_meta()->$var = $value; + } + else { + parent::__set($column, $value); + } + } + +} \ No newline at end of file diff --git a/3.0/modules/aws_s3/models/aws_s3_meta.php b/3.0/modules/aws_s3/models/aws_s3_meta.php new file mode 100644 index 00000000..7010c595 --- /dev/null +++ b/3.0/modules/aws_s3/models/aws_s3_meta.php @@ -0,0 +1,6 @@ + S3 file transfers diff --git a/3.0/modules/aws_s3/views/admin_aws_s3.html.php b/3.0/modules/aws_s3/views/admin_aws_s3.html.php new file mode 100644 index 00000000..05d340de --- /dev/null +++ b/3.0/modules/aws_s3/views/admin_aws_s3.html.php @@ -0,0 +1,16 @@ + + +
      + +

      + +

      + +

      donating to help support future development."); ?> + +

      + +
      +
      + + diff --git a/3.0/modules/basket/helpers/basket_theme.php b/3.0/modules/basket/helpers/basket_theme.php index 1ad535e5..db2c91da 100644 --- a/3.0/modules/basket/helpers/basket_theme.php +++ b/3.0/modules/basket/helpers/basket_theme.php @@ -20,7 +20,7 @@ class basket_theme_Core { static function head($theme) { - $theme->css("basket.css"); + return $theme->css("basket.css"); } static function header_top($theme) { diff --git a/3.0/modules/basket/module.info b/3.0/modules/basket/module.info index 559c59aa..965a7df3 100644 --- a/3.0/modules/basket/module.info +++ b/3.0/modules/basket/module.info @@ -1,3 +1,7 @@ name = "Shopping Basket" description = "Provides a simple shopping basket and checkout with paypal integration" version = 5 +author_name = "" +author_url = "" +info_url = "http://codex.gallery2.org/Gallery3:Modules:basket" +discuss_url = "http://gallery.menalto.com/forum_module_basket" diff --git a/3.0/modules/batchtag/controllers/batchtag.php b/3.0/modules/batchtag/controllers/batchtag.php index ec012719..01f2e7ff 100644 --- a/3.0/modules/batchtag/controllers/batchtag.php +++ b/3.0/modules/batchtag/controllers/batchtag.php @@ -1,7 +1,7 @@ post('name')}&item_id={$input->post('item_id')}&tag_subitems={$input->post('tag_subitems')}&csrf={$input->post('csrf')}")); + } + + public function tagitems2() { + // Tag all non-album items in the current album with the specified tags. + + // Prevent Cross Site Request Forgery + access::verify_csrf(); + + $input = Input::instance(); + + // Variables + if (($input->get("batchtag_max") == false) || ($input->get("batchtag_max") == "0")) { + $batchtag_max = "50"; + } else { + $batchtag_max = $input->get("batchtag_max"); + } + if ($input->get("batchtag_items_processed") == false) { + $batchtag_items_processed = "0"; + } else { + $batchtag_items_processed = $input->get("batchtag_items_processed"); + } + // Figure out if the contents of sub-albums should also be tagged - $str_tag_subitems = $input->post("tag_subitems"); + $str_tag_subitems = $input->get("tag_subitems"); $children = ""; if ($str_tag_subitems == false) { // Generate an array of all non-album items in the current album. $children = ORM::factory("item") - ->where("parent_id", "=", $input->post("item_id")) + ->where("parent_id", "=", $input->get("item_id")) ->where("type", "!=", "album") ->find_all(); } else { // Generate an array of all non-album items in the current album // and any sub albums. - $item = ORM::factory("item", $input->post("item_id")); + $item = ORM::factory("item", $input->get("item_id")); $children = $item->descendants(); } + // Loop through each item in the album and make sure the user has // access to view and edit it. - foreach ($children as $child) { - if (access::can("view", $child) && access::can("edit", $child) && !$child->is_album()) { + $children_count = "0"; + $tag_count = "0"; - // Assuming the user can view/edit the current item, loop - // through each tag that was submitted and apply it to - // the current item. - foreach (explode(",", $input->post("name")) as $tag_name) { - $tag_name = trim($tag_name); - if ($tag_name) { - tag::add($child, $tag_name); + //echo Kohana::debug($children); + + echo ''; + + foreach ($children as $child) { + + if ($tag_count < $batchtag_max) { + + if ($children_count >= $batchtag_items_processed) { + if (access::can("view", $child) && access::can("edit", $child) && !$child->is_album()) { + + // Assuming the user can view/edit the current item, loop + // through each tag that was submitted and apply it to + // the current item. + foreach (explode(",", $input->get("name")) as $tag_name) { + $tag_name = trim($tag_name); + if ($tag_name) { + tag::add($child, $tag_name); + } + // $tag_count should be inside the foreach loop as it is depending on the number of time tag:add is run + $tag_count++; + } } - } - } + echo '' . "\n"; + $children_count++; + $batchtag_max_new = $tag_count; + echo ''; + } else { $children_count++; } + + } else { break; } + } - // Redirect back to the album. - $item = ORM::factory("item", $input->post("item_id")); - url::redirect(url::abs_site("{$item->type}s/{$item->id}")); + if ($tag_count < $batchtag_max) { + // Redirect back to the album. + $item = ORM::factory("item", $input->get("item_id")); + url::redirect(url::abs_site("{$item->type}s/{$item->id}")); + //echo url::abs_site("{$item->type}s/{$item->id}"); + } else { + url::redirect(url::abs_site("batchtag/tagitems2?name={$input->get('name')}&item_id={$input->get('item_id')}&tag_subitems={$input->get('tag_subitems')}&batchtag_items_processed=$children_count&batchtag_max=$batchtag_max&csrf={$input->get('csrf')}")); + //echo url::abs_site("batchtag/tagitems2?name={$input->get('name')}&item_id={$input->get('item_id')}&tag_subitems={$input->get('tag_subitems')}&batchtag_items_processed=$children_count&batchtag_max=$batchtag_max&csrf={$input->get('csrf')}"); + } } } diff --git a/3.0/modules/batchtag/helpers/batchtag_block.php b/3.0/modules/batchtag/helpers/batchtag_block.php index f1be1387..01fe1216 100644 --- a/3.0/modules/batchtag/helpers/batchtag_block.php +++ b/3.0/modules/batchtag/helpers/batchtag_block.php @@ -1,7 +1,7 @@ module == "tag") { + $data->messages["warn"][] = t("The BatchTag module requires the Tags module."); + } + } + static function module_change($changes) { // See if the Tags module is installed, // tell the user to install it if it isn't. diff --git a/3.0/modules/batchtag/helpers/batchtag_installer.php b/3.0/modules/batchtag/helpers/batchtag_installer.php index bdf64d5a..d0c03163 100644 --- a/3.0/modules/batchtag/helpers/batchtag_installer.php +++ b/3.0/modules/batchtag/helpers/batchtag_installer.php @@ -1,7 +1,7 @@ - \ No newline at end of file + + diff --git a/3.0/modules/calendarview/controllers/calendarview.php b/3.0/modules/calendarview/controllers/calendarview.php index d5d23943..c1302ba5 100644 --- a/3.0/modules/calendarview/controllers/calendarview.php +++ b/3.0/modules/calendarview/controllers/calendarview.php @@ -1,7 +1,7 @@ css("calendarview_calendar.css"); $template->set_global("calendar_user", $display_user); $template->page_title = t("Gallery :: Calendar"); $template->content = new View("calendarview_year.html"); diff --git a/3.0/modules/calendarview/helpers/calendarview_event.php b/3.0/modules/calendarview/helpers/calendarview_event.php index 4564b500..731a662a 100644 --- a/3.0/modules/calendarview/helpers/calendarview_event.php +++ b/3.0/modules/calendarview/helpers/calendarview_event.php @@ -1,7 +1,7 @@ css("calendarview_menu.css"); + return $theme->css("calendarview_calendar.css"); } } diff --git a/3.0/modules/calendarview/libraries/Calendar_Breadcrumb.php b/3.0/modules/calendarview/libraries/Calendar_Breadcrumb.php index 60502667..751af272 100644 --- a/3.0/modules/calendarview/libraries/Calendar_Breadcrumb.php +++ b/3.0/modules/calendarview/libraries/Calendar_Breadcrumb.php @@ -1,7 +1,7 @@

      "; - - // Figure out if any photos were taken for the current month. - if ($calendar_user == "-1") { - $month_count = ORM::factory("item") - ->viewable() - ->where("type", "!=", "album") - ->where("captured", ">=", mktime(0, 0, 0, $counter_months, 1, $calendar_year)) - ->where("captured", "<", mktime(0, 0, 0, $counter_months+1, 1, $calendar_year)) - ->find_all() - ->count(); - } else { - $month_count = ORM::factory("item") - ->viewable() - ->where("owner_id", "=", $calendar_user) - ->where("type", "!=", "album") - ->where("captured", ">=", mktime(0, 0, 0, $counter_months, 1, $calendar_year)) - ->where("captured", "<", mktime(0, 0, 0, $counter_months+1, 1, $calendar_year)) - ->find_all() - ->count(); - } - if ($month_count > 0) { - $month_url = url::site("calendarview/month/" . $calendar_year . "/" . $calendar_user . "/" . $counter_months . "/"); - } else { - $month_url = ""; - } - $calendar = new PHPCalendar($counter_months, $calendar_year, $month_url); - - // If there are photos, loop through each day in the month and display links on the correct dates. - if ($month_count > 0) { - $curr_day = 1; - $MAX_DAYS = date('t', mktime(00, 00, 00, $counter_months, 1, $calendar_year)); - while ($curr_day < $MAX_DAYS) { - if ($calendar_user == "-1") { - $day_count = ORM::factory("item") - ->viewable() - ->where("type", "!=", "album") - ->where("captured", ">=", mktime(0, 0, 0, $counter_months, $curr_day, $calendar_year)) - ->where("captured", "<", mktime(0, 0, 0, $counter_months, ($curr_day + 1), $calendar_year)) - ->find_all() - ->count(); - } else { - $day_count = ORM::factory("item") - ->viewable() - ->where("owner_id", "=", $calendar_user) - ->where("type", "!=", "album") - ->where("captured", ">=", mktime(0, 0, 0, $counter_months, $curr_day, $calendar_year)) - ->where("captured", "<", mktime(0, 0, 0, $counter_months, ($curr_day + 1), $calendar_year)) - ->find_all() - ->count(); - } - if ($day_count > 0) { - $calendar->event($curr_day, url::site("calendarview/day/" . $calendar_year . "/" . $calendar_user . "/" . $counter_months . "/" . $curr_day)); - } - $curr_day++; - } - - // Do the last day of the month seperately, because the mktime code is different. - if ($calendar_user == "-1") { - $day_count = ORM::factory("item") - ->viewable() - ->where("type", "!=", "album") - ->where("captured", ">=", mktime(0, 0, 0, $counter_months, $MAX_DAYS, $calendar_year)) - ->where("captured", "<",mktime(0, 0, 0, ($counter_months + 1), 1, $calendar_year)) - ->find_all() - ->count(); - } else { - $day_count = ORM::factory("item") - ->viewable() - ->where("owner_id", "=", $calendar_user) - ->where("type", "!=", "album") - ->where("captured", ">=", mktime(0, 0, 0, $counter_months, $MAX_DAYS, $calendar_year)) - ->where("captured", "<", mktime(0, 0, 0, ($counter_months + 1), 1, $calendar_year)) - ->find_all() - ->count(); - } - if ($day_count > 0) { - $calendar->event($MAX_DAYS, url::site("calendarview/day/" . $calendar_year . "/" . $calendar_user . "/" . $counter_months . "/" . $MAX_DAYS)); - } - } - echo $calendar->render(); - print "
    "; - $counter_months++; - } - - // Do December seperately, because the mktime code is different. - print "
    "; + // Search the db for all photos that were taken during the selected year. if ($calendar_user == "-1") { - $month_count = ORM::factory("item") + $items_for_year = ORM::factory("item") ->viewable() ->where("type", "!=", "album") - ->where("captured", ">=", mktime(0, 0, 0, $counter_months, 1, $calendar_year)) + ->where("captured", ">=", mktime(0, 0, 0, 1, 1, $calendar_year)) ->where("captured", "<", mktime(0, 0, 0, 1, 1, ($calendar_year + 1))) - ->find_all() - ->count(); + ->order_by("captured") + ->find_all(); } else { - $month_count = ORM::factory("item") + $items_for_year = ORM::factory("item") ->viewable() ->where("owner_id", "=", $calendar_user) ->where("type", "!=", "album") - ->where("captured", ">=", mktime(0, 0, 0, $counter_months, 1, $calendar_year)) + ->where("captured", ">=", mktime(0, 0, 0, 1, 1, $calendar_year)) ->where("captured", "<", mktime(0, 0, 0, 1, 1, ($calendar_year + 1))) - ->find_all() - ->count(); + ->order_by("captured") + ->find_all(); } - if ($month_count > 0) { + + // Set up some initial variables. + $counter_months = 1; + $counter_days = 0; + $counter = 0; + + // Set up the January Calendar. + // Check and see if any photos were taken in January, + // If so, make the month title into a clickable link. + print "
    "; + if ((count($items_for_year) > 0) && (date("n", $items_for_year[$counter]->captured) == 1)) { $month_url = url::site("calendarview/month/" . $calendar_year . "/" . $calendar_user . "/" . $counter_months . "/"); } else { $month_url = ""; } $calendar = new PHPCalendar($counter_months, $calendar_year, $month_url); - if ($month_count > 0) { - $curr_day = 1; - $MAX_DAYS = date('t', mktime(00, 00, 00, $counter_months, 1, $calendar_year)); - while ($curr_day < $MAX_DAYS) { - if ($calendar_user == "-1") { - $day_count = ORM::factory("item") - ->viewable() - ->where("type", "!=", "album") - ->where("captured", ">=", mktime(0, 0, 0, $counter_months, $curr_day, $calendar_year)) - ->where("captured", "<", mktime(0, 0, 0, $counter_months, ($curr_day + 1), $calendar_year)) - ->find_all() - ->count(); + + // Loop through each photo taken during this year, and see what month and day they were taken on. + // Make the corresponding dates on the calendars into clickable links. + while ($counter < (count($items_for_year))) { + + // Check and see if we've switched to a new month. + // If so, render the current calendar and set up a new one. + while (date("n", $items_for_year[$counter]->captured) > $counter_months) { + echo $calendar->render(); + print "
    "; + $counter_months++; + $counter_days = 0; + print "
    "; + if (date("n", $items_for_year[$counter]->captured) == $counter_months) { + $month_url = url::site("calendarview/month/" . $calendar_year . "/" . $calendar_user . "/" . $counter_months . "/"); } else { - $day_count = ORM::factory("item") - ->viewable() - ->where("owner_id", "=", $calendar_user) - ->where("type", "!=", "album") - ->where("captured", ">=", mktime(0, 0, 0, $counter_months, $curr_day, $calendar_year)) - ->where("captured", "<", mktime(0, 0, 0, $counter_months, ($curr_day + 1), $calendar_year)) - ->find_all() - ->count(); + $month_url = ""; } - if ($day_count > 0) { - $calendar->event($curr_day, url::site("calendarview/day/" . $calendar_year . "/" . $calendar_user . "/" . $counter_months . "/" . $curr_day)); - } - $curr_day++; - } - if ($calendar_user == "-1") { - $day_count = ORM::factory("item") - ->viewable() - ->where("type", "!=", "album") - ->where("captured", ">=", mktime(0, 0, 0, $counter_months, $MAX_DAYS, $calendar_year)) - ->where("captured", "<", mktime(0, 0, 0, 1, 1, $calendar_year+1)) - ->find_all() - ->count(); - } else { - $day_count = ORM::factory("item") - ->viewable() - ->where("owner_id", "=", $calendar_user) - ->where("type", "!=", "album") - ->where("captured", ">=", mktime(0, 0, 0, $counter_months, $MAX_DAYS, $calendar_year)) - ->where("captured", "<", mktime(0, 0, 0, 1, 1, $calendar_year+1)) - ->find_all() - ->count(); - } - if ($day_count > 0) { - $calendar->event($MAX_DAYS, url::site("calendarview/day/" . $calendar_year . "/" . $calendar_user . "/" . $counter_months . "/" . $MAX_DAYS)); + $calendar = new PHPCalendar($counter_months, $calendar_year, $month_url); } + + // If the day of the current photo is different then the day of the previous photo, + // then add a link to the calendar for this date and set the current day to this day. + if (date("j", $items_for_year[$counter]->captured) > $counter_days) { + $counter_days = date("j", $items_for_year[$counter]->captured); + $calendar->event($counter_days, url::site("calendarview/day/" . $calendar_year . "/" . $calendar_user . "/" . $counter_months . "/" . $counter_days)); + } + + // Move onto the next photo. + $counter++; } - $counter_months++; + + // Print out the last calendar to be generated. echo $calendar->render(); print "
    "; -?> \ No newline at end of file + $counter_months++; + + // If the calendar that was previously rendered was not December, + // then print out a few empty months for the rest of the year. + while ($counter_months < 13) { + print "
    "; + $month_url = ""; + $calendar = new PHPCalendar($counter_months, $calendar_year, $month_url); + echo $calendar->render(); + print "
    "; + $counter_months++; + } +?> +dynamic_bottom() ?> diff --git a/3.0/modules/calendarview/views/calpage.html.php b/3.0/modules/calendarview/views/calpage.html.php index f98352b9..3dab5fc0 100644 --- a/3.0/modules/calendarview/views/calpage.html.php +++ b/3.0/modules/calendarview/views/calpage.html.php @@ -1,51 +1,42 @@ - +html_attributes() ?> xml:lang="en" lang="en"> + start_combining("script,css") ?> <? if ($page_title): ?> <?= $page_title ?> <? else: ?> <? if ($theme->item()): ?> - <? if ($theme->item()->is_album()): ?> - <?= t("Browse Album :: %album_title", array("album_title" => $theme->item()->title)) ?> - <? elseif ($theme->item()->is_photo()): ?> - <?= t("Photo :: %photo_title", array("photo_title" => $theme->item()->title)) ?> - <? else: ?> - <?= t("Movie :: %movie_title", array("movie_title" => $theme->item()->title)) ?> - <? endif ?> + <?= $theme->item()->title ?> <? elseif ($theme->tag()): ?> - <?= t("Browse Tag :: %tag_title", array("tag_title" => $theme->tag()->name)) ?> + <?= t("Photos tagged with %tag_title", array("tag_title" => $theme->tag()->name)) ?> <? else: /* Not an item, not a tag, no page_title specified. Help! */ ?> - <?= t("Gallery") ?> + <?= item::root()->title ?> <? endif ?> <? endif ?> - " type="image/x-icon" /> - css("yui/reset-fonts-grids.css") ?> - css("superfish/css/superfish.css") ?> - css("themeroller/ui.base.css") ?> - css("gallery.common.css") ?> - css("screen.css") ?> - + " + type="image/x-icon" /> + page_type == "collection"): ?> - - - + + + + + script("json2-min.js") ?> script("jquery.js") ?> script("jquery.form.js") ?> script("jquery-ui.js") ?> @@ -58,9 +49,8 @@ script("gallery.dialog.js") ?> script("superfish/js/superfish.js") ?> script("jquery.localscroll.js") ?> - script("ui.init.js") ?> - head() they get combined */ ?> + page_subtype == "photo"): ?> script("jquery.scrollTo.js") ?> script("gallery.show_full_size.js") ?> @@ -69,6 +59,23 @@ head() ?> + + + script("ui.init.js") ?> + css("yui/reset-fonts-grids.css") ?> + css("superfish/css/superfish.css") ?> + css("themeroller/ui.base.css") ?> + css("screen.css") ?> + + + + get_combined("script") ?> + + + get_combined("css") ?> body_attributes() ?>> @@ -87,15 +94,16 @@ user_menu() ?> header_top() ?> - + header_bottom() ?>
    + @@ -120,6 +128,8 @@ + +
@@ -151,4 +161,4 @@
page_bottom() ?> - + \ No newline at end of file diff --git a/3.0/modules/captionator/controllers/captionator.php b/3.0/modules/captionator/controllers/captionator.php index 007ee86f..8b380f66 100644 --- a/3.0/modules/captionator/controllers/captionator.php +++ b/3.0/modules/captionator/controllers/captionator.php @@ -1,7 +1,7 @@ content = new View("captionator_dialog.html"); $v->content->album = $album; + $v->content->enable_tags = module::is_active("tag"); + if ($v->content->enable_tags) { + $v->content->tags = array(); + foreach ($album->viewable()->children() as $child) { + $item = ORM::factory("item", $child->id); + $tag_names = array(); + foreach (tag::item_tags($item) as $tag) { + $tag_names[] = $tag->name; + } + $v->content->tags[$child->id] = implode(", ", $tag_names); + } + } print $v; } @@ -42,12 +54,27 @@ class Captionator_Controller extends Controller { if (Input::instance()->post("save")) { $titles = Input::instance()->post("title"); $descriptions = Input::instance()->post("description"); + $filenames = Input::instance()->post("filename"); + $internetaddresses = Input::instance()->post("internetaddress"); + $tags = Input::instance()->post("tags"); + $enable_tags = module::is_active("tag"); foreach (array_keys($titles) as $id) { $item = ORM::factory("item", $id); if ($item->loaded() && access::can("edit", $item)) { $item->title = $titles[$id]; $item->description = $descriptions[$id]; + $item->name = $filenames[$id]; + $item->slug = $internetaddresses[$id]; $item->save(); + if ($enable_tags) { + tag::clear_all($item); + foreach (explode(",", $tags[$id]) as $tag_name) { + if ($tag_name) { + tag::add($item, trim($tag_name)); + } + } + tag::compact(); + } } } message::success(t("Captions saved")); diff --git a/3.0/modules/captionator/helpers/captionator_event.php b/3.0/modules/captionator/helpers/captionator_event.php index d00c04ae..43e501f8 100644 --- a/3.0/modules/captionator/helpers/captionator_event.php +++ b/3.0/modules/captionator/helpers/captionator_event.php @@ -1,7 +1,7 @@
+
id}") ?>" method="post" id="g-captionator-form">
@@ -17,12 +34,26 @@
  • - +
  • + +
  • + + +
  • + +
  • + + +
  • +
  • + + +
diff --git a/3.0/modules/carousel/controllers/admin_carousel.php b/3.0/modules/carousel/controllers/admin_carousel.php new file mode 100644 index 00000000..0852ec3f --- /dev/null +++ b/3.0/modules/carousel/controllers/admin_carousel.php @@ -0,0 +1,183 @@ +_get_view(); + } + + public function handler() { + access::verify_csrf(); + + $form = $this->_get_form(); + if ($form->validate()) { + module::set_var( + "carousel", "circular", $form->carousel->circular->value); + module::set_var( + "carousel", "autoscroll", $form->carousel->autoscroll->value); + module::set_var( + "carousel", "autostart", $form->carousel->autostart->value); + module::set_var( + "carousel", "speed", $form->carousel->speed->value); + module::set_var( + "carousel", "mousewheel", $form->carousel->mousewheel->value); + + module::set_var( + "carousel", "title2", $form->recent->title2->value); + module::set_var( + "carousel", "thumbsize2", $form->recent->thumbsize2->value); + module::set_var( + "carousel", "visible2", $form->recent->visible2->value); + module::set_var( + "carousel", "quantity2", $form->recent->quantity2->value); + module::set_var( + "carousel", "onphoto2", $form->recent->onphoto2->value); + module::set_var( + "carousel", "onalbum2", $form->recent->onalbum2->value); + + module::set_var( + "carousel", "title3", $form->popular->title3->value); + module::set_var( + "carousel", "thumbsize3", $form->popular->thumbsize3->value); + module::set_var( + "carousel", "visible3", $form->popular->visible3->value); + module::set_var( + "carousel", "quantity3", $form->popular->quantity3->value); + module::set_var( + "carousel", "onphoto3", $form->popular->onphoto3->value); + module::set_var( + "carousel", "onalbum3", $form->popular->onalbum3->value); + + module::set_var( + "carousel", "title", $form->random->title->value); + module::set_var( + "carousel", "thumbsize", $form->random->thumbsize->value); + module::set_var( + "carousel", "visible", $form->random->visible->value); + module::set_var( + "carousel", "quantity", $form->random->quantity->value); + module::set_var( + "carousel", "onphoto", $form->random->onphoto->value); + module::set_var( + "carousel", "onalbum", $form->random->onalbum->value); + + message::success(t("Your settings have been saved.")); + url::redirect("admin/carousel"); + } + print $this->_get_view($form); + } + + private function _get_view($form=null) { + $v = new Admin_View("admin.html"); + $v->content = new View("admin_carousel.html"); + $v->content->form = empty($form) ? $this->_get_form() : $form; + return $v; + } + + private function _get_form() { + for ($i = 5; $i <= 50; $i+=5) { + $range[$i] = "$i"; + } + $shortrange = array(); + for ($i = 1; $i < 21; $i++) { + $key=((float)$i / 2); + $shortrange["$key"] = sprintf("%.1f", (float)$i / 2); + } + if (module::get_var("carousel", "autoscroll") == true) { + $disableme == "false"; + } else { + $disableme == "true"; + } + $form = new Forge("admin/carousel/handler", "", "post", array("id" => "g-admin-form")); + + $group = $form->group("carousel")->label(t("General carousel settings")); + $group->checkbox("circular")->label(t('Enable the carousel to be circular so it starts over again from the beggining.')) + ->checked(module::get_var("carousel", "circular", "0")); + $group->checkbox("autoscroll")->label(t('Carousel should auto scroll. Toggle value to change settings below.')) + ->onClick("toggle()") + ->id("autoscroll") + ->checked(module::get_var("carousel", "autoscroll", "0")); + $group->input("autostart")->label(t("Enter the value of the auto start. (800)")) + ->value(module::get_var("carousel", "autostart", "800")) + ->id("auto") + ->disabled("false") + ->rules("valid_numeric|length[1,5]"); + $group->input("speed")->label(t('Enter the scrolling speed of the carousel. (1000)')) + ->value(module::get_var("carousel", "speed", "1000")) + ->id("speed") + ->disabled($disableme) + ->rules("valid_numeric|length[1,5]"); + $group->checkbox("mousewheel")->label(t('Enable mouse wheel. Allows for mouse wheel to scroll items.')) + ->checked(module::get_var("carousel", "mousewheel", "0")); + + $group = $form->group("recent")->label(t("Recent carousel block")); + $group->input("title2")->label(t('Enter the title of the recent block.')) + ->value(module::get_var("carousel", "title2", "Recent items")); + $group->input("thumbsize2")->label(t('Enter the size of the thumbs. (pixels)')) + ->value(module::get_var("carousel", "thumbsize2", "200")) + ->rules("valid_numeric|length[2,3]"); + $group->dropdown("visible2")->label(t('Enter number of thumbs to show. (height of carousel)')) + ->options($shortrange) + ->selected(module::get_var("carousel", "visible2", "1")); + $group->dropdown("quantity2")->label(t("Choose the toal quantity of thumbs in recent carousel.")) + ->options($range) + ->selected(module::get_var("carousel", "quantity2", "25")); + $group->checkbox("onalbum2")->label(t("Show on album & collection pages")) + ->checked(module::get_var("carousel", "onalbum2", "0")); + $group->checkbox("onphoto2")->label(t("Show on photo pages")) + ->checked(module::get_var("carousel", "onphoto2", "0")); + + $group = $form->group("popular")->label(t("Popular carousel block")); + $group->input("title3")->label(t('Enter the title of the popular block.')) + ->value(module::get_var("carousel", "title3", "Popular items")); + $group->input("thumbsize3")->label(t('Enter the thumb size. (pixels)')) + ->value(module::get_var("carousel", "thumbsize3", "200")) + ->rules("valid_numeric|length[2,3]"); + $group->dropdown("visible3")->label(t('Enter number of thumbs to show. (height of carousel)')) + ->options($shortrange) + ->selected(module::get_var("carousel", "visible3", "1")); + $group->dropdown("quantity3")->label(t("Choose the toal quantity of thumbs in popular carousel.")) + ->options($range) + ->selected(module::get_var("carousel", "quantity3", "25")); + $group->checkbox("onalbum3")->label(t("Show on album & collection pages")) + ->checked(module::get_var("carousel", "onalbum3", "0")); + $group->checkbox("onphoto3")->label(t("Show on photo pages")) + ->checked(module::get_var("carousel", "onphoto3", "0")); + + $group = $form->group("random")->label(t("Random carousel block. Some issues with smaller galleries.")); + $group->input("title")->label(t('Enter the title of the random block.')) + ->value(module::get_var("carousel", "title", "Random items")); + $group->input("thumbsize")->label(t('Enter the thumb size. (pixels)')) + ->value(module::get_var("carousel", "thumbsize", "200")) + ->rules("valid_numeric|length[2,3]"); + $group->dropdown("visible")->label(t('Enter number of thumbs to show. (height of carousel)')) + ->options($shortrange) + ->selected(module::get_var("carousel", "visible", "1")); + $group->dropdown("quantity")->label(t("Choose the toal quantity of thumbs in random carousel.")) + ->options($range) + ->selected(module::get_var("carousel", "quantity", "25")); + $group->checkbox("onalbum")->label(t("Show on album & collection pages")) + ->checked(module::get_var("carousel", "onalbum", "0")); + $group->checkbox("onphoto")->label(t("Show on photo pages")) + ->checked(module::get_var("carousel", "onphoto", "0")); + + $form->submit("submit")->value(t("Save")); + return $form; + } +} \ No newline at end of file diff --git a/3.0/modules/carousel/css/carousel.css b/3.0/modules/carousel/css/carousel.css new file mode 100644 index 00000000..28b9defb --- /dev/null +++ b/3.0/modules/carousel/css/carousel.css @@ -0,0 +1,30 @@ +.jcarousel-container { + -moz-border-radius: 10px; + background: #F0F6F9; + border: 1px solid #346F97; +} + +.jcarousel-container-vertical { + width: 75px; + height: 245px; + padding: 40px 20px; +} + +.jcarousel-clip-vertical { + width: 75px; + height: 245px; +} + +.jcarousel-item { + width: 75px; + height: 75px; +} + +.jcarousel-item-vertical { + margin-bottom: 10px; +} + +.jcarousel-item-placeholder { + background: #fff; + color: #000; +} \ No newline at end of file diff --git a/3.0/modules/carousel/helpers/carousel_block.php b/3.0/modules/carousel/helpers/carousel_block.php new file mode 100644 index 00000000..6141fcae --- /dev/null +++ b/3.0/modules/carousel/helpers/carousel_block.php @@ -0,0 +1,61 @@ + t("Recent items carousel"), + "carousel_popular" => t("Popular items carousel"), + "carousel_random" => t("Random items carousel")); + } + + static function get($block_id, $theme) { + $block = ""; + switch ($block_id) { + case "carousel_recent": + if (module::get_var("carousel", "onalbum2") && $theme->page_type == "collection" || + module::get_var("carousel", "onphoto2") && $theme->page_type == "item") { + $block = new Block(); + $block->css_id = "g-carousel-rec"; + $block->title = module::get_var("carousel", "title2", "Recent items"); + $block->content = new View("carousel_recent.html"); + } + break; + case "carousel_popular": + if (module::get_var("carousel", "onalbum3") && $theme->page_type == "collection" || + module::get_var("carousel", "onphoto3") && $theme->page_type == "item") { + $block = new Block(); + $block->css_id = "g-carousel-pop"; + $block->title = module::get_var("carousel", "title3", "Popular items"); + $block->content = new View("carousel_popular.html"); + } + break; + case "carousel_random": + if (module::get_var("carousel", "onalbum") && $theme->page_type == "collection" || + module::get_var("carousel", "onphoto") && $theme->page_type == "item") { + $block = new Block(); + $block->css_id = "g-carousel-ran"; + $block->title = module::get_var("carousel", "title", "Random items"); + $block->content = new View("carousel_random.html"); + } + break; + } + return $block; + } +} \ No newline at end of file diff --git a/3.0/modules/carousel/helpers/carousel_event.php b/3.0/modules/carousel/helpers/carousel_event.php new file mode 100644 index 00000000..ffe2ac69 --- /dev/null +++ b/3.0/modules/carousel/helpers/carousel_event.php @@ -0,0 +1,28 @@ +get("settings_menu") + ->append(Menu::factory("link") + ->id("carousel_menu") + ->label(t("Carousel")) + ->url(url::site("admin/carousel"))); + } +} diff --git a/3.0/modules/carousel/helpers/carousel_theme.php b/3.0/modules/carousel/helpers/carousel_theme.php new file mode 100644 index 00000000..fe1f9abe --- /dev/null +++ b/3.0/modules/carousel/helpers/carousel_theme.php @@ -0,0 +1,24 @@ +script("jcarousellite.min.js"); + } +} \ No newline at end of file diff --git a/3.0/modules/carousel/js/jcarousellite.min.js b/3.0/modules/carousel/js/jcarousellite.min.js new file mode 100644 index 00000000..f16734ae --- /dev/null +++ b/3.0/modules/carousel/js/jcarousellite.min.js @@ -0,0 +1 @@ +(function($){$.fn.jCarouselLite=function(o){o=$.extend({btnPrev:null,btnNext:null,btnGo:null,mouseWheel:false,auto:null,speed:200,easing:null,vertical:false,circular:true,visible:3,start:0,scroll:1,beforeStart:null,afterEnd:null},o||{});return this.each(function(){var b=false,animCss=o.vertical?"top":"left",sizeCss=o.vertical?"height":"width";var c=$(this),ul=$("ul",c),tLi=$("li",ul),tl=tLi.size(),v=o.visible;if(o.circular){ul.prepend(tLi.slice(tl-v-1+1).clone()).append(tLi.slice(0,v).clone());o.start+=v}var f=$("li",ul),itemLength=f.size(),curr=o.start;c.css("visibility","visible");f.css({overflow:"hidden",float:o.vertical?"none":"left"});ul.css({margin:"0",padding:"0",position:"relative","list-style-type":"none","z-index":"1"});c.css({overflow:"hidden",position:"relative","z-index":"2",left:"0px"});var g=o.vertical?height(f):width(f);var h=g*itemLength;var j=g*v;f.css({width:f.width(),height:f.height()});ul.css(sizeCss,h+"px").css(animCss,-(curr*g));c.css(sizeCss,j+"px");if(o.btnPrev)$(o.btnPrev).click(function(){return go(curr-o.scroll)});if(o.btnNext)$(o.btnNext).click(function(){return go(curr+o.scroll)});if(o.btnGo)$.each(o.btnGo,function(i,a){$(a).click(function(){return go(o.circular?o.visible+i:i)})});if(o.mouseWheel&&c.mousewheel)c.mousewheel(function(e,d){return d>0?go(curr-o.scroll):go(curr+o.scroll)});if(o.auto)setInterval(function(){go(curr+o.scroll)},o.auto+o.speed);function vis(){return f.slice(curr).slice(0,v)};function go(a){if(!b){if(o.beforeStart)o.beforeStart.call(this,vis());if(o.circular){if(a<=o.start-v-1){ul.css(animCss,-((itemLength-(v*2))*g)+"px");curr=a==o.start-v-1?itemLength-(v*2)-1:itemLength-(v*2)-o.scroll}else if(a>=itemLength-v+1){ul.css(animCss,-((v)*g)+"px");curr=a==itemLength-v+1?v+1:v+o.scroll}else curr=a}else{if(a<0||a>itemLength-v)return;else curr=a}b=true;ul.animate(animCss=="left"?{left:-(curr*g)}:{top:-(curr*g)},o.speed,o.easing,function(){if(o.afterEnd)o.afterEnd.call(this,vis());b=false});if(!o.circular){$(o.btnPrev+","+o.btnNext).removeClass("disabled");$((curr-o.scroll<0&&o.btnPrev)||(curr+o.scroll>itemLength-v&&o.btnNext)||[]).addClass("disabled")}}return false}})};function css(a,b){return parseInt($.css(a[0],b))||0};function width(a){return a[0].offsetWidth+css(a,'marginLeft')+css(a,'marginRight')};function height(a){return a[0].offsetHeight+css(a,'marginTop')+css(a,'marginBottom')}})(jQuery); \ No newline at end of file diff --git a/3.0/modules/carousel/js/jcarousellite_orig.js b/3.0/modules/carousel/js/jcarousellite_orig.js new file mode 100644 index 00000000..f68b5ed0 --- /dev/null +++ b/3.0/modules/carousel/js/jcarousellite_orig.js @@ -0,0 +1,364 @@ +/** + * jCarouselLite - jQuery plugin to navigate images/any content in a carousel style widget. + * @requires jQuery v1.2 or above + * + * http://gmarwaha.com/jquery/jcarousellite/ + * + * Copyright (c) 2007 Ganeshji Marwaha (gmarwaha.com) + * Dual licensed under the MIT and GPL licenses: + * http://www.opensource.org/licenses/mit-license.php + * http://www.gnu.org/licenses/gpl.html + * + * Version: 1.0.1 + * Note: Requires jquery 1.2 or above from version 1.0.1 + */ + +/** + * Creates a carousel-style navigation widget for images/any-content from a simple HTML markup. + * + * The HTML markup that is used to build the carousel can be as simple as... + * + * + * + * As you can see, this snippet is nothing but a simple div containing an unordered list of images. + * You don't need any special "class" attribute, or a special "css" file for this plugin. + * I am using a class attribute just for the sake of explanation here. + * + * To navigate the elements of the carousel, you need some kind of navigation buttons. + * For example, you will need a "previous" button to go backward, and a "next" button to go forward. + * This need not be part of the carousel "div" itself. It can be any element in your page. + * Lets assume that the following elements in your document can be used as next, and prev buttons... + * + * + * + * + * Now, all you need to do is call the carousel component on the div element that represents it, and pass in the + * navigation buttons as options. + * + * $(".carousel").jCarouselLite({ + * btnNext: ".next", + * btnPrev: ".prev" + * }); + * + * That's it, you would have now converted your raw div, into a magnificient carousel. + * + * There are quite a few other options that you can use to customize it though. + * Each will be explained with an example below. + * + * @param an options object - You can specify all the options shown below as an options object param. + * + * @option btnPrev, btnNext : string - no defaults + * @example + * $(".carousel").jCarouselLite({ + * btnNext: ".next", + * btnPrev: ".prev" + * }); + * @desc Creates a basic carousel. Clicking "btnPrev" navigates backwards and "btnNext" navigates forward. + * + * @option btnGo - array - no defaults + * @example + * $(".carousel").jCarouselLite({ + * btnNext: ".next", + * btnPrev: ".prev", + * btnGo: [".0", ".1", ".2"] + * }); + * @desc If you don't want next and previous buttons for navigation, instead you prefer custom navigation based on + * the item number within the carousel, you can use this option. Just supply an array of selectors for each element + * in the carousel. The index of the array represents the index of the element. What i mean is, if the + * first element in the array is ".0", it means that when the element represented by ".0" is clicked, the carousel + * will slide to the first element and so on and so forth. This feature is very powerful. For example, i made a tabbed + * interface out of it by making my navigation elements styled like tabs in css. As the carousel is capable of holding + * any content, not just images, you can have a very simple tabbed navigation in minutes without using any other plugin. + * The best part is that, the tab will "slide" based on the provided effect. :-) + * + * @option mouseWheel : boolean - default is false + * @example + * $(".carousel").jCarouselLite({ + * mouseWheel: true + * }); + * @desc The carousel can also be navigated using the mouse wheel interface of a scroll mouse instead of using buttons. + * To get this feature working, you have to do 2 things. First, you have to include the mouse-wheel plugin from brandon. + * Second, you will have to set the option "mouseWheel" to true. That's it, now you will be able to navigate your carousel + * using the mouse wheel. Using buttons and mouseWheel or not mutually exclusive. You can still have buttons for navigation + * as well. They complement each other. To use both together, just supply the options required for both as shown below. + * @example + * $(".carousel").jCarouselLite({ + * btnNext: ".next", + * btnPrev: ".prev", + * mouseWheel: true + * }); + * + * @option auto : number - default is null, meaning autoscroll is disabled by default + * @example + * $(".carousel").jCarouselLite({ + * auto: 800, + * speed: 500 + * }); + * @desc You can make your carousel auto-navigate itself by specfying a millisecond value in this option. + * The value you specify is the amount of time between 2 slides. The default is null, and that disables auto scrolling. + * Specify this value and magically your carousel will start auto scrolling. + * + * @option speed : number - 200 is default + * @example + * $(".carousel").jCarouselLite({ + * btnNext: ".next", + * btnPrev: ".prev", + * speed: 800 + * }); + * @desc Specifying a speed will slow-down or speed-up the sliding speed of your carousel. Try it out with + * different speeds like 800, 600, 1500 etc. Providing 0, will remove the slide effect. + * + * @option easing : string - no easing effects by default. + * @example + * $(".carousel").jCarouselLite({ + * btnNext: ".next", + * btnPrev: ".prev", + * easing: "bounceout" + * }); + * @desc You can specify any easing effect. Note: You need easing plugin for that. Once specified, + * the carousel will slide based on the provided easing effect. + * + * @option vertical : boolean - default is false + * @example + * $(".carousel").jCarouselLite({ + * btnNext: ".next", + * btnPrev: ".prev", + * vertical: true + * }); + * @desc Determines the direction of the carousel. true, means the carousel will display vertically. The next and + * prev buttons will slide the items vertically as well. The default is false, which means that the carousel will + * display horizontally. The next and prev items will slide the items from left-right in this case. + * + * @option circular : boolean - default is true + * @example + * $(".carousel").jCarouselLite({ + * btnNext: ".next", + * btnPrev: ".prev", + * circular: false + * }); + * @desc Setting it to true enables circular navigation. This means, if you click "next" after you reach the last + * element, you will automatically slide to the first element and vice versa. If you set circular to false, then + * if you click on the "next" button after you reach the last element, you will stay in the last element itself + * and similarly for "previous" button and first element. + * + * @option visible : number - default is 3 + * @example + * $(".carousel").jCarouselLite({ + * btnNext: ".next", + * btnPrev: ".prev", + * visible: 4 + * }); + * @desc This specifies the number of items visible at all times within the carousel. The default is 3. + * You are even free to experiment with real numbers. Eg: "3.5" will have 3 items fully visible and the + * last item half visible. This gives you the effect of showing the user that there are more images to the right. + * + * @option start : number - default is 0 + * @example + * $(".carousel").jCarouselLite({ + * btnNext: ".next", + * btnPrev: ".prev", + * start: 2 + * }); + * @desc You can specify from which item the carousel should start. Remember, the first item in the carousel + * has a start of 0, and so on. + * + * @option scrool : number - default is 1 + * @example + * $(".carousel").jCarouselLite({ + * btnNext: ".next", + * btnPrev: ".prev", + * scroll: 2 + * }); + * @desc The number of items that should scroll/slide when you click the next/prev navigation buttons. By + * default, only one item is scrolled, but you may set it to any number. Eg: setting it to "2" will scroll + * 2 items when you click the next or previous buttons. + * + * @option beforeStart, afterEnd : function - callbacks + * @example + * $(".carousel").jCarouselLite({ + * btnNext: ".next", + * btnPrev: ".prev", + * beforeStart: function(a) { + * alert("Before animation starts:" + a); + * }, + * afterEnd: function(a) { + * alert("After animation ends:" + a); + * } + * }); + * @desc If you wanted to do some logic in your page before the slide starts and after the slide ends, you can + * register these 2 callbacks. The functions will be passed an argument that represents an array of elements that + * are visible at the time of callback. + * + * + * @cat Plugins/Image Gallery + * @author Ganeshji Marwaha/ganeshread@gmail.com + */ + +(function($) { // Compliant with jquery.noConflict() +$.fn.jCarouselLite = function(o) { + o = $.extend({ + btnPrev: null, + btnNext: null, + btnGo: null, + mouseWheel: false, + auto: null, + hoverPause: false, + + speed: 200, + easing: null, + + vertical: false, + circular: true, + visible: 3, + start: 0, + scroll: 1, + + beforeStart: null, + afterEnd: null + }, o || {}); + + return this.each(function() { // Returns the element collection. Chainable. + + var running = false, animCss=o.vertical?"top":"left", sizeCss=o.vertical?"height":"width"; + var div = $(this), ul = $("ul", div), tLi = $("li", ul), tl = tLi.size(), v = o.visible; + + if(o.circular) { + ul.prepend(tLi.slice(tl-v+1).clone()) + .append(tLi.slice(0,o.scroll).clone()); + o.start += v-1; + } + + var li = $("li", ul), itemLength = li.size(), curr = o.start; + div.css("visibility", "visible"); + + li.css({overflow: "hidden", float: o.vertical ? "none" : "left"}); + ul.css({margin: "0", padding: "0", position: "relative", "list-style-type": "none", "z-index": "1"}); + div.css({overflow: "hidden", position: "relative", "z-index": "2", left: "0px"}); + + var liSize = o.vertical ? height(li) : width(li); // Full li size(incl margin)-Used for animation + var ulSize = liSize * itemLength; // size of full ul(total length, not just for the visible items) + var divSize = liSize * v; // size of entire div(total length for just the visible items) + + li.css({width: li.width(), height: li.height()}); + ul.css(sizeCss, ulSize+"px").css(animCss, -(curr*liSize)); + + div.css(sizeCss, divSize+"px"); // Width of the DIV. length of visible images + + if(o.btnPrev) { + $(o.btnPrev).click(function() { + return go(curr-o.scroll); + }); + if(o.hoverPause) { + $(o.btnPrev).hover(function(){stopAuto();}, function(){startAuto();}); + } + } + + + if(o.btnNext) { + $(o.btnNext).click(function() { + return go(curr+o.scroll); + }); + if(o.hoverPause) { + $(o.btnNext).hover(function(){stopAuto();}, function(){startAuto();}); + } + } + + if(o.btnGo) + $.each(o.btnGo, function(i, val) { + $(val).click(function() { + return go(o.circular ? o.visible+i : i); + }); + }); + + if(o.mouseWheel && div.mousewheel) + div.mousewheel(function(e, d) { + return d>0 ? go(curr-o.scroll) : go(curr+o.scroll); + }); + + var autoInterval; + + function startAuto() { + stopAuto(); + autoInterval = setInterval(function() { + go(curr+o.scroll); + }, o.auto+o.speed); + }; + + function stopAuto() { + clearInterval(autoInterval); + }; + + if(o.auto) { + if(o.hoverPause) { + div.hover(function(){stopAuto();}, function(){startAuto();}); + } + startAuto(); + }; + + function vis() { + return li.slice(curr).slice(0,v); + }; + + function go(to) { + if(!running) { + + if(o.beforeStart) + o.beforeStart.call(this, vis()); + + if(o.circular) { // If circular we are in first or last, then goto the other end + if(to<0) { // If before range, then go around + ul.css(animCss, -( (curr + tl) * liSize)+"px"); + curr = to + tl; + } else if(to>itemLength-v) { // If beyond range, then come around + ul.css(animCss, -( (curr - tl) * liSize ) + "px" ); + curr = to - tl; + } else curr = to; + } else { // If non-circular and to points to first or last, we just return. + if(to<0 || to>itemLength-v) return; + else curr = to; + } // If neither overrides it, the curr will still be "to" and we can proceed. + + running = true; + + ul.animate( + animCss == "left" ? { left: -(curr*liSize) } : { top: -(curr*liSize) } , o.speed, o.easing, + function() { + if(o.afterEnd) + o.afterEnd.call(this, vis()); + running = false; + } + ); + // Disable buttons when the carousel reaches the last/first, and enable when not + if(!o.circular) { + $(o.btnPrev + "," + o.btnNext).removeClass("disabled"); + $( (curr-o.scroll<0 && o.btnPrev) + || + (curr+o.scroll > itemLength-v && o.btnNext) + || + [] + ).addClass("disabled"); + } + + } + return false; + }; + }); +}; + +function css(el, prop) { + return parseInt($.css(el[0], prop)) || 0; +}; +function width(el) { + return el[0].offsetWidth + css(el, 'marginLeft') + css(el, 'marginRight'); +}; +function height(el) { + return el[0].offsetHeight + css(el, 'marginTop') + css(el, 'marginBottom'); +}; + +})(jQuery); \ No newline at end of file diff --git a/3.0/modules/carousel/js/jquery.mousewheel.min.js b/3.0/modules/carousel/js/jquery.mousewheel.min.js new file mode 100644 index 00000000..05ebb0a9 --- /dev/null +++ b/3.0/modules/carousel/js/jquery.mousewheel.min.js @@ -0,0 +1,11 @@ +/* Copyright (c) 2009 Brandon Aaron (http://brandonaaron.net) + * Dual licensed under the MIT (http://www.opensource.org/licenses/mit-license.php) + * and GPL (http://www.opensource.org/licenses/gpl-license.php) licenses. + * Thanks to: http://adomas.org/javascript-mouse-wheel/ for some pointers. + * Thanks to: Mathias Bank(http://www.mathias-bank.de) for a scope bug fix. + * + * Version: 3.0.2 + * + * Requires: 1.2.2+ + */ +(function(c){var a=["DOMMouseScroll","mousewheel"];c.event.special.mousewheel={setup:function(){if(this.addEventListener){for(var d=a.length;d;){this.addEventListener(a[--d],b,false)}}else{this.onmousewheel=b}},teardown:function(){if(this.removeEventListener){for(var d=a.length;d;){this.removeEventListener(a[--d],b,false)}}else{this.onmousewheel=null}}};c.fn.extend({mousewheel:function(d){return d?this.bind("mousewheel",d):this.trigger("mousewheel")},unmousewheel:function(d){return this.unbind("mousewheel",d)}});function b(f){var d=[].slice.call(arguments,1),g=0,e=true;f=c.event.fix(f||window.event);f.type="mousewheel";if(f.wheelDelta){g=f.wheelDelta/120}if(f.detail){g=-f.detail/3}d.unshift(f,g);return c.event.handle.apply(this,d)}})(jQuery); \ No newline at end of file diff --git a/3.0/modules/carousel/module.info b/3.0/modules/carousel/module.info new file mode 100644 index 00000000..0ee02423 --- /dev/null +++ b/3.0/modules/carousel/module.info @@ -0,0 +1,7 @@ +name = "Carousel" +description = "Add a vertical carousel for recent & popular items in the sidebar." +version = 1.0 +author_name = "floridave" +author_url = "http://codex.gallery2.org/User:Floridave" +info_url = "http://codex.gallery2.org/Gallery3:Modules:carousel" +discuss_url = "http://gallery.menalto.com/forum_module_all_carousel" \ No newline at end of file diff --git a/3.0/modules/carousel/views/admin_carousel.html.php b/3.0/modules/carousel/views/admin_carousel.html.php new file mode 100644 index 00000000..8c3197e2 --- /dev/null +++ b/3.0/modules/carousel/views/admin_carousel.html.php @@ -0,0 +1,23 @@ + + + diff --git a/3.0/modules/carousel/views/carousel_popular.html.php b/3.0/modules/carousel/views/carousel_popular.html.php new file mode 100644 index 00000000..887cb5c2 --- /dev/null +++ b/3.0/modules/carousel/views/carousel_popular.html.php @@ -0,0 +1,47 @@ + +viewable() + ->where("type", "!=", "album") + ->order_by("view_count", "DESC") + ->find_all($quantity); +?> + + + + + \ No newline at end of file diff --git a/3.0/modules/carousel/views/carousel_random.html.php b/3.0/modules/carousel/views/carousel_random.html.php new file mode 100644 index 00000000..54f864cc --- /dev/null +++ b/3.0/modules/carousel/views/carousel_random.html.php @@ -0,0 +1,49 @@ + +viewable() + ->where("rand_key", "<", ((float)mt_rand()) / (float)mt_getrandmax()) + ->merge_where(NULL) + ->order_by("rand_key", "DESC") + ->find_all($quantity); +?> + + + + + \ No newline at end of file diff --git a/3.0/modules/carousel/views/carousel_recent.html.php b/3.0/modules/carousel/views/carousel_recent.html.php new file mode 100644 index 00000000..95f3d610 --- /dev/null +++ b/3.0/modules/carousel/views/carousel_recent.html.php @@ -0,0 +1,48 @@ + +viewable() + ->where("type", "!=", "album") + ->order_by("created", "DESC") + ->find_all($quantity); +?> + + + + + \ No newline at end of file diff --git a/3.0/modules/contactowner/controllers/admin_contactowner.php b/3.0/modules/contactowner/controllers/admin_contactowner.php index 73a82ee3..26b684ab 100644 --- a/3.0/modules/contactowner/controllers/admin_contactowner.php +++ b/3.0/modules/contactowner/controllers/admin_contactowner.php @@ -1,7 +1,7 @@ name; } + // If item_id is set, include a link to the item. + $email_body = ""; + if (!empty($item_id)) { + $item = ORM::factory("item", $item_id); + $email_body = "This message refers to type}s/{$item->id}") . "\">this page."; + } + // Make a new form with a couple of text boxes. $form = new Forge("contactowner/sendemail/{$user_id}", "", "post", array("id" => "g-contact-owner-send-form")); @@ -53,7 +60,7 @@ class ContactOwner_Controller extends Controller { ->error_messages("required", t("You must enter a subject")); $sendmail_fields->textarea("email_body") ->label(t("Message:")) - ->value("") + ->value($email_body) ->id("g-contactowner-email-body") ->rules('required') ->error_messages("required", t("You must enter a message")); @@ -67,7 +74,7 @@ class ContactOwner_Controller extends Controller { return $form; } - public function emailowner() { + public function emailowner($item_id) { // Display a form that a vistor can use to contact the site owner. // If this page is disabled, show a 404 error. @@ -76,13 +83,13 @@ class ContactOwner_Controller extends Controller { } // Set up and display the actual page. - $template = new Theme_View("page.html", "other", "Contact"); - $template->content = new View("contactowner_emailform.html"); - $template->content->sendmail_form = $this->get_email_form("-1"); - print $template; + $view = new View("contactowner_emailform.html"); + $view->sendmail_form = $this->get_email_form("-1", $item_id); + + print $view; } - public function emailid($user_id) { + public function emailid($user_id, $item_id) { // Display a form that a vistor can use to contact a registered user. // If this page is disabled, show a 404 error. @@ -91,10 +98,11 @@ class ContactOwner_Controller extends Controller { } // Set up and display the actual page. - $template = new Theme_View("page.html", "other", "Contact"); - $template->content = new View("contactowner_emailform.html"); - $template->content->sendmail_form = $this->get_email_form($user_id); - print $template; + // Set up and display the actual page. + $view = new View("contactowner_emailform.html"); + $view->sendmail_form = $this->get_email_form($user_id, $item_id); + + print $view; } public function sendemail($user_id) { @@ -147,18 +155,12 @@ class ContactOwner_Controller extends Controller { ->message($str_emailbody) ->send(); - // Display a message telling the visitor that their email has been sent. - $template = new Theme_View("page.html", "other", "Contact"); - $template->content = new View("contactowner_emailform.html"); - $template->content->sendmail_form = t("Your Message Has Been Sent."); - print $template; + message::info(t("Your Message Has Been Sent.")); + json::reply(array("result" => "success")); } else { // Set up and display the actual page. - $template = new Theme_View("page.html", "other", "Contact"); - $template->content = new View("contactowner_emailform.html"); - $template->content->sendmail_form = $form; - print $template; + json::reply(array("result" => "error", "html" => (string) $form)); } } } diff --git a/3.0/modules/contactowner/helpers/contactowner_block.php b/3.0/modules/contactowner/helpers/contactowner_block.php index b10252b3..c2629a56 100644 --- a/3.0/modules/contactowner/helpers/contactowner_block.php +++ b/3.0/modules/contactowner/helpers/contactowner_block.php @@ -1,7 +1,7 @@ 0) && ($userDetails[0]->email != "") && (module::get_var("contactowner", "contact_user_link") == true)) { $block->content->userLink = "item->owner_id) . "\">" . t("Contact") . " " . + $theme->item->owner_id) . "/" . $theme->item->id . "\" class='g-dialog-link'>" . t("Contact") . " " . $userDetails[0]->name . ""; $displayBlock = true; } @@ -61,8 +61,13 @@ class contactowner_block_Core { // Figure out if the contact site owner link should be displayed. if (module::get_var("contactowner", "contact_owner_link")) { - $block->content->ownerLink = "" . t(module::get_var("contactowner", "contact_button_text")) . ""; + if ($theme->item()) { + $block->content->ownerLink = "item->id . + "\" class='g-dialog-link'>" . t(module::get_var("contactowner", "contact_button_text")) . ""; + } else { + $block->content->ownerLink = "" . t(module::get_var("contactowner", "contact_button_text")) . ""; + } $displayBlock = true; } diff --git a/3.0/modules/contactowner/helpers/contactowner_event.php b/3.0/modules/contactowner/helpers/contactowner_event.php index 5c8483d3..7c527155 100644 --- a/3.0/modules/contactowner/helpers/contactowner_event.php +++ b/3.0/modules/contactowner/helpers/contactowner_event.php @@ -1,7 +1,7 @@ /** * Gallery - a web based photo album viewer and editor - * Copyright (C) 2000-2010 Bharat Mediratta + * Copyright (C) 2000-2011 Bharat Mediratta * * 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 diff --git a/3.0/modules/developer/views/block.txt.php b/3.0/modules/developer/views/block.txt.php index aae11c89..28a8d9db 100644 --- a/3.0/modules/developer/views/block.txt.php +++ b/3.0/modules/developer/views/block.txt.php @@ -3,7 +3,7 @@ /** * Gallery - a web based photo album viewer and editor - * Copyright (C) 2000-2010 Bharat Mediratta + * Copyright (C) 2000-2011 Bharat Mediratta * * 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 diff --git a/3.0/modules/developer/views/controller.txt.php b/3.0/modules/developer/views/controller.txt.php index b73ae815..664ff987 100644 --- a/3.0/modules/developer/views/controller.txt.php +++ b/3.0/modules/developer/views/controller.txt.php @@ -2,7 +2,7 @@ /** * Gallery - a web based photo album viewer and editor - * Copyright (C) 2000-2010 Bharat Mediratta + * Copyright (C) 2000-2011 Bharat Mediratta * * 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 diff --git a/3.0/modules/developer/views/event.txt.php b/3.0/modules/developer/views/event.txt.php index ac5db4e3..32a48520 100644 --- a/3.0/modules/developer/views/event.txt.php +++ b/3.0/modules/developer/views/event.txt.php @@ -2,7 +2,7 @@ /** * Gallery - a web based photo album viewer and editor - * Copyright (C) 2000-2010 Bharat Mediratta + * Copyright (C) 2000-2011 Bharat Mediratta * * 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 diff --git a/3.0/modules/developer/views/installer.txt.php b/3.0/modules/developer/views/installer.txt.php index 6748ac46..cf6662d5 100644 --- a/3.0/modules/developer/views/installer.txt.php +++ b/3.0/modules/developer/views/installer.txt.php @@ -2,7 +2,7 @@ /** * Gallery - a web based photo album viewer and editor - * Copyright (C) 2000-2010 Bharat Mediratta + * Copyright (C) 2000-2011 Bharat Mediratta * * 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 diff --git a/3.0/modules/developer/views/theme.txt.php b/3.0/modules/developer/views/theme.txt.php index 190ff828..e4467f43 100644 --- a/3.0/modules/developer/views/theme.txt.php +++ b/3.0/modules/developer/views/theme.txt.php @@ -2,7 +2,7 @@ /** * Gallery - a web based photo album viewer and editor - * Copyright (C) 2000-2010 Bharat Mediratta + * Copyright (C) 2000-2011 Bharat Mediratta * * 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 diff --git a/3.0/modules/displaytags/helpers/displaytags_block.php b/3.0/modules/displaytags/helpers/displaytags_block.php index ea63bb77..8fc530f1 100644 --- a/3.0/modules/displaytags/helpers/displaytags_block.php +++ b/3.0/modules/displaytags/helpers/displaytags_block.php @@ -1,7 +1,7 @@ module == "tag") { + $data->messages["warn"][] = t("The DisplayTags module requires the Tags module."); + } + } + + static function module_change($changes) { + if (!module::is_active("tag") || in_array("tag", $changes->deactivate)) { + site_status::warning( + t("The DisplayTags module requires the Tags module. Activate the Tags module now", + array("url" => html::mark_clean(url::site("admin/modules")))), + "displaytags_needs_tag"); + } else { + site_status::clear("displaytags_needs_tag"); + } + } +} diff --git a/3.0/themes/greydragon/helpers/greydragon_installer.php b/3.0/modules/displaytags/helpers/displaytags_installer.php similarity index 66% rename from 3.0/themes/greydragon/helpers/greydragon_installer.php rename to 3.0/modules/displaytags/helpers/displaytags_installer.php index 461e6914..808def8a 100644 --- a/3.0/themes/greydragon/helpers/greydragon_installer.php +++ b/3.0/modules/displaytags/helpers/displaytags_installer.php @@ -1,30 +1,36 @@ - \ No newline at end of file +> 8) + (($hash & 0xff000000) >> 24) - : $hash; + $output = $hash; + + if( version_compare(PHP_VERSION, '5.2.7', '<') ) { + $str = str_pad(dechex($hash), 8, '0', STR_PAD_LEFT); + $output = hexdec($str{6}.$str{7}.$str{4}.$str{5}.$str{2}.$str{3}.$str{0}.$str{1}); + } + + return $output; } } diff --git a/3.0/modules/downloadalbum/helpers/downloadalbum_event.php b/3.0/modules/downloadalbum/helpers/downloadalbum_event.php index e58512ac..e8159003 100644 --- a/3.0/modules/downloadalbum/helpers/downloadalbum_event.php +++ b/3.0/modules/downloadalbum/helpers/downloadalbum_event.php @@ -1,7 +1,7 @@ css("downloadalbum_menu.css"); + return $theme->css("downloadalbum_menu.css"); } } diff --git a/3.0/modules/downloadalbum/module.info b/3.0/modules/downloadalbum/module.info index 11c52ba2..f547fd4a 100644 --- a/3.0/modules/downloadalbum/module.info +++ b/3.0/modules/downloadalbum/module.info @@ -1,3 +1,7 @@ name = "DownloadAlbum" description = "Displays a link to download a ZIP archive of the current album." version = 2 +author_name = "" +author_url = "" +info_url = "http://codex.gallery2.org/Gallery3:Modules:downloadalbum" +discuss_url = "http://gallery.menalto.com/forum_module_downloadalbum" diff --git a/3.0/modules/downloadfullsize/controllers/admin_downloadfullsize.php b/3.0/modules/downloadfullsize/controllers/admin_downloadfullsize.php index 1b55bd5c..6836c9c8 100644 --- a/3.0/modules/downloadfullsize/controllers/admin_downloadfullsize.php +++ b/3.0/modules/downloadfullsize/controllers/admin_downloadfullsize.php @@ -1,7 +1,7 @@ item && access::can("view_full", $theme->item)) { - $theme->css("downloadfullsize_menu.css"); + return $theme->css("downloadfullsize_menu.css"); } } } diff --git a/3.0/modules/downloadfullsize/module.info b/3.0/modules/downloadfullsize/module.info index 6c732c9d..078371a9 100644 --- a/3.0/modules/downloadfullsize/module.info +++ b/3.0/modules/downloadfullsize/module.info @@ -1,3 +1,7 @@ name = "DownloadFullsize" description = "Displays a link to download the fullsize version of the current photo." version = 1 +author_name = "" +author_url = "" +info_url = "http://codex.gallery2.org/Gallery3:Modules:downloadfullsize" +discuss_url = "http://gallery.menalto.com/forum_module_downloadfullsize" diff --git a/3.0/modules/dynamic/controllers/admin_dynamic.php b/3.0/modules/dynamic/controllers/admin_dynamic.php index 0180fef3..5c64f1d8 100644 --- a/3.0/modules/dynamic/controllers/admin_dynamic.php +++ b/3.0/modules/dynamic/controllers/admin_dynamic.php @@ -1,6 +1,6 @@ _get_form(); - if ($form->validate()) { - foreach (array("updates", "popular") as $album) { - $album_defn = unserialize(module::get_var("dynamic", $album)); - $group = $form->inputs[$album]; - $album_defn->enabled = $group->inputs["{$album}_enabled"]->value; - $album_defn->description = $group->inputs["{$album}_description"]->value; - $album_defn->limit = $group->inputs["{$album}_limit"] === "" ? null : - $group->inputs["{$album}_limit"]->value; - module::set_var("dynamic", $album, serialize($album_defn)); + $errors = array_fill_keys(array_keys($form), ""); + if ($_POST) { + $post = new Validation($_POST); + $post->add_rules("updates_enabled", array("valid", "numeric")); + $post->add_rules("popular_enabled", array("valid", "numeric")); + $post->add_rules("updates_limit", array("valid", "numeric")); + $post->add_rules("popular_limit", array("valid", "numeric")); + $post->add_rules("updates_description", "length[0,2048]"); + $post->add_rules("popular_description", "length[0,2048]"); + if ($post->validate()) { + foreach (array("updates", "popular") as $album) { + $album_defn = unserialize(module::get_var("dynamic", $album)); + $album_defn->enabled = $post["{$album}_enabled"]; + $album_defn->description = $post["{$album}_description"]; + $album_defn->limit = $post["{$album}_limit"] === "" ? null : $post["{$album}_limit"]; + module::set_var("dynamic", $album, serialize($album_defn)); + } + + message::success(t("Dynamic Albums Configured")); + + url::redirect("admin/dynamic"); + } else { + $form = arr::overwrite($form, $post->as_array()); + $errors = arr::overwrite($errors, $post->errors()); } - - message::success(t("Dynamic Albums Configured")); - - url::redirect("admin/dynamic"); } - print $this->_get_view($form); + print $this->_get_view($form, $errors); } - private function _get_view($form=null) { + private function _get_view($form=null, $errors=null) { $v = new Admin_View("admin.html"); $v->content = new View("admin_dynamic.html"); $v->content->form = empty($form) ? $this->_get_form() : $form; + $v->content->tabs = array("updates" => t("Recent changes"), "popular" => t("Most viewed")); + $v->content->errors = $errors; return $v; } private function _get_form() { + $form = array(); + foreach (array("updates", "popular") as $album) { + $album_defn = unserialize(module::get_var("dynamic", $album)); + $form["{$album}_enabled"] = $album_defn->enabled; + $form["{$album}_limit"] = $album_defn->limit; + $form["{$album}_description"] = $album_defn->description; + } + + return $form; + } + + private function _get_form2() { $form = new Forge("admin/dynamic/handler", "", "post", array("id" => "g-admin-form")); diff --git a/3.0/modules/dynamic/controllers/dynamic.php b/3.0/modules/dynamic/controllers/dynamic.php index fae825c8..10a7a6f5 100644 --- a/3.0/modules/dynamic/controllers/dynamic.php +++ b/3.0/modules/dynamic/controllers/dynamic.php @@ -1,6 +1,6 @@ get("page", "1"); $album_defn = unserialize(module::get_var("dynamic", $album)); - $children_count = $album_defn->limit; - if (empty($children_count)) { - $children_count = ORM::factory("item") - ->viewable() - ->where("type", "!=", "album") - ->count_all(); + $display_limit = $album_defn->limit; + $children_count = ORM::factory("item") + ->viewable() + ->where("type", "!=", "album") + ->count_all(); + if (!empty($display_limit)) { + $children_count = min($children_count, $display_limit); } - $offset = ($page-1) * $page_size; - - $max_pages = ceil($children_count / $page_size); + $offset = ($page - 1) * $page_size; + $max_pages = max(ceil($children_count / $page_size), 1); // Make sure that the page references a valid offset if ($page < 1 || ($children_count && $page > ceil($children_count / $page_size))) { diff --git a/3.0/modules/dynamic/helpers/dynamic_block.php b/3.0/modules/dynamic/helpers/dynamic_block.php index 42861c51..bf7dcd8f 100644 --- a/3.0/modules/dynamic/helpers/dynamic_block.php +++ b/3.0/modules/dynamic/helpers/dynamic_block.php @@ -1,6 +1,6 @@ +

-
- + "g-admin-form")) ?> + +
+
    + $label): ?> +
  • + +
+ +
+
    +
  • + + +
  • +
  • + + + " . t("Limit must be numeric") ?> +
  • +
  • + + + " . t("Description must be less than 2048 bytes") ?> +
  • +
      +
+
+
diff --git a/3.0/modules/ecard/controllers/admin_ecard.php b/3.0/modules/ecard/controllers/admin_ecard.php index 640ce40a..1608b0e1 100644 --- a/3.0/modules/ecard/controllers/admin_ecard.php +++ b/3.0/modules/ecard/controllers/admin_ecard.php @@ -1,7 +1,7 @@ _get_admin_form(); if ($form->validate()) { - module::set_var("ecard", "sender", $form->ecard->sender->value); + module::set_var("ecard","send_plain",$form->ecard->send_plain->value); + module::set_var("ecard", "sender", $form->ecard->sender->value); module::set_var("ecard", "bcc", $form->ecard->bcc->value); module::set_var("ecard", "subject", $form->ecard->subject->value); module::set_var("ecard", "message", $form->ecard->message->value); + module::set_var("ecard", "max_length", $form->ecard->max_length->value); module::set_var("ecard", "access_permissions", $form->ecard->access_permissions->value); module::set_var("ecard", "location", $form->ecard->location->value); message::success(t("eCard settings updated")); @@ -54,9 +56,18 @@ class Admin_ecard_Controller extends Admin_Controller { ->value(module::get_var("ecard", "bcc", "")); $ecard_settings->input("subject")->label(t("E-mail subject")) ->value(module::get_var("ecard", "subject")); - $ecard_settings->textarea("message")->label(t("E-mail message. Valid keywords are \"%toname\" (recipient's name) and \"%fromname\" (sender's name))")) + $ecard_settings->textarea("message")->label(t("E-mail message. Valid keywords are \"%fromname\" (sender's name))")) ->value(module::get_var("ecard", "message")); - $ecard_settings->dropdown("access_permissions") + $ecard_settings->input("max_length") + ->label(t("Maximum message length")) + ->value(module::get_var("ecard","max_length")); + if(module::is_active("watermark")) { + $ecard_settings->checkbox("send_plain") + ->label(t("Allow users to send non-watermarked versions")) + ->value(true) + ->checked(module::get_var("ecard","send_plain")); + } + $ecard_settings->dropdown("access_permissions") ->label(t("Who can send eCards?")) ->options(array("everybody" => t("Everybody"), "registered_users" => t("Only registered users"))) diff --git a/3.0/modules/ecard/controllers/ecard.php b/3.0/modules/ecard/controllers/ecard.php index 6ca30df7..82777443 100644 --- a/3.0/modules/ecard/controllers/ecard.php +++ b/3.0/modules/ecard/controllers/ecard.php @@ -1,7 +1,7 @@ item = $item; - $v->subject = module::get_var("ecard", "subject"); - $to_name = $form->send_ecard->to_name->value; - $from_name = $form->send_ecard->from_name->value; - $bcc = module::get_var("ecard", "bcc"); - $v->message = t(module::get_var("ecard", "message"), array("toname" => $to_name, "fromname" => $from_name)); - $v->custom_message = $form->send_ecard->text->value; - $v->image = $item->name; - $to = $form->send_ecard->inputs["to_email"]->value; - $from = $form->send_ecard->inputs["from_email"]->value; - $headers = array("from" => $from_name."<".$from.">", "to" => $to, "subject" => module::get_var("ecard", "subject")); - require_once(MODPATH. "ecard/lib/mime.php"); - $mime = new Mail_mime("\n"); - $mime->setHTMLBody($v->render()); - $mime->addHTMLImage($item->resize_path(),$item->mime_type,$item->name); - $body = $mime->get(array('html_charset' => 'UTF-8', 'text_charset' => 'UTF-8','text_encoding' => '8bit','head_charset' => 'UTF-8')); - self::_notify($headers['to'], $headers['from'], $headers['subject'], $item, $body, $mime->headers(), $bcc); + $to_array = explode(",",$form->send_ecard->inputs["to_email"]->value); + foreach($to_array as $to) { + $v = new View("ecard_email.html"); + $v->item = $item; + $v->subject = module::get_var("ecard", "subject"); + $from_name = $form->send_ecard->from_name->value; + $bcc = module::get_var("ecard", "bcc"); + if($form->send_ecard->send_to_self->checked == true) { + $cc = $form->send_ecard->inputs["from_email"]->value; + } + $v->message = t(module::get_var("ecard", "message"), array("fromname" => $from_name)); + $v->custom_message = $form->send_ecard->text->value; + $v->image = $item->name; + $from = $form->send_ecard->inputs["from_email"]->value; + $headers = array("from" => $from_name."<".$from.">", "to" => $to, "subject" => module::get_var("ecard", "subject")); + require_once(MODPATH. "ecard/lib/mime.php"); + $mime = new Mail_mime("\n"); + $mime->setHTMLBody($v->render()); + if($form->send_ecard->send_fresh->checked == true) { + $tmpfile = tempnam(TMPPATH, "clean"); + if($form->send_ecard->send_thumbnail->checked == true) { + $options = array("width" => module::get_var("gallery", "thumb_size"), "height" => module::get_var("gallery", "thumb_size"), "master" => Image::AUTO); + gallery_graphics::resize($item->file_path(), $tmpfile, $options); + $mime->addHTMLImage($tmpfile,$item->mime_type,$item->name); + } else { + $options = array("width" => module::get_var("gallery", "resize_size"), "height" => module::get_var("gallery", "resize_size"), "master" => Image::AUTO); + gallery_graphics::resize($item->file_path(), $tmpfile, $options); + $mime->addHTMLImage($tmpfile,$item->mime_type,$item->name); + } + } else { + if($form->send_ecard->send_thumbnail->checked == true) { + $mime->addHTMLImage($item->thumb_path(),$item->mime_type,$item->name); + } else { + $mime->addHTMLImage($item->resize_path(),$item->mime_type,$item->name); + } + } + $body = $mime->get(array('html_charset' => 'UTF-8', 'text_charset' => 'UTF-8','text_encoding' => '8bit','head_charset' => 'UTF-8')); + self::_notify($headers['to'], $headers['from'], $headers['subject'], $item, $body, $mime->headers(), $bcc, $cc); + } + unlink($tmpfile); message::success("eCard successfully sent"); json::reply(array("result" => "success")); - } else { + } else { json::reply(array("result" => "error", "html" => (string) $form)); - } + } } /** * Present a form for sending a new ecard. @@ -73,9 +95,11 @@ class Ecard_Controller extends Controller { if (!ecard::can_send_ecard()) { access::forbidden(); } - print ecard::prefill_send_form(ecard::get_send_form($item)); + $v_form = new View("ecard_form.html"); + $v_form->item_id = $item_id; + print $v_form->render(); } - private static function _notify($to, $from, $subject, $item, $text, $headers, $bcc) { + private static function _notify($to, $from, $subject, $item, $text, $headers, $bcc, $cc) { $sendmail = Sendmail::factory(); $sendmail ->to($to) @@ -84,6 +108,9 @@ class Ecard_Controller extends Controller { if(isset($bcc)) { $sendmail->header("bcc",$bcc); } + if(isset($cc)) { + $sendmail->header("cc",$cc); + } foreach($headers as $key => $value) { $sendmail->header($key,$value); } diff --git a/3.0/modules/ecard/helpers/ecard.php b/3.0/modules/ecard/helpers/ecard.php index 13485954..a786521b 100644 --- a/3.0/modules/ecard/helpers/ecard.php +++ b/3.0/modules/ecard/helpers/ecard.php @@ -1,7 +1,7 @@ id}", "", "post", array("id" => "g-ecard-form")); + static function get_send_form($item_id) { + $form = new Forge("ecard/send/{$item_id}", "", "post", array("id" => "g-ecard-form")); $group = $form->group("send_ecard")->label(t("Send eCard")); $group->input("from_name") ->label(t("Your name")) @@ -38,23 +38,32 @@ class ecard_Core { ->rules("required|valid_email") ->error_messages("required", t("You must enter a valid email address")) ->error_messages("invalid", t("You must enter a valid email address")); - $group->input("to_name") - ->label(t("Recipient's Name")) - ->id("g-recipient") - ->rules("required") - ->error_messages("required", t("You must enter a recipient's name")); $group->input("to_email") - ->label(t("Recipient's e-mail")) + ->label(t("Recipient's e-mail. Separate multiple recipients with a comma.")) ->id("g-recip-email") - ->rules("required|valid_email") - ->error_messages("required", t("You must enter a valid email address")) - ->error_messages("invalid", t("You must enter a valid email address")); + ->rules("required") + ->error_messages("required", t("You must enter a valid email address")); $group->textarea("text") - ->label(t("Message")) + ->label(t("Message (".module::get_var("ecard","max_length")." chars max)")) ->id("g-text") + ->maxlength(module::get_var("ecard","max_length")) ->rules("required") ->error_messages("required", t("You must enter a message")); - $group->hidden("item_id")->value($item->id); + $group->checkbox("send_to_self") + ->label(t("Send yourself a copy")) + ->value(true) + ->checked(false); + $group->checkbox("send_thumbnail") + ->label(t("Send thumbnail image, instead of resized image.")) + ->value(true) + ->checked(false); + if(module::get_var("ecard","send_plain") == true && module::is_active("watermark")) { + $group->checkbox("send_fresh") + ->label(t("Send non-watermarked image.")) + ->value(true) + ->checked(false); + } + $group->hidden("item_id")->value($item_id); module::event("ecard_send_form", $form); module::event("captcha_protect_form", $form); $group->submit("")->value(t("Send"))->class("ui-state-default ui-corner-all"); diff --git a/3.0/modules/ecard/helpers/ecard_block.php b/3.0/modules/ecard/helpers/ecard_block.php index 051c55c6..d90755ab 100644 --- a/3.0/modules/ecard/helpers/ecard_block.php +++ b/3.0/modules/ecard/helpers/ecard_block.php @@ -1,7 +1,7 @@ item() && $theme->item()->is_photo() && module::get_var("ecard", "location") == "sidebar") { $block = new Block(); - $block->css_id = "g-send-ecard"; + $block->css_id = "g-sendecard"; $block->title = t("eCard"); $block->content = new View("ecard_block.html"); } diff --git a/3.0/modules/ecard/helpers/ecard_event.php b/3.0/modules/ecard/helpers/ecard_event.php index 06165b8f..ebbd5442 100644 --- a/3.0/modules/ecard/helpers/ecard_event.php +++ b/3.0/modules/ecard/helpers/ecard_event.php @@ -1,7 +1,7 @@ css("ecard.css"); + return $theme->css("ecard.css"); } } \ No newline at end of file diff --git a/3.0/modules/ecard/module.info b/3.0/modules/ecard/module.info index 95c8f6a4..2300f1ad 100644 --- a/3.0/modules/ecard/module.info +++ b/3.0/modules/ecard/module.info @@ -1,4 +1,7 @@ name = "E-Card" description = "Send a photo as a postcard" -version = 4 - +version = 11 +author_name = "" +author_url = "" +info_url = "http://codex.gallery2.org/Gallery3:Modules:ecard" +discuss_url = "http://gallery.menalto.com/forum_module_ecard" diff --git a/3.0/modules/ecard/views/ecard_block.html.php b/3.0/modules/ecard/views/ecard_block.html.php index 3f307a1d..d8aa4e4e 100644 --- a/3.0/modules/ecard/views/ecard_block.html.php +++ b/3.0/modules/ecard/views/ecard_block.html.php @@ -1,6 +1,6 @@ -id}") ?>" id="g-send-ecard" +id}") ?>" class="g-dialog-link g-button ui-state-default ui-corner-all"> - + diff --git a/3.0/modules/ecard/views/ecard_form.html.php b/3.0/modules/ecard/views/ecard_form.html.php new file mode 100644 index 00000000..fc22e95b --- /dev/null +++ b/3.0/modules/ecard/views/ecard_form.html.php @@ -0,0 +1 @@ + Send eCard \ No newline at end of file diff --git a/3.0/modules/editcaptured/css/editcaptured.css b/3.0/modules/editcaptured/css/editcaptured.css new file mode 100644 index 00000000..84e8853c --- /dev/null +++ b/3.0/modules/editcaptured/css/editcaptured.css @@ -0,0 +1,9 @@ +#g-dialog select { + display: inline; +} +.g-editcaptured-usedate { + display: inline; +} +.g-editcaptured-setsubitems { + display: inline; +} diff --git a/3.0/modules/editcaptured/helpers/editcaptured_event.php b/3.0/modules/editcaptured/helpers/editcaptured_event.php new file mode 100644 index 00000000..00b5735b --- /dev/null +++ b/3.0/modules/editcaptured/helpers/editcaptured_event.php @@ -0,0 +1,154 @@ +id == 1) + return; + + // Search if there are at least some child items containing a captured date + $model = ORM::factory("item") + ->where("parent_id", "=", $item->id) + ->where("captured", "IS NOT", null) + ->order_by("captured", "ASC"); + $first_child = $model->find(); + if (!$first_child->id) $first_child = null; + + // Chose preselected option, depending on wheather item already has captured date or not + if ($item->captured) { + $dateoptions_preselect = "selected"; + } else { + $dateoptions_preselect = "remove"; + } + + // Depending on wheather there are child items or not, we generate the dropdown options + if ($first_child) { + $dateoptions = array("selected" => t("Selected Date"), + "oldest" => t("Date of oldest Child"), + "youngest" => t("Date of youngest Child"), + "now" => t("Current Date"), + "remove" => t("Remove Date")); + + // If there are child items with captured date, we preset the date field with the oldest item + if (!$item->captured && $first_child) { + $item->captured = $first_child->captured; + $dateoptions_preselect = "oldest"; + } + } else { + $dateoptions = array("selected" => t("Selected Date"), + "now" => t("Current Date"), + "remove" => t("Remove Date")); + } + + // Add captured date field to the form + $form->edit_item->dateselect("capturedate") + ->label(t("Captured")) + ->minutes(1) + ->years(1970, date('Y')+1) + ->value($item->captured); + + // Add dropdown menu for options to the form + $form->edit_item->dropdown("capturedate_usedate") + ->options($dateoptions) + ->id("g-editcaptured-usedate") + ->selected($dateoptions_preselect); + + // Add checkbox for users who want to change the captured date of subitems, too + if ($item->is_album()) { + $form->edit_item->checkbox("capturedate_setsubitems") + ->label(t("Set also subitems's date")) + ->id("g-editcaptured-setsubitems"); + } + } + + static function item_edit_form_completed($item, $form) { + // Change the item's captured field to the specified value. + + // We don't want to change the root element, so check for that + if ($item->id == 1) { + return; + } + + // Depending on the dropdown option, we set the date + switch ($form->edit_item->capturedate_usedate->value) { + + // Just use the date selected in the form + case "selected": + $item->captured = $form->edit_item->capturedate->value; + break; + + // Use the date of the oldest child (we check again if there is such a child) + case "oldest": + $model = ORM::factory("item") + ->where("parent_id", "=", $item->id) + ->where("captured", "IS NOT", null) + ->order_by("captured", "ASC"); + $first_child = $model->find(); + if ($first_child->id) { + $item->captured = $first_child->captured; + } else { + $item->captured = null; + } + break; + + // Use the date of the youngest child (we check again if there is such a child) + case "youngest": + $model = ORM::factory("item") + ->where("parent_id", "=", $item->id) + ->where("captured", "IS NOT", null) + ->order_by("captured", "DESC"); + $first_child = $model->find(); + if ($first_child->id) { + $item->captured = $first_child->captured; + } else { + $item->captured = null; + } + break; + + // Use the current date + case "now": + $item->captured = time(); + break; + + // Remove the date + case "remove": + $item->captured = null; + } + + $item->save(); + + // Set the date also for all subitems (at the moment only direct subitems are supported + if ($item->is_album() && $form->edit_item->capturedate_setsubitems->checked) { + foreach (ORM::factory("item")->where("parent_id", "=", $item->id)->find_all() as $subitem) { + if ($subitem->loaded() && access::can("edit", $subitem)) { + $subitem->captured = $item->captured; + $subitem->save(); + } + } + //message::success(t("Changed captured date of subitems")); + } + + } + +} + diff --git a/3.0/modules/editcaptured/helpers/editcaptured_theme.php b/3.0/modules/editcaptured/helpers/editcaptured_theme.php new file mode 100644 index 00000000..7458860c --- /dev/null +++ b/3.0/modules/editcaptured/helpers/editcaptured_theme.php @@ -0,0 +1,31 @@ +item()) { + return; + } + $item = $theme->item(); + if ( $item && access::can("edit", $item) ) { + $theme->css("editcaptured.css"); + } + } +} diff --git a/3.0/modules/editcaptured/module.info b/3.0/modules/editcaptured/module.info new file mode 100644 index 00000000..28fedee4 --- /dev/null +++ b/3.0/modules/editcaptured/module.info @@ -0,0 +1,7 @@ +name = "Edit Captured Date" +description = "Edit the capture date of an element manually or semiautomatically based on date of subitems." +version = 2 +author_name = "" +author_url = "" +info_url = "http://codex.gallery2.org/Gallery3:Modules:editcaptured" +discuss_url = "http://gallery.menalto.com/forum_module_editcaptured" diff --git a/3.0/modules/editcreation/helpers/editcreation_event.php b/3.0/modules/editcreation/helpers/editcreation_event.php index c76e730d..8820d8fa 100644 --- a/3.0/modules/editcreation/helpers/editcreation_event.php +++ b/3.0/modules/editcreation/helpers/editcreation_event.php @@ -1,7 +1,7 @@ item(); if ( $item && access::can("edit", $item) ) { - $theme->css("editcreation.css"); + return $theme->css("editcreation.css"); } } } diff --git a/3.0/modules/editcreation/module.info b/3.0/modules/editcreation/module.info index 3b98c089..fef83519 100755 --- a/3.0/modules/editcreation/module.info +++ b/3.0/modules/editcreation/module.info @@ -1,3 +1,7 @@ name = "Edit Creation" description = "Manually edit the creation date of an item in Gallery." version = 2 +author_name = "" +author_url = "" +info_url = "http://codex.gallery2.org/Gallery3:Modules:editcreation" +discuss_url = "http://gallery.menalto.com/forum_module_editcreation" diff --git a/3.0/modules/embed_videos/controllers/embedded_videos.php b/3.0/modules/embed_videos/controllers/embedded_videos.php index 6c86e3a0..fc7281f2 100644 --- a/3.0/modules/embed_videos/controllers/embedded_videos.php +++ b/3.0/modules/embed_videos/controllers/embedded_videos.php @@ -1,7 +1,7 @@ item(); if ($item && $item->is_photo()) { $embedded_video = ORM::factory("embedded_video") diff --git a/3.0/modules/embed_videos/models/embedded_video.php b/3.0/modules/embed_videos/models/embedded_video.php index 6ea97e8f..7f0ae949 100644 --- a/3.0/modules/embed_videos/models/embedded_video.php +++ b/3.0/modules/embed_videos/models/embedded_video.php @@ -1,7 +1,7 @@ order_by("exif_coordinates.latitude", "ASC") ->descendants(); $curr_album = ORM::factory("item")->where("id", "=", $type_id)->find_all(); - $map_title = $curr_album[0]->name; + $map_title = $curr_album[0]->title; } elseif ($map_type == "user") { // Generate an array of all items uploaded by the current user that // have exif gps coordinates and order by latitude (to group items diff --git a/3.0/modules/exif_gps/helpers/exif_gps.php b/3.0/modules/exif_gps/helpers/exif_gps.php index d3440424..823b4b29 100644 --- a/3.0/modules/exif_gps/helpers/exif_gps.php +++ b/3.0/modules/exif_gps/helpers/exif_gps.php @@ -1,7 +1,7 @@ get("completed"); // Generate an array of the next 100 photos to check. - $all_photos = ORM::factory("item") - ->where("id", ">", $last_id) - ->where("type", "=", "photo") - ->find_all(100); + //$all_photos = ORM::factory("item") + // ->where("id", ">", $last_id) + // ->where("type", "=", "photo") + // ->order_by("id") + // ->find_all(100); // Check each photo in the array to see if it already has exif gps data associated with it. // If it doesn't, attempt to extract gps coordinates. foreach (ORM::factory("item") ->where("id", ">", $last_id) ->where("type", "=", "photo") + ->order_by("id") ->find_all(100) as $item) { $record = ORM::factory("exif_coordinate")->where("item_id", "=", $item->id)->find(); diff --git a/3.0/modules/exif_gps/helpers/exif_gps_theme.php b/3.0/modules/exif_gps/helpers/exif_gps_theme.php index 160373a2..90431195 100644 --- a/3.0/modules/exif_gps/helpers/exif_gps_theme.php +++ b/3.0/modules/exif_gps/helpers/exif_gps_theme.php @@ -1,7 +1,7 @@ css("exif_gps_menu.css"); + return $theme->css("exif_gps_menu.css"); } } diff --git a/3.0/modules/exif_gps/models/exif_coordinate.php b/3.0/modules/exif_gps/models/exif_coordinate.php index 481da1cd..e3286d93 100644 --- a/3.0/modules/exif_gps/models/exif_coordinate.php +++ b/3.0/modules/exif_gps/models/exif_coordinate.php @@ -1,7 +1,7 @@ + - + diff --git a/3.0/modules/exif_gps/views/exif_gps_dynamic_sidebar.html.php b/3.0/modules/exif_gps/views/exif_gps_dynamic_sidebar.html.php index d5b497dc..ff28e101 100644 --- a/3.0/modules/exif_gps/views/exif_gps_dynamic_sidebar.html.php +++ b/3.0/modules/exif_gps/views/exif_gps_dynamic_sidebar.html.php @@ -19,4 +19,4 @@ google.setOnLoadCallback(initialize); - + diff --git a/3.0/modules/exif_gps/views/exif_gps_map.html.php b/3.0/modules/exif_gps/views/exif_gps_map.html.php index 6c8a59ee..95f6221c 100644 --- a/3.0/modules/exif_gps/views/exif_gps_map.html.php +++ b/3.0/modules/exif_gps/views/exif_gps_map.html.php @@ -62,14 +62,14 @@ infowindow.open(map,marker); }); - + // If there is a maximum auto-zoom value, then set up an event to check the zoom // level the first time it is changed, and adjust it if necessary. // (if we call map.getZoom right after .fitBounds, getZoom will return the initial // zoom level, not the auto zoom level, this way we get the auto zoomed value). google.maps.event.addListener(map, 'zoom_changed', function() { if (google_zoom_hack) { - if (map.getZoom() > 18) map.setZoom(18); + if (map.getZoom() > ) map.setZoom(); google_zoom_hack = false; } }); diff --git a/3.0/modules/export_facebook/controllers/export_facebook.php b/3.0/modules/export_facebook/controllers/export_facebook.php index 62f2e6df..e40f9a40 100644 --- a/3.0/modules/export_facebook/controllers/export_facebook.php +++ b/3.0/modules/export_facebook/controllers/export_facebook.php @@ -1,7 +1,7 @@ css("favourites.css"); - $theme->script("favourites.js"); + return $theme->css("favourites.css") + . $theme->script("favourites.js"); } static function header_top($theme) { diff --git a/3.0/modules/favourites/module.info b/3.0/modules/favourites/module.info index aa2df84a..a3d6b898 100644 --- a/3.0/modules/favourites/module.info +++ b/3.0/modules/favourites/module.info @@ -1,3 +1,7 @@ name = "Favourites" description = "Allows users and guests to create favourite lists and then e-mail them to people." version = 1 +author_name = "" +author_url = "" +info_url = "http://codex.gallery2.org/Gallery3:Modules:favourites" +discuss_url = "http://gallery.menalto.com/forum_module_favourites" diff --git a/3.0/modules/gmaps/module.info b/3.0/modules/gmaps/module.info index 12dd61d4..e524eb69 100644 --- a/3.0/modules/gmaps/module.info +++ b/3.0/modules/gmaps/module.info @@ -1,3 +1,7 @@ name = "Google Maps" description = "Integrate with the Google Maps service" version = 1 +author_name = "" +author_url = "" +info_url = "http://codex.gallery2.org/Gallery3:Modules:gmaps" +discuss_url = "http://gallery.menalto.com/forum_module_gmaps" diff --git a/3.0/modules/google_analytics/controllers/admin_google_analytics.php b/3.0/modules/google_analytics/controllers/admin_google_analytics.php index 84b7daeb..4a28ad8d 100644 --- a/3.0/modules/google_analytics/controllers/admin_google_analytics.php +++ b/3.0/modules/google_analytics/controllers/admin_google_analytics.php @@ -1,7 +1,7 @@ script("highroller.js"); - printf("", url::site("highroller/pick_theme")); + return $theme->script("highroller.js") + . sprintf("", url::site("highroller/pick_theme")); } static function header_top($theme) { diff --git a/3.0/modules/highroller/module.info b/3.0/modules/highroller/module.info index 9b573a98..7b89e9cb 100644 --- a/3.0/modules/highroller/module.info +++ b/3.0/modules/highroller/module.info @@ -1,3 +1,7 @@ name = "High Roller" description = "Let users choose from a selection of ThemeRoller themes" version = 1 +author_name = "" +author_url = "" +info_url = "http://codex.gallery2.org/Gallery3:Modules:highroller" +discuss_url = "http://gallery.menalto.com/forum_module_highroller" diff --git a/3.0/modules/html_uploader/controllers/uploader.php b/3.0/modules/html_uploader/controllers/uploader.php index 78c64468..0b9b5351 100644 --- a/3.0/modules/html_uploader/controllers/uploader.php +++ b/3.0/modules/html_uploader/controllers/uploader.php @@ -1,7 +1,7 @@ script("kbd_nav.js"); - } -} \ No newline at end of file diff --git a/3.0/modules/kbd_nav/js/kbd_nav.js b/3.0/modules/kbd_nav/js/kbd_nav.js deleted file mode 100644 index 25eb7210..00000000 --- a/3.0/modules/kbd_nav/js/kbd_nav.js +++ /dev/null @@ -1,102 +0,0 @@ -/** -* -* Copyright (c) 2010 Serguei Dosyukov, http://blog.dragonsoft.us -* -* Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation -* files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, -* modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the -* Software is furnished to do so, subject to the following conditions: -* -* The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES -* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR -* IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -* -*/ - -$.fn.KbdNavigation = function(options, callback) { - - this.options = options || {}; - var opt = this.options; - this.callback = callback || null; - var clbk = this.callback; - - $(this).bind("keydown", function(event) { - if ($('#sb-body-inner>img#sb-content').is(':visible')) { - return false; - } - // ignore shortcuts when inside a jQuery dialog; otherwise it becomes impossible - // to navigate the cursor inside an input box - if ($('.ui-widget-overlay').is(':visible')) { - return true; - } - - var direction = "ltr"; - if (document.body) { - if (window.getComputedStyle) { - direction = window.getComputedStyle(document.body, null).direction; - } else if (document.body.currentStyle) { - direction = document.body.currentStyle.direction; - } - } - - var lnk = ""; - var lnk_first, lnk_prev, lnk_parent, lnk_next, lnk_last; - - if(opt.first) { lnk_first = opt.first; } else { lnk_first = $("#g-navi-first").attr("href"); } - if(opt.prev) { lnk_prev = opt.prev; } else { lnk_prev = $("#g-navi-prev").attr("href"); } - if(opt.parent) { lnk_parent = opt.parent; } else { lnk_parent = $("#g-navi-parent").attr("href"); } - if(opt.next) { lnk_next = opt.next; } else { lnk_next = $("#g-navi-next").attr("href"); } - if(opt.last) { lnk_last = opt.last; } else { lnk_last = $("#g-navi-last").attr("href"); } - - // Support for standard Wind Theme tags - if(!lnk_first) { lnk_first = $(".g-paginator .ui-icon-seek-first").parent().attr("href"); } - if(!lnk_prev) { lnk_prev = $(".g-paginator .ui-icon-seek-prev").parent().attr("href"); } - if(!lnk_next) { lnk_next = $(".g-paginator .ui-icon-seek-next").parent().attr("href"); } - if(!lnk_last) { lnk_last = $(".g-paginator .ui-icon-seek-end").parent().attr("href"); } - - var keyCode = event.keyCode; - - if (direction == "rtl") { - switch(keyCode) { - case 0x25: // Left - keyCode = 0x27; - break; - case 0x27: // Right - keyCode = 0x25; - break; - } - } - - switch(keyCode) { - case 0x25: // Ctr+Left/Left - if(event.ctrlKey) { lnk = lnk_first; } else { lnk = lnk_prev; } - break; - case 0x26: // Ctrl+Up - if(event.ctrlKey) { lnk = lnk_parent; } - break; - case 0x27: // Ctrl+Right/Right - if(event.ctrlKey) { lnk = lnk_last; } else { lnk = lnk_next; } - break; - } - - if(lnk) { - if(typeof clbk == 'function') { - clbk(); - return false; - } else { - window.location = lnk; - return true; - } - } - - return true; - }); -} - -$(document).ready( function() { - $(document).KbdNavigation({}); - if ($('#sb-content').is(':visible')) { return true; } -}); diff --git a/3.0/modules/kbd_nav/module.info b/3.0/modules/kbd_nav/module.info deleted file mode 100644 index 2eda7c73..00000000 --- a/3.0/modules/kbd_nav/module.info +++ /dev/null @@ -1,3 +0,0 @@ -name = "Kbd Navigation" -description = "Adds keyboard navigation to the gallery.
Version 1.5 | By Serguei Dosyukov | Visit plugin Site | Support" -version = 5 diff --git a/3.0/modules/keeporiginal/controllers/keeporiginal.php b/3.0/modules/keeporiginal/controllers/keeporiginal.php index 0bb3aa4f..36f6affe 100644 --- a/3.0/modules/keeporiginal/controllers/keeporiginal.php +++ b/3.0/modules/keeporiginal/controllers/keeporiginal.php @@ -1,7 +1,7 @@ css("language_flags_sidebar.css"); + return $theme->css("language_flags_sidebar.css"); } } diff --git a/3.0/modules/language_flags/module.info b/3.0/modules/language_flags/module.info index d0838d10..56fa94ab 100644 --- a/3.0/modules/language_flags/module.info +++ b/3.0/modules/language_flags/module.info @@ -1,3 +1,7 @@ name = "Language Flags" description = "Replaces the language selection drop-down box with clickable flags." -version = 1 \ No newline at end of file +version = 1 +author_name = "" +author_url = "" +info_url = "http://codex.gallery2.org/Gallery3:Modules:language_flags" +discuss_url = "http://gallery.menalto.com/forum_module_language_flags" diff --git a/3.0/modules/latestalbums/helpers/latestalbums_rss.php b/3.0/modules/latestalbums/helpers/latestalbums_rss.php index 8aca12a7..aa34088c 100644 --- a/3.0/modules/latestalbums/helpers/latestalbums_rss.php +++ b/3.0/modules/latestalbums/helpers/latestalbums_rss.php @@ -1,7 +1,7 @@ "ldap", "allow_updates" => false, "params" => array( - "groups" => array("eng", "google", "guest"), + "groups" => array("engineering", "everybody", "guest"), "everybody_group" => "guest", - "registered_users_group" => "google", - "admins" => array("mediratta", "martinm"), - "url" => "ldaps://ldap.corp.google.com/", - "group_domain" => "ou=Posix,ou=Groups,dc=google,dc=com", - "user_domain" => "ou=People,dc=google,dc=com", + "registered_users_group" => "everybody", + "admins" => array("alice", "bob"), + "url" => "ldaps://ldap.mycompany.com/", + "group_domain" => "ou=Posix,ou=Groups,dc=ymcompany,dc=com", + "user_domain" => "ou=People,dc=MyCompany,dc=com", "bind_rdn" => null, "bind_password" => null, ) diff --git a/3.0/modules/ldap/helpers/ldap_installer.php b/3.0/modules/ldap/helpers/ldap_installer.php index 37269748..d9bdbfd4 100644 --- a/3.0/modules/ldap/helpers/ldap_installer.php +++ b/3.0/modules/ldap/helpers/ldap_installer.php @@ -1,7 +1,7 @@ ldap_entry["displayname"][0]; + if (!empty($this->ldap_entry["displayname"][0])) { + return $this->ldap_entry["displayname"][0]; + } + return $this->ldap_entry["cn"][0]; } public function __get($key) { diff --git a/3.0/modules/ldap/module.info b/3.0/modules/ldap/module.info index 06fa311b..96785139 100644 --- a/3.0/modules/ldap/module.info +++ b/3.0/modules/ldap/module.info @@ -1,3 +1,7 @@ name = "LDAP" description = "Use LDAP for authentication" version = 1 +author_name = "" +author_url = "" +info_url = "http://codex.gallery2.org/Gallery3:Modules:ldap" +discuss_url = "http://gallery.menalto.com/forum_module_ldap" diff --git a/3.0/modules/metadescription/helpers/metadescription_event.php b/3.0/modules/metadescription/helpers/metadescription_event.php index bde007b0..7e773d7e 100644 --- a/3.0/modules/metadescription/helpers/metadescription_event.php +++ b/3.0/modules/metadescription/helpers/metadescription_event.php @@ -1,7 +1,7 @@ module == "tag") { + $data->messages["warn"][] = t("The MetaDescription module requires the Tags module."); + } + } } diff --git a/3.0/modules/metadescription/helpers/metadescription_installer.php b/3.0/modules/metadescription/helpers/metadescription_installer.php index 4ca8f169..6609ecd9 100644 --- a/3.0/modules/metadescription/helpers/metadescription_installer.php +++ b/3.0/modules/metadescription/helpers/metadescription_installer.php @@ -1,7 +1,7 @@ item()) { + if ($theme->item() || $theme->tag()) { $metaView = new View("metadescription_block.html"); $metaView->tags = $tagsItem; return $metaView; diff --git a/3.0/modules/metadescription/module.info b/3.0/modules/metadescription/module.info index 19c2cd48..7010a0d1 100644 --- a/3.0/modules/metadescription/module.info +++ b/3.0/modules/metadescription/module.info @@ -1,3 +1,7 @@ name = "MetaDescription" description = "Automatically generates and inserts KEYWORD and DESCRIPTION meta tags into any theme." version = 1 +author_name = "rWatcher" +author_url = "http://codex.gallery2.org/User:RWatcher" +info_url = "http://codex.gallery2.org/Gallery3:Modules:metadescription" +discuss_url = "http://gallery.menalto.com/node/102477" diff --git a/3.0/modules/minislideshow/controllers/admin_minislideshow.php b/3.0/modules/minislideshow/controllers/admin_minislideshow.php index 0e4cd54f..f66a495a 100644 --- a/3.0/modules/minislideshow/controllers/admin_minislideshow.php +++ b/3.0/modules/minislideshow/controllers/admin_minislideshow.php @@ -1,7 +1,7 @@ "g-mini-slideshow-admin-form")); - // Get location of slideshow files. $group_slideshow_files = $form->group("Minislideshow"); $group_slideshow_files->input("slideshow_url") @@ -124,4 +123,4 @@ class Admin_Minislideshow_Controller extends Admin_Controller { // Return the newly generated form. return $form; } -} \ No newline at end of file +} diff --git a/3.0/modules/minislideshow/controllers/minislideshow.php b/3.0/modules/minislideshow/controllers/minislideshow.php index 1eccdd8f..bd52f67f 100644 --- a/3.0/modules/minislideshow/controllers/minislideshow.php +++ b/3.0/modules/minislideshow/controllers/minislideshow.php @@ -1,7 +1,7 @@ module == "rss") { + $data->messages["warn"][] = t("The MiniSlide Show module requires the RSS module."); + } + } + static function album_menu($menu, $theme) { // Add an option to access the slideshow from the album view. $menu diff --git a/3.0/modules/minislideshow/helpers/minislideshow_installer.php b/3.0/modules/minislideshow/helpers/minislideshow_installer.php index 5c40e83c..3edcf98a 100644 --- a/3.0/modules/minislideshow/helpers/minislideshow_installer.php +++ b/3.0/modules/minislideshow/helpers/minislideshow_installer.php @@ -1,7 +1,7 @@ item()) { - return; - } - - return new View("minislideshow_header_block.html"); + return $theme->css("minislideshow_menu.css"); } } diff --git a/3.0/modules/minislideshow/module.info b/3.0/modules/minislideshow/module.info index a64a54e2..923b02d5 100644 --- a/3.0/modules/minislideshow/module.info +++ b/3.0/modules/minislideshow/module.info @@ -1,3 +1,7 @@ name = "MiniSlide Show" description = "Display MiniSlide Show on your Gallery." version = 1 +author_name = "rWatcher" +author_url = "http://codex.gallery2.org/User:RWatcher" +info_url = "http://codex.gallery2.org/Gallery3:Modules:minislideshow" +discuss_url = "http://gallery.menalto.com/node/90362" diff --git a/3.0/modules/minislideshow/views/minislideshow_dialog.html.php b/3.0/modules/minislideshow/views/minislideshow_dialog.html.php index c9507594..9ae60c0b 100644 --- a/3.0/modules/minislideshow/views/minislideshow_dialog.html.php +++ b/3.0/modules/minislideshow/views/minislideshow_dialog.html.php @@ -15,4 +15,4 @@ flashvars="xmlUrl= Embed: " width="485" height="300" align="middle" pluginspage="http://www.macromedia.com/go/getflashplayer" type="application/x-shockwave-flash" name="minislide" wmode="transparent" allowFullscreen="true" allowScriptAccess="always" quality="high" flashvars="xmlUrl=">" readonly> -
\ No newline at end of file +
diff --git a/3.0/modules/minislideshow/views/minislideshow_header_block.html.php b/3.0/modules/minislideshow/views/minislideshow_header_block.html.php deleted file mode 100644 index c52d0117..00000000 --- a/3.0/modules/minislideshow/views/minislideshow_header_block.html.php +++ /dev/null @@ -1,5 +0,0 @@ - - -" /> - - diff --git a/3.0/modules/moduleorder/controllers/admin_moduleorder.php b/3.0/modules/moduleorder/controllers/admin_moduleorder.php index 05b8efa0..3eb7fca1 100644 --- a/3.0/modules/moduleorder/controllers/admin_moduleorder.php +++ b/3.0/modules/moduleorder/controllers/admin_moduleorder.php @@ -1,7 +1,7 @@ script("jquery.jcarousel.min.js"); - $theme->css("skin.css"); $showelements = module::get_var("navcarousel", "showelements", "7"); $childcount = $theme->item->parent()->viewable()->children_count(); $itemoffset = intval(floor($showelements / 2)); @@ -64,7 +62,10 @@ class navcarousel_theme_Core { $onwinload = "});\n $(window).load(function () {\n"; } - Return "\n + return + $theme->script("jquery.jcarousel.min.js") + . $theme->css("skin.css") + . "\n + + + + script("json2-min.js") ?> + script("jquery.js") ?> + script("jquery.form.js") ?> + script("jquery-ui.js") ?> + script("gallery.common.js") ?> + + + script("gallery.ajax.js") ?> + script("gallery.dialog.js") ?> + script("superfish/js/superfish.js") ?> + script("jquery.localscroll.js") ?> + + + page_subtype == "photo"): ?> + script("jquery.scrollTo.js") ?> + script("gallery.show_full_size.js") ?> + page_subtype == "movie"): ?> + script("flowplayer.js") ?> + + + head() ?> + + + script("ui.init.js") ?> + css("yui/reset-fonts-grids.css") ?> + css("superfish/css/superfish.css") ?> + + css("dark/themeroller/ui.base.css") ?> + css("dark/screen_colors.css") ?> + css("dark/screen_candy.css") ?> + + css("clean/themeroller/ui.base.css") ?> + css("clean/screen_colors.css") ?> + css("clean/screen_candy.css") ?> + + css("screen_layout_base.css") ?> + css("screen_fonts.css") ?> + + css("screen_layout_wide.css") ?> + + css("screen_layout_fixed.css") ?> + + + + + get_combined("script") ?> + + + get_combined("css") ?> + + + body_attributes() ?>> + page_top() ?> + +
+ +
+ + site_status() ?> +
+
+ + + + + + user_menu() ?> + header_top() ?> +
+ + 1 ) { ?> + $display_name) { ?> + + + + installed_locales = array_merge(array("" => t("« none »")), $locales); ?> + selected = (string) locales::cookie_locale(); ?> + + +
+ + + + + header_bottom() ?> +
+ + + +
    + + + > + + url) : ?> + title) ?> + + title) ?> + + + + +
+ + + +
+
+
+
+
+ messages() ?> + +
+
+
+ item() && !empty($parents))): ?> + + +
+ page_subtype != "login"): ?> + + +
+
+ +
+ page_bottom() ?> + + diff --git a/3.0/modules/tag_albums/-- Theme Files/greydragon/views/calpage.html.php b/3.0/modules/tag_albums/-- Theme Files/greydragon/views/calpage.html.php new file mode 100644 index 00000000..9d3341de --- /dev/null +++ b/3.0/modules/tag_albums/-- Theme Files/greydragon/views/calpage.html.php @@ -0,0 +1,297 @@ + + +load_sessioninfo(); ?> + +html_attributes() ?> xml:lang="en" lang="en" is_rtl)? "dir=rtl" : null; ?> > +item(); + if (($theme->enable_pagecache) and (isset($item))): + // Page will expire in 60 seconds + header('Expires: ' . gmdate('D, d M Y H:i:s', time() + 60).'GMT'); + header("Cache-Control: public"); + header("Cache-Control: post-check=3600, pre-check=43200", false); + header("Content-Type: text/html; charset=UTF-8"); + header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT"); + endif; +?> + + + +start_combining("script,css") ?> + + + +item()): ?> +bb2html($theme->item()->title, 2); ?> +tag()): ?> + $theme->bb2html($theme->tag()->name, 2))) ?> + +bb2html(item::root()->title, 2); ?> + + +<?= $_title ?> +disable_seosupport): ?> + + + + + + +blendpagetrans): ?> + + + + + + " /> + +allow_root_page): ?> +: ; action-uri=url(); ?>?root=yes; icon-uri=favicon.ico" /> +: ; action-uri=url(); ?>?root=no; icon-uri=favicon.ico" /> + +: ; action-uri=url(); ?>; icon-uri=favicon.ico" /> + +admin): ?> + +: ; action-uri=; icon-uri=favicon.ico" /> + + + + +appletouchicon): ?> + + +script("json2-min.js") ?> +script("jquery.js") ?> +script("jquery.form.js") ?> +script("jquery-ui.js") ?> +script("gallery.common.js") ?> + + +script("gallery.ajax.js"); ?> +script("gallery.dialog.js"); ?> + + +page_subtype == "photo"): ?> +script("jquery.scrollTo.js"); ?> +page_subtype == "movie"): ?> +script("flowplayer.js") ?> + + +head() ?> + + +script("animation.js"); ?> +script("ui.support.js"); ?> + +theme_css_inject(); ?> + + +get_combined("css"); ?> + +css_link("colorpacks/" . $theme->colorpack . "/colors.css", FALSE); ?> +css_link("framepacks/" . $theme->framepack . "/frame.css", FALSE); ?> +custom_css_path != ""): ?> +css_link($theme->custom_css_path, TRUE); ?> + + +get_combined("script") ?> + + +thumb_inpage): ?> + + + +item()): ?> +item(); ?> + + + +body_attributes() ?>show_root_page)? ' id="g-rootpage"' : null; ?> is_rtl)? "class=\"rtl\"" : null; ?> > +page_top() ?> +site_status() ?> +guest) or ($theme->show_guest_menu)) and ($theme->mainmenu_position == "bar")): ?> + +
+ site_menu($theme->item() ? "#g-item-id-{$theme->item()->id}" : "") ?> +
+ +
+header_top() ?> + +bb2html($header_text, 1) ?> + + + + +guest) or ($theme->show_guest_menu)) and ($theme->mainmenu_position != "bar")): ?> +
+ site_menu($theme->item() ? "#g-item-id-{$theme->item()->id}" : "") ?> +
+ + +messages() ?> +header_bottom() ?> + +loginmenu_position == "header"): ?> +user_menu() ?> + + + +breadcrumb_menu($theme, null); ?> + +breadcrumbs_position == "hide"): + else: + $limit_title_length = module::get_var("gallery", "visible_title_length", 999); + + $breadcrumb_content .= ''; + endif; + + print $breadcrumb_content; + + // End Edit. +?> + +custom_header(); ?> +
+page_subtype != "login") and ($theme->page_subtype != "reauthenticate") and ($theme->sidebarvisible == "top")): ?> +
+ +
+ +
+
+show_root_page): ?> + sidebar_menu($item->url()) ?> +
"> + + album_menu() ?> + + photo_menu() ?> + + movie_menu() ?> + + tag_menu() ?> + +
+ +sidebarvisible): + case "left": + echo '
'; + $closediv = TRUE; + break; + case "none": + case "top": + case "bottom": + if (($theme->thumb_inpage) and ($page_subtype == "photo")): + echo '
'; + $closediv = TRUE; + else: + $closediv = FALSE; + endif; + break; + default: + echo '
'; + $closediv = TRUE; + break; + endswitch; ?> +page_subtype != "login") and ($theme->page_subtype != "reauthenticate")): ?> +sidebarvisible == "none") or ($theme->sidebarvisible == "bottom") or ($theme->sidebarvisible == "top")): ?> +thumb_inpage) and ($page_subtype == "photo")): ?> +

 

'; ?> +get_block_html("thumbnav"); ?> + + + + + +" : null; ?> + +sidebarvisible): + case "left": + echo '
'; + break; + case "none": + case "top": + case "bottom": + if (($theme->thumb_inpage) and ($page_subtype == "photo")): + echo '
'; + else: + echo '
'; + endif; + break; + default: + echo '
'; + break; + endswitch; + + if ($theme->show_root_page): + echo new View("rootpage.html"); + else: + echo $content; + endif; ?> +
+
+
+page_subtype != "login") and ($theme->page_subtype != "reauthenticate") and ($theme->sidebarvisible == "bottom")): ?> +
+ +
+ + +page_bottom() ?> + + diff --git a/3.1/themes/greydragon/views/paginator.html.php b/3.0/modules/tag_albums/-- Theme Files/greydragon/views/paginator.html.php similarity index 81% rename from 3.1/themes/greydragon/views/paginator.html.php rename to 3.0/modules/tag_albums/-- Theme Files/greydragon/views/paginator.html.php index 9b5e725e..5918299c 100644 --- a/3.1/themes/greydragon/views/paginator.html.php +++ b/3.0/modules/tag_albums/-- Theme Files/greydragon/views/paginator.html.php @@ -1,23 +1,19 @@ id . "/" . $tag_id . "/" . $album_id); + } elseif ($page_type == "") { + } + endfor; + else: + // End rWatcher Mod. + switch ($page_type) { case "collection": - if ($item): + if (isset($item)): $parent = $item->parent(); endif; $current_page = $page; @@ -61,15 +73,17 @@ endfor; break; case "item": - if ($item): + if (isset($item)): $parent = $item->parent(); endif; $current_page = $position; $total_pages = $total; - $siblings = $item->parent()->children(); - for ($i = 1; $i <= $total; $i++): - $_pagelist[$i] = $siblings[$i-1]->url(); - endfor; + if (isset($parent)): + $siblings = $parent->children(); + for ($i = 1; $i <= $total; $i++): + $_pagelist[$i] = $siblings[$i-1]->url(); + endfor; + endif; break; default: $current_page = 1; @@ -77,6 +91,9 @@ $_pagelist[1] = url::site(); break; } +// rWatcher Mod + endif; +// End rWatcher Mod. if ($total_pages <= 1): $pagination_msg = " "; @@ -167,11 +184,15 @@   - + + + " id="g-navi-parent" href="">  + " id="g-navi-parent" href="url() ?>">    + " class="ui-right" id="g-navi-next" href="">  diff --git a/3.0/modules/tag_albums/-- Theme Files/greydragon/views/photo.html.php b/3.0/modules/tag_albums/-- Theme Files/greydragon/views/photo.html.php new file mode 100644 index 00000000..5d3ede73 --- /dev/null +++ b/3.0/modules/tag_albums/-- Theme Files/greydragon/views/photo.html.php @@ -0,0 +1,122 @@ + +desc_allowbbcode): + $_description = $theme->bb2html($item->description, 1); + else: + $_description = nl2br(html::purify($item->description)); + endif; + + if ($theme->is_photometa_visible): + $_description .= ''; + endif; + + switch ($theme->photo_popupbox): + case "preview": + $include_list = FALSE; + $include_single = TRUE; + break; + case "none": + $include_list = FALSE; + $include_single = FALSE; + break; + default: + $include_list = TRUE; + $include_single = TRUE; + break; + endswitch; +?> + +
+ bb2html(html::purify($item->title), 1); ?> +
+

+
+ add_paginator("top"); ?> + photo_top() ?> + photo_descmode == "top") and ($_description)): ?> +
+ +
+ resize_top($item) ?> + resize_width; + +// rWatcher Modification. + $siblings = ""; + if (isset($dynamic_siblings)) { + $siblings = $dynamic_siblings; + } else { + $siblings = $item->parent()->children(); + } +// End rWatcher Modification + ?> + +
+ \n"; + $script .= " if (document.images) {\n"; + for ($i = 0; ($i <= count($siblings) - 1); $i++): + if ($siblings[$i]->rand_key == $item->rand_key): ?> + " title="bb2html(html::purify($item->title), 2) ?>" href="file_url() : $item->resize_url(); ?>"> + resize_img(array("id" => "g-photo-id-{$item->id}", "class" => "g-resize", "alt" => $_title)) ?> + + resize_url() . "\";\n"; + endif; + if ($i > 0): + $script .= " var image_preload_p = new Image();\n image_preload_p.src = \"" . $siblings[$i-1]->resize_url() . "\";\n"; + endif; + else: + if ($include_list): ?> + is_album()): ?> + file_url() : $siblings[$i]->resize_url(); ?>">  + + + + + \n"; ?> + photo_descmode): + case "overlay_top": + $_align = "g-align-top"; + break; + case "overlay_bottom": + $_align = "g-align-bottom"; + break; + default: + break; + endswitch; + endif; ?> + + +
+ + +
+ +
+ resize_bottom($item) ?> +
+ photo_descmode == "bottom") and ($_description)): ?> +
+ + add_paginator("bottom"); ?> + photo_bottom() ?> +
+ \ No newline at end of file diff --git a/3.0/modules/tag_albums/-- Theme Files/greydragon/views/tag_albums_album.html.php b/3.0/modules/tag_albums/-- Theme Files/greydragon/views/tag_albums_album.html.php new file mode 100644 index 00000000..3a348d3b --- /dev/null +++ b/3.0/modules/tag_albums/-- Theme Files/greydragon/views/tag_albums_album.html.php @@ -0,0 +1,135 @@ + +album_top() was changed to $theme->dynamic_top(). + // $item->title and $item->description have been changed to $title and $description. + // + // The g-album-grid block was also taken from album.html.php. The section for uploading new photos to an empty album + // has been removed. Also, $theme->context_menu has been removed as well (it was crashing the page). +?> + +
+ dynamic_top() ?> +

bb2html(html::purify($title), 1) ?>

+
+ +add_paginator("top"); ?> + +album_descmode == "top") and ($description)): ?> +
bb2html(html::purify($description), 1) ?>
+ + + +
+
+
+
+ + +
+
    + + $child): ?> +thumb_height > $thumb_item->thumb_width); + + $item_class = $child->is_album() ? "g-album" : "g-photo"; + $content = '
  • thumb_top($child); + + if ($theme->thumb_topalign): + $_shift = ""; + else: + if (($theme->crop_factor == 1) and (!$is_portrait)): + $_shift = 'style="margin-top: ' . intval(($theme->_thumb_size_y - $thumb_item->thumb_height) / 2) . 'px;"'; + else: + if (($theme->crop_factor > 0) and ($is_portrait)): + $_shift = 'style="margin-top: -' . intval(($thumb_item->thumb_height - $theme->_thumb_size_y) / 2) . 'px;"'; + else: + $_shift = ""; + endif; + endif; + endif; + + // $ss = 'z-index: 22; opacity: 1; -ms-transform: rotate(' . (-15 + rand(0, 31)) . 'deg);'; style="' . $ss . '" + + $content .= '

    '; + $content .= ''; + if ($thumb_item->has_thumb()): + $content .= $thumb_item->thumb_img(); + else: + $content .= 'No Image'; + endif; + $content .= '

    '; + + if (($theme->thumb_metamode != "hide") and ($_thumb_descmode == "overlay_bottom")): + $_thumb_metamode = "merged"; + else: + $_thumb_metamode = $theme->thumb_metamode; + endif; + + if (($_thumb_descmode == "overlay") or ($_thumb_descmode == "overlay_top") or ($_thumb_descmode == "overlay_bottom")): + $content .= '
      bb2html(html::purify($child->title), 2) . ''; + if ($_thumb_metamode == "merged"): + $content .= $theme->thumb_info($child); + endif; + $content .= '
    '; + endif; + + if (($_thumb_metamode == "default") and ($_thumb_descmode != "overlay_bottom")): + $content .= ''; + endif; + + if ($_thumb_descmode == "bottom"): + $content .= '
      '; + $content .= '
    • ' . $theme->bb2html(html::purify($child->title), 2) . '
    • '; + if ($_thumb_metamode == "merged"): + $content .= $theme->thumb_info($child); + endif; + $content .= '
    '; + endif; + + /* + if ($addcontext): + $_text = $this->context_menu($child, "#g-item-id-{$child->id} .g-thumbnail"); + $content .= (stripos($_text, '
  • '))? $_text : null; + endif; + */ + + $content .= '
'; + $content .= $theme->thumb_bottom($child); + $content .= ''; + + print $content; + // End rWatcher Edit. +?> + + +
  • + + +
    +dynamic_bottom() ?> + +album_descmode == "bottom") and ($description)): ?> +
    bb2html(html::purify($description), 1) ?>
    + + +add_paginator("bottom"); ?> diff --git a/3.0/modules/tag_albums/controllers/admin_tag_albums.php b/3.0/modules/tag_albums/controllers/admin_tag_albums.php new file mode 100644 index 00000000..6267e33c --- /dev/null +++ b/3.0/modules/tag_albums/controllers/admin_tag_albums.php @@ -0,0 +1,123 @@ +content = new View("admin_tag_albums.html"); + + // Generate a form for the admin Settings. + $view->content->tag_albums_form = $this->_get_admin_form(); + + // Display the page. + print $view; + } + + private function _get_admin_form() { + $form = new Forge("admin/tag_albums/saveprefs", "", "post", + array("id" => "g-tag-albums-admin-form")); + + $tag_albums_tagsort_group = $form->group("Tag_Albums_Tag_Sort")->label(t("\"All Tags\" Album Preferences")); + $tag_albums_tagsort_group->input("tag_page_title") + ->label(t("Page Title")) + ->value(module::get_var("tag_albums", "tag_page_title")); + $tag_albums_tagsort_group->dropdown("tag_index") + ->label(t("Tag album's index should display:")) + ->options( + array("default" => "(default) Individual Tag Albums", + "tagcloudpage" => "Tag Cloud Page Module", + "alltags" => "All Tags Module")) + ->selected(module::get_var("tag_albums", "tag_index")); + + $tag_albums_tagsort_group->dropdown("tag_sort_by") + ->label(t("Sort \"All Tags\" Albums By:")) + ->options( + array("name" => "Name", + "count" => "Count", + "id" => "ID Number")) + ->selected(module::get_var("tag_albums", "tag_sort_by")); + $tag_albums_tagsort_group->dropdown("tag_sort_direction") + ->label(t("Display Albums In:")) + ->options( + array("ASC" => "Ascending Order", + "DESC" => "Descending")) + ->selected(module::get_var("tag_albums", "tag_sort_direction")); + + $tag_index_scope_options["tag_index_scope"] = Array(t("Use tag album index setting for \"*\" albums as well?"), module::get_var("tag_albums", "tag_index_scope")); + $tag_albums_tagsort_group->checklist("tag_index_scope") + ->options($tag_index_scope_options); + + $tag_index_filter_options["tag_index_filter"] = Array(t("Display filter links on \"All Tags\" album pages?"), module::get_var("tag_albums", "tag_index_filter")); + $tag_albums_tagsort_group->checklist("tag_index_filter") + ->options($tag_index_filter_options); + + $tag_albums_tagitemsort_group = $form->group("Tag_Albums_Tag_Item_Sort")->label(t("\"All Tags\" Sub-Album Preferences")); + $tag_albums_tagitemsort_group->dropdown("subalbum_sort_by") + ->label(t("Sort Contents of Sub-Albums By:")) + ->options( + array("title" => "Title", + "name" => "File name", + "captured" => "Date captured", + "created" => "Date uploaded", + "updated" => "Date modified", + "view_count" => "Number of views")) + ->selected(module::get_var("tag_albums", "subalbum_sort_by")); + $tag_albums_tagitemsort_group->dropdown("subalbum_sort_direction") + ->label(t("Display Contents of Sub-Albums In:")) + ->options( + array("ASC" => "Ascending Order", + "DESC" => "Descending")) + ->selected(module::get_var("tag_albums", "subalbum_sort_direction")); + + // Add a save button to the form. + $form->submit("SaveSettings")->value(t("Save")); + + // Return the newly generated form. + return $form; + } + + public function saveprefs() { + // Prevent Cross Site Request Forgery + access::verify_csrf(); + + $form = $this->_get_admin_form(); + if ($form->validate()) { + Kohana_Log::add("error",print_r($form,1)); + module::set_var("tag_albums", "tag_page_title", $form->Tag_Albums_Tag_Sort->tag_page_title->value); + module::set_var("tag_albums", "tag_index", $form->Tag_Albums_Tag_Sort->tag_index->value); + module::set_var("tag_albums", "tag_index_scope", count($form->Tag_Albums_Tag_Sort->tag_index_scope->value)); + module::set_var("tag_albums", "tag_index_filter", count($form->Tag_Albums_Tag_Sort->tag_index_filter->value)); + module::set_var("tag_albums", "tag_sort_by", $form->Tag_Albums_Tag_Sort->tag_sort_by->value); + module::set_var("tag_albums", "tag_sort_direction", $form->Tag_Albums_Tag_Sort->tag_sort_direction->value); + module::set_var("tag_albums", "subalbum_sort_by", $form->Tag_Albums_Tag_Item_Sort->subalbum_sort_by->value); + module::set_var("tag_albums", "subalbum_sort_direction", $form->Tag_Albums_Tag_Item_Sort->subalbum_sort_direction->value); + message::success(t("Your settings have been saved.")); + + url::redirect("admin/tag_albums"); + } + + // Else show the page with errors + $view = new Admin_View("admin.html"); + $view->content = new View("admin_tag_albums.html"); + $view->content->tag_albums_form = $form; + print $view; + } +} diff --git a/3.0/modules/tag_albums/controllers/tag_albums.php b/3.0/modules/tag_albums/controllers/tag_albums.php new file mode 100644 index 00000000..c4b981d7 --- /dev/null +++ b/3.0/modules/tag_albums/controllers/tag_albums.php @@ -0,0 +1,853 @@ +where("id", "=", $id) + ->find_all(); + + // If it doesn't exist, redirect to the modules root page. + if (count($album_tags) == 0) { + url::redirect("tag_albums/"); + } + + // If it does exist, and is set to *, load a list of all tags. + if ($album_tags[0]->tags == "*") { + $this->index($id, ""); + } else { + // Otherwise, populate this page with the specified items. + + // Inherit permissions, title and description from the album that linked to this page. + $album = ORM::factory("item", $album_tags[0]->album_id); + access::required("view", $album); + $page_title = $album->title; + $page_description = $album->description; + + // Determine page sort order. + $sort_page_field = $album->sort_column; + $sort_page_direction = $album->sort_order; + + // Determine search type (AND/OR) and generate an array of the tag ids. + $tag_ids = Array(); + foreach (explode(",", $album_tags[0]->tags) as $tag_name) { + $tag = ORM::factory("tag")->where("name", "=", trim($tag_name))->find(); + if ($tag->loaded()) { + $tag_ids[] = $tag->id; + } + } + $album_tags_search_type = $album_tags[0]->search_type; + + // Figure out how many items to display on each page. + $page_size = module::get_var("gallery", "page_size", 9); + + // If this page was reached from a breadcrumb, figure out what page to load from the show id. + $show = Input::instance()->get("show"); + if ($show) { + $child = ORM::factory("item", $show); + $index = $this->_get_position($child->$sort_page_field, $child->id, $tag_ids, "items." . $sort_page_field, $sort_page_direction, $album_tags_search_type, true); + if ($index) { + $page = ceil($index / $page_size); + url::redirect("tag_albums/album/" . $id . "/" . urlencode($album->name) . "?page=$page"); + } + } + + // Figure out how many items are in this "virtual album" + $count = $this->_count_records($tag_ids, $album_tags_search_type, true); + + // Figure out which page # the visitor is on and + // don't allow the visitor to go below page 1. + $page = Input::instance()->get("page", 1); + if ($page < 1) { + url::redirect("tag_albums/album/" . $id); + } + + // First item to display. + $offset = ($page - 1) * $page_size; + + // Figure out what the highest page number is. + $max_pages = ceil($count / $page_size); + + // Don't let the visitor go past the last page. + if ($max_pages && $page > $max_pages) { + url::redirect("tag_albums/album/{$id}/?page=$max_pages"); + } + + // Figure out which items to display on this page and store their details in $children. + $tag_children = $this->_get_records($tag_ids, $page_size, $offset, "items." . $sort_page_field, $sort_page_direction, $album_tags_search_type, true); + $children = Array(); + foreach ($tag_children as $one_child) { + $child_tag = new Tag_Albums_Item($one_child->title, url::site("tag_albums/show/" . $one_child->id . "/0/" . $id . "/" . urlencode($one_child->name)), $one_child->type); + $child_tag->id = $one_child->id; + $child_tag->view_count = $one_child->view_count; + $child_tag->owner = identity::lookup_user($one_child->owner_id); + if ($one_child->has_thumb()) { + $child_tag->set_thumb($one_child->thumb_url(), $one_child->thumb_width, $one_child->thumb_height); + } + $children[] = $child_tag; + } + + // Set up the previous and next page buttons. + if ($page > 1) { + $previous_page = $page - 1; + $view->previous_page_link = url::site("tag_albums/album/{$id}/?page={$previous_page}"); + } + if ($page < $max_pages) { + $next_page = $page + 1; + $view->next_page_link = url::site("tag_albums/album/{$id}/?page={$next_page}"); + } + + // Set up breadcrumbs. + $tag_album_breadcrumbs = Array(); + $counter = 0; + $tag_album_breadcrumbs[$counter++] = new Tag_Albums_Breadcrumb($album->title, ""); + $parent_item = ORM::factory("item", $album->parent_id); + while ($parent_item->id != 1) { + $tag_album_breadcrumbs[$counter++] = new Tag_Albums_Breadcrumb($parent_item->title, $parent_item->url()); + $parent_item = ORM::factory("item", $parent_item->parent_id); + } + $tag_album_breadcrumbs[$counter++] = new Tag_Albums_Breadcrumb($parent_item->title, $parent_item->url()); + $tag_album_breadcrumbs[1]->url .= "?show=" . $album->id; + $tag_album_breadcrumbs = array_reverse($tag_album_breadcrumbs, true); + + // Set up and display the actual page. + $parent_album = ORM::factory("item", $album->parent_id); + $template = new Theme_View("calpage.html", "other", "Tag Albums"); + $template->page_title = $page_title; + $template->set_global("page", $page); + $template->set_global("page_size", $page_size); + $template->set_global("max_pages", $max_pages); + $template->set_global("children", $children); + $template->set_global("children_count", $count); + $template->set_global("parent_url", $parent_album->url()); // Used by Grey Dragon. + $template->content = new View("tag_albums_album.html"); + $template->content->title = $page_title; + $template->content->description = $page_description; + $template->set_global("breadcrumbs", $tag_album_breadcrumbs); + print $template; + } + } + + public function filter($id, $filter) { + // Display the index page, but only show albums for + // tags whose name begins with $filter. + $this->index($id, $filter); + } + + public function index($id, $filter) { + // Load a page containing sub-albums for each tag in the gallery. + + // Check to see if the user has overridden default behavior, and act accordingly. + if ((module::get_var("tag_albums", "tag_index_scope", "false")) || ($id == "")) { + $tag_album_index_type = module::get_var("tag_albums", "tag_index", "default"); + if (($tag_album_index_type == "tagcloudpage") && (module::is_active("tag_cloud_page"))) { + $redirect_url = "tag_cloud_page/"; + if ($id) { + $redirect_url .= "?album={$id}"; + } + url::redirect($redirect_url); + return; + } elseif (($tag_album_index_type == "alltags") && (module::is_active("all_tags"))) { + $redirect_url = "all_tags/"; + if ($id) { + $redirect_url .= "?album={$id}"; + } + url::redirect($redirect_url); + return; + } + } + + // If an ID was specified, make sure it's valid. + $album_tags = ORM::factory("tags_album_id") + ->where("id", "=", $id) + ->find_all(); + if (count($album_tags) == 0) { + $id = ""; + } + + // Inherit permissions, title and description from the album that linked to this page, + // if available, if not use the root album and some default values. + $album = ""; + $page_title = module::get_var("tag_albums", "tag_page_title", "All Tags"); + $page_description = ""; + if ($id == "") { + $album = ORM::factory("item", 1); + access::required("view", $album); + } else { + $album = ORM::factory("item", $album_tags[0]->album_id); + access::required("view", $album); + $page_title = $album->title; + $page_description = $album->description; + } + + // Figure out sort order from module preferences. + $sort_page_field = module::get_var("tag_albums", "tag_sort_by", "name"); + $sort_page_direction = module::get_var("tag_albums", "tag_sort_direction", "ASC"); + + // Figure out how many items to display on each page. + $page_size = module::get_var("gallery", "page_size", 9); + + // If this page was reached from a breadcrumb, figure out what page to load from the show id. + $show = Input::instance()->get("show"); + if ($show) { + $child = ORM::factory("tag", $show); + $comp = ""; + if (!strcasecmp($sort_page_direction, "DESC")) { + $comp = ">"; + } else { + $comp = "<"; + } + $index = ORM::factory("tag") + ->where($sort_page_field, $comp, $child->$sort_page_field) + ->order_by("tags." . $sort_page_field, $sort_page_direction) + ->count_all(); + $tag_model = ORM::factory("tag") + ->where($sort_page_field, "=", $child->$sort_page_field) + ->order_by("tags." . $sort_page_field, $sort_page_direction) + ->find_all(); + foreach ($tag_model as $one_tag) { + $index++; + if ($one_tag->id == $show) { + break; + } + } + if ($index) { + $page = ceil($index / $page_size); + if ($id == "") { + url::redirect("tag_albums/?page=$page"); + } else { + url::redirect("tag_albums/album/" . $id . "/" . urlencode($album->title) . "?page=$page"); + } + } + } + + // Figure out which page # the visitor is on and + // don't allow the visitor to go below page 1. + $page = Input::instance()->get("page", 1); + if ($page < 1) { + url::redirect("tag_albums/"); + } + + // First item to display. + $offset = ($page - 1) * $page_size; + + // Determine the total number of items, + // for page numbering purposes. + $all_tags_count_model = ORM::factory("tag"); + if ($filter != "") { + if ($filter == "NUM") { + $all_tags_count_model->open(); + $all_tags_count_model->where("tags.name", "LIKE", "0%"); + $counter = 1; + while ($counter < 10) { + $all_tags_count_model->or_where("tags.name", "LIKE", ($counter++) . "%"); + } + $all_tags_count_model->close(); + } else { + $all_tags_count_model->where("tags.name", "LIKE", $filter . "%"); + } + } + $all_tags_count = $all_tags_count_model->count_all(); + + // Figure out what the highest page number is. + $max_pages = ceil($all_tags_count / $page_size); + + // Don't let the visitor go past the last page. + if ($max_pages && $page > $max_pages) { + url::redirect("tag_albums/?page=$max_pages"); + } + + // Figure out which items to display on this page. + $display_tags_model = ORM::factory("tag"); + if ($filter != "") { + if ($filter == "NUM") { + $display_tags_model->open(); + $display_tags_model->where("tags.name", "LIKE", "0%"); + $counter = 1; + while ($counter < 10) { + $display_tags_model->or_where("tags.name", "LIKE", ($counter++) . "%"); + } + $display_tags_model->close(); + } else { + $display_tags_model->where("tags.name", "LIKE", $filter . "%"); + } + } + $display_tags_model->order_by("tags." . $sort_page_field, $sort_page_direction); + $display_tags = $display_tags_model->find_all($page_size, $offset); + + // Set up the previous and next page buttons. + if ($page > 1) { + $previous_page = $page - 1; + $view->previous_page_link = url::site("tag_albums/album/" . $id . "/?page={$previous_page}"); + } + if ($page < $max_pages) { + $next_page = $page + 1; + $view->next_page_link = url::site("tag_albums/album/" . $id . "/?page={$next_page}"); + } + + // Generate an arry of "fake" items, one for each tag on the page. + // Grab thumbnails from the most recently uploaded item for each tag, if available. + $children = Array(); + foreach ($display_tags as $one_tag) { + $tag_item = ORM::factory("item") + ->viewable() + ->join("items_tags", "items.id", "items_tags.item_id") + ->where("items_tags.tag_id", "=", $one_tag->id) + ->order_by("items.id", "DESC") + ->find_all(1, 0); + $child_tag = new Tag_Albums_Item($one_tag->name, url::site("tag_albums/tag/" . $one_tag->id . "/" . $id . "/" . urlencode($one_tag->name)), "album"); + if (count($tag_item) > 0) { + if ($tag_item[0]->has_thumb()) { + $child_tag->set_thumb($tag_item[0]->thumb_url(), $tag_item[0]->thumb_width, $tag_item[0]->thumb_height); + } + } + $children[] = $child_tag; + } + + // Set up breadcrumbs. + $tag_album_breadcrumbs = Array(); + $parent_url = ""; + if ($id != "") { + $counter = 0; + $tag_album_breadcrumbs[$counter++] = new Tag_Albums_Breadcrumb($album->title, ""); + $parent_item = ORM::factory("item", $album->parent_id); + $parent_url = $parent_item->url(); + while ($parent_item->id != 1) { + $tag_album_breadcrumbs[$counter++] = new Tag_Albums_Breadcrumb($parent_item->title, $parent_item->url()); + $parent_item = ORM::factory("item", $parent_item->parent_id); + } + $tag_album_breadcrumbs[$counter++] = new Tag_Albums_Breadcrumb($parent_item->title, $parent_item->url()); + $tag_album_breadcrumbs[1]->url .= "?show=" . $album->id; + $tag_album_breadcrumbs = array_reverse($tag_album_breadcrumbs, true); + } else { + $parent_url = item::root()->url(); + $tag_album_breadcrumbs[0] = new Tag_Albums_Breadcrumb(item::root()->title, item::root()->url()); + $tag_album_breadcrumbs[1] = new Tag_Albums_Breadcrumb($page_title, ""); + } + + // Set up and display the actual page. + $template = new Theme_View("calpage.html", "other", "Tag Albums"); + $template->page_title = $page_title; + $template->set_global("page", $page); + $template->set_global("page_size", $page_size); + $template->set_global("max_pages", $max_pages); + $template->set_global("children", $children); + $template->set_global("children_count", $all_tags_count); + $template->set_global("parent_url", $parent_url); // Used by Grey Dragon. + $template->content = new View("tag_albums_album.html"); + $template->content->title = $page_title; + $template->content->description = $page_description; + $template->content->filter_text = $this->_get_filter_html($id, $filter); + $template->set_global("breadcrumbs", $tag_album_breadcrumbs); + print $template; + } + + public function tag($id, $album_id) { + // Display a dynamic album containing everything tagged with a specific tag where, + // TAG is $id. + // Optionally, set the breadcrumbs to make this page look like an album where the + // album is $album_id. + + // Make sure $album_id is valid, clear it out if it isn't. + $album_tags = ORM::factory("tags_album_id") + ->where("id", "=", $album_id) + ->find_all(); + if (count($album_tags) == 0) { + $album_id = ""; + } + + // Figure out sort order from module preferences. + $sort_page_field = module::get_var("tag_albums", "subalbum_sort_by", "title"); + $sort_page_direction = module::get_var("tag_albums", "subalbum_sort_direction", "ASC"); + + // Figure out how many items to display on each page. + $page_size = module::get_var("gallery", "page_size", 9); + + // If this page was reached from a breadcrumb, figure out what page to load from the show id. + $show = Input::instance()->get("show"); + if ($show) { + $child = ORM::factory("item", $show); + $index = $this->_get_position($child->$sort_page_field, $child->id, Array($id), "items." . $sort_page_field, $sort_page_direction, "OR", true); + if ($index) { + $page = ceil($index / $page_size); + url::redirect("tag_albums/tag/" . $id . "/" . $album_id . "?page=$page"); + } + } + + // Figure out which page # the visitor is on and + // don't allow the visitor to go below page 1. + $page = Input::instance()->get("page", 1); + if ($page < 1) { + url::redirect("tag_albums/tag/" . $id . "/" . $album_id); + } + + // First item to display. + $offset = ($page - 1) * $page_size; + + // Determine the total number of items, + // for page numbering purposes. + $count = $this->_count_records(Array($id), "OR", true); + + // Figure out what the highest page number is. + $max_pages = ceil($count / $page_size); + + // Don't let the visitor go past the last page. + if ($max_pages && $page > $max_pages) { + url::redirect("tag_albums/tag/{$id}/" . $album_id . "/?page=$max_pages"); + } + + // Figure out which items to display on this page. + $tag_children = $this->_get_records(Array($id), $page_size, $offset, "items." . $sort_page_field, $sort_page_direction, "OR", true); + + // Create an array of "fake" items to display on the page. + $children = Array(); + foreach ($tag_children as $one_child) { + $child_tag = new Tag_Albums_Item($one_child->title, url::site("tag_albums/show/" . $one_child->id . "/" . $id . "/" . $album_id . "/" . urlencode($one_child->name)), $one_child->type); + $child_tag->id = $one_child->id; + $child_tag->view_count = $one_child->view_count; + $child_tag->owner = identity::lookup_user($one_child->owner_id); + if ($one_child->has_thumb()) { + $child_tag->set_thumb($one_child->thumb_url(), $one_child->thumb_width, $one_child->thumb_height); + } + $children[] = $child_tag; + } + + // Set up the previous and next page buttons. + if ($page > 1) { + $previous_page = $page - 1; + $view->previous_page_link = url::site("tag_albums/tag/{$id}/" . $album_id . "/?page={$previous_page}"); + } + if ($page < $max_pages) { + $next_page = $page + 1; + $view->next_page_link = url::site("tag_albums/tag/{$id}/" . $album_id . "/?page={$next_page}"); + } + + // Load the current tag. + $display_tag = ORM::factory("tag", $id); + + // Set up breadcrumbs for the page. + $tag_album_breadcrumbs = Array(); + $parent_url = ""; + if ($album_id != "") { + $counter = 0; + $tag_album_breadcrumbs[$counter++] = new Tag_Albums_Breadcrumb($display_tag->name, ""); + $parent_item = ORM::factory("item", $album_tags[0]->album_id); + if ($album_tags[0]->tags != "*") { + $parent_item = ORM::factory("item", $parent_item->parent_id); + } + $parent_url = $parent_item->url(); // Used by Grey Dragon. + while ($parent_item->id != 1) { + $tag_album_breadcrumbs[$counter++] = new Tag_Albums_Breadcrumb($parent_item->title, $parent_item->url()); + $parent_item = ORM::factory("item", $parent_item->parent_id); + } + $tag_album_breadcrumbs[$counter++] = new Tag_Albums_Breadcrumb($parent_item->title, $parent_item->url()); + $parent_item = ORM::factory("item", $album_tags[0]->album_id); + if ((module::get_var("tag_albums", "tag_index_scope", "false")) && (module::get_var("tag_albums", "tag_index", "default") != "default")) { + $tag_album_breadcrumbs[1]->url = url::site("tag_albums/album/" . $album_id . "/" . urlencode($parent_item->name)); + } else { + $tag_album_breadcrumbs[1]->url = url::site("tag_albums/album/" . $album_id . "/" . urlencode($parent_item->name)) . "?show=" . $id; + } + $tag_album_breadcrumbs = array_reverse($tag_album_breadcrumbs, true); + } else { + $parent_url = url::site("tag_albums/"); + $tag_album_breadcrumbs[0] = new Tag_Albums_Breadcrumb(item::root()->title, item::root()->url()); + if (module::get_var("tag_albums", "tag_index", "default") == "default") { + $tag_album_breadcrumbs[1] = new Tag_Albums_Breadcrumb(module::get_var("tag_albums", "tag_page_title", "All Tags"), url::site("tag_albums/") . "?show=" . $id); + } else { + $tag_album_breadcrumbs[1] = new Tag_Albums_Breadcrumb(module::get_var("tag_albums", "tag_page_title", "All Tags"), url::site("tag_albums/")); + } + $tag_album_breadcrumbs[2] = new Tag_Albums_Breadcrumb($display_tag->name, ""); + } + + // Set up and display the actual page. + $template = new Theme_View("calpage.html", "other", "Tag Albums"); + $template->page_title = $display_tag->name; + $template->set_global("page", $page); + $template->set_global("page_size", $page_size); + $template->set_global("max_pages", $max_pages); + $template->set_global("children", $children); + $template->set_global("children_count", $count); + $template->set_global("parent_url", $parent_url); // Used by Grey Dragon. + $template->content = new View("tag_albums_album.html"); + $template->content->title = $display_tag->name; + $template->set_global("breadcrumbs", $tag_album_breadcrumbs); + print $template; + } + + public function show($item_id, $tag_id, $album_id) { + // Display the specified photo or video ($item_id) with breadcrumbs + // that point back to a virtual album ($tag_id / $album_id). + + // Make sure #album_id is valid, clear it out if it isn't. + $album_tags = ORM::factory("tags_album_id") + ->where("id", "=", $album_id) + ->find_all(); + if (count($album_tags) == 0) { + $album_id = ""; + } + + // Load the tag and item, make sure the user has access to the item. + $display_tag = ORM::factory("tag", $tag_id); + $item = ORM::factory("item", $item_id); + access::required("view", $item); + $parent_url = ""; + + // Figure out sort order from module preferences. + $sort_page_field = ""; + $sort_page_direction = ""; + if (($tag_id > 0) || (count($album_tags) == 0)) { + $sort_page_field = module::get_var("tag_albums", "subalbum_sort_by", "title"); + $sort_page_direction = module::get_var("tag_albums", "subalbum_sort_direction", "ASC"); + } else { + $parent_album = ORM::factory("item", $album_tags[0]->album_id); + $sort_page_field = $parent_album->sort_column; + $sort_page_direction = $parent_album->sort_order; + } + + // Load the number of items in the parent album, and determine previous and next items. + $sibling_count = ""; + $tag_children = ""; + $previous_item = ""; + $next_item = ""; + $position = 0; + $dynamic_siblings = ""; + if ($tag_id > 0) { + $sibling_count = $this->_count_records(Array($tag_id), "OR", false); + $position = $this->_get_position($item->$sort_page_field, $item->id, Array($tag_id), "items." . $sort_page_field, $sort_page_direction, $album_tags_search_type, false); + if ($position > 1) { + $previous_item_object = $this->_get_records(Array($tag_id), 1, $position-2, "items." . $sort_page_field, $sort_page_direction, $album_tags_search_type, false); + if (count($previous_item_object) > 0) { + $previous_item = new Tag_Albums_Item($previous_item_object[0]->title, url::site("tag_albums/show/" . $previous_item_object[0]->id . "/" . $tag_id . "/" . $album_id), $previous_item_object[0]->type); + } + } + $next_item_object = $this->_get_records(Array($tag_id), 1, $position, "items." . $sort_page_field, $sort_page_direction, $album_tags_search_type, false); + if (count($next_item_object) > 0) { + $next_item = new Tag_Albums_Item($next_item_object[0]->title, url::site("tag_albums/show/" . $next_item_object[0]->id . "/" . $tag_id . "/" . $album_id), $next_item_object[0]->type); + } + $dynamic_siblings = $this->_get_records(Array($tag_id), null, null, "items." . $sort_page_field, $sort_page_direction, $album_tags_search_type, false); + } else { + $tag_ids = Array(); + foreach (explode(",", $album_tags[0]->tags) as $tag_name) { + $tag = ORM::factory("tag")->where("name", "=", trim($tag_name))->find(); + if ($tag->loaded()) { + $tag_ids[] = $tag->id; + } + } + $album_tags_search_type = $album_tags[0]->search_type; + $sibling_count = $this->_count_records($tag_ids, $album_tags_search_type, false); + $position = $this->_get_position($item->$sort_page_field, $item->id, $tag_ids, "items." . $sort_page_field, $sort_page_direction, $album_tags_search_type, false); + if ($position > 1) { + $previous_item_object = $this->_get_records($tag_ids, 1, $position-2, "items." . $sort_page_field, $sort_page_direction, $album_tags_search_type, false); + if (count($previous_item_object) > 0) { + $previous_item = new Tag_Albums_Item($previous_item_object[0]->title, url::site("tag_albums/show/" . $previous_item_object[0]->id . "/" . $tag_id . "/" . $album_id), $previous_item_object[0]->type); + } + } + $next_item_object = $this->_get_records($tag_ids, 1, $position, "items." . $sort_page_field, $sort_page_direction, $album_tags_search_type, false); + if (count($next_item_object) > 0) { + $next_item = new Tag_Albums_Item($next_item_object[0]->title, url::site("tag_albums/show/" . $next_item_object[0]->id . "/" . $tag_id . "/" . $album_id), $next_item_object[0]->type); + } + $dynamic_siblings = $this->_get_records($tag_ids, null, null, "items." . $sort_page_field, $sort_page_direction, $album_tags_search_type, false); + } + + // Set up breadcrumbs + $tag_album_breadcrumbs = Array(); + if ($album_id != "") { + $counter = 0; + $tag_album_breadcrumbs[$counter++] = new Tag_Albums_Breadcrumb($item->title, ""); + if ($album_tags[0]->tags == "*") { + $tag_album_breadcrumbs[$counter++] = new Tag_Albums_Breadcrumb($display_tag->name, url::site("tag_albums/tag/" . $display_tag->id . "/" . $album_id)); + } + $parent_item = ORM::factory("item", $album_tags[0]->album_id); + if ($album_tags[0]->tags == "*") { + $parent_url = url::site("tag_albums/tag/" . $display_tag->id . "/" . $album_id); + } else { + $parent_url = $parent_item->url(); + } + $tag_album_breadcrumbs[$counter++] = new Tag_Albums_Breadcrumb($parent_item->title, url::site("tag_albums/album/" . $album_id)); + $parent_item = ORM::factory("item", $parent_item->parent_id); + while ($parent_item->id != 1) { + $tag_album_breadcrumbs[$counter++] = new Tag_Albums_Breadcrumb($parent_item->title, $parent_item->url()); + $parent_item = ORM::factory("item", $parent_item->parent_id); + } + $tag_album_breadcrumbs[$counter++] = new Tag_Albums_Breadcrumb($parent_item->title, $parent_item->url()); + $tag_album_breadcrumbs[1]->url .= "?show=" . $item->id; + $tag_album_breadcrumbs = array_reverse($tag_album_breadcrumbs, true); + } else { + $tag_album_breadcrumbs[0] = new Tag_Albums_Breadcrumb(item::root()->title, item::root()->url()); + $tag_album_breadcrumbs[1] = new Tag_Albums_Breadcrumb(module::get_var("tag_albums", "tag_page_title", "All Tags"), url::site("tag_albums/")); + $tag_album_breadcrumbs[2] = new Tag_Albums_Breadcrumb($display_tag->name, url::site("tag_albums/tag/" . $display_tag->id) . "?show=" . $item->id); + $tag_album_breadcrumbs[3] = new Tag_Albums_Breadcrumb($item->title, ""); + $parent_url = url::site("tag_albums/tag/" . $display_tag->id); + } + + // Increase the items view count. + $item->increment_view_count(); + + // Load the page. + if ($item->is_photo()) { + $template = new Theme_View("calpage.html", "item", "photo"); + $template->page_title = $item->title; + $template->set_global("children", Array()); + $template->set_global("item", $item); + $template->set_global("previous_item", $previous_item); + $template->set_global("next_item", $next_item); + $template->set_global("is_tagalbum_page", true); // used for grey dragon + $template->set_global("tag_id", $tag_id); // used for grey dragon + $template->set_global("album_id", $album_id); // used for grey dragon + $template->set_global("parent_url", $parent_url); // Used by Grey Dragon. + $template->set_global("dynamic_siblings", $dynamic_siblings); // Used by Grey Dragon. + $template->set_global("children_count", 0); + $template->set_global("position", $position); + $template->set_global("sibling_count", $sibling_count); + $template->content = new View("photo.html"); + $template->content->title = $item->title; + $template->set_global("breadcrumbs", $tag_album_breadcrumbs); + print $template; + } elseif ($item->is_movie()) { + $template = new Theme_View("calpage.html", "item", "movie"); + $template->page_title = $item->title; + $template->set_global("children", Array()); + $template->set_global("item", $item); + $template->set_global("previous_item", $previous_item); + $template->set_global("next_item", $next_item); + $template->set_global("is_tagalbum_page", true); // used for grey dragon + $template->set_global("tag_id", $tag_id); // used for grey dragon + $template->set_global("album_id", $album_id); // used for grey dragon + $template->set_global("parent_url", $parent_url); // Used by Grey Dragon. + $template->set_global("dynamic_siblings", $dynamic_siblings); // Used by Grey Dragon. + $template->set_global("children_count", 0); + $template->set_global("position", $position); + $template->set_global("sibling_count", $sibling_count); + $template->content = new View("movie.html"); + $template->content->title = $item->title; + $template->set_global("breadcrumbs", $tag_album_breadcrumbs); + print $template; + } else { + // If it's something we don't know how to deal with, just redirect to its real page. + url::redirect(url::abs_site("{$item->type}s/{$item->id}")); + } + } + + private function _get_position($item_title, $item_id, $tag_ids, $sort_field, $sort_direction, $search_type, $include_albums) { + // Determine an item's position within a virtual album. + + // Convert ASC/DESC to < or > characters. + if (!strcasecmp($sort_direction, "DESC")) { + $comp = ">"; + } else { + $comp = "<"; + } + + // Figure out how many items are _before the current item. + $items_model = ORM::factory("item"); + if ($search_type == "AND") { + $items_model->select('COUNT("*") AS result_count'); + } else { + $items_model->select("items.id"); + } + $items_model->viewable(); + $items_model->join("items_tags", "items.id", "items_tags.item_id"); + $items_model->open(); + $items_model->where("items_tags.tag_id", "=", $tag_ids[0]); + $counter = 1; + while ($counter < count($tag_ids)) { + $items_model->or_where("items_tags.tag_id", "=", $tag_ids[$counter]); + $counter++; + } + $items_model->close(); + if ($include_albums == false) { + $items_model->and_where("items.type", "!=", "album"); + } + $items_model->and_where($sort_field, $comp, $item_title); + $items_model->order_by($sort_field, $sort_direction); + $items_model->group_by("items.id"); + if ($search_type == "AND") { + $items_model->having("result_count", "=", count($tag_ids)); + } + $position = count($items_model->find_all()); + + // In case multiple items have identical sort criteria, query for + // everything with the same criteria, and increment the position + // one at a time until we find the right item. + $items_model = ORM::factory("item"); + if ($search_type == "AND") { + $items_model->select("items.id"); + $items_model->select('COUNT("*") AS result_count'); + } else { + $items_model->select("items.id"); + } + $items_model->viewable(); + $items_model->join("items_tags", "items.id", "items_tags.item_id"); + $items_model->open(); + $items_model->where("items_tags.tag_id", "=", $tag_ids[0]); + $counter = 1; + while ($counter < count($tag_ids)) { + $items_model->or_where("items_tags.tag_id", "=", $tag_ids[$counter]); + $counter++; + } + $items_model->close(); + if ($include_albums == false) { + $items_model->and_where("items.type", "!=", "album"); + } + $items_model->and_where($sort_field, "=", $item_title); + $items_model->order_by($sort_field, $sort_direction); + $items_model->group_by("items.id"); + if ($search_type == "AND") { + $items_model->having("result_count", "=", count($tag_ids)); + } + $match_items = $items_model->find_all(); + foreach ($match_items as $one_item) { + $position++; + if ($one_item->id == $item_id) { + break; + } + } + + return ($position); + } + + private function _get_records($tag_ids, $page_size, $offset, $sort_field, $sort_direction, $search_type, $include_albums) { + // Returns an array of items to be displayed on the current page. + + $items_model = ORM::factory("item"); + if ($search_type == "AND") { + // For some reason, if I do 'select("*")' the item ids all have values that are 1000+ + // higher then they should be. So instead, I'm manually selecting each column that I need. + $items_model->select("items.id"); + $items_model->select("items.name"); + $items_model->select("items.title"); + $items_model->select("items.view_count"); + $items_model->select("items.owner_id"); + $items_model->select("items.rand_key"); + $items_model->select("items.type"); + $items_model->select("items.thumb_width"); + $items_model->select("items.thumb_height"); + $items_model->select("items.left_ptr"); + $items_model->select("items.right_ptr"); + $items_model->select("items.relative_path_cache"); + $items_model->select('COUNT("*") AS result_count'); + } + $items_model->viewable(); + $items_model->join("items_tags", "items.id", "items_tags.item_id"); + $items_model->open(); + $items_model->where("items_tags.tag_id", "=", $tag_ids[0]); + $counter = 1; + while ($counter < count($tag_ids)) { + $items_model->or_where("items_tags.tag_id", "=", $tag_ids[$counter]); + $counter++; + } + $items_model->close(); + if ($include_albums == false) { + $items_model->and_where("items.type", "!=", "album"); + } + $items_model->order_by($sort_field, $sort_direction); + $items_model->group_by("items.id"); + if ($search_type == "AND") { + $items_model->having("result_count", "=", count($tag_ids)); + } + return $items_model->find_all($page_size, $offset); + } + + private function _get_filter_html($album_id, $str_filter) { + // Generate HTML to display filter links on the index page. + + // Make sure $album_id is set. + if ($album_id == "") { + $album_id = 0; + } + + // Generate the links. + $str_html = "Filter: "; + if ($str_filter != "") { + if ($album_id > 0) { + $str_html .= "(All) "; + } else { + $str_html .= "(All) "; + } + } + if ($str_filter == "NUM") { + $str_html .= "# "; + } else { + $str_html .= "# "; + } + foreach(range('A','Z') as $letter) { + if ($letter == $str_filter) { + $str_html .= $letter . " "; + } else { + $str_html .= ""; + $str_html .= $letter . " "; + } + } + + // Return the HTML. + return $str_html; + } + + private function _count_records($tag_ids, $search_type, $include_albums) { + // Count the number of viewable items for the designated tag(s) + // and return that number. + + if (count($tag_ids) == 0) { + // If no tags were specified, return 0. + return 0; + + } elseif (count($tag_ids) == 1) { + // if one tag was specified, we can use count_all to get the number. + $count = ORM::factory("item") + ->viewable() + ->join("items_tags", "items.id", "items_tags.item_id") + ->where("items_tags.tag_id", "=", $tag_ids[0]); + if ($include_albums == false) { + $count->and_where("items.type", "!=", "album"); + } + return $count->count_all(); + + } else { + // If multiple tags were specified, count_all won't work, + // so we'll have to do count(find_all) instead. + $items_model = ORM::factory("item"); + if ($search_type == "AND") { + $items_model->select('COUNT("*") AS result_count'); + } else { + $items_model->select('items.id'); + } + $items_model->viewable(); + $items_model->join("items_tags", "items.id", "items_tags.item_id"); + $items_model->where("items_tags.tag_id", "=", $tag_ids[0]); + $counter = 1; + while ($counter < count($tag_ids)) { + $items_model->or_where("items_tags.tag_id", "=", $tag_ids[$counter]); + $counter++; + } + if ($include_albums == false) { + $items_model->and_where("items.type", "!=", "album"); + } + $items_model->group_by("items.id"); + if ($search_type == "AND") { + $items_model->having("result_count", "=", count($tag_ids)); + } + + return count($items_model->find_all()); + } + } +} diff --git a/3.0/modules/tag_albums/helpers/tag_albums_block.php b/3.0/modules/tag_albums/helpers/tag_albums_block.php new file mode 100644 index 00000000..7243722c --- /dev/null +++ b/3.0/modules/tag_albums/helpers/tag_albums_block.php @@ -0,0 +1,40 @@ + t("Tag Albums")); + } + + static function get($block_id, $theme) { + $block = ""; + + switch ($block_id) { + case "tag_albums": + // Make a new sidebar block. + $block = new Block(); + $block->css_id = "g-tag-albums"; + $block->title = t("Tag Albums"); + $block->content = new View("tag_albums_block.html"); + + break; + } + return $block; + } +} diff --git a/3.0/modules/tag_albums/helpers/tag_albums_event.php b/3.0/modules/tag_albums/helpers/tag_albums_event.php new file mode 100644 index 00000000..033293f1 --- /dev/null +++ b/3.0/modules/tag_albums/helpers/tag_albums_event.php @@ -0,0 +1,110 @@ +module == "tag") { + $data->messages["warn"][] = t("The Tag Albums module requires the Tags module."); + } + } + + static function module_change($changes) { + // See if the Tags module is installed, + // tell the user to install it if it isn't. + if (!module::is_active("tag") || in_array("tag", $changes->deactivate)) { + site_status::warning( + t("The Tag Albums module requires the Tags module. " . + "Activate the Tags module now", + array("url" => url::site("admin/modules"))), + "tag_albums_needs_tag"); + } else { + site_status::clear("tag_albums_needs_tag"); + } + } + + static function admin_menu($menu, $theme) { + // Add a link to the admin page to the Content menu. + $menu->get("settings_menu") + ->append(Menu::factory("link") + ->id("tag_albums") + ->label(t("Tag Albums Settings")) + ->url(url::site("admin/tag_albums"))); + } + + static function item_edit_form($item, $form) { + // Create fields on the album edit screen to allow the user to link + // the album to a tag_albums page. + if (!($item->is_album())) { + return; + } + + $url = url::site("tags/autocomplete"); + $form->script("") + ->text("$('form input[name=tag_albums]').ready(function() { + $('form input[name=tag_albums]').autocomplete( + '$url', {max: 30, multiple: true, multipleSeparator: ',', cacheLength: 1}); + });"); + + $album_tags = ORM::factory("tags_album_id") + ->where("album_id", "=", $item->id) + ->find_all(); + + $tag_names = ""; + $tag_album_type = "OR"; + if (count($album_tags) > 0) { + $tag_names = $album_tags[0]->tags; + $tag_album_type = $album_tags[0]->search_type; + } + + $tags_album_group = $form->edit_item->group("tags_album_group"); + $tags_album_group->dropdown("tags_album_type") + ->options( + array("OR" => t("Display items that contain ANY of the following tags:"), + "AND" => t("Display items that contain ALL of the following tags:"))) + ->selected($tag_album_type); + $tags_album_group->input("tag_albums") + ->value($tag_names); + } + + static function item_deleted($item) { + // Whenever an item is deleted, delete any corresponding data. + db::build()->delete("tags_album_ids")->where("album_id", "=", $item->id)->execute(); + } + + static function item_edit_form_completed($item, $form) { + // Update the database with any changes to the tag_albums field. + if (!($item->is_album())) { + return; + } + + $record = ORM::factory("tags_album_id")->where("album_id", "=", $item->id)->find(); + + if ($form->edit_item->tags_album_group->tag_albums->value != "") { + if (!$record->loaded()) { + $record->album_id = $item->id; + } + $record->tags = $form->edit_item->tags_album_group->tag_albums->value; + $record->search_type = $form->edit_item->tags_album_group->tags_album_type->value; + $record->save(); + } else { + db::build()->delete("tags_album_ids")->where("album_id", "=", $item->id)->execute(); + } + } +} diff --git a/3.0/modules/tag_albums/helpers/tag_albums_installer.php b/3.0/modules/tag_albums/helpers/tag_albums_installer.php new file mode 100644 index 00000000..ee3df5e2 --- /dev/null +++ b/3.0/modules/tag_albums/helpers/tag_albums_installer.php @@ -0,0 +1,69 @@ +query("CREATE TABLE IF NOT EXISTS {tags_album_ids} ( + `id` int(9) NOT NULL auto_increment, + `album_id` int(9) NOT NULL, + `tags` varchar(2048) default NULL, + `search_type` varchar(128) NOT NULL, + PRIMARY KEY (`id`), + KEY(`album_id`, `id`)) + DEFAULT CHARSET=utf8;"); + + // Set up some default values. + module::set_var("tag_albums", "tag_sort_by", "name"); + module::set_var("tag_albums", "tag_sort_direction", "ASC"); + module::set_var("tag_albums", "subalbum_sort_by", "title"); + module::set_var("tag_albums", "subalbum_sort_direction", "ASC"); + module::set_var("tag_albums", "tag_index", "default"); + module::set_var("tag_albums", "tag_index_scope", "0"); + module::set_var("tag_albums", "tag_index_filter", "0"); + + // Set the module's version number. + module::set_version("tag_albums", 2); + } + + static function upgrade($version) { + if ($version == 1) { + module::set_var("tag_albums", "tag_index", "default"); + module::set_var("tag_albums", "tag_index_scope", "0"); + module::set_var("tag_albums", "tag_index_filter", "0"); + module::set_version("tag_albums", 2); + } + } + + static function deactivate() { + site_status::clear("tag_albums_needs_tag"); + } + + static function can_activate() { + $messages = array(); + if (!module::is_active("tag")) { + $messages["warn"][] = t("The Tag Albums module requires the Tags module."); + } + return $messages; + } + + static function uninstall() { + module::delete("tag_albums"); + } +} diff --git a/3.0/modules/tag_albums/helpers/tag_albums_theme.php b/3.0/modules/tag_albums/helpers/tag_albums_theme.php new file mode 100644 index 00000000..84f9a633 --- /dev/null +++ b/3.0/modules/tag_albums/helpers/tag_albums_theme.php @@ -0,0 +1,34 @@ +item()) { + $album_tags = ORM::factory("tags_album_id") + ->where("album_id", "=", $theme->item->id) + ->find_all(); + if (count($album_tags) > 0) { + url::redirect(url::abs_site("tag_albums/album/" . $album_tags[0]->id . "/" . urlencode($theme->item->name))); + } + } + return; + } +} diff --git a/3.0/modules/tag_albums/libraries/Tag_Albums_Breadcrumb.php b/3.0/modules/tag_albums/libraries/Tag_Albums_Breadcrumb.php new file mode 100644 index 00000000..ba576e49 --- /dev/null +++ b/3.0/modules/tag_albums/libraries/Tag_Albums_Breadcrumb.php @@ -0,0 +1,31 @@ +title = $new_title; + $this->url = $new_url; + } +} diff --git a/3.0/modules/tag_albums/libraries/Tag_Albums_Item.php b/3.0/modules/tag_albums/libraries/Tag_Albums_Item.php new file mode 100644 index 00000000..a90c5239 --- /dev/null +++ b/3.0/modules/tag_albums/libraries/Tag_Albums_Item.php @@ -0,0 +1,114 @@ +item_type == "album") { + return true; + } else { + return false; + } + } + + public function has_thumb() { + if ($this->thumb_url != "") { + return true; + } else { + return false; + } + } + + public function thumb_img($extra_attrs=array(), $max=null, $center_vertically=false) { + list ($height, $width) = $this->scale_dimensions($max); + if ($center_vertically && $max) { + // The constant is divide by 2 to calculate the file and 10 to convert to em + $margin_top = (int)(($max - $height) / 20); + $extra_attrs["style"] = "margin-top: {$margin_top}em"; + $extra_attrs["title"] = $this->title; + } + $attrs = array_merge($extra_attrs, + array( + "src" => $this->thumb_url(), + "alt" => $this->title, + "width" => $width, + "height" => $height) + ); + // html::image forces an absolute url which we don't want + return ""; + } + + public function scale_dimensions($max) { + $width = $this->thumb_width; + $height = $this->thumb_height; + + if ($width <= $max && $height <= $max) { + return array($height, $width); + } + + if ($height) { + if (isset($max)) { + if ($width > $height) { + $height = (int)($max * $height / $width); + $width = $max; + } else { + $width = (int)($max * $width / $height); + $height = $max; + } + } + } else { + // Missing thumbnail, can happen on albums with no photos yet. + // @todo we should enforce a placeholder for those albums. + $width = 0; + $height = 0; + } + return array($height, $width); + } + + public function thumb_url() { + return $this->thumb_url; + } + + public function url() { + return $this->url; + } + + public function set_thumb($new_url, $new_width, $new_height) { + $this->thumb_url = $new_url; + $this->thumb_width = $new_width; + $this->thumb_height = $new_height; + } + + public function __construct($new_title, $new_url, $new_type) { + $this->title = $new_title; + $this->url = $new_url; + $this->item_type = $new_type; + $this->type = $new_type; + } +} diff --git a/3.0/modules/tag_albums/models/tag.php b/3.0/modules/tag_albums/models/tag.php new file mode 100644 index 00000000..0cc47030 --- /dev/null +++ b/3.0/modules/tag_albums/models/tag.php @@ -0,0 +1,145 @@ +loaded()) { + // Set reasonable defaults + $this->count = 0; + } + } + + /** + * Return all viewable items associated with this tag. + * @param integer $limit number of rows to limit result to + * @param integer $offset offset in result to start returning rows from + * @param string $type the type of item (album, photo) + * @return ORM_Iterator + */ + public function items($limit=null, $offset=null, $type=null) { + $model = ORM::factory("item") + ->viewable() + ->join("items_tags", "items.id", "items_tags.item_id") + ->where("items_tags.tag_id", "=", $this->id); + if ($type) { + $model->where("items.type", "=", $type); + } + return $model->find_all($limit, $offset); + } + + /** + * Return the count of all viewable items associated with this tag. + * @param string $type the type of item (album, photo) + * @return integer + */ + public function items_count($type=null) { + $model = ORM::factory("item") + ->viewable() + ->join("items_tags", "items.id", "items_tags.item_id") + ->where("items_tags.tag_id", "=", $this->id); + + if ($type) { + $model->where("items.type", "=", $type); + } + return $model->count_all(); + } + + /** + * Overload ORM::save() to trigger an item_related_update event for all items that are related + * to this tag. + */ + public function save() { + $related_item_ids = array(); + foreach (db::build() + ->select("item_id") + ->from("items_tags") + ->where("tag_id", "=", $this->id) + ->execute() as $row) { + $related_item_ids[$row->item_id] = 1; + } + + if (isset($this->object_relations["items"])) { + $added = array_diff($this->changed_relations["items"], $this->object_relations["items"]); + $removed = array_diff($this->object_relations["items"], $this->changed_relations["items"]); + if (isset($this->changed_relations["items"])) { + $changed = array_merge($added, $removed); + } + $this->count = count($this->object_relations["items"]) + count($added) - count($removed); + } + + $result = parent::save(); + + if (!empty($changed)) { + foreach (ORM::factory("item")->where("id", "IN", $changed)->find_all() as $item) { + module::event("item_related_update", $item); + } + } + + return $result; + } + + /** + * Overload ORM::delete() to trigger an item_related_update event for all items that are + * related to this tag, and delete all items_tags relationships. + */ + public function delete($ignored_id=null) { + $related_item_ids = array(); + foreach (db::build() + ->select("item_id") + ->from("items_tags") + ->where("tag_id", "=", $this->id) + ->execute() as $row) { + $related_item_ids[$row->item_id] = 1; + } + + db::build()->delete("items_tags")->where("tag_id", "=", $this->id)->execute(); + $result = parent::delete(); + + if ($related_item_ids) { + foreach (ORM::factory("item") + ->where("id", "IN", array_keys($related_item_ids)) + ->find_all() as $item) { + module::event("item_related_update", $item); + } + } + return $result; + } + + /** + * Return the server-relative url to this item, eg: + * /gallery3/index.php/tags/35 + * + * @param string $query the query string (eg "page=3") + */ + public function url($query=null) { + $album_id = Input::instance()->get("album"); + if (!($album_id)) { + $album_id = 0; + } + $url = url::site("/tag_albums/tag/{$this->id}/{$album_id}/" . urlencode($this->name)); + if ($query) { + $url .= "?$query"; + } + return $url; + } +} diff --git a/3.0/modules/tag_albums/models/tags_album_id.php b/3.0/modules/tag_albums/models/tags_album_id.php new file mode 100644 index 00000000..a9b16b4f --- /dev/null +++ b/3.0/modules/tag_albums/models/tags_album_id.php @@ -0,0 +1,21 @@ + +

    + +

    +
    +
    + +
    diff --git a/3.0/modules/tag_albums/views/calpage.html.php b/3.0/modules/tag_albums/views/calpage.html.php new file mode 100644 index 00000000..3dab5fc0 --- /dev/null +++ b/3.0/modules/tag_albums/views/calpage.html.php @@ -0,0 +1,164 @@ + + +html_attributes() ?> xml:lang="en" lang="en"> + + + start_combining("script,css") ?> + + <? if ($page_title): ?> + <?= $page_title ?> + <? else: ?> + <? if ($theme->item()): ?> + <?= $theme->item()->title ?> + <? elseif ($theme->tag()): ?> + <?= t("Photos tagged with %tag_title", array("tag_title" => $theme->tag()->name)) ?> + <? else: /* Not an item, not a tag, no page_title specified. Help! */ ?> + <?= item::root()->title ?> + <? endif ?> + <? endif ?> + + " + type="image/x-icon" /> + + page_type == "collection"): ?> + + + + + + + + script("json2-min.js") ?> + script("jquery.js") ?> + script("jquery.form.js") ?> + script("jquery-ui.js") ?> + script("gallery.common.js") ?> + + + script("gallery.ajax.js") ?> + script("gallery.dialog.js") ?> + script("superfish/js/superfish.js") ?> + script("jquery.localscroll.js") ?> + + + page_subtype == "photo"): ?> + script("jquery.scrollTo.js") ?> + script("gallery.show_full_size.js") ?> + page_subtype == "movie"): ?> + script("flowplayer.js") ?> + + + head() ?> + + + script("ui.init.js") ?> + css("yui/reset-fonts-grids.css") ?> + css("superfish/css/superfish.css") ?> + css("themeroller/ui.base.css") ?> + css("screen.css") ?> + + + + get_combined("script") ?> + + + get_combined("css") ?> + + + body_attributes() ?>> + page_top() ?> +
    + site_status() ?> +
    +
    + + + + + + user_menu() ?> + header_top() ?> + + + + + + header_bottom() ?> +
    + + + + +
      + + + > + + url) : ?> + title) ?> + + title) ?> + + + + +
    + + + + + +
    +
    +
    +
    +
    + messages() ?> + +
    +
    +
    +
    + page_subtype != "login"): ?> + + +
    +
    + +
    + page_bottom() ?> + + \ No newline at end of file diff --git a/3.0/modules/tag_albums/views/tag_albums_album.html.php b/3.0/modules/tag_albums/views/tag_albums_album.html.php new file mode 100644 index 00000000..620d3c81 --- /dev/null +++ b/3.0/modules/tag_albums/views/tag_albums_album.html.php @@ -0,0 +1,50 @@ + +album_top() was changed to $theme->dynamic_top(). + // $item->title and $item->description have been changed to $title and $description. + // + // The g-album-grid block was also taken from album.html.php. The section for uploading new photos to an empty album + // has been removed. Also, $theme->context_menu has been removed as well (it was crashing the page). +?> +
    + dynamic_top() ?> +

    +
    +
    + + +
    +
    +
    +
    + + + +dynamic_bottom() ?> + +paginator() ?> diff --git a/3.0/modules/tag_albums/views/tag_albums_block.html.php b/3.0/modules/tag_albums/views/tag_albums_block.html.php new file mode 100644 index 00000000..d4b08087 --- /dev/null +++ b/3.0/modules/tag_albums/views/tag_albums_block.html.php @@ -0,0 +1,4 @@ + + diff --git a/3.0/modules/tag_cloud/controllers/admin_tag_cloud.php b/3.0/modules/tag_cloud/controllers/admin_tag_cloud.php index 777b9b7c..2d42e703 100644 --- a/3.0/modules/tag_cloud/controllers/admin_tag_cloud.php +++ b/3.0/modules/tag_cloud/controllers/admin_tag_cloud.php @@ -1,7 +1,7 @@ script("swfobject.js"); - $theme->script("tag_cloud.js"); + return $theme->script("swfobject.js") + . $theme->script("tag_cloud.js"); } } \ No newline at end of file diff --git a/3.0/modules/tag_cloud/module.info b/3.0/modules/tag_cloud/module.info index af8f9ce1..72c95532 100644 --- a/3.0/modules/tag_cloud/module.info +++ b/3.0/modules/tag_cloud/module.info @@ -1,3 +1,7 @@ name = "Tag Cloud" description = "3D tag cloud" version = 1 +author_name = "" +author_url = "" +info_url = "http://codex.gallery2.org/Gallery3:Modules:tag_cloud" +discuss_url = "http://gallery.menalto.com/forum_module_tag_cloud" diff --git a/3.0/modules/tag_cloud_page/controllers/tag_cloud_page.php b/3.0/modules/tag_cloud_page/controllers/tag_cloud_page.php new file mode 100644 index 00000000..2fc045df --- /dev/null +++ b/3.0/modules/tag_cloud_page/controllers/tag_cloud_page.php @@ -0,0 +1,66 @@ +content = new View("tag_cloud_page_cloud.html"); + $template->content->title = t("Tag Cloud"); + + // If the tag cloud module is active, load its settings from the database. + if (module::is_active("tag_cloud")) { + $options = array(); + foreach (array("tagcolor", "background_color", "mouseover", "transparent", "speed", "distribution") + as $option) { + $value = module::get_var("tag_cloud", $option, null); + if (!empty($value)) { + switch ($option) { + case "tagcolor": + $options["tcolor"] = $value; + break; + case "mouseover": + $options["hicolor"] = $value; + break; + case "background_color": + $options["bgColor"] = $value; + break; + case "transparent": + $options["wmode"] = "transparent"; + break; + case "speed": + $options["tspeed"] = $value; + break; + case "distribution": + $options["distr"] = "true"; + break; + } + } + } + $template->content->options = $options; + } + + // Display the page. + print $template; + } +} diff --git a/3.0/modules/tag_cloud_page/css/tag_cloud_page.css b/3.0/modules/tag_cloud_page/css/tag_cloud_page.css new file mode 100644 index 00000000..1eacad23 --- /dev/null +++ b/3.0/modules/tag_cloud_page/css/tag_cloud_page.css @@ -0,0 +1,73 @@ +/* Tag cloud page ~~~~~~~~~~~~~~~~~~~~~~~ */ + +#g-tag-cloud-page ul { + font-size: 1.2em; + text-align: justify; +} + +#g-tag-cloud-page ul li { + display: inline; + line-height: 1.5em; + text-align: justify; +} + +#g-tag-cloud-page ul li a { + text-decoration: none; +} + +#g-tag-cloud-page ul li span { + display: none; +} + +#g-tag-cloud-page ul li.size0 a { + color: #9cf; + font-size: 70%; + font-weight: 100; +} + +#g-tag-cloud-page ul li.size1 a { + color: #9cf; + font-size: 80%; + font-weight: 100; +} + +#g-tag-cloud-page ul li.size2 a { + color: #69f; + font-size: 90%; + font-weight: 300; +} + +#g-tag-cloud-page ul li.size3 a { + color: #69c; + font-size: 100%; + font-weight: 500; +} + +#g-tag-cloud-page ul li.size4 a { + color: #369; + font-size: 110%; + font-weight: 700; +} + +#g-tag-cloud-page ul li.size5 a { + color: #0e2b52; + font-size: 120%; + font-weight: 900; +} + +#g-tag-cloud-page ul li.size6 a { + color: #0e2b52; + font-size: 130%; + font-weight: 900; +} + +#g-tag-cloud-page ul li.size7 a { + color: #0e2b52; + font-size: 140%; + font-weight: 900; +} + +#g-tag-cloud-page ul li a:hover { + color: #f30; + text-decoration: underline; +} diff --git a/3.0/modules/tag_cloud_page/helpers/tag_cloud_page_block.php b/3.0/modules/tag_cloud_page/helpers/tag_cloud_page_block.php new file mode 100644 index 00000000..4ac5278b --- /dev/null +++ b/3.0/modules/tag_cloud_page/helpers/tag_cloud_page_block.php @@ -0,0 +1,40 @@ + t("Tag Cloud Page Link")); + } + + static function get($block_id, $theme) { + // Generate the sidebar block for linking to the tag cloud page. + $block = ""; + switch ($block_id) { + case "tag_cloud_page": + $block = new Block(); + $block->css_id = "g-tag-cloud-page"; + $block->title = t("Tag Cloud"); + $block->content = new View("tag_cloud_page_block.html"); + + break; + } + return $block; + } +} diff --git a/3.0/modules/tag_cloud_page/helpers/tag_cloud_page_event.php b/3.0/modules/tag_cloud_page/helpers/tag_cloud_page_event.php new file mode 100644 index 00000000..32f0ada0 --- /dev/null +++ b/3.0/modules/tag_cloud_page/helpers/tag_cloud_page_event.php @@ -0,0 +1,40 @@ +deactivate)) { + site_status::warning( + t("The Tag Cloud Page module requires the Tags module. " . + "Activate the Tags module now", + array("url" => url::site("admin/modules"))), + "tag_cloud_page_needs_tag"); + } else { + site_status::clear("tag_cloud_page_needs_tag"); + } + } + + static function pre_deactivate($data) { + if ($data->module == "tag") { + $data->messages["warn"][] = t("The Tag Cloud Page module requires the Tags module."); + } + } +} diff --git a/3.0/modules/tag_cloud_page/helpers/tag_cloud_page_installer.php b/3.0/modules/tag_cloud_page/helpers/tag_cloud_page_installer.php new file mode 100644 index 00000000..4f12115a --- /dev/null +++ b/3.0/modules/tag_cloud_page/helpers/tag_cloud_page_installer.php @@ -0,0 +1,32 @@ +script("tag_cloud_page.js"); + } + + // Load the tag cloud page's css code. + return $theme->css("tag_cloud_page.css"); + } +} diff --git a/3.0/modules/tag_cloud_page/js/tag_cloud_page.js b/3.0/modules/tag_cloud_page/js/tag_cloud_page.js new file mode 100644 index 00000000..66d1ddab --- /dev/null +++ b/3.0/modules/tag_cloud_page/js/tag_cloud_page.js @@ -0,0 +1,89 @@ +(function($) { + $.widget("ui.gallery_tag_cloud_page", { + _init: function() { + var self = this; + self._set_tag_cloud(); + this._ajax_form(); + this._autocomplete(); + }, + + _autocomplete: function() { + var url = $("#g-tag-cloud-page-animation").attr("ref") + "/autocomplete"; + $("#g-add-tag-form input:text").autocomplete( + url, { + max: 30, + multiple: true, + multipleSeparator: ',', + cacheLength: 1} + ); + }, + + _ajax_form: function() { + var self = this; + var form = $("#g-add-tag-form"); + form.ajaxForm({ + dataType: "json", + success: function(data) { + if (data.result == "success") { + $.get($("#g-tag-cloud-page-animation").attr("ref"), function(data, textStatus) { + $("#g-tag-cloud-movie-page").remove(); + $("#g-tag-cloud-page-animation").append("
    " + data + "
    "); + self._set_tag_cloud(); + }); + } + form.resetForm(); + $("#g-add-tag-form :text").blur(); + } + }); + }, + + _set_tag_cloud: function() { + var self = this; + var taglist = $("#g-tag-cloud-page-animation a"); + + if (taglist.length == 0) { + return; + } + var width = $("#g-tag-cloud-page-animation").width(); + var tags = document.createElement("tags"); + taglist.each(function(i) { + var addr = $(this).clone(); + $(addr).attr("style", "font-size: 14pt;"); + $(tags).append(addr); + }); + + var flashvars = { + tcolor: self.options.tcolor, + tcolor2: self.options.tcolor2, + mode: "tags", + distr: self.options.distr, + tspeed: self.options.tspeed, + hicolor: self.options.hicolor, + tagcloud: escape("" + $(tags).html() + "").toLowerCase() + }; + var params = { + bgcolor: self.options.bgColor, + wmode: self.options.wmode, + allowscriptaccess: self.options.scriptAccess + }; + + swfobject.embedSWF(self.options.movie, "g-tag-cloud-movie-page", width, .60 * width, "9", false, + flashvars, params); + } + }); + + $.extend($.ui.gallery_tag_cloud_page, { + defaults: { + bgColor: "0xFFFFFF", + wmode: "transparent", + scriptAccess: "always", + tcolor: "0x333333", + tcolor2: "0x009900", + hicolor: "0x000000", + tspeed: "100", + distr: "true", + mode: "tag" + } + }); + +})(jQuery); diff --git a/3.0/modules/tag_cloud_page/module.info b/3.0/modules/tag_cloud_page/module.info new file mode 100644 index 00000000..aebb40cb --- /dev/null +++ b/3.0/modules/tag_cloud_page/module.info @@ -0,0 +1,7 @@ +name = "Tag Cloud Page" +description = "Displays a tag cloud of all tags used in the Gallery on a seperate page." +version = 1 +author_name = "" +author_url = "" +info_url = "http://codex.gallery2.org/Gallery3:Modules:tag_cloud_page" +discuss_url = "http://gallery.menalto.com/forum_module_tag_cloud_page" diff --git a/3.0/modules/tag_cloud_page/views/tag_cloud_page_block.html.php b/3.0/modules/tag_cloud_page/views/tag_cloud_page_block.html.php new file mode 100644 index 00000000..46fd70ea --- /dev/null +++ b/3.0/modules/tag_cloud_page/views/tag_cloud_page_block.html.php @@ -0,0 +1,2 @@ + +">View cloud diff --git a/3.0/modules/tag_cloud_page/views/tag_cloud_page_cloud.html.php b/3.0/modules/tag_cloud_page/views/tag_cloud_page_cloud.html.php new file mode 100644 index 00000000..acd31ed4 --- /dev/null +++ b/3.0/modules/tag_cloud_page/views/tag_cloud_page_cloud.html.php @@ -0,0 +1,35 @@ + +
    +
    + dynamic_top() ?> +
    +

    +
    +
    + + + +
    +
    "> +
    + count_all()); ?> +
    +
    +
    + + +
    + count_all()); ?> +
    + + +dynamic_bottom() ?> diff --git a/3.0/modules/tag_it/controllers/tag_it.php b/3.0/modules/tag_it/controllers/tag_it.php index ba2ab6db..53dc5bf3 100644 --- a/3.0/modules/tag_it/controllers/tag_it.php +++ b/3.0/modules/tag_it/controllers/tag_it.php @@ -1,7 +1,7 @@ t("Tags In Album")); + } + + static function get($block_id, $theme) { + $block = ""; + + switch ($block_id) { + case "tagsinalbum": + if (($theme->item) && ($theme->item->is_album())) { + $item = $theme->item; + $all_tags = ORM::factory("tag") + ->join("items_tags", "items_tags.tag_id", "tags.id") + ->join("items", "items.id", "items_tags.item_id", "LEFT") + ->where("items.parent_id", "=", $item->id) + ->order_by("tags.id", "ASC") + ->find_all(); + if (count($all_tags) > 0) { + $block = new Block(); + $block->css_id = "g-tags-in-album-block"; + $block->title = t("In this album"); + $block->content = new View("tagsinalbum_sidebar.html"); + $block->content->all_tags = $all_tags; + } + } + break; + } + return $block; + } +} diff --git a/3.0/modules/tagsinalbum/helpers/tagsinalbum_event.php b/3.0/modules/tagsinalbum/helpers/tagsinalbum_event.php new file mode 100644 index 00000000..fe7339ae --- /dev/null +++ b/3.0/modules/tagsinalbum/helpers/tagsinalbum_event.php @@ -0,0 +1,37 @@ +module == "tag") { + $data->messages["warn"][] = t("The Tags In Album module requires the Tags module."); + } + } + + static function module_change($changes) { + if (!module::is_active("tag") || in_array("tag", $changes->deactivate)) { + site_status::warning( + t("The Tags In Album module requires the Tags module. Activate the Tags module now", + array("url" => html::mark_clean(url::site("admin/modules")))), + "tagsinalbum_needs_tag"); + } else { + site_status::clear("tagsinalbum_needs_tag"); + } + } +} diff --git a/3.0/modules/tagsinalbum/helpers/tagsinalbum_installer.php b/3.0/modules/tagsinalbum/helpers/tagsinalbum_installer.php new file mode 100644 index 00000000..09f82108 --- /dev/null +++ b/3.0/modules/tagsinalbum/helpers/tagsinalbum_installer.php @@ -0,0 +1,44 @@ + +id) { + $tag = ORM::factory("tag", $one_tag->id); + $display_tags[] = array(html::clean($tag->name), $tag->url()); + $last_tagid = $one_tag->id; + } + if (module::get_var("tagsinalbum", "max_display_tags") > 0) { + if (count($display_tags) == module::get_var("tagsinalbum", "max_display_tags")) { + break; + } + } + } + + // Sort the array. + asort($display_tags); + + // Print out the list of tags as clickable links. + $not_first = 0; + foreach ($display_tags as $one_tag) { + if ($not_first++ > 0) { + print ", "; + } + print "" . $one_tag[0] . ""; + } +?> diff --git a/3.0/modules/tagsmap/controllers/admin_tagsmap.php b/3.0/modules/tagsmap/controllers/admin_tagsmap.php index 6a774521..40d87119 100644 --- a/3.0/modules/tagsmap/controllers/admin_tagsmap.php +++ b/3.0/modules/tagsmap/controllers/admin_tagsmap.php @@ -1,7 +1,7 @@ dropdown("google_default_type") ->label(t("Default Map Type")) ->options( - array("G_NORMAL_MAP", "G_SATELLITE_MAP", "G_HYBRID_MAP", - "G_PHYSICAL_MAP", "G_SATELLITE_3D_MAP")); + array("G_NORMAL_MAP" => "Normal", + "G_SATELLITE_MAP" => "Satellite", + "G_HYBRID_MAP" => "Hybrid", + "G_PHYSICAL_MAP" => "Physical", + "G_SATELLITE_3D_MAP" => "Google Earth")) + ->selected(module::get_var("tagsmap", "googlemap_type")); // Add a save button to the form. $form->submit("SaveSettings")->value(t("Save")); diff --git a/3.0/modules/tagsmap/controllers/tagsmap.php b/3.0/modules/tagsmap/controllers/tagsmap.php index f5554e72..8725db86 100644 --- a/3.0/modules/tagsmap/controllers/tagsmap.php +++ b/3.0/modules/tagsmap/controllers/tagsmap.php @@ -1,7 +1,7 @@ module == "tag") { + $data->messages["warn"][] = t("The TagsMap module requires the Tags module."); + } + } + static function admin_menu($menu, $theme) { // Add a link to the TagsMap admin page to the Content menu. $menu->get("content_menu") diff --git a/3.0/modules/tagsmap/helpers/tagsmap_installer.php b/3.0/modules/tagsmap/helpers/tagsmap_installer.php index 9f91f6d8..4567d4df 100644 --- a/3.0/modules/tagsmap/helpers/tagsmap_installer.php +++ b/3.0/modules/tagsmap/helpers/tagsmap_installer.php @@ -1,7 +1,7 @@ css("tagsmap_menu.css"); + return $theme->css("tagsmap_menu.css"); } } diff --git a/3.0/modules/tagsmap/models/tags_gps.php b/3.0/modules/tagsmap/models/tags_gps.php index e219d245..31f7943f 100644 --- a/3.0/modules/tagsmap/models/tags_gps.php +++ b/3.0/modules/tagsmap/models/tags_gps.php @@ -1,7 +1,7 @@ name(t("Generate theme")); $v->task = task::create($task_def, - array("path" => $extract_path, - "original_name" => $form->theme->original->value, - "theme_name" => $form->theme->theme_name->value, - "display_name" => $form->theme->display_name->value, - "description" => $form->theme->description->value, - "is_admin" => $session->get("themeroller_is_admin"))); + array("path" => $extract_path, + "user_name" => SafeString::purify(identity::active_user()->name), + "original_name" => SafeString::purify($form->theme->original->value), + "theme_name" => SafeString::purify($form->theme->theme_name->value), + "display_name" => SafeString::purify($form->theme->display_name->value), + "description" => SafeString::purify($form->theme->description->value), + "author_url" => SafeString::purify($form->theme->author_url->value), + "info_url" => SafeString::purify($form->theme->info_url->value), + "discuss_url" => SafeString::purify($form->theme->discuss_url->value), + "is_admin" => $session->get("themeroller_is_admin"))); json::reply(array("html" => (string) $v)); } else { @@ -169,9 +173,13 @@ class Admin_Themeroller_Controller extends Admin_Controller { } $form_group->textarea("description")->label(t("Description")) ->id("g-description") - ->value(t("A generated theme based on the ui themeroller '%name' styling", array("name" => str_replace("admin_", "", $theme_name)))) + ->value(t("A generated theme based on the ui themeroller '%name' styling", + array("name" => str_replace("admin_", "", $theme_name)))) ->rules("required") ->error_messages("required", t("You must enter a theme description name")); + $form_group->input("author_url")->label(t("Author url"))->id("g-author-url"); + $form_group->input("info_url")->label(t("Info url"))->id("g-info-url"); + $form_group->input("discuss_url")->label(t("Theme Name"))->id("g-discuss-url"); $form_group->submit("")->value(t("Create")); return $form; diff --git a/3.0/modules/themeroller/data/views/page.html.php b/3.0/modules/themeroller/data/views/page.html.php index ffd5a173..06851344 100644 --- a/3.0/modules/themeroller/data/views/page.html.php +++ b/3.0/modules/themeroller/data/views/page.html.php @@ -4,47 +4,40 @@ + start_combining("script,css") ?> <? if ($page_title): ?> <?= $page_title ?> <? else: ?> <? if ($theme->item()): ?> - <? if ($theme->item()->is_album()): ?> - <?= t("Browse Album :: %album_title", array("album_title" => $theme->item()->title)) ?> - <? elseif ($theme->item()->is_photo()): ?> - <?= t("Photo :: %photo_title", array("photo_title" => $theme->item()->title)) ?> - <? else: ?> - <?= t("Movie :: %movie_title", array("movie_title" => $theme->item()->title)) ?> - <? endif ?> + <?= $theme->item()->title ?> <? elseif ($theme->tag()): ?> - <?= t("Browse Tag :: %tag_title", array("tag_title" => $theme->tag()->name)) ?> + <?= t("Photos tagged with %tag_title", array("tag_title" => $theme->tag()->name)) ?> <? else: /* Not an item, not a tag, no page_title specified. Help! */ ?> - <?= t("Gallery") ?> + <?= item::root()->title ?> <? endif ?> <? endif ?> - " type="image/x-icon" /> - css("yui/reset-fonts-grids.css") ?> - css("superfish/css/superfish.css") ?> - css("themeroller/ui.base.css") ?> - css("screen.css") ?> - + " + type="image/x-icon" /> + " /> page_type == "collection"): ?> - + + + script("json2-min.js") ?> script("jquery.js") ?> script("jquery.form.js") ?> script("jquery-ui.js") ?> @@ -57,7 +50,6 @@ script("gallery.dialog.js") ?> script("superfish/js/superfish.js") ?> script("jquery.localscroll.js") ?> - script("ui.init.js") ?> head() they get combined */ ?> page_subtype == "photo"): ?> @@ -68,6 +60,26 @@ head() ?> + + + script("ui.init.js") ?> + css("yui/reset-fonts-grids.css") ?> + css("superfish/css/superfish.css") ?> + css("themeroller/ui.base.css") ?> + css("screen.css") ?> + + css("screen-rtl.css") ?> + + + + + get_combined("css") ?> + + + get_combined("script") ?> body_attributes() ?>> @@ -100,19 +112,22 @@ > - + causes Gallery3 to display the page + // containing that photo. For now, we just do it for + // the immediate parent so that when you go back up a + // level you're on the right page. ?> item()->id}" : null) ?>"> - title, 15)) ?> + + title, + module::get_var("gallery", "visible_title_length"))) ?>
  • "> - item()->title, 15)) ?> + item()->title, + module::get_var("gallery", "visible_title_length"))) ?>
  • diff --git a/3.0/modules/themeroller/helpers/themeroller.php b/3.0/modules/themeroller/helpers/themeroller.php index 561fa169..44a102cc 100644 --- a/3.0/modules/themeroller/helpers/themeroller.php +++ b/3.0/modules/themeroller/helpers/themeroller.php @@ -1,6 +1,6 @@ display_name = $task->get("display_name"); - foreach ($parameters["colors"] as $color => $value) { - $v->$color = $value; + foreach (array("screen", "screen-rtl") as $file) { + $css_file = "{$theme_path}/css/$file.css"; + $v = new View(($is_admin ? "admin" : "site") . "_{$file}.css"); + $v->display_name = $task->get("display_name"); + foreach ($parameters["colors"] as $color => $value) { + $v->$color = $value; + } + ob_start(); + print $v->render(); + file_put_contents($css_file, ob_get_contents()); + ob_end_clean(); } - ob_start(); - print $v->render(); - file_put_contents($file, ob_get_contents()); - ob_end_clean(); $completed++; $task->log(t("Generated screen css: %path", array("path" => $file))); $task->status = t("Screen css generated"); @@ -229,14 +232,18 @@ class themeroller_task_Core { $task->status = t("Thumbnail generated"); $task->set("mode", "generate_theme_info"); $completed++; - $task->log(t("Generated theme thumbnail: %path", array("path" => "{$theme_path}thumbnail.png"))); + $task->log(t("Generated theme thumbnail: %path", + array("path" => "{$theme_path}thumbnail.png"))); break; case "generate_theme_info": $file = "{$theme_path}/theme.info"; $v = new View("theme.info"); $v->display_name = $task->get("display_name"); $v->description = $task->get("description"); - $v->user_name = identity::active_user()->name; + $v->user_name = $task->get("user_name"); + $v->author_url = $task->get("author_url"); + $v->info_url = $task->get("info_url"); + $v->discuss_url = $task->get("discuss_url"); $v->is_admin = $is_admin; $v->definition = json_encode($parameters["colors"]); ob_start(); diff --git a/3.0/modules/themeroller/module.info b/3.0/modules/themeroller/module.info index 0e50286e..aaa16bd6 100755 --- a/3.0/modules/themeroller/module.info +++ b/3.0/modules/themeroller/module.info @@ -1,3 +1,7 @@ -name = "Theme generator" +name = "Theme Roller" description = "Use a JQuery UI theme to create a Gallery3 Theme" version = 1 +author_name = "" +author_url = "" +info_url = "http://codex.gallery2.org/Gallery3:Modules:themeroller" +discuss_url = "http://gallery.menalto.com/forum_module_themeroller" diff --git a/3.0/modules/themeroller/views/admin_screen-rtl.css.php b/3.0/modules/themeroller/views/admin_screen-rtl.css.php new file mode 100644 index 00000000..196d5313 --- /dev/null +++ b/3.0/modules/themeroller/views/admin_screen-rtl.css.php @@ -0,0 +1,299 @@ +/** + * Gallery 3 Admin Right yo left language styles + */ + +.rtl { + direction: rtl; +} + + #g-header, + #g-content, + #g-sidebar, + #g-footer, + caption, + th, + #g-dialog, + .g-context-menu li a, + .g-message-box li, + #g-site-status li { + text-align: right; +} + + .g-text-right { + text-align: left; +} + + .g-error, + .g-info, + .g-success, + .g-warning, + #g-add-photos-status .g-success, + #g-add-photos-status .g-error { + background-position: center right; + padding-right: 30px !important; +} + + form li.g-error, + form li.g-info, + form li.g-success, + form li.g-warning { + padding-right: 0 !important; +} + + .g-left, + .g-inline li, + #g-content #g-album-grid .g-item, + .sf-menu li, + .g-breadcrumbs li, + .g-paginator li, + .g-buttonset li, + .ui-icon-left .ui-icon, + .g-short-form li, + form ul ul li, + input[type="submit"], + input[type="reset"], + input.checkbox, + input[type=checkbox], + input.radio, + input[type=radio] { + float: right; +} + + .g-right, + .ui-icon-right .ui-icon { + float: left; +} + + .g-inline li { + margin-right: 1em; +} + + .g-inline li.g-first { + margin-right: 0; +} + + .g-breadcrumbs li { + background: transparent url('../images/ico-separator-rtl.png') no-repeat scroll right center; + padding: 1em 18px 1em 8px; +} + + .g-breadcrumbs .g-first { + background: none; + padding-right: 0; +} + + input.checkbox { + margin-left: .4em; +} + + #g-add-comment { + right: inherit; + left: 0; +} + + .ui-icon-left .ui-icon { + margin-left: .2em; +} + + .ui-icon-right .ui-icon { + margin-right: .2em; +} + +/* RTL Corner radius ~~~~~~~~~~~~~~~~~~~~~~ */ + .g-buttonset .ui-corner-tl { + -moz-border-radius-topleft: 0; + -webkit-border-top-left-radius: 0; + border-top-left-radius: 0; + -moz-border-radius-topright: 5px !important; + -webkit-border-top-right-radius: 5px !important; + border-top-right-radius: 5px !important; +} + + .g-buttonset .ui-corner-tr { + -moz-border-radius-topright: 0; + -webkit-border-top-right-radius: 0; + border-top-right-radius: 0; + -moz-border-radius-topleft: 5px !important; + -webkit-border-top-left-radius: 5px !important; + border-top-left-radius: 5px !important; +} + + .g-buttonset .ui-corner-bl { + -moz-border-radius-bottomleft: 0; + -webkit-border-bottom-left-radius: 0; + border-bottom-left-radius: 0; + -moz-border-radius-bottomright: 5px !important; + -webkit-border-bottom-right-radius: 5px !important; + border-bottom-right-radius: 5px !important; +} + + .g-buttonset .ui-corner-br { + -moz-border-radius-bottomright: 0; + -webkit-border-bottom-right-radius: 0; + border-bottom-right-radius: 0; + -moz-border-radius-bottomleft: 5px !important; + -webkit-border-bottom-left-radius: 5px !important; + border-bottom-left-radius: 5px !important; +} + + .g-buttonset .ui-corner-right, + .ui-progressbar .ui-corner-right { + -moz-border-radius-topright: 0; + -webkit-border-top-right-radius: 0; + border-top-right-radius: 0; + -moz-border-radius-topleft: 5px !important; + -webkit-border-top-left-radius: 5px !important; + border-top-left-radius: 5px !important; + -moz-border-radius-bottomright: 0; + -webkit-border-bottom-right-radius: 0; + border-bottom-right-radius: 0; + -moz-border-radius-bottomleft: 5px !important; + -webkit-border-bottom-left-radius: 5px !important; + border-bottom-left-radius: 5px !important; +} + + .g-buttonset .ui-corner-left, + .ui-progressbar .ui-corner-left { + -moz-border-radius-topleft: 0; + -webkit-border-top-left-radius: 0; + border-top-left-radius: 0; + -moz-border-radius-topright: 5px !important; + -webkit-border-top-right-radius: 5px !important; + border-top-right-radius: 5px !important; + -moz-border-radius-bottomleft: 0; + -webkit-border-bottom-left-radius: 0; + border-bottom-left-radius: 0; + -moz-border-radius-bottomright: 5px !important; + -webkit-border-bottom-right-radius: 5px !important; + border-bottom-right-radius: 5px !important; +} + +/* RTL Superfish ~~~~~~~~~~~~~~~~~~~~~~~~~ */ + + .sf-menu a { + border-left: none; + border-right:1px solid #; +} + + .sf-menu a.sf-with-ul { + padding-left: 2.25em; + padding-right: 1em; +} + + .sf-sub-indicator { + background: url("themeroller/images/ui-icons__256x240.png") no-repeat -96px -16px; /* 8-bit indexed alpha png. IE6 gets solid image only */ + left: .75em !important; + right: auto; +} + + a > .sf-sub-indicator { /* give all except IE6 the correct values */ + top: .8em; + background-position: -10px -100px; /* use translucent arrow for modern browsers*/ +} +/* apply hovers to modern browsers */ + a:focus > .sf-sub-indicator, + a:hover > .sf-sub-indicator, + a:active > .sf-sub-indicator, + li:hover > a > .sf-sub-indicator, + li.sfHover > a > .sf-sub-indicator { + background-position: 0 -100px; /* arrow hovers for modern browsers*/ +} + +/* point right for anchors in subs */ + .sf-menu ul .sf-sub-indicator { background-position: 0 0; } + .sf-menu ul a > .sf-sub-indicator { background-position: -10px 0; } +/* apply hovers to modern browsers */ + .sf-menu ul a:focus > .sf-sub-indicator, + .sf-menu ul a:hover > .sf-sub-indicator, + .sf-menu ul a:active > .sf-sub-indicator, + .sf-menu ul li:hover > a > .sf-sub-indicator, + .sf-menu ul li.sfHover > a > .sf-sub-indicator { + background-position: 0 0; /* arrow hovers for modern browsers*/ +} + + .sf-menu li:hover ul, + .sf-menu li.sfHover ul { + right: 0; + left: auto; +} + + ul.sf-menu li li:hover ul, + ul.sf-menu li li.sfHover ul { + right: 12em; /* match ul width */ + left: auto; +} + ul.sf-menu li li li:hover ul, + ul.sf-menu li li li.sfHover ul { + right: 12em; /* match ul width */ + left: auto; +} + +/*** shadows for all but IE6 ***/ + .sf-shadow ul { + background: url('../images/superfish-shadow.png') no-repeat bottom left; + border-top-right-radius: 0; + border-bottom-left-radius: 0; + -moz-border-radius-topright: 0; + -moz-border-radius-bottomleft: 0; + -webkit-border-top-right-radius: 0; + -webkit-border-bottom-left-radius: 0; + -moz-border-radius-topleft: 17px; + -moz-border-radius-bottomright: 17px; + -webkit-border-top-left-radius: 17px; + -webkit-border-bottom-right-radius: 17px; + border-top-left-radius: 17px; + border-bottom-right-radius: 17px; +} + +/* RTL ThemeRoller ~~~~~~~~~~~~~~~~~~~~~~~~ */ + + .ui-dialog .ui-dialog-titlebar { + padding: 0.5em 1em 0.3em 0.3em; +} + + .ui-dialog .ui-dialog-title { + float: right; +} + + .ui-dialog .ui-dialog-titlebar-close { + left: 0.3em; + right: auto; +} + + #g-content #g-album-grid .g-item, + #g-site-theme, + #g-admin-theme, + .g-selected img, + .g-available .g-block img, + #g-content #g-photo-stream .g-item, + li.g-group, + #g-server-add-admin { + float: right; +} + + #g-admin-graphics .g-available .g-block { + float: right; + margin-left: 1em; + margin-right: 0em; +} + + #g-site-admin-menu { + left: auto; + right: 150px; +} + + #g-header #g-login-menu { + float: left; +} + + #g-header #g-login-menu li { + margin-left: 0; + padding-left: 0; + padding-right: 1.2em; +} + + .g-selected img, + .g-available .g-block img { + margin: 0 0 1em 1em; +} + diff --git a/3.0/modules/themeroller/views/admin_screen.css.php b/3.0/modules/themeroller/views/admin_screen.css.php index 54ea97f4..68659be2 100644 --- a/3.0/modules/themeroller/views/admin_screen.css.php +++ b/3.0/modules/themeroller/views/admin_screen.css.php @@ -13,7 +13,6 @@ * 7) Navigation and menus * 8) jQuery and jQuery UI * 9) Module color overrides - * 10) Right-to-left language styles * * @todo Review g-buttonset-vertical */ @@ -98,7 +97,16 @@ a:hover, text-decoration: none; } +/* Lists ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ + +ul.g-text li, +.g-text ul li { + list-style-type: disc; + margin-left: 1em; +} + /* Forms ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ + form { margin: 0; } @@ -415,11 +423,6 @@ th { background-color: #; } -ul.enumeration li { - list-style-type: disc; - margin-left: 20px; -} - /*** ****************************************************************** * 3) Page layout containers *********************************************************************/ @@ -1126,303 +1129,3 @@ a > .sf-sub-indicator { .g-default-group .g-user { color: # !important; } - -/** ******************************************************************* - * 10) Right to left styles - *********************************************************************/ - -.rtl { - direction: rtl; -} - -.rtl #g-header, -.rtl #g-content, -.rtl #g-sidebar, -.rtl #g-footer, -.rtl caption, -.rtl th, -.rtl #g-dialog, -.rtl .g-context-menu li a, -.rtl .g-message-box li, -.rtl #g-site-status li { - text-align: right; -} - -.rtl .g-text-right { - text-align: left; -} - -.rtl .g-error, -.rtl .g-info, -.rtl .g-success, -.rtl .g-warning, -.rtl #g-add-photos-status .g-success, -.rtl #g-add-photos-status .g-error { - background-position: center right; - padding-right: 30px !important; -} - -.rtl form li.g-error, -.rtl form li.g-info, -.rtl form li.g-success, -.rtl form li.g-warning { - padding-right: 0 !important; -} - -.rtl .g-left, -.rtl .g-inline li, -.rtl #g-content #g-album-grid .g-item, -.rtl .sf-menu li, -.rtl .g-breadcrumbs li, -.rtl .g-paginator li, -.rtl .g-buttonset li, -.rtl .ui-icon-left .ui-icon, -.rtl .g-short-form li, -.rtl form ul ul li, -.rtl input[type="submit"], -.rtl input[type="reset"], -.rtl input.checkbox, -.rtl input[type=checkbox], -.rtl input.radio, -.rtl input[type=radio] { - float: right; -} - -.rtl .g-right, -.rtl .ui-icon-right .ui-icon { - float: left; -} - -.rtl .g-inline li { - margin-right: 1em; -} - -.rtl .g-inline li.g-first { - margin-right: 0; -} - -.rtl .g-breadcrumbs li { - background: transparent url('../images/ico-separator-rtl.png') no-repeat scroll right center; - padding: 1em 18px 1em 8px; -} - -.rtl .g-breadcrumbs .g-first { - background: none; - padding-right: 0; -} - -.rtl input.checkbox { - margin-left: .4em; -} - -.rtl #g-add-comment { - right: inherit; - left: 0; -} - -.rtl .ui-icon-left .ui-icon { - margin-left: .2em; -} - -.rtl .ui-icon-right .ui-icon { - margin-right: .2em; -} - -/* RTL Corner radius ~~~~~~~~~~~~~~~~~~~~~~ */ -.rtl .g-buttonset .ui-corner-tl { - -moz-border-radius-topleft: 0; - -webkit-border-top-left-radius: 0; - border-top-left-radius: 0; - -moz-border-radius-topright: 5px !important; - -webkit-border-top-right-radius: 5px !important; - border-top-right-radius: 5px !important; -} - -.rtl .g-buttonset .ui-corner-tr { - -moz-border-radius-topright: 0; - -webkit-border-top-right-radius: 0; - border-top-right-radius: 0; - -moz-border-radius-topleft: 5px !important; - -webkit-border-top-left-radius: 5px !important; - border-top-left-radius: 5px !important; -} - -.rtl .g-buttonset .ui-corner-bl { - -moz-border-radius-bottomleft: 0; - -webkit-border-bottom-left-radius: 0; - border-bottom-left-radius: 0; - -moz-border-radius-bottomright: 5px !important; - -webkit-border-bottom-right-radius: 5px !important; - border-bottom-right-radius: 5px !important; -} - -.rtl .g-buttonset .ui-corner-br { - -moz-border-radius-bottomright: 0; - -webkit-border-bottom-right-radius: 0; - border-bottom-right-radius: 0; - -moz-border-radius-bottomleft: 5px !important; - -webkit-border-bottom-left-radius: 5px !important; - border-bottom-left-radius: 5px !important; -} - -.rtl .g-buttonset .ui-corner-right, -.rtl .ui-progressbar .ui-corner-right { - -moz-border-radius-topright: 0; - -webkit-border-top-right-radius: 0; - border-top-right-radius: 0; - -moz-border-radius-topleft: 5px !important; - -webkit-border-top-left-radius: 5px !important; - border-top-left-radius: 5px !important; - -moz-border-radius-bottomright: 0; - -webkit-border-bottom-right-radius: 0; - border-bottom-right-radius: 0; - -moz-border-radius-bottomleft: 5px !important; - -webkit-border-bottom-left-radius: 5px !important; - border-bottom-left-radius: 5px !important; -} - -.rtl .g-buttonset .ui-corner-left, -.rtl .ui-progressbar .ui-corner-left { - -moz-border-radius-topleft: 0; - -webkit-border-top-left-radius: 0; - border-top-left-radius: 0; - -moz-border-radius-topright: 5px !important; - -webkit-border-top-right-radius: 5px !important; - border-top-right-radius: 5px !important; - -moz-border-radius-bottomleft: 0; - -webkit-border-bottom-left-radius: 0; - border-bottom-left-radius: 0; - -moz-border-radius-bottomright: 5px !important; - -webkit-border-bottom-right-radius: 5px !important; - border-bottom-right-radius: 5px !important; -} - -/* RTL Superfish ~~~~~~~~~~~~~~~~~~~~~~~~~ */ - -.rtl .sf-menu a { - border-left: none; - border-right:1px solid #; -} - -.rtl .sf-menu a.sf-with-ul { - padding-left: 2.25em; - padding-right: 1em; -} - -.rtl .sf-sub-indicator { - background: url("themeroller/images/ui-icons__256x240.png") no-repeat -96px -16px; /* 8-bit indexed alpha png. IE6 gets solid image only */ - left: .75em !important; - right: auto; -} - -.rtl a > .sf-sub-indicator { /* give all except IE6 the correct values */ - top: .8em; - background-position: -10px -100px; /* use translucent arrow for modern browsers*/ -} -/* apply hovers to modern browsers */ -.rtl a:focus > .sf-sub-indicator, -.rtl a:hover > .sf-sub-indicator, -.rtl a:active > .sf-sub-indicator, -.rtl li:hover > a > .sf-sub-indicator, -.rtl li.sfHover > a > .sf-sub-indicator { - background-position: 0 -100px; /* arrow hovers for modern browsers*/ -} - -/* point right for anchors in subs */ -.rtl .sf-menu ul .sf-sub-indicator { background-position: 0 0; } -.rtl .sf-menu ul a > .sf-sub-indicator { background-position: -10px 0; } -/* apply hovers to modern browsers */ -.rtl .sf-menu ul a:focus > .sf-sub-indicator, -.rtl .sf-menu ul a:hover > .sf-sub-indicator, -.rtl .sf-menu ul a:active > .sf-sub-indicator, -.rtl .sf-menu ul li:hover > a > .sf-sub-indicator, -.rtl .sf-menu ul li.sfHover > a > .sf-sub-indicator { - background-position: 0 0; /* arrow hovers for modern browsers*/ -} - -.rtl .sf-menu li:hover ul, -.rtl .sf-menu li.sfHover ul { - right: 0; - left: auto; -} - -.rtl ul.sf-menu li li:hover ul, -.rtl ul.sf-menu li li.sfHover ul { - right: 12em; /* match ul width */ - left: auto; -} -.rtl ul.sf-menu li li li:hover ul, -.rtl ul.sf-menu li li li.sfHover ul { - right: 12em; /* match ul width */ - left: auto; -} - -/*** shadows for all but IE6 ***/ -.rtl .sf-shadow ul { - background: url('../images/superfish-shadow.png') no-repeat bottom left; - border-top-right-radius: 0; - border-bottom-left-radius: 0; - -moz-border-radius-topright: 0; - -moz-border-radius-bottomleft: 0; - -webkit-border-top-right-radius: 0; - -webkit-border-bottom-left-radius: 0; - -moz-border-radius-topleft: 17px; - -moz-border-radius-bottomright: 17px; - -webkit-border-top-left-radius: 17px; - -webkit-border-bottom-right-radius: 17px; - border-top-left-radius: 17px; - border-bottom-right-radius: 17px; -} - -/* RTL ThemeRoller ~~~~~~~~~~~~~~~~~~~~~~~~ */ - -.rtl .ui-dialog .ui-dialog-titlebar { - padding: 0.5em 1em 0.3em 0.3em; -} - -.rtl .ui-dialog .ui-dialog-title { - float: right; -} - -.rtl .ui-dialog .ui-dialog-titlebar-close { - left: 0.3em; - right: auto; -} - -.rtl #g-content #g-album-grid .g-item, -.rtl #g-site-theme, -.rtl #g-admin-theme, -.rtl .g-selected img, -.rtl .g-available .g-block img, -.rtl #g-content #g-photo-stream .g-item, -.rtl li.g-group, -.rtl #g-server-add-admin { - float: right; -} - -.rtl #g-admin-graphics .g-available .g-block { - float: right; - margin-left: 1em; - margin-right: 0em; -} - -.rtl #g-site-admin-menu { - left: auto; - right: 150px; -} - -.rtl #g-header #g-login-menu { - float: left; -} - -.rtl #g-header #g-login-menu li { - margin-left: 0; - padding-left: 0; - padding-right: 1.2em; -} - -.rtl .g-selected img, -.rtl .g-available .g-block img { - margin: 0 0 1em 1em; -} - diff --git a/3.0/modules/themeroller/views/site_screen-rtl.css.php b/3.0/modules/themeroller/views/site_screen-rtl.css.php new file mode 100644 index 00000000..991234cb --- /dev/null +++ b/3.0/modules/themeroller/views/site_screen-rtl.css.php @@ -0,0 +1,320 @@ + +/** + * Gallery 3 right to left language styles + */ + +.rtl { + direction: rtl; +} + + #g-header, + #g-content, + #g-sidebar, + #g-footer, + caption, + th, + #g-dialog, + .g-context-menu li a, + .g-message-box li, + #g-site-status li { + text-align: right; +} + + .g-text-right { + text-align: left; +} + + .g-error, + .g-info, + .g-success, + .g-warning, + #g-add-photos-status .g-success, + #g-add-photos-status .g-error { + background-position: center right; + padding-right: 30px !important; +} + + form li.g-error, + form li.g-info, + form li.g-success, + form li.g-warning { + padding-right: 0 !important; +} + + .g-left, + .g-inline li, + #g-content #g-album-grid .g-item, + .sf-menu li, + .g-breadcrumbs li, + .g-paginator li, + .g-buttonset li, + .ui-icon-left .ui-icon, + .g-short-form li, + form ul ul li, + input[type="submit"], + input[type="reset"], + input.checkbox, + input[type=checkbox], + input.radio, + input[type=radio] { + float: right; +} + + .g-right, + .ui-icon-right .ui-icon { + float: left; +} + + .g-inline li { + margin-right: 1em; +} + + .g-inline li.g-first { + margin-right: 0; +} + + .g-breadcrumbs li { + background: transparent url('../images/ico-separator-rtl.png') no-repeat scroll right center; + padding: 1em 18px 1em 8px; +} + + .g-breadcrumbs .g-first { + background: none; + padding-right: 0; +} + + input.checkbox { + margin-left: .4em; +} + + #g-add-comment { + right: inherit; + left: 0; +} + + .ui-icon-left .ui-icon { + margin-left: .2em; +} + + .ui-icon-right .ui-icon { + margin-right: .2em; +} + +/* RTL Corner radius ~~~~~~~~~~~~~~~~~~~~~~ */ + .g-buttonset .ui-corner-tl { + -moz-border-radius-topleft: 0; + -webkit-border-top-left-radius: 0; + border-top-left-radius: 0; + -moz-border-radius-topright: 5px !important; + -webkit-border-top-right-radius: 5px !important; + border-top-right-radius: 5px !important; +} + + .g-buttonset .ui-corner-tr { + -moz-border-radius-topright: 0; + -webkit-border-top-right-radius: 0; + border-top-right-radius: 0; + -moz-border-radius-topleft: 5px !important; + -webkit-border-top-left-radius: 5px !important; + border-top-left-radius: 5px !important; +} + + .g-buttonset .ui-corner-bl { + -moz-border-radius-bottomleft: 0; + -webkit-border-bottom-left-radius: 0; + border-bottom-left-radius: 0; + -moz-border-radius-bottomright: 5px !important; + -webkit-border-bottom-right-radius: 5px !important; + border-bottom-right-radius: 5px !important; +} + + .g-buttonset .ui-corner-br { + -moz-border-radius-bottomright: 0; + -webkit-border-bottom-right-radius: 0; + border-bottom-right-radius: 0; + -moz-border-radius-bottomleft: 5px !important; + -webkit-border-bottom-left-radius: 5px !important; + border-bottom-left-radius: 5px !important; +} + + .g-buttonset .ui-corner-right, + .ui-progressbar .ui-corner-right { + -moz-border-radius-topright: 0; + -webkit-border-top-right-radius: 0; + border-top-right-radius: 0; + -moz-border-radius-topleft: 5px !important; + -webkit-border-top-left-radius: 5px !important; + border-top-left-radius: 5px !important; + -moz-border-radius-bottomright: 0; + -webkit-border-bottom-right-radius: 0; + border-bottom-right-radius: 0; + -moz-border-radius-bottomleft: 5px !important; + -webkit-border-bottom-left-radius: 5px !important; + border-bottom-left-radius: 5px !important; +} + + .g-buttonset .ui-corner-left, + .ui-progressbar .ui-corner-left { + -moz-border-radius-topleft: 0; + -webkit-border-top-left-radius: 0; + border-top-left-radius: 0; + -moz-border-radius-topright: 5px !important; + -webkit-border-top-right-radius: 5px !important; + border-top-right-radius: 5px !important; + -moz-border-radius-bottomleft: 0; + -webkit-border-bottom-left-radius: 0; + border-bottom-left-radius: 0; + -moz-border-radius-bottomright: 5px !important; + -webkit-border-bottom-right-radius: 5px !important; + border-bottom-right-radius: 5px !important; +} + +/* RTL Superfish ~~~~~~~~~~~~~~~~~~~~~~~~~ */ + + .sf-menu a { + border-left: none; + border-right:1px solid #; +} + + .sf-menu a.sf-with-ul { + padding-left: 2.25em; + padding-right: 1em; +} + + .sf-sub-indicator { + left: .75em !important; + right: auto; + background: url("themeroller/images/ui-icons__256x240.png") no-repeat -10px -100px; /* 8-bit indexed alpha png. IE6 gets solid image only */ +} + + a > .sf-sub-indicator { /* give all except IE6 the correct values */ + top: .8em; + background-position: -10px -100px; /* use translucent arrow for modern browsers*/ +} +/* apply hovers to modern browsers */ + a:focus > .sf-sub-indicator, + a:hover > .sf-sub-indicator, + a:active > .sf-sub-indicator, + li:hover > a > .sf-sub-indicator, + li.sfHover > a > .sf-sub-indicator { + background-position: 0 -100px; /* arrow hovers for modern browsers*/ +} + +/* point right for anchors in subs */ + .sf-menu ul .sf-sub-indicator { background-position: 0 0; } + .sf-menu ul a > .sf-sub-indicator { background-position: -10px 0; } +/* apply hovers to modern browsers */ + .sf-menu ul a:focus > .sf-sub-indicator, + .sf-menu ul a:hover > .sf-sub-indicator, + .sf-menu ul a:active > .sf-sub-indicator, + .sf-menu ul li:hover > a > .sf-sub-indicator, + .sf-menu ul li.sfHover > a > .sf-sub-indicator { + background-position: 0 0; /* arrow hovers for modern browsers*/ +} + + .sf-menu li:hover ul, + .sf-menu li.sfHover ul { + right: 0; + left: auto; +} + + ul.sf-menu li li:hover ul, + ul.sf-menu li li.sfHover ul { + right: 12em; /* match ul width */ + left: auto; +} + ul.sf-menu li li li:hover ul, + ul.sf-menu li li li.sfHover ul { + right: 12em; /* match ul width */ + left: auto; +} + +/*** shadows for all but IE6 ***/ + .sf-shadow ul { + background: url('../../../lib/superfish/images/shadow.png') no-repeat bottom left; + padding: 0 0 9px 8px; + border-top-right-radius: 0; + border-bottom-left-radius: 0; + -moz-border-radius-topright: 0; + -moz-border-radius-bottomleft: 0; + -webkit-border-top-right-radius: 0; + -webkit-border-bottom-left-radius: 0; + -moz-border-radius-topleft: 17px; + -moz-border-radius-bottomright: 17px; + -webkit-border-top-left-radius: 17px; + -webkit-border-bottom-right-radius: 17px; + border-top-left-radius: 17px; + border-bottom-right-radius: 17px; +} + +/* RTL ThemeRoller ~~~~~~~~~~~~~~~~~~~~~~~~ */ + + .ui-dialog .ui-dialog-titlebar { + padding: 0.5em 1em 0.3em 0.3em; +} + + .ui-dialog .ui-dialog-title { + float: right; +} + + .ui-dialog .ui-dialog-titlebar-close { + left: 0.3em; + right: auto; +} + +/* RTL paginator ~~~~~~~~~~~~~~~~~~~~~~~~~~ */ + + .g-paginator .g-info { + width: 35%; +} + + .g-paginator .g-text-right { + margin-left: 0; +} + + .g-paginator .ui-icon-seek-end { + background-position: -80px -160px; +} + + .g-paginator .ui-icon-seek-next { + background-position: -48px -160px; +} + + .g-paginator .ui-icon-seek-prev { + background-position: -32px -160px; +} + + .g-paginator .ui-icon-seek-first { + background-position: -64px -160px; +} + + #g-header #g-login-menu, + #g-header #g-quick-search-form { + clear: left; + float: left; +} + + #g-header #g-login-menu li { + margin-left: 0; + padding-left: 0; + padding-right: 1.2em; +} + + #g-site-menu { + left: auto; + right: 150px; +} + + #g-view-menu #g-slideshow-link { + background-image: url('../images/ico-view-slideshow-rtl.png'); +} + + #g-sidebar .g-block-content { + padding-right: 1em; + padding-left: 0; +} + + #g-footer #g-credits li { + padding-left: 1.2em !important; + padding-right: 0; +} diff --git a/3.0/modules/themeroller/views/site_screen.css.php b/3.0/modules/themeroller/views/site_screen.css.php index 933f8c48..315611f8 100644 --- a/3.0/modules/themeroller/views/site_screen.css.php +++ b/3.0/modules/themeroller/views/site_screen.css.php @@ -15,7 +15,6 @@ * 8) jQuery and jQuery UI * 9) Organize module style * 10) Tag module styles - * 11) Right-to-left language styles */ /** ******************************************************************* @@ -1217,323 +1216,3 @@ div#g-action-status { color: #f30; text-decoration: underline; } - -/** ******************************************************************* - * 11) Right to left language styles - *********************************************************************/ - -.rtl { - direction: rtl; -} - -.rtl #g-header, -.rtl #g-content, -.rtl #g-sidebar, -.rtl #g-footer, -.rtl caption, -.rtl th, -.rtl #g-dialog, -.rtl .g-context-menu li a, -.rtl .g-message-box li, -.rtl #g-site-status li { - text-align: right; -} - -.rtl .g-text-right { - text-align: left; -} - -.rtl .g-error, -.rtl .g-info, -.rtl .g-success, -.rtl .g-warning, -.rtl #g-add-photos-status .g-success, -.rtl #g-add-photos-status .g-error { - background-position: center right; - padding-right: 30px !important; -} - -.rtl form li.g-error, -.rtl form li.g-info, -.rtl form li.g-success, -.rtl form li.g-warning { - padding-right: 0 !important; -} - -.rtl .g-left, -.rtl .g-inline li, -.rtl #g-content #g-album-grid .g-item, -.rtl .sf-menu li, -.rtl .g-breadcrumbs li, -.rtl .g-paginator li, -.rtl .g-buttonset li, -.rtl .ui-icon-left .ui-icon, -.rtl .g-short-form li, -.rtl form ul ul li, -.rtl input[type="submit"], -.rtl input[type="reset"], -.rtl input.checkbox, -.rtl input[type=checkbox], -.rtl input.radio, -.rtl input[type=radio] { - float: right; -} - -.rtl .g-right, -.rtl .ui-icon-right .ui-icon { - float: left; -} - -.rtl .g-inline li { - margin-right: 1em; -} - -.rtl .g-inline li.g-first { - margin-right: 0; -} - -.rtl .g-breadcrumbs li { - background: transparent url('../images/ico-separator-rtl.png') no-repeat scroll right center; - padding: 1em 18px 1em 8px; -} - -.rtl .g-breadcrumbs .g-first { - background: none; - padding-right: 0; -} - -.rtl input.checkbox { - margin-left: .4em; -} - -.rtl #g-add-comment { - right: inherit; - left: 0; -} - -.rtl .ui-icon-left .ui-icon { - margin-left: .2em; -} - -.rtl .ui-icon-right .ui-icon { - margin-right: .2em; -} - -/* RTL Corner radius ~~~~~~~~~~~~~~~~~~~~~~ */ -.rtl .g-buttonset .ui-corner-tl { - -moz-border-radius-topleft: 0; - -webkit-border-top-left-radius: 0; - border-top-left-radius: 0; - -moz-border-radius-topright: 5px !important; - -webkit-border-top-right-radius: 5px !important; - border-top-right-radius: 5px !important; -} - -.rtl .g-buttonset .ui-corner-tr { - -moz-border-radius-topright: 0; - -webkit-border-top-right-radius: 0; - border-top-right-radius: 0; - -moz-border-radius-topleft: 5px !important; - -webkit-border-top-left-radius: 5px !important; - border-top-left-radius: 5px !important; -} - -.rtl .g-buttonset .ui-corner-bl { - -moz-border-radius-bottomleft: 0; - -webkit-border-bottom-left-radius: 0; - border-bottom-left-radius: 0; - -moz-border-radius-bottomright: 5px !important; - -webkit-border-bottom-right-radius: 5px !important; - border-bottom-right-radius: 5px !important; -} - -.rtl .g-buttonset .ui-corner-br { - -moz-border-radius-bottomright: 0; - -webkit-border-bottom-right-radius: 0; - border-bottom-right-radius: 0; - -moz-border-radius-bottomleft: 5px !important; - -webkit-border-bottom-left-radius: 5px !important; - border-bottom-left-radius: 5px !important; -} - -.rtl .g-buttonset .ui-corner-right, -.rtl .ui-progressbar .ui-corner-right { - -moz-border-radius-topright: 0; - -webkit-border-top-right-radius: 0; - border-top-right-radius: 0; - -moz-border-radius-topleft: 5px !important; - -webkit-border-top-left-radius: 5px !important; - border-top-left-radius: 5px !important; - -moz-border-radius-bottomright: 0; - -webkit-border-bottom-right-radius: 0; - border-bottom-right-radius: 0; - -moz-border-radius-bottomleft: 5px !important; - -webkit-border-bottom-left-radius: 5px !important; - border-bottom-left-radius: 5px !important; -} - -.rtl .g-buttonset .ui-corner-left, -.rtl .ui-progressbar .ui-corner-left { - -moz-border-radius-topleft: 0; - -webkit-border-top-left-radius: 0; - border-top-left-radius: 0; - -moz-border-radius-topright: 5px !important; - -webkit-border-top-right-radius: 5px !important; - border-top-right-radius: 5px !important; - -moz-border-radius-bottomleft: 0; - -webkit-border-bottom-left-radius: 0; - border-bottom-left-radius: 0; - -moz-border-radius-bottomright: 5px !important; - -webkit-border-bottom-right-radius: 5px !important; - border-bottom-right-radius: 5px !important; -} - -/* RTL Superfish ~~~~~~~~~~~~~~~~~~~~~~~~~ */ - -.rtl .sf-menu a { - border-left: none; - border-right:1px solid #; -} - -.rtl .sf-menu a.sf-with-ul { - padding-left: 2.25em; - padding-right: 1em; -} - -.rtl .sf-sub-indicator { - left: .75em !important; - right: auto; - background: url("themeroller/images/ui-icons__256x240.png") no-repeat -10px -100px; /* 8-bit indexed alpha png. IE6 gets solid image only */ -} - -.rtl a > .sf-sub-indicator { /* give all except IE6 the correct values */ - top: .8em; - background-position: -10px -100px; /* use translucent arrow for modern browsers*/ -} -/* apply hovers to modern browsers */ -.rtl a:focus > .sf-sub-indicator, -.rtl a:hover > .sf-sub-indicator, -.rtl a:active > .sf-sub-indicator, -.rtl li:hover > a > .sf-sub-indicator, -.rtl li.sfHover > a > .sf-sub-indicator { - background-position: 0 -100px; /* arrow hovers for modern browsers*/ -} - -/* point right for anchors in subs */ -.rtl .sf-menu ul .sf-sub-indicator { background-position: 0 0; } -.rtl .sf-menu ul a > .sf-sub-indicator { background-position: -10px 0; } -/* apply hovers to modern browsers */ -.rtl .sf-menu ul a:focus > .sf-sub-indicator, -.rtl .sf-menu ul a:hover > .sf-sub-indicator, -.rtl .sf-menu ul a:active > .sf-sub-indicator, -.rtl .sf-menu ul li:hover > a > .sf-sub-indicator, -.rtl .sf-menu ul li.sfHover > a > .sf-sub-indicator { - background-position: 0 0; /* arrow hovers for modern browsers*/ -} - -.rtl .sf-menu li:hover ul, -.rtl .sf-menu li.sfHover ul { - right: 0; - left: auto; -} - -.rtl ul.sf-menu li li:hover ul, -.rtl ul.sf-menu li li.sfHover ul { - right: 12em; /* match ul width */ - left: auto; -} -.rtl ul.sf-menu li li li:hover ul, -.rtl ul.sf-menu li li li.sfHover ul { - right: 12em; /* match ul width */ - left: auto; -} - -/*** shadows for all but IE6 ***/ -.rtl .sf-shadow ul { - background: url('../../../lib/superfish/images/shadow.png') no-repeat bottom left; - padding: 0 0 9px 8px; - border-top-right-radius: 0; - border-bottom-left-radius: 0; - -moz-border-radius-topright: 0; - -moz-border-radius-bottomleft: 0; - -webkit-border-top-right-radius: 0; - -webkit-border-bottom-left-radius: 0; - -moz-border-radius-topleft: 17px; - -moz-border-radius-bottomright: 17px; - -webkit-border-top-left-radius: 17px; - -webkit-border-bottom-right-radius: 17px; - border-top-left-radius: 17px; - border-bottom-right-radius: 17px; -} - -/* RTL ThemeRoller ~~~~~~~~~~~~~~~~~~~~~~~~ */ - -.rtl .ui-dialog .ui-dialog-titlebar { - padding: 0.5em 1em 0.3em 0.3em; -} - -.rtl .ui-dialog .ui-dialog-title { - float: right; -} - -.rtl .ui-dialog .ui-dialog-titlebar-close { - left: 0.3em; - right: auto; -} - -/* RTL paginator ~~~~~~~~~~~~~~~~~~~~~~~~~~ */ - -.rtl .g-paginator .g-info { - width: 35%; -} - -.rtl .g-paginator .g-text-right { - margin-left: 0; -} - -.rtl .g-paginator .ui-icon-seek-end { - background-position: -80px -160px; -} - -.rtl .g-paginator .ui-icon-seek-next { - background-position: -48px -160px; -} - -.rtl .g-paginator .ui-icon-seek-prev { - background-position: -32px -160px; -} - -.rtl .g-paginator .ui-icon-seek-first { - background-position: -64px -160px; -} - -.rtl #g-header #g-login-menu, -.rtl #g-header #g-quick-search-form { - clear: left; - float: left; -} - -.rtl #g-header #g-login-menu li { - margin-left: 0; - padding-left: 0; - padding-right: 1.2em; -} - -.rtl #g-site-menu { - left: auto; - right: 150px; -} - -.rtl #g-view-menu #g-slideshow-link { - background-image: url('../images/ico-view-slideshow-rtl.png'); -} - -.rtl #g-sidebar .g-block-content { - padding-right: 1em; - padding-left: 0; -} - -.rtl #g-footer #g-credits li { - padding-left: 1.2em !important; - padding-right: 0; -} diff --git a/3.0/modules/themeroller/views/theme.info.php b/3.0/modules/themeroller/views/theme.info.php index eb8ead8f..ba061661 100644 --- a/3.0/modules/themeroller/views/theme.info.php +++ b/3.0/modules/themeroller/views/theme.info.php @@ -1,9 +1,12 @@ -name = "" -description = "" +name = for_js() . "\n" ?> +description = for_js() . "\n" ?> version = 1 -author = "" -site = "" -admin = "" +author = for_js() . "\n" ?> +site = +admin = +author_url = for_js() . "\n" ?> +info_url = for_js() . "\n" ?> +discuss_url = for_js() . "\n" ?> ; definition = diff --git a/3.0/modules/transcode/controllers/admin_transcode.php b/3.0/modules/transcode/controllers/admin_transcode.php new file mode 100644 index 00000000..b91b1284 --- /dev/null +++ b/3.0/modules/transcode/controllers/admin_transcode.php @@ -0,0 +1,166 @@ + 0) { + module::set_var("transcode", "ffmpeg_path", $_REQUEST['ffmpeg_path']); + $data['success'] = true; + $data['codecs'] = self::_get_supported_audio_codecs($_REQUEST['ffmpeg_path']); + } + else { + $error = ""; + switch ($val) { + case 0: $error = "Empty file path provided"; break; + case -1: $error = "File does not exist"; break; + case -2: $error = "Path is a directory"; break; + default: $error = "Unspecified error"; + } + $data['error'] = $error; + } + echo json_encode($data); + } + + public function index() { + $form = $this->_get_form(); + + if (request::method() == "post") { + access::verify_csrf(); + + if ($form->validate()) { + module::set_var("transcode", "ffmpeg_path", $_POST['ffmpeg_path']); + module::set_var("transcode", "ffmpeg_flags", $_POST['ffmpeg_flags']); + module::set_var("transcode", "audio_codec", $_POST['audio_codec']); + module::set_var("transcode", "ffmpeg_audio_kbits", (isset($_POST['ffmpeg_audio_kbits']) ? $_POST['ffmpeg_audio_kbits'] : false)); + + module::set_var("transcode", "resolution_240p", (isset($_POST['resolution_240p']) ? $_POST['resolution_240p'] : false)); + module::set_var("transcode", "resolution_360p", (isset($_POST['resolution_360p']) ? $_POST['resolution_360p'] : false)); + module::set_var("transcode", "resolution_480p", (isset($_POST['resolution_480p']) ? $_POST['resolution_480p'] : false)); + module::set_var("transcode", "resolution_576p", (isset($_POST['resolution_576p']) ? $_POST['resolution_576p'] : false)); + module::set_var("transcode", "resolution_720p", (isset($_POST['resolution_720p']) ? $_POST['resolution_720p'] : false)); + module::set_var("transcode", "resolution_1080p", (isset($_POST['resolution_1080p']) ? $_POST['resolution_1080p'] : false)); + + message::success(t("Settings have been saved")); + url::redirect("admin/transcode"); + } + else { + message::error(t("There was a problem with the submitted form. Please check your values and try again.")); + } + } + + print $this->_get_view(); + } + + private function _get_view($form = null) { + $v = new Admin_View("admin.html"); + $v->page_title = t("Gallery 3 :: Manage Transcoding Settings"); + + $v->content = new View("admin_transcode.html"); + $v->content->form = empty($form) ? $this->_get_form() : $form; + + return $v; + } + + private function _get_supported_audio_codecs($given_path = null) { + + $flv_compatible_codecs = array("aac" => "aac", "adpcm_swf" => "adpcm_swf", "mp3" => "libmp3lame"); + + if ($given_path) + $ffmpegPath = $given_path; + else + $ffmpegPath = module::get_var("transcode", "ffmpeg_path", transcode::whereis("ffmpeg")); + + $legacy = false; + exec($ffmpegPath . " -codecs", $codecs); + if (count($codecs) == 0) { + $legacy = true; + exec($ffmpegPath . " -formats 2>&1", $codecs); + } + + $search = true; + if ($legacy) $search = false; + + $found = array(); + foreach ($codecs as $line) { + if ($search) { + if (strpos($line, "DEA")) { + $bits = preg_split("/[\s]+/", $line); + if (in_array($bits[2], $flv_compatible_codecs)) { + $key = array_search($bits[2], $flv_compatible_codecs); + $found[$key] = $flv_compatible_codecs[$key]; + } + } + } + + if ($legacy && strpos($line, "Codecs:") !== false) { + $search = true; + continue; + } + if ($legacy && $search && strpos($line, "Bitstream filters:")) { + $search = false; + continue; + } + } + return $found; + } + + private function _get_form() { + $form = new Forge("admin/transcode", "", "post", array("id" => "g-admin-transcode-form")); + + $group = $form->group("system")->label(t("System")); + + $ffmpegPath = transcode::whereis("ffmpeg"); + $codecs = $this->_get_supported_audio_codecs(); + + $group ->input("ffmpeg_path") + ->id("ffmpeg_path") + ->label(t("Path to ffmpeg binary:")) + ->value(module::get_var("transcode", "ffmpeg_path", $ffmpegPath)) + ->callback("transcode::verify_ffmpeg_path") + ->error_messages("required", t("You must enter the path to ffmpeg")) + ->error_messages("invalid", t("File does not exist")) + ->error_messages("is_dir", t("File is a directory")) + ->message("Auto detected ffmpeg here: " . $ffmpegPath . "
    Click here to verify ffmpeg path and continue."); + + $group ->input("ffmpeg_flags") + ->id("ffmpeg_flags") + ->label(t("Extra ffmpeg flags:")) + ->value(module::get_var("transcode", "ffmpeg_flags")); + + $group ->dropdown("audio_codec") + ->id("audio_codec") + ->label(t("Audio codec to use:")) + ->options($codecs) + ->selected(module::get_var("transcode", "audio_codec")); + + $group ->checkbox("ffmpeg_audio_kbits") + ->label(t("Send audio bitrate as kbits instead of bits/s")) + ->checked(module::get_var("transcode", "ffmpeg_audio_kbits")); + + $group = $form->group("resolutions")->label(t("Resolutions")); + + $group ->checkbox("resolution_240p") + ->label("240p") + ->checked(module::get_var("transcode", "resolution_240p")); + $group ->checkbox("resolution_360p") + ->label("360p") + ->checked(module::get_var("transcode", "resolution_360p")); + $group ->checkbox("resolution_480p") + ->label("480p") + ->checked(module::get_var("transcode", "resolution_480p")); + $group ->checkbox("resolution_576p") + ->label("576p") + ->checked(module::get_var("transcode", "resolution_576p")); + $group ->checkbox("resolution_720p") + ->label("720p") + ->checked(module::get_var("transcode", "resolution_720p")); + $group ->checkbox("resolution_1080p") + ->label("1080p") + ->checked(module::get_var("transcode", "resolution_1080p")); + + $form->submit("submit")->value(t("Save")); + return $form; + } +} diff --git a/3.0/modules/transcode/helpers/transcode.php b/3.0/modules/transcode/helpers/transcode.php new file mode 100644 index 00000000..f6026ec2 --- /dev/null +++ b/3.0/modules/transcode/helpers/transcode.php @@ -0,0 +1,59 @@ +value); + switch ($v) { + case 0: $field->add_error("required", 1); break; + case -1: $field->add_error("invalid", 1); break; + case -2: $field->add_error("is_dir", 1); break; + } + } + + static function log($item) { + + if (is_string($item) || is_numeric($item)) {} + else + $item = print_r($item, true); + + $fh = fopen(VARPATH . "modules/transcode/log/transcode.log", "a"); + fwrite($fh, date("Y-m-d H:i:s") . ": " . $item . "\n"); + fclose($fh); + + } + +} diff --git a/3.0/modules/transcode/helpers/transcode_event.php b/3.0/modules/transcode/helpers/transcode_event.php new file mode 100644 index 00000000..774f1275 --- /dev/null +++ b/3.0/modules/transcode/helpers/transcode_event.php @@ -0,0 +1,204 @@ +get("settings_menu") + ->append(Menu::factory("link") + ->id("transcode_menu") + ->label(t("Video Transcoding")) + ->url(url::site("admin/transcode"))); + } + + static function item_deleted($item) { + if ($item->is_movie()) { + transcode::log("Deleting transcoded files for item " . $item->id); + if (is_dir(VARPATH . "modules/transcode/flv/" . $item->id)) { + self::rrmdir(VARPATH . "modules/transcode/flv/" . $item->id); + } + db::build()->delete("transcode_resolutions")->where("item_id", "=", $item->id)->execute(); + } + } + + static function rrmdir($dir) { + if (is_dir($dir)) { + $objects = scandir($dir); + foreach ($objects as $object) { + if ($object != "." && $object != "..") { + if (filetype($dir."/".$object) == "dir") + self::rrmdir($dir."/".$object); + else + unlink($dir."/".$object); + } + } + reset($objects); + rmdir($dir); + } + } + + private static function _getVideoInfo($file) { + $ffmpegPath = module::get_var("transcode", "ffmpeg_path"); + + $op = array(); + @exec($ffmpegPath . ' -i "' . $file . '" 2>&1', $op); + + $file = new stdclass(); + $file->video = new stdclass(); + $file->audio = new stdclass(); + $file->audio->has = false; + + foreach ($op as $line) { + transcode::log($line); + + if (preg_match('/Duration\: (\d{2}):(\d{2}):(\d{2})\.(\d{2})/', $line, $matches)) { + $file->video->duration = $matches[3] . "." . $matches[4]; + $file->video->duration += $matches[2] * 60; + $file->video->duration += $matches[1] * 3600; + } + else if (preg_match('/Stream #0\.\d(\(\w*\))?\: Video\:/', $line)) { + $bits = preg_split('/[\s]+/', $line); + + for ($i = 0; $i < count($bits); $i++) { + if ($bits[$i] == "fps,") $file->video->fps = $bits[$i - 1]; + else if ($bits[$i] == "kb/s,") $file->video->bitrate = $bits[$i - 1] * 1024; + } + + $file->video->codec = $bits[4]; + list($file->video->width, $file->video->height) = explode('x', $bits[6]); + } + else if (preg_match('/Stream #0\.\d(\(\w*\))?+\: Audio\: (\w*)\,/', $line, $matches)) { + $file->audio->has = true; + $file->audio->codec = $matches[2]; + + if (preg_match('/(\d*) Hz/', $line, $hz)) + $file->audio->samplerate = $hz[1]; + if (preg_match('/(\d*) channels?/', $line, $channels)) + $file->audio->channels = $channels[1]; + if (preg_match('/(\d*) kb\/s/', $line, $bitrate)) + $file->audio->bitrate = $bitrate[1]; + } + } + + return $file; + } + + static function item_created($item) { + if ($item->is_movie()) { + transcode::log("Item created - is a movie. Let's create a transcode task or 2.."); + $ffmpegPath = module::get_var("transcode", "ffmpeg_path"); + + $fileObj = self::_getVideoInfo($item->file_path()); + transcode::log($fileObj); + + // Save our needed variables + $srcFile = $item->file_path(); + $srcWidth = transcode::makeMultipleTwo($fileObj->video->width); + $srcHeight = transcode::makeMultipleTwo($fileObj->video->height); + $aspect = $srcWidth / $srcHeight; + + $srcFPS = $fileObj->video->fps; + + $srcAR = $fileObj->audio->samplerate; + if ($srcAR > 44100) $srcAR = 44100; + + $accepted_sample_rates = array(11025, 22050, 44100); + + if (!in_array($srcAR, $accepted_sample_rates)) { + // if the input sample rate isn't an accepted rate, find the next lowest rate that is + $below = true; $rate = 0; + if ($srcAR < 11025) { + $rate = 11025; + } + else { + foreach ($accepted_sample_rates as $r) { + transcode::log("testing audio rate '" . $r . "' against input rate '" . $srcAR . "'"); + if ($r < $srcAR) { + $rate = $r; + } + } + } + $srcAR = $rate; + } + + $srcACodec = module::get_var("transcode", "audio_codec"); + + $heights = array(); + if (module::get_var("transcode", "resolution_240p")) array_push($heights, 240); + if (module::get_var("transcode", "resolution_360p")) array_push($heights, 360); + if (module::get_var("transcode", "resolution_480p")) array_push($heights, 480); + if (module::get_var("transcode", "resolution_576p")) array_push($heights, 576); + if (module::get_var("transcode", "resolution_720p")) array_push($heights, 720); + if (module::get_var("transcode", "resolution_1080p")) array_push($heights, 1080); + + if (!is_dir(VARPATH . "modules/transcode/flv/" . $item->id)) + @mkdir(VARPATH . "modules/transcode/flv/" . $item->id); + + $xtraFlags = module::get_var("transcode", "ffmpeg_flags", ""); + + foreach ($heights as $destHeight) { + transcode::log("srcHeight: " . $srcHeight . ", destheight: " . $destHeight); + + // don't bother upscaling, there's no advantage to it... + if ($destHeight > $srcHeight) continue; + + $destFormat = module::get_var("transcode", "format", "flv"); + $destWidth = floor($destHeight * $aspect); + if ($destWidth % 2) + $destWidth = ceil($destHeight * $aspect); + + transcode::log("destination resolution: " . $destWidth . "x" . $destHeight); + + $destFile = VARPATH . "modules/transcode/flv/" . $item->id . "/" . $destWidth . "x" . $destHeight . ".flv"; + + switch ($destHeight) { + case 240: $destVB = 128; $srcAB = 16 * ($fileObj->audio->channels ? $fileObj->audio->channels : 2); break; + case 360: $destVB = 384; $srcAB = 16 * ($fileObj->audio->channels ? $fileObj->audio->channels : 2); break; + case 480: $destVB = 1024; $srcAB = 32 * ($fileObj->audio->channels ? $fileObj->audio->channels : 2); break; + case 576: $destVB = 2048; $srcAB = 32 * ($fileObj->audio->channels ? $fileObj->audio->channels : 2); break; + case 720: $destVB = 4096; $srcAB = 64 * ($fileObj->audio->channels ? $fileObj->audio->channels : 2); break; + case 1080; $destVB = 8192; $srcAB = 64 * ($fileObj->audio->channels ? $fileObj->audio->channels : 2); break; + } + $destVB *= 1024; + $srcAB *= 1024; + + $cmd = + $ffmpegPath . " " . + "-i \"" . $srcFile . "\" "; + if ($fileObj->audio->has) + $cmd .= + "-y -acodec " . $srcACodec . " " . + "-ar " . $srcAR . " " . + "-ab " . $srcAB . " "; + else + $cmd .= + "-an "; + + $cmd .= + "-vb " . $destVB . " " . + "-f " . $destFormat . " " . + "-s " . $destWidth . "x" . $destHeight . " " . + $xtraFlags . " " . + "\"" . $destFile . "\""; + + transcode::log($cmd); + + $task_def = + Task_Definition::factory() + ->callback("transcode_task::transcode") + ->name("Video Transcode to " . $destWidth . "x" . $destHeight) + ->severity(log::SUCCESS); + + $task = + task::create($task_def, + array("ffmpeg_cmd" => $cmd, + "width" => $destWidth, + "height" => $destHeight, + "item_id" => $item->id) + ); + + task::run($task->id); + } + } + } +} diff --git a/3.0/modules/transcode/helpers/transcode_installer.php b/3.0/modules/transcode/helpers/transcode_installer.php new file mode 100644 index 00000000..6501e4f0 --- /dev/null +++ b/3.0/modules/transcode/helpers/transcode_installer.php @@ -0,0 +1,42 @@ +query("CREATE TABLE IF NOT EXISTS {transcode_resolutions} ( + `id` int(9) NOT NULL auto_increment, + `item_id` int(9) NOT NULL, + `resolution` varchar(16) NOT NULL, + PRIMARY KEY (`id`) + ) DEFAULT CHARSET=utf8;"); + + @mkdir(VARPATH . "modules/transcode"); + @mkdir(VARPATH . "modules/transcode/log"); + @mkdir(VARPATH . "modules/transcode/flv"); + + self::setversion(); + } + static function uninstall() { + Database::instance()->query("DROP TABLE {transcode_resolutions}"); + dir::unlink(VARPATH . "modules/transcode"); + } + + static function upgrade($version) { + if ($version < self::getversion()) + self::setversion(); + } + + static function deactivate() {} + static function activate() {} + static function can_activate() { + $messages = array(); + if (!function_exists("exec")) { + $messages["warn"][] = t("exec() is required to auto-detect the ffmpeg binary. You must specify the path to the ffmpeg binary manually before you can convert videos."); + } + return $messages; + } +} diff --git a/3.0/modules/transcode/helpers/transcode_task.php b/3.0/modules/transcode/helpers/transcode_task.php new file mode 100644 index 00000000..da51bc27 --- /dev/null +++ b/3.0/modules/transcode/helpers/transcode_task.php @@ -0,0 +1,109 @@ +id . " started."); + + $cmd = $task->get("ffmpeg_cmd"); + + $logfile = VARPATH . "modules/transcode/log/" . time() . ".log"; + $task->set("logfile", $logfile); + + $output = ""; + $return_val = 0; + self::fork($cmd, $logfile); + + // wait for ffmpeg to fire up.. + sleep(2); + + while ($time = self::GetEncodedTime($logfile)) { + transcode::log("encoded time: " . $time); + + if (self::$duration > 0) { + $task->state = "encoding"; + $task->status = "Encoding..."; + $pct = sprintf("%0.0f", ($time / self::$duration) * 100); + $task->percent_complete = $pct; + $task->save(); + } + usleep(500000); + } + + $output = @file_get_contents($logfile); + + transcode::log("ffmpeg job completed."); + + if ($output) { + $task->percent_complete = 100; + $task->done = true; + $task->state = "success"; + $task->status = "Transcoding complete."; + + transcode::log("insert into transcode table to indicate success"); + $res = ORM::factory('transcode_resolution'); + $res->resolution = $task->get("width") . "x" . $task->get("height"); + $res->item_id = $task->get("item_id"); + $res->save(); + } + else { + transcode::log("Error transcoding. ffmpeg output:"); + transcode::log($output); + $task->percent_complete = 100; + $task->done = true; + $task->state = "error"; + $task->status = "Transcoding error."; + } + $task->save(); + + } + + static function fork($shellCmd, $logfile) { + $cmd = "nice " . $shellCmd . " > " . $logfile . " 2>&1 &"; + transcode::log("executing: " . $cmd); + exec($cmd); + } + + static function GetEncodedTime($logfile) { + if (!file_exists($logfile)) { + transcode::log("can't open FFMPEG-Log '" . $logfile . "'"); + return false; + } + else { + $FFMPEGLog = @file_get_contents($logfile); + + $dPos = strpos($FFMPEGLog, " Duration: "); + self::$duration = self::durationToSecs(substr($FFMPEGLog, $dPos + 11, 11)); + + $FFMPEGLog = str_replace("\r", "\n", $FFMPEGLog); + + $lines = explode("\n", $FFMPEGLog); + $line = $lines[count($lines) - 2]; + + if ($tpos = strpos($line, "time=")) { + $bpos = strpos($line, " bitrate="); + + $time = substr($line, $tpos + 5, $bpos - ($tpos + 5)); + return $time; + } + else { + return false; + } + } + } + + static function durationToSecs($durstr) { + list($hr, $min, $sec) = explode(":", $durstr); + + $secs = $hr * 3600; + $secs += $min * 60; + $secs += $sec; + + return $secs; + } +} diff --git a/3.0/modules/transcode/helpers/transcode_theme.php b/3.0/modules/transcode/helpers/transcode_theme.php new file mode 100644 index 00000000..371576ac --- /dev/null +++ b/3.0/modules/transcode/helpers/transcode_theme.php @@ -0,0 +1,19 @@ +css_id = "g-resolutions"; + $block->title = t("Alternative Resolutions"); + + $view = new View("transcode_resolution_variants.html"); + $view->item = $theme->item(); + $view->resolutions = ORM::factory("transcode_resolution")->where("item_id", "=", $view->item->id)->find_all(); + + $block->content = $view; + return $block; + } + +} \ No newline at end of file diff --git a/3.1/themes/greydragon/views/exif_sidebar.html.php b/3.0/modules/transcode/models/transcode_resolution.php similarity index 53% rename from 3.1/themes/greydragon/views/exif_sidebar.html.php rename to 3.0/modules/transcode/models/transcode_resolution.php index 115bfc86..f02cf11c 100644 --- a/3.1/themes/greydragon/views/exif_sidebar.html.php +++ b/3.0/modules/transcode/models/transcode_resolution.php @@ -1 +1,4 @@ + + +
    +

    + +

    + +
    + +
    +
    + + diff --git a/3.0/modules/transcode/views/transcode_resolution_variants.html.php b/3.0/modules/transcode/views/transcode_resolution_variants.html.php new file mode 100644 index 00000000..6c1b5256 --- /dev/null +++ b/3.0/modules/transcode/views/transcode_resolution_variants.html.php @@ -0,0 +1,29 @@ + + +is_movie()): ?> + 0): ?> + + + +

    No alternative resolutions available.

    + + diff --git a/3.0/modules/transliterate/helpers/transliterate.php b/3.0/modules/transliterate/helpers/transliterate.php new file mode 100644 index 00000000..fb15cf26 --- /dev/null +++ b/3.0/modules/transliterate/helpers/transliterate.php @@ -0,0 +1,6515 @@ + "C", "£" => "PS", "Â¥" => "Y=", "§" => "SS", "©" => "(c)", "ª" => "a", + "®" => "(r)", "°" => "deg", "²" => "2", "³" => "3", "µ" => "u", "¶" => "P", + "¹" => "1", "º" => "o", "¼" => "1/4", "½" => "1/2", "¾" => "3/4", "À" => "A", + "Ã" => "A", "Â" => "A", "Ã" => "A", "Ä" => "A", "Ã…" => "A", "Æ" => "AE", + "Ç" => "C", "È" => "E", "É" => "E", "Ê" => "E", "Ë" => "E", "ÃŒ" => "I", + "Ã" => "I", "ÃŽ" => "I", "Ã" => "I", "Ã" => "D", "Ñ" => "N", "Ã’" => "O", + "Ó" => "O", "Ô" => "O", "Õ" => "O", "Ö" => "O", "×" => "x", "Ø" => "O", + "Ù" => "U", "Ú" => "U", "Û" => "U", "Ãœ" => "U", "Ã" => "U", "Þ" => "Th", + "ß" => "ss", "à" => "a", "á" => "a", "â" => "a", "ã" => "a", "ä" => "a", + "Ã¥" => "a", "æ" => "ae", "ç" => "c", "è" => "e", "é" => "e", "ê" => "e", + "ë" => "e", "ì" => "i", "í" => "i", "î" => "i", "ï" => "i", "ð" => "d", + "ñ" => "n", "ò" => "o", "ó" => "o", "ô" => "o", "õ" => "o", "ö" => "o", + "ø" => "o", "ù" => "u", "ú" => "u", "û" => "u", "ü" => "u", "ý" => "y", + "þ" => "th", "ÿ" => "y", "Ä" => "a", "Ä‚" => "A", "ă" => "a", "Ä„" => "A", + "Ä…" => "a", "Ć" => "C", "ć" => "c", "Ĉ" => "C", "ĉ" => "c", "ÄŠ" => "C", + "Ä‹" => "c", "ÄŒ" => "C", "Ä" => "c", "ÄŽ" => "D", "Ä" => "d", "Ä" => "D", + "Ä‘" => "d", "Ä’" => "E", "Ä“" => "e", "Ä”" => "E", "Ä•" => "e", "Ä–" => "E", + "Ä—" => "e", "Ę" => "E", "Ä™" => "e", "Äš" => "E", "Ä›" => "e", "Äœ" => "G", + "Ä" => "g", "Äž" => "G", "ÄŸ" => "g", "Ä " => "G", "Ä¡" => "g", "Ä¢" => "G", + "Ä£" => "g", "Ĥ" => "H", "Ä¥" => "h", "Ħ" => "H", "ħ" => "h", "Ĩ" => "I", + "Ä©" => "i", "Ī" => "I", "Ä«" => "i", "Ĭ" => "I", "Ä­" => "i", "Ä®" => "I", + "į" => "i", "Ä°" => "I", "ı" => "i", "IJ" => "IJ", "Ä´" => "J", "ĵ" => "j", + "Ķ" => "K", "Ä·" => "k", "ĸ" => "k", "Ĺ" => "L", "ĺ" => "l", "Ä»" => "L", + "ļ" => "l", "Ľ" => "L", "ľ" => "l", "Ä¿" => "L", "Å€" => "l", "Å" => "L", + "Å‚" => "l", "Ń" => "N", "Å„" => "n", "Å…" => "N", "ņ" => "n", "Ň" => "N", + "ň" => "n", "ʼn" => "'n", "ÅŠ" => "ng", "Å‹" => "NG", "ÅŒ" => "O", "Å" => "o", + "ÅŽ" => "O", "Å" => "o", "Å" => "O", "Å‘" => "o", "Å’" => "OE", "Å“" => "oe", + "Å”" => "R", "Å•" => "r", "Å–" => "R", "Å—" => "r", "Ř" => "R", "Å™" => "r", + "Åš" => "S", "Å›" => "s", "Åœ" => "S", "Å" => "s", "Åž" => "S", "ÅŸ" => "s", + "Å " => "S", "Å¡" => "s", "Å¢" => "T", "Å£" => "t", "Ť" => "T", "Å¥" => "t", + "Ŧ" => "T", "ŧ" => "t", "Ũ" => "U", "Å©" => "u", "Ū" => "U", "Å«" => "u", + "Ŭ" => "U", "Å­" => "u", "Å®" => "U", "ů" => "u", "Å°" => "U", "ű" => "u", + "Ų" => "U", "ų" => "u", "Å´" => "W", "ŵ" => "w", "Ŷ" => "Y", "Å·" => "y", + "Ÿ" => "Y", "Ź" => "Z", "ź" => "z", "Å»" => "Z", "ż" => "z", "Ž" => "Z", + "ž" => "z", "Å¿" => "s", "Æ€" => "b", "Æ" => "B", "Æ‚" => "B", "ƃ" => "b", + "Æ„" => "6", "Æ…" => "6", "Ɔ" => "O", "Ƈ" => "C", "ƈ" => "c", "Ɖ" => "D", + "ÆŠ" => "D", "Æ‹" => "D", "ÆŒ" => "d", "Æ" => "d", "ÆŽ" => "3", "Æ" => "E", + "Æ‘" => "F", "Æ’" => "f", "Æ“" => "G", "Æ”" => "G", "Æ•" => "hv", "Æ–" => "I", + "Æ—" => "I", "Ƙ" => "K", "Æ™" => "k", "Æš" => "l", "Æ›" => "l", "Æœ" => "W", + "Æ" => "N", "Æž" => "n", "ÆŸ" => "O", "Æ " => "O", "Æ¡" => "o", "Æ¢" => "OI", + "Æ£" => "oi", "Ƥ" => "P", "Æ¥" => "p", "Ʀ" => "YR", "Ƨ" => "2", "ƨ" => "2", + "Æ©" => "SH", "ƪ" => "sh", "Æ«" => "t", "Ƭ" => "T", "Æ­" => "t", "Æ®" => "T", + "Ư" => "U", "Æ°" => "u", "Ʊ" => "Y", "Ʋ" => "V", "Ƴ" => "Y", "Æ´" => "y", + "Ƶ" => "Z", "ƶ" => "z", "Æ·" => "ZH", "Ƹ" => "ZH", "ƹ" => "zh", "ƺ" => "zh", + "Æ»" => "2", "Ƽ" => "5", "ƽ" => "5", "ƾ" => "ts", "Æ¿" => "w", "Ç„" => "DZ", + "Ç…" => "Dz", "dž" => "dz", "LJ" => "LJ", "Lj" => "Lj", "lj" => "lj", "ÇŠ" => "NJ", + "Ç‹" => "Nj", "ÇŒ" => "nj", "Ç" => "A", "ÇŽ" => "a", "Ç" => "I", "Ç" => "i", + "Ç‘" => "O", "Ç’" => "o", "Ç“" => "U", "Ç”" => "u", "Ç•" => "U", "Ç–" => "u", + "Ç—" => "U", "ǘ" => "u", "Ç™" => "U", "Çš" => "u", "Ç›" => "U", "Çœ" => "u", + "Çž" => "A", "ÇŸ" => "a", "Ç " => "A", "Ç¡" => "a", "Ç¢" => "AE", "Ç£" => "ae", + "Ǥ" => "G", "Ç¥" => "g", "Ǧ" => "G", "ǧ" => "g", "Ǩ" => "K", "Ç©" => "k", + "Ǫ" => "O", "Ç«" => "o", "Ǭ" => "O", "Ç­" => "o", "Ç®" => "ZH", "ǯ" => "zh", + "Ç°" => "j", "DZ" => "DZ", "Dz" => "D", "dz" => "dz", "Ç´" => "G", "ǵ" => "g", + "Ƕ" => "HV", "Ç·" => "W", "Ǹ" => "N", "ǹ" => "n", "Ǻ" => "A", "Ç»" => "a", + "Ǽ" => "AE", "ǽ" => "ae", "Ǿ" => "O", "Ç¿" => "o", "È" => "a", "È‚" => "A", + "ȃ" => "a", "È„" => "E", "È…" => "e", "Ȇ" => "E", "ȇ" => "e", "Ȉ" => "I", + "ȉ" => "i", "ÈŠ" => "I", "È‹" => "i", "ÈŒ" => "O", "È" => "o", "ÈŽ" => "O", + "È" => "o", "È" => "R", "È‘" => "r", "È’" => "R", "È“" => "r", "È”" => "U", + "È•" => "u", "È–" => "U", "È—" => "u", "Ș" => "S", "È™" => "s", "Èš" => "T", + "È›" => "t", "Èœ" => "Y", "È" => "y", "Èž" => "H", "ÈŸ" => "h", "È¢" => "OU", + "È£" => "ou", "Ȥ" => "Z", "È¥" => "z", "Ȧ" => "A", "ȧ" => "a", "Ȩ" => "E", + "È©" => "e", "Ȫ" => "O", "È«" => "o", "Ȭ" => "O", "È­" => "o", "È®" => "O", + "ȯ" => "o", "È°" => "O", "ȱ" => "o", "Ȳ" => "Y", "ȳ" => "y", "É" => "a", + "É‘" => "a", "É’" => "a", "É“" => "b", "É”" => "o", "É•" => "c", "É–" => "d", + "É—" => "d", "ɘ" => "e", "É›" => "e", "Éœ" => "e", "É" => "e", "Éž" => "e", + "ÉŸ" => "j", "É " => "g", "É¡" => "g", "É¢" => "g", "É£" => "g", "ɤ" => "u", + "É¥" => "Y", "ɦ" => "h", "ɧ" => "h", "ɨ" => "i", "É©" => "i", "ɪ" => "I", + "É«" => "l", "ɬ" => "l", "É­" => "l", "É®" => "lZ", "ɯ" => "W", "É°" => "W", + "ɱ" => "m", "ɲ" => "n", "ɳ" => "n", "É´" => "n", "ɵ" => "o", "ɶ" => "OE", + "É·" => "O", "ɸ" => "F", "ɹ" => "R", "ɺ" => "R", "É»" => "R", "ɼ" => "R", + "ɽ" => "r", "ɾ" => "r", "É¿" => "R", "Ê€" => "R", "Ê" => "R", "Ê‚" => "s", + "ʃ" => "S", "Ê„" => "j", "Ê…" => "S", "ʆ" => "S", "ʇ" => "t", "ʈ" => "t", + "ʉ" => "U", "ÊŠ" => "U", "Ê‹" => "v", "Ê" => "W", "ÊŽ" => "Y", "Ê" => "Y", + "Ê" => "z", "Ê‘" => "z", "Ê’" => "Z", "Ê“" => "Z", "Ê—" => "C", "Ê™" => "B", + "Êš" => "E", "Ê›" => "G", "Êœ" => "H", "Ê" => "j", "Êž" => "k", "ÊŸ" => "L", + "Ê " => "q", "Ê£" => "dz", "ʤ" => "dZ", "Ê¥" => "dz", "ʦ" => "ts", "ʧ" => "tS", + "ʨ" => "tC", "Ê©" => "fN", "ʪ" => "ls", "Ê«" => "lz", "ʬ" => "WW", "Ê°" => "k", + "ʱ" => "h", "ʲ" => "j", "ʳ" => "r", "Ê´" => "r", "ʵ" => "r", "ʶ" => "r", + "Ê·" => "w", "ʸ" => "y", "Ë…" => "V", "ˇ" => "V", "Ë•" => "V", "˘" => "V", + "Ëž" => "R", "ËŸ" => "X", "Ë " => "G", "Ë¡" => "l", "Ë¢" => "s", "Ë£" => "x", + "ˬ" => "V", "Ά" => "A", "Έ" => "E", "Ή" => "E", "Ί" => "I", "ÎŒ" => "O", + "ÎŽ" => "U", "Î" => "O", "Î" => "I", "Α" => "A", "Î’" => "B", "Γ" => "G", + "Δ" => "D", "Ε" => "E", "Ζ" => "Z", "Η" => "E", "Θ" => "Th", "Ι" => "I", + "Κ" => "K", "Λ" => "L", "Îœ" => "M", "Î" => "N", "Ξ" => "Ks", "Ο" => "O", + "Π" => "P", "Ρ" => "R", "Σ" => "S", "Τ" => "T", "Î¥" => "U", "Φ" => "Ph", + "Χ" => "Kh", "Ψ" => "Ps", "Ω" => "O", "Ϊ" => "I", "Ϋ" => "U", "ά" => "a", + "έ" => "e", "ή" => "e", "ί" => "i", "ΰ" => "u", "α" => "a", "β" => "b", + "γ" => "g", "δ" => "d", "ε" => "e", "ζ" => "z", "η" => "e", "θ" => "th", + "ι" => "i", "κ" => "k", "λ" => "l", "μ" => "m", "ν" => "n", "ξ" => "x", + "ο" => "o", "Ï€" => "p", "Ï" => "r", "Ï‚" => "s", "σ" => "s", "Ï„" => "t", + "Ï…" => "u", "φ" => "ph", "χ" => "kh", "ψ" => "ps", "ω" => "o", "ÏŠ" => "i", + "Ï‹" => "u", "ÏŒ" => "o", "Ï" => "u", "ÏŽ" => "o", "Ï" => "b", "Ï‘" => "th", + "Ï’" => "U", "Ï“" => "U", "Ï”" => "U", "Ï•" => "ph", "Ï–" => "p", "Ïš" => "St", + "Ï›" => "st", "Ïœ" => "W", "Ï" => "w", "Ïž" => "Q", "ÏŸ" => "q", "Ï " => "Sp", + "Ï¡" => "sp", "Ï¢" => "Sh", "Ï£" => "sh", "Ϥ" => "F", "Ï¥" => "f", "Ϧ" => "Kh", + "ϧ" => "kh", "Ϩ" => "H", "Ï©" => "h", "Ϫ" => "G", "Ï«" => "g", "Ϭ" => "CH", + "Ï­" => "ch", "Ï®" => "Ti", "ϯ" => "ti", "Ï°" => "k", "ϱ" => "r", "ϲ" => "c", + "ϳ" => "j", "Ð" => "Io", "Ђ" => "Dj", "Ѓ" => "Gj", "Є" => "Ie", "Ð…" => "Dz", + "І" => "I", "Ї" => "Yi", "Ј" => "J", "Љ" => "Lj", "Њ" => "Nj", "Ћ" => "Tsh", + "ÐŒ" => "Kj", "Ð" => "I", "ÐŽ" => "U", "Ð" => "Dzh", "Ð" => "A", "Б" => "B", + "Ð’" => "V", "Г" => "G", "Д" => "D", "Е" => "Ie", "Ж" => "Zh", "З" => "Z", + "И" => "I", "Й" => "I", "К" => "K", "Л" => "L", "Ðœ" => "M", "Ð" => "N", + "О" => "O", "П" => "P", "Р" => "R", "С" => "S", "Т" => "T", "У" => "U", + "Ф" => "F", "Ð¥" => "Kh", "Ц" => "Ts", "Ч" => "Ch", "Ш" => "Sh", "Щ" => "Shch", + "Ы" => "Y", "Э" => "E", "Ю" => "Iu", "Я" => "Ia", "а" => "a", "б" => "b", + "в" => "v", "г" => "gh", "д" => "d", "е" => "ie", "ж" => "zh", "з" => "z", + "и" => "i", "й" => "i", "к" => "k", "л" => "l", "м" => "m", "н" => "n", + "о" => "o", "п" => "p", "Ñ€" => "r", "Ñ" => "s", "Ñ‚" => "t", "у" => "u", + "Ñ„" => "f", "Ñ…" => "kh", "ц" => "ts", "ч" => "ch", "ш" => "sh", "щ" => "shch", + "Ñ‹" => "y", "Ñ" => "e", "ÑŽ" => "iu", "Ñ" => "ia", "Ñ" => "ie", "Ñ‘" => "io", + "Ñ’" => "dj", "Ñ“" => "gj", "Ñ”" => "ie", "Ñ•" => "dz", "Ñ–" => "i", "Ñ—" => "yi", + "ј" => "j", "Ñ™" => "lj", "Ñš" => "nj", "Ñ›" => "tsh", "Ñœ" => "kj", "Ñ" => "i", + "Ñž" => "u", "ÑŸ" => "dzh", "Ñ " => "O", "Ñ¡" => "o", "Ñ¢" => "E", "Ñ£" => "e", + "Ѥ" => "Ie", "Ñ¥" => "ie", "Ѧ" => "E", "ѧ" => "e", "Ѩ" => "Ie", "Ñ©" => "ie", + "Ѫ" => "O", "Ñ«" => "o", "Ѭ" => "Io", "Ñ­" => "io", "Ñ®" => "Ks", "ѯ" => "ks", + "Ñ°" => "Ps", "ѱ" => "ps", "Ѳ" => "F", "ѳ" => "f", "Ñ´" => "Y", "ѵ" => "y", + "Ѷ" => "Y", "Ñ·" => "y", "Ѹ" => "u", "ѹ" => "u", "Ѻ" => "O", "Ñ»" => "o", + "Ѽ" => "O", "ѽ" => "o", "Ѿ" => "Ot", "Ñ¿" => "ot", "Ò€" => "Q", "Ò" => "q", + "Ò‚" => "*1000*", "Òˆ" => "*100.000*", "Ò‰" => "*1.000.000*", "ÒŽ" => "R'", "Ò" => "r'", "Ò" => "G'", + "Ò‘" => "g'", "Ò’" => "G'", "Ò“" => "g'", "Ò”" => "G'", "Ò•" => "g'", "Ò–" => "Zh'", + "Ò—" => "zh'", "Ò˜" => "Z'", "Ò™" => "z'", "Òš" => "K'", "Ò›" => "k'", "Òœ" => "K'", + "Ò" => "k'", "Òž" => "K'", "ÒŸ" => "k'", "Ò " => "K'", "Ò¡" => "k'", "Ò¢" => "N'", + "Ò£" => "n'", "Ò¤" => "Ng", "Ò¥" => "ng", "Ò¦" => "P'", "Ò§" => "p'", "Ò¨" => "Kh", + "Ò©" => "kh", "Òª" => "S'", "Ò«" => "s'", "Ò¬" => "T'", "Ò­" => "t'", "Ò®" => "U", + "Ò¯" => "u", "Ò°" => "U'", "Ò±" => "u'", "Ò²" => "Kh'", "Ò³" => "kh'", "Ò´" => "Tts", + "Òµ" => "tts", "Ò¶" => "Ch'", "Ò·" => "ch'", "Ò¸" => "Ch'", "Ò¹" => "ch'", "Òº" => "H", + "Ò»" => "h", "Ò¼" => "Ch", "Ò½" => "ch", "Ò¾" => "Ch'", "Ò¿" => "ch'", "Ó" => "Zh", + "Ó‚" => "zh", "Óƒ" => "K'", "Ó„" => "k'", "Ó‡" => "N'", "Óˆ" => "n'", "Ó‹" => "Ch", + "ÓŒ" => "ch", "Ó" => "a", "Ó‘" => "a", "Ó’" => "A", "Ó“" => "a", "Ó”" => "Ae", + "Ó•" => "ae", "Ó–" => "Ie", "Ó—" => "ie", "Óœ" => "Zh", "Ó" => "zh", "Óž" => "Z", + "ÓŸ" => "z", "Ó " => "Dz", "Ó¡" => "dz", "Ó¢" => "I", "Ó£" => "i", "Ó¤" => "I", + "Ó¥" => "i", "Ó¦" => "O", "Ó§" => "o", "Ó¨" => "O", "Ó©" => "o", "Óª" => "O", + "Ó«" => "o", "Ó¬" => "E", "Ó­" => "e", "Ó®" => "U", "Ó¯" => "u", "Ó°" => "U", + "Ó±" => "u", "Ó²" => "U", "Ó³" => "u", "Ó´" => "Ch", "Óµ" => "ch", "Ó¸" => "Y", + "Ó¹" => "y", "Ô±" => "A", "Ô²" => "B", "Ô³" => "G", "Ô´" => "D", "Ôµ" => "E", + "Ô¶" => "Z", "Ô·" => "E", "Ô¸" => "E", "Ô¹" => "T`", "Ôº" => "Zh", "Ô»" => "I", + "Ô¼" => "L", "Ô½" => "Kh", "Ô¾" => "Ts", "Ô¿" => "K", "Õ€" => "H", "Õ" => "Dz", + "Õ‚" => "Gh", "Õƒ" => "Ch", "Õ„" => "M", "Õ…" => "Y", "Õ†" => "N", "Õ‡" => "Sh", + "Õˆ" => "O", "Õ‰" => "Ch`", "ÕŠ" => "P", "Õ‹" => "J", "ÕŒ" => "Rh", "Õ" => "S", + "ÕŽ" => "V", "Õ" => "T", "Õ" => "R", "Õ‘" => "Ts`", "Õ’" => "W", "Õ“" => "P`", + "Õ”" => "K`", "Õ•" => "O", "Õ–" => "F", "Õ¡" => "a", "Õ¢" => "b", "Õ£" => "g", + "Õ¤" => "d", "Õ¥" => "e", "Õ¦" => "z", "Õ§" => "e", "Õ¨" => "e", "Õ©" => "t`", + "Õª" => "zh", "Õ«" => "i", "Õ¬" => "l", "Õ­" => "kh", "Õ®" => "ts", "Õ¯" => "k", + "Õ°" => "h", "Õ±" => "dz", "Õ²" => "gh", "Õ³" => "ch", "Õ´" => "m", "Õµ" => "y", + "Õ¶" => "n", "Õ·" => "sh", "Õ¸" => "o", "Õ¹" => "ch`", "Õº" => "p", "Õ»" => "j", + "Õ¼" => "rh", "Õ½" => "s", "Õ¾" => "v", "Õ¿" => "t", "Ö€" => "r", "Ö" => "ts`", + "Ö‚" => "w", "Öƒ" => "p`", "Ö„" => "k`", "Ö…" => "o", "Ö†" => "f", "Ö‡" => "ew", + "Ö±" => "e", "Ö²" => "a", "Ö³" => "o", "Ö´" => "i", "Öµ" => "e", "Ö¶" => "e", + "Ö·" => "a", "Ö¸" => "a", "Ö¹" => "o", "Ö»" => "u", "ב" => "b", "×’" => "g", + "ד" => "d", "×”" => "h", "ו" => "v", "×–" => "z", "×—" => "kh", "ט" => "t", + "×™" => "y", "ך" => "k", "×›" => "k", "ל" => "l", "×" => "m", "מ" => "m", + "ן" => "n", "× " => "n", "ס" => "s", "×£" => "p", "פ" => "p", "×¥" => "ts", + "צ" => "ts", "ק" => "q", "ר" => "r", "ש" => "sh", "ת" => "t", "×°" => "V", + "×±" => "oy", "ײ" => "i", "Ø¢" => "a", "ؤ" => "w'", "ئ" => "y'", "ب" => "b", + "ت" => "t", "Ø«" => "th", "ج" => "j", "Ø­" => "H", "Ø®" => "kh", "د" => "d", + "Ø°" => "dh", "ر" => "r", "ز" => "z", "س" => "s", "Ø´" => "sh", "ص" => "S", + "ض" => "D", "Ø·" => "T", "ظ" => "Z", "غ" => "G", "Ù" => "f", "Ù‚" => "q", + "Ùƒ" => "k", "Ù„" => "l", "Ù…" => "m", "Ù†" => "n", "Ù‡" => "h", "Ùˆ" => "w", + "ÙŠ" => "y", "Ù‹" => "an", "ÙŒ" => "un", "Ù" => "in", "ÙŽ" => "a", "Ù" => "u", + "Ù" => "i", "Ù‘" => "W", "Ù¡" => "1", "Ù¢" => "2", "Ù£" => "3", "Ù¤" => "4", + "Ù¥" => "5", "Ù¦" => "6", "Ù§" => "7", "Ù¨" => "8", "Ù©" => "9", "Ù¶" => "'w", + "Ù·" => "'u", "Ù¸" => "'y", "Ù¹" => "tt", "Ùº" => "tth", "Ù»" => "b", "Ù¼" => "t", + "Ù½" => "T", "Ù¾" => "p", "Ù¿" => "th", "Ú€" => "bh", "Ú" => "'h", "Ú‚" => "H", + "Úƒ" => "ny", "Ú„" => "dy", "Ú…" => "H", "Ú†" => "ch", "Ú‡" => "cch", "Úˆ" => "dd", + "Ú‰" => "D", "ÚŠ" => "D", "Ú‹" => "Dt", "ÚŒ" => "dh", "Ú" => "ddh", "ÚŽ" => "d", + "Ú" => "D", "Ú" => "D", "Ú‘" => "rr", "Ú’" => "R", "Ú“" => "R", "Ú”" => "R", + "Ú•" => "R", "Ú–" => "R", "Ú—" => "R", "Ú˜" => "j", "Ú™" => "R", "Úš" => "S", + "Ú›" => "S", "Úœ" => "S", "Ú" => "S", "Úž" => "S", "ÚŸ" => "T", "Ú " => "GH", + "Ú¡" => "F", "Ú¢" => "F", "Ú£" => "F", "Ú¤" => "v", "Ú¥" => "f", "Ú¦" => "ph", + "Ú§" => "Q", "Ú¨" => "Q", "Ú©" => "kh", "Úª" => "k", "Ú«" => "K", "Ú¬" => "K", + "Ú­" => "ng", "Ú®" => "K", "Ú¯" => "g", "Ú°" => "G", "Ú±" => "N", "Ú²" => "G", + "Ú³" => "G", "Ú´" => "G", "Úµ" => "L", "Ú¶" => "L", "Ú·" => "L", "Ú¸" => "L", + "Ú¹" => "N", "Úº" => "N", "Ú»" => "N", "Ú¼" => "N", "Ú½" => "N", "Ú¾" => "h", + "Ú¿" => "Ch", "Û€" => "hy", "Û" => "h", "Û‚" => "H", "Û„" => "W", "Û…" => "oe", + "Û†" => "oe", "Û‡" => "u", "Ûˆ" => "yu", "Û‰" => "yu", "ÛŠ" => "W", "Û‹" => "v", + "ÛŒ" => "y", "Û" => "Y", "ÛŽ" => "Y", "Û" => "W", "Û’" => "y", "Û“" => "y'", + "Û•" => "ae", "Û±" => "1", "Û²" => "2", "Û³" => "3", "Û´" => "4", "Ûµ" => "5", + "Û¶" => "6", "Û·" => "7", "Û¸" => "8", "Û¹" => "9", "Ûº" => "Sh", "Û»" => "D", + "Û¼" => "Gh", "Û¾" => "+m", "Ü’" => "b", "Ü“" => "g", "Ü”" => "g", "Ü•" => "d", + "Ü–" => "d", "Ü—" => "h", "ܘ" => "w", "Ü™" => "z", "Üš" => "H", "Ü›" => "t", + "Üœ" => "t", "Ü" => "y", "Üž" => "yh", "ÜŸ" => "k", "Ü " => "l", "Ü¡" => "m", + "Ü¢" => "n", "Ü£" => "s", "ܤ" => "s", "ܦ" => "p", "ܧ" => "p", "ܨ" => "S", + "Ü©" => "q", "ܪ" => "r", "Ü«" => "sh", "ܬ" => "t", "Ü°" => "a", "ܱ" => "a", + "ܲ" => "a", "ܳ" => "A", "Ü´" => "A", "ܵ" => "A", "ܶ" => "e", "Ü·" => "e", + "ܸ" => "e", "ܹ" => "E", "ܺ" => "i", "Ü»" => "i", "ܼ" => "u", "ܽ" => "u", + "ܾ" => "u", "Ü¿" => "o", "Ý…" => "X", "݆" => "Q", "Þ€" => "h", "Þ" => "sh", + "Þ‚" => "n", "Þƒ" => "r", "Þ„" => "b", "Þ…" => "L", "Þ†" => "k", "Þˆ" => "v", + "Þ‰" => "m", "ÞŠ" => "f", "Þ‹" => "dh", "ÞŒ" => "th", "Þ" => "l", "ÞŽ" => "g", + "Þ" => "ny", "Þ" => "s", "Þ‘" => "d", "Þ’" => "z", "Þ“" => "t", "Þ”" => "y", + "Þ•" => "p", "Þ–" => "j", "Þ—" => "ch", "Þ˜" => "tt", "Þ™" => "hh", "Þš" => "kh", + "Þ›" => "th", "Þœ" => "z", "Þ" => "sh", "Þž" => "s", "ÞŸ" => "d", "Þ " => "t", + "Þ¡" => "z", "Þ£" => "gh", "Þ¤" => "q", "Þ¥" => "w", "Þ¦" => "a", "Þ§" => "aa", + "Þ¨" => "i", "Þ©" => "ee", "Þª" => "u", "Þ«" => "oo", "Þ¬" => "e", "Þ­" => "ey", + "Þ®" => "o", "Þ¯" => "oa", "à¤" => "N", "ं" => "N", "ः" => "H", "अ" => "a", + "आ" => "aa", "इ" => "i", "ई" => "ii", "उ" => "u", "ऊ" => "uu", "ऋ" => "R", + "ऌ" => "L", "à¤" => "eN", "ऎ" => "e", "à¤" => "e", "à¤" => "ai", "ऑ" => "oN", + "ऒ" => "o", "ओ" => "o", "औ" => "au", "क" => "k", "ख" => "kh", "ग" => "g", + "घ" => "gh", "ङ" => "ng", "च" => "c", "छ" => "ch", "ज" => "j", "à¤" => "jh", + "ञ" => "ny", "ट" => "tt", "ठ" => "tth", "ड" => "dd", "ढ" => "ddh", "ण" => "nn", + "त" => "t", "थ" => "th", "द" => "d", "ध" => "dh", "न" => "n", "ऩ" => "nnn", + "प" => "p", "फ" => "ph", "ब" => "b", "भ" => "bh", "म" => "m", "य" => "y", + "र" => "r", "ऱ" => "rr", "ल" => "l", "ळ" => "l", "ऴ" => "lll", "व" => "v", + "श" => "sh", "ष" => "ss", "स" => "s", "ह" => "h", "ा" => "aa", "ि" => "i", + "ी" => "ii", "à¥" => "u", "ू" => "uu", "ृ" => "R", "ॄ" => "RR", "ॅ" => "eN", + "ॆ" => "e", "े" => "e", "ै" => "ai", "ॉ" => "oN", "ॊ" => "o", "ो" => "o", + "ौ" => "au", "à¥" => "AUM", "क़" => "q", "ख़" => "khh", "ग़" => "ghh", "ज़" => "z", + "ड़" => "dddh", "à¥" => "rh", "फ़" => "f", "य़" => "yy", "ॠ" => "RR", "ॡ" => "LL", + "ॢ" => "L", "ॣ" => "LL", "१" => "1", "२" => "2", "३" => "3", "४" => "4", + "५" => "5", "६" => "6", "७" => "7", "८" => "8", "९" => "9", "à¦" => "N", + "ং" => "N", "ঃ" => "H", "অ" => "a", "আ" => "aa", "ই" => "i", "ঈ" => "ii", + "উ" => "u", "ঊ" => "uu", "ঋ" => "R", "ঌ" => "RR", "à¦" => "e", "à¦" => "ai", + "ও" => "o", "ঔ" => "au", "ক" => "k", "খ" => "kh", "গ" => "g", "ঘ" => "gh", + "ঙ" => "ng", "চ" => "c", "ছ" => "ch", "জ" => "j", "à¦" => "jh", "ঞ" => "ny", + "ট" => "tt", "ঠ" => "tth", "ড" => "dd", "ঢ" => "ddh", "ণ" => "nn", "ত" => "t", + "থ" => "th", "দ" => "d", "ধ" => "dh", "ন" => "n", "প" => "p", "ফ" => "ph", + "ব" => "b", "ভ" => "bh", "ম" => "m", "য" => "y", "র" => "r", "ল" => "l", + "শ" => "sh", "ষ" => "ss", "স" => "s", "হ" => "h", "া" => "aa", "ি" => "i", + "ী" => "ii", "à§" => "u", "ূ" => "uu", "ৃ" => "R", "ৄ" => "RR", "ে" => "e", + "ৈ" => "ai", "ো" => "o", "ৌ" => "au", "ড়" => "rr", "à§" => "rh", "য়" => "yy", + "ৠ" => "RR", "ৡ" => "LL", "ৢ" => "L", "ৣ" => "LL", "১" => "1", "২" => "2", + "৩" => "3", "৪" => "4", "৫" => "5", "৬" => "6", "৭" => "7", "৮" => "8", + "৯" => "9", "ৰ" => "r'", "ৱ" => "r`", "৲" => "Rs", "৳" => "Rs", "৴" => "1", + "৵" => "2", "৶" => "3", "৷" => "4", "৹" => "16", "ਂ" => "N", "ਅ" => "a", + "ਆ" => "aa", "ਇ" => "i", "ਈ" => "ii", "ਉ" => "u", "ਊ" => "uu", "à¨" => "ee", + "à¨" => "ai", "ਓ" => "oo", "ਔ" => "au", "ਕ" => "k", "ਖ" => "kh", "ਗ" => "g", + "ਘ" => "gh", "ਙ" => "ng", "ਚ" => "c", "ਛ" => "ch", "ਜ" => "j", "à¨" => "jh", + "ਞ" => "ny", "ਟ" => "tt", "ਠ" => "tth", "ਡ" => "dd", "ਢ" => "ddh", "ਣ" => "nn", + "ਤ" => "t", "ਥ" => "th", "ਦ" => "d", "ਧ" => "dh", "ਨ" => "n", "ਪ" => "p", + "ਫ" => "ph", "ਬ" => "b", "ਭ" => "bb", "ਮ" => "m", "ਯ" => "y", "ਰ" => "r", + "ਲ" => "l", "ਲ਼" => "ll", "ਵ" => "v", "ਸ਼" => "sh", "ਸ" => "s", "ਹ" => "h", + "ਾ" => "aa", "ਿ" => "i", "à©€" => "ii", "à©" => "u", "à©‚" => "uu", "ੇ" => "ee", + "ੈ" => "ai", "à©‹" => "oo", "à©Œ" => "au", "à©™" => "khh", "à©š" => "ghh", "à©›" => "z", + "à©œ" => "rr", "à©ž" => "f", "੧" => "1", "੨" => "2", "à©©" => "3", "੪" => "4", + "à©«" => "5", "੬" => "6", "à©­" => "7", "à©®" => "8", "੯" => "9", "à©°" => "N", + "ੱ" => "H", "à©´" => "G.E.O.", "àª" => "N", "ં" => "N", "ઃ" => "H", "અ" => "a", + "આ" => "aa", "ઇ" => "i", "ઈ" => "ii", "ઉ" => "u", "ઊ" => "uu", "ઋ" => "R", + "àª" => "eN", "àª" => "e", "àª" => "ai", "ઑ" => "oN", "ઓ" => "o", "ઔ" => "au", + "ક" => "k", "ખ" => "kh", "ગ" => "g", "ઘ" => "gh", "ઙ" => "ng", "ચ" => "c", + "છ" => "ch", "જ" => "j", "àª" => "jh", "ઞ" => "ny", "ટ" => "tt", "ઠ" => "tth", + "ડ" => "dd", "ઢ" => "ddh", "ણ" => "nn", "ત" => "t", "થ" => "th", "દ" => "d", + "ધ" => "dh", "ન" => "n", "પ" => "p", "ફ" => "ph", "બ" => "b", "ભ" => "bh", + "મ" => "m", "ય" => "ya", "ર" => "r", "લ" => "l", "ળ" => "ll", "વ" => "v", + "શ" => "sh", "ષ" => "ss", "સ" => "s", "હ" => "h", "ા" => "aa", "િ" => "i", + "à«€" => "ii", "à«" => "u", "à«‚" => "uu", "ૃ" => "R", "à«„" => "RR", "à«…" => "eN", + "ે" => "e", "ૈ" => "ai", "ૉ" => "oN", "à«‹" => "o", "à«Œ" => "au", "à«" => "AUM", + "à« " => "RR", "૧" => "1", "૨" => "2", "à«©" => "3", "૪" => "4", "à««" => "5", + "૬" => "6", "à«­" => "7", "à«®" => "8", "૯" => "9", "à¬" => "N", "ଂ" => "N", + "ଃ" => "H", "ଅ" => "a", "ଆ" => "aa", "ଇ" => "i", "ଈ" => "ii", "ଉ" => "u", + "ଊ" => "uu", "ଋ" => "R", "ଌ" => "L", "à¬" => "e", "à¬" => "ai", "ଓ" => "o", + "ଔ" => "au", "କ" => "k", "ଖ" => "kh", "ଗ" => "g", "ଘ" => "gh", "ଙ" => "ng", + "ଚ" => "c", "ଛ" => "ch", "ଜ" => "j", "à¬" => "jh", "ଞ" => "ny", "ଟ" => "tt", + "ଠ" => "tth", "ଡ" => "dd", "ଢ" => "ddh", "ଣ" => "nn", "ତ" => "t", "ଥ" => "th", + "ଦ" => "d", "ଧ" => "dh", "ନ" => "n", "ପ" => "p", "ଫ" => "ph", "ବ" => "b", + "ଭ" => "bh", "ମ" => "m", "ଯ" => "y", "ର" => "r", "ଲ" => "l", "ଳ" => "ll", + "ଶ" => "sh", "ଷ" => "ss", "ସ" => "s", "ହ" => "h", "ା" => "aa", "ି" => "i", + "à­€" => "ii", "à­" => "u", "à­‚" => "uu", "à­ƒ" => "R", "à­‡" => "e", "à­ˆ" => "ai", + "à­‹" => "o", "à­Œ" => "au", "à­œ" => "rr", "à­" => "rh", "à­Ÿ" => "yy", "à­ " => "RR", + "à­¡" => "LL", "à­§" => "1", "à­¨" => "2", "à­©" => "3", "à­ª" => "4", "à­«" => "5", + "à­¬" => "6", "à­­" => "7", "à­®" => "8", "à­¯" => "9", "ஂ" => "N", "ஃ" => "H", + "à®…" => "a", "ஆ" => "aa", "இ" => "i", "ஈ" => "ii", "உ" => "u", "ஊ" => "uu", + "எ" => "e", "à®" => "ee", "à®" => "ai", "à®’" => "o", "ஓ" => "oo", "à®”" => "au", + "க" => "k", "à®™" => "ng", "ச" => "c", "ஜ" => "j", "ஞ" => "ny", "ட" => "tt", + "ண" => "nn", "த" => "t", "ந" => "n", "ன" => "nnn", "ப" => "p", "à®®" => "m", + "ய" => "y", "à®°" => "r", "à®±" => "rr", "ல" => "l", "ள" => "ll", "à®´" => "lll", + "வ" => "v", "à®·" => "ss", "ஸ" => "s", "ஹ" => "h", "ா" => "aa", "ி" => "i", + "ீ" => "ii", "à¯" => "u", "ூ" => "uu", "ெ" => "e", "ே" => "ee", "ை" => "ai", + "ொ" => "o", "ோ" => "oo", "ௌ" => "au", "௧" => "1", "௨" => "2", "௩" => "3", + "௪" => "4", "௫" => "5", "௬" => "6", "௭" => "7", "௮" => "8", "௯" => "9", + "௰" => "+10+", "௱" => "+100+", "௲" => "+1000+", "à°" => "N", "à°‚" => "N", "à°ƒ" => "H", + "à°…" => "a", "à°†" => "aa", "à°‡" => "i", "à°ˆ" => "ii", "à°‰" => "u", "à°Š" => "uu", + "à°‹" => "R", "à°Œ" => "L", "à°Ž" => "e", "à°" => "ee", "à°" => "ai", "à°’" => "o", + "à°“" => "oo", "à°”" => "au", "à°•" => "k", "à°–" => "kh", "à°—" => "g", "à°˜" => "gh", + "à°™" => "ng", "à°š" => "c", "à°›" => "ch", "à°œ" => "j", "à°" => "jh", "à°ž" => "ny", + "à°Ÿ" => "tt", "à° " => "tth", "à°¡" => "dd", "à°¢" => "ddh", "à°£" => "nn", "à°¤" => "t", + "à°¥" => "th", "à°¦" => "d", "à°§" => "dh", "à°¨" => "n", "à°ª" => "p", "à°«" => "ph", + "à°¬" => "b", "à°­" => "bh", "à°®" => "m", "à°¯" => "y", "à°°" => "r", "à°±" => "rr", + "à°²" => "l", "à°³" => "ll", "à°µ" => "v", "à°¶" => "sh", "à°·" => "ss", "à°¸" => "s", + "à°¹" => "h", "à°¾" => "aa", "à°¿" => "i", "à±€" => "ii", "à±" => "u", "ూ" => "uu", + "ృ" => "R", "ౄ" => "RR", "ె" => "e", "ే" => "ee", "ై" => "ai", "ొ" => "o", + "ో" => "oo", "ౌ" => "au", "à± " => "RR", "ౡ" => "LL", "౧" => "1", "౨" => "2", + "౩" => "3", "౪" => "4", "౫" => "5", "౬" => "6", "à±­" => "7", "à±®" => "8", + "౯" => "9", "ಂ" => "N", "ಃ" => "H", "ಅ" => "a", "ಆ" => "aa", "ಇ" => "i", + "ಈ" => "ii", "ಉ" => "u", "ಊ" => "uu", "ಋ" => "R", "ಌ" => "L", "ಎ" => "e", + "à²" => "ee", "à²" => "ai", "ಒ" => "o", "ಓ" => "oo", "ಔ" => "au", "ಕ" => "k", + "ಖ" => "kh", "ಗ" => "g", "ಘ" => "gh", "ಙ" => "ng", "ಚ" => "c", "ಛ" => "ch", + "ಜ" => "j", "à²" => "jh", "ಞ" => "ny", "ಟ" => "tt", "ಠ" => "tth", "ಡ" => "dd", + "ಢ" => "ddh", "ಣ" => "nn", "ತ" => "t", "ಥ" => "th", "ದ" => "d", "ಧ" => "dh", + "ನ" => "n", "ಪ" => "p", "ಫ" => "ph", "ಬ" => "b", "ಭ" => "bh", "ಮ" => "m", + "ಯ" => "y", "ರ" => "r", "ಱ" => "rr", "ಲ" => "l", "ಳ" => "ll", "ವ" => "v", + "ಶ" => "sh", "ಷ" => "ss", "ಸ" => "s", "ಹ" => "h", "ಾ" => "aa", "ಿ" => "i", + "à³€" => "ii", "à³" => "u", "ೂ" => "uu", "ೃ" => "R", "ೄ" => "RR", "ೆ" => "e", + "ೇ" => "ee", "ೈ" => "ai", "ೊ" => "o", "ೋ" => "oo", "ೌ" => "au", "ೞ" => "lll", + "à³ " => "RR", "ೡ" => "LL", "೧" => "1", "೨" => "2", "೩" => "3", "೪" => "4", + "೫" => "5", "೬" => "6", "à³­" => "7", "à³®" => "8", "೯" => "9", "à´‚" => "N", + "à´ƒ" => "H", "à´…" => "a", "à´†" => "aa", "à´‡" => "i", "à´ˆ" => "ii", "à´‰" => "u", + "à´Š" => "uu", "à´‹" => "R", "à´Œ" => "L", "à´Ž" => "e", "à´" => "ee", "à´" => "ai", + "à´’" => "o", "à´“" => "oo", "à´”" => "au", "à´•" => "k", "à´–" => "kh", "à´—" => "g", + "à´˜" => "gh", "à´™" => "ng", "à´š" => "c", "à´›" => "ch", "à´œ" => "j", "à´" => "jh", + "à´ž" => "ny", "à´Ÿ" => "tt", "à´ " => "tth", "à´¡" => "dd", "à´¢" => "ddh", "à´£" => "nn", + "à´¤" => "t", "à´¥" => "th", "à´¦" => "d", "à´§" => "dh", "à´¨" => "n", "à´ª" => "p", + "à´«" => "ph", "à´¬" => "b", "à´­" => "bh", "à´®" => "m", "à´¯" => "y", "à´°" => "r", + "à´±" => "rr", "à´²" => "l", "à´³" => "ll", "à´´" => "lll", "à´µ" => "v", "à´¶" => "sh", + "à´·" => "ss", "à´¸" => "s", "à´¹" => "h", "à´¾" => "aa", "à´¿" => "i", "ീ" => "ii", + "àµ" => "u", "ൂ" => "uu", "ൃ" => "R", "െ" => "e", "േ" => "ee", "ൈ" => "ai", + "ൊ" => "o", "ോ" => "oo", "ൌ" => "au", "ൠ" => "RR", "ൡ" => "LL", "൧" => "1", + "൨" => "2", "൩" => "3", "൪" => "4", "൫" => "5", "൬" => "6", "൭" => "7", + "൮" => "8", "൯" => "9", "ං" => "N", "ඃ" => "H", "අ" => "a", "ආ" => "aa", + "ඇ" => "ae", "ඈ" => "aae", "ඉ" => "i", "ඊ" => "ii", "උ" => "u", "ඌ" => "uu", + "à¶" => "R", "ඎ" => "RR", "à¶" => "L", "à¶" => "LL", "එ" => "e", "ඒ" => "ee", + "ඓ" => "ai", "ඔ" => "o", "ඕ" => "oo", "ඖ" => "au", "ක" => "k", "ඛ" => "kh", + "ග" => "g", "à¶" => "gh", "ඞ" => "ng", "ඟ" => "nng", "ච" => "c", "ඡ" => "ch", + "ජ" => "j", "ඣ" => "jh", "ඤ" => "ny", "ඥ" => "jny", "ඦ" => "nyj", "ට" => "tt", + "ඨ" => "tth", "ඩ" => "dd", "ඪ" => "ddh", "ණ" => "nn", "ඬ" => "nndd", "ත" => "t", + "ථ" => "th", "ද" => "d", "ධ" => "dh", "න" => "n", "ඳ" => "nd", "ප" => "p", + "ඵ" => "ph", "බ" => "b", "භ" => "bh", "ම" => "m", "ඹ" => "mb", "ය" => "y", + "ර" => "r", "ල" => "l", "à·€" => "v", "à·" => "sh", "à·‚" => "ss", "à·ƒ" => "s", + "à·„" => "h", "à·…" => "ll", "à·†" => "f", "à·" => "aa", "à·" => "ae", "à·‘" => "aae", + "à·’" => "i", "à·“" => "ii", "à·”" => "u", "à·–" => "uu", "à·˜" => "R", "à·™" => "e", + "à·š" => "ee", "à·›" => "ai", "à·œ" => "o", "à·" => "oo", "à·ž" => "au", "à·Ÿ" => "L", + "à·²" => "RR", "à·³" => "LL", "à¸" => "k", "ข" => "kh", "ฃ" => "kh", "ค" => "kh", + "ฅ" => "kh", "ฆ" => "kh", "ง" => "ng", "จ" => "cch", "ฉ" => "ch", "ช" => "ch", + "ซ" => "ch", "ฌ" => "ch", "à¸" => "y", "ฎ" => "d", "à¸" => "t", "à¸" => "th", + "ฑ" => "th", "ฒ" => "th", "ณ" => "n", "ด" => "d", "ต" => "t", "ถ" => "th", + "ท" => "th", "ธ" => "th", "น" => "n", "บ" => "b", "ป" => "p", "ผ" => "ph", + "à¸" => "f", "พ" => "ph", "ฟ" => "f", "ภ" => "ph", "ม" => "m", "ย" => "y", + "ร" => "r", "ฤ" => "R", "ล" => "l", "ฦ" => "L", "ว" => "w", "ศ" => "s", + "ษ" => "s", "ส" => "s", "ห" => "h", "ฬ" => "l", "ฮ" => "h", "ะ" => "a", + "ั" => "a", "า" => "aa", "ำ" => "am", "ิ" => "i", "ี" => "ii", "ึ" => "ue", + "ื" => "uue", "ุ" => "u", "ู" => "uu", "฿" => "Bh.", "เ" => "e", "à¹" => "ae", + "โ" => "o", "ใ" => "ai", "ไ" => "ai", "ๅ" => "ao", "à¹" => "M", "๑" => "1", + "๒" => "2", "๓" => "3", "๔" => "4", "๕" => "5", "๖" => "6", "๗" => "7", + "๘" => "8", "๙" => "9", "àº" => "k", "ຂ" => "kh", "ຄ" => "kh", "ງ" => "ng", + "ຈ" => "ch", "ຊ" => "s", "àº" => "ny", "ດ" => "d", "ຕ" => "h", "ຖ" => "th", + "ທ" => "th", "ນ" => "n", "ບ" => "b", "ປ" => "p", "ຜ" => "ph", "àº" => "f", + "ພ" => "ph", "ຟ" => "f", "ມ" => "m", "ຢ" => "y", "ຣ" => "r", "ລ" => "l", + "ວ" => "w", "ສ" => "s", "ຫ" => "h", "ະ" => "a", "າ" => "aa", "ຳ" => "am", + "ິ" => "i", "ີ" => "ii", "ຶ" => "y", "ື" => "yy", "ຸ" => "u", "ູ" => "uu", + "ົ" => "o", "ຼ" => "l", "ຽ" => "ny", "ເ" => "e", "à»" => "ei", "ໂ" => "o", + "ໃ" => "ay", "ໄ" => "ai", "à»" => "M", "໑" => "1", "à»’" => "2", "໓" => "3", + "à»”" => "4", "໕" => "5", "à»–" => "6", "à»—" => "7", "໘" => "8", "à»™" => "9", + "ໜ" => "hn", "à»" => "hm", "༑" => "X", "༒" => "XX", "༓" => "X", "༡" => "1", + "༢" => "2", "༣" => "3", "༤" => "4", "༥" => "5", "༦" => "6", "༧" => "7", + "༨" => "8", "༩" => "9", "༪" => ".5", "༫" => "1.5", "༬" => "2.5", "༭" => "3.5", + "༮" => "4.5", "༯" => "5.5", "༰" => "6.5", "༱" => "7.5", "༲" => "8.5", "༳" => "-.5", + "ཀ" => "k", "à½" => "kh", "ག" => "g", "གྷ" => "gh", "ང" => "ng", "ཅ" => "c", + "ཆ" => "ch", "ཇ" => "j", "ཉ" => "ny", "ཊ" => "tt", "ཋ" => "tth", "ཌ" => "dd", + "à½" => "ddh", "ཎ" => "nn", "à½" => "t", "à½" => "th", "ད" => "d", "དྷ" => "dh", + "ན" => "n", "པ" => "p", "ཕ" => "ph", "བ" => "b", "བྷ" => "bh", "མ" => "m", + "ཙ" => "ts", "ཚ" => "tsh", "ཛ" => "dz", "ཛྷ" => "dzh", "à½" => "w", "ཞ" => "zh", + "ཟ" => "z", "ཡ" => "y", "ར" => "r", "ལ" => "l", "ཤ" => "sh", "ཥ" => "ssh", + "ས" => "s", "ཧ" => "h", "ཨ" => "a", "ཀྵ" => "kss", "ཪ" => "r", "ཱ" => "aa", + "ི" => "i", "ཱི" => "ii", "ུ" => "u", "ཱུ" => "uu", "ྲྀ" => "R", "ཷ" => "RR", + "ླྀ" => "L", "ཹ" => "LL", "ེ" => "e", "ཻ" => "ee", "ོ" => "o", "ཽ" => "oo", + "ཾ" => "M", "ཿ" => "H", "ྀ" => "i", "à¾" => "ii", "à¾" => "k", "ྑ" => "kh", + "ྒ" => "g", "ྒྷ" => "gh", "ྔ" => "ng", "ྕ" => "c", "ྖ" => "ch", "ྗ" => "j", + "ྙ" => "ny", "ྚ" => "tt", "ྛ" => "tth", "ྜ" => "dd", "à¾" => "ddh", "ྞ" => "nn", + "ྟ" => "t", "ྠ" => "th", "ྡ" => "d", "ྡྷ" => "dh", "ྣ" => "n", "ྤ" => "p", + "ྥ" => "ph", "ྦ" => "b", "ྦྷ" => "bh", "ྨ" => "m", "ྩ" => "ts", "ྪ" => "tsh", + "ྫ" => "dz", "ྫྷ" => "dzh", "ྭ" => "w", "ྮ" => "zh", "ྯ" => "z", "ྱ" => "y", + "ྲ" => "r", "ླ" => "l", "ྴ" => "sh", "ྵ" => "ss", "ྶ" => "s", "ྷ" => "h", + "ྸ" => "a", "ྐྵ" => "kss", "ྺ" => "w", "ྻ" => "y", "ྼ" => "r", "྾" => "X", + "྿" => ":X:", "à¿€" => "O", "à¿" => "o", "à¿‚" => "o", "࿃" => "(O)", "á€" => "kh", + "ဂ" => "g", "ဃ" => "gh", "င" => "ng", "စ" => "c", "ဆ" => "ch", "ဇ" => "j", + "ဈ" => "jh", "ဉ" => "ny", "ည" => "nny", "ဋ" => "tt", "ဌ" => "tth", "á€" => "dd", + "ဎ" => "ddh", "á€" => "nn", "á€" => "tt", "ထ" => "th", "ဒ" => "d", "ဓ" => "dh", + "န" => "n", "ပ" => "p", "ဖ" => "ph", "ဗ" => "b", "ဘ" => "bh", "မ" => "m", + "ယ" => "y", "ရ" => "r", "လ" => "l", "á€" => "w", "သ" => "s", "ဟ" => "h", + "ဠ" => "ll", "အ" => "a", "ဣ" => "i", "ဤ" => "ii", "ဥ" => "u", "ဦ" => "uu", + "ဧ" => "e", "ဩ" => "o", "ဪ" => "au", "ာ" => "aa", "ိ" => "i", "ီ" => "ii", + "ု" => "u", "ူ" => "uu", "ေ" => "e", "ဲ" => "ai", "ံ" => "N", "á" => "1", + "á‚" => "2", "áƒ" => "3", "á„" => "4", "á…" => "5", "á†" => "6", "á‡" => "7", + "áˆ" => "8", "á‰" => "9", "áŒ" => "n*", "á" => "r*", "áŽ" => "l*", "á" => "e*", + "á" => "sh", "á‘" => "ss", "á’" => "R", "á“" => "RR", "á”" => "L", "á•" => "LL", + "á–" => "R", "á—" => "RR", "á˜" => "L", "á™" => "LL", "á‚ " => "A", "á‚¡" => "B", + "á‚¢" => "G", "á‚£" => "D", "Ⴄ" => "E", "á‚¥" => "V", "Ⴆ" => "Z", "Ⴇ" => "T`", + "Ⴈ" => "I", "á‚©" => "K", "Ⴊ" => "L", "á‚«" => "M", "Ⴌ" => "N", "á‚­" => "O", + "á‚®" => "P", "Ⴏ" => "Zh", "á‚°" => "R", "Ⴑ" => "S", "Ⴒ" => "T", "Ⴓ" => "U", + "á‚´" => "P`", "Ⴕ" => "K`", "Ⴖ" => "G'", "á‚·" => "Q", "Ⴘ" => "Sh", "Ⴙ" => "Ch`", + "Ⴚ" => "C`", "á‚»" => "Z'", "Ⴜ" => "C", "Ⴝ" => "Ch", "Ⴞ" => "X", "á‚¿" => "J", + "Ⴠ" => "H", "áƒ" => "E", "Ⴢ" => "Y", "Ⴣ" => "W", "Ⴤ" => "Xh", "Ⴥ" => "OE", + "áƒ" => "a", "ბ" => "b", "გ" => "g", "დ" => "d", "ე" => "e", "ვ" => "v", + "ზ" => "z", "თ" => "t`", "ი" => "i", "კ" => "k", "ლ" => "l", "მ" => "m", + "ნ" => "n", "áƒ" => "o", "პ" => "p", "ჟ" => "zh", "რ" => "r", "ს" => "s", + "ტ" => "t", "უ" => "u", "ფ" => "p`", "ქ" => "k`", "ღ" => "g'", "ყ" => "q", + "შ" => "sh", "ჩ" => "ch`", "ც" => "c`", "ძ" => "z'", "წ" => "c", "ჭ" => "ch", + "ხ" => "x", "ჯ" => "j", "ჰ" => "h", "ჱ" => "e", "ჲ" => "y", "ჳ" => "w", + "ჴ" => "xh", "ჵ" => "oe", "ჶ" => "f", "á„" => "gg", "á„‚" => "n", "ᄃ" => "d", + "á„„" => "dd", "á„…" => "r", "ᄆ" => "m", "ᄇ" => "b", "ᄈ" => "bb", "ᄉ" => "s", + "á„Š" => "ss", "á„Œ" => "j", "á„" => "jj", "á„Ž" => "c", "á„" => "k", "á„" => "t", + "á„‘" => "p", "á„’" => "h", "á„“" => "ng", "á„”" => "nn", "á„•" => "nd", "á„–" => "nb", + "á„—" => "dg", "ᄘ" => "rn", "á„™" => "rr", "á„š" => "rh", "á„›" => "rN", "á„œ" => "mb", + "á„" => "mN", "á„ž" => "bg", "á„Ÿ" => "bn", "á„¡" => "bs", "á„¢" => "bsg", "á„£" => "bst", + "ᄤ" => "bsb", "á„¥" => "bss", "ᄦ" => "bsj", "ᄧ" => "bj", "ᄨ" => "bc", "á„©" => "bt", + "ᄪ" => "bp", "á„«" => "bN", "ᄬ" => "bbN", "á„­" => "sg", "á„®" => "sn", "ᄯ" => "sd", + "á„°" => "sr", "ᄱ" => "sm", "ᄲ" => "sb", "ᄳ" => "sbg", "á„´" => "sss", "ᄵ" => "s", + "ᄶ" => "sj", "á„·" => "sc", "ᄸ" => "sk", "ᄹ" => "st", "ᄺ" => "sp", "á„»" => "sh", + "á…€" => "Z", "á…" => "g", "á…‚" => "d", "á…ƒ" => "m", "á…„" => "b", "á……" => "s", + "á…†" => "Z", "á…ˆ" => "j", "á…‰" => "c", "á…Š" => "t", "á…‹" => "p", "á…Œ" => "N", + "á…" => "j", "á…’" => "ck", "á…“" => "ch", "á…–" => "pb", "á…—" => "pN", "á…˜" => "hh", + "á…™" => "Q", "á…¡" => "a", "á…¢" => "ae", "á…£" => "ya", "á…¤" => "yae", "á…¥" => "eo", + "á…¦" => "e", "á…§" => "yeo", "á…¨" => "ye", "á…©" => "o", "á…ª" => "wa", "á…«" => "wae", + "á…¬" => "oe", "á…­" => "yo", "á…®" => "u", "á…¯" => "weo", "á…°" => "we", "á…±" => "wi", + "á…²" => "yu", "á…³" => "eu", "á…´" => "yi", "á…µ" => "i", "á…¶" => "a-o", "á…·" => "a-u", + "á…¸" => "ya-o", "á…¹" => "ya-yo", "á…º" => "eo-o", "á…»" => "eo-u", "á…¼" => "eo-eu", "á…½" => "yeo-o", + "á…¾" => "yeo-u", "á…¿" => "o-eo", "ᆀ" => "o-e", "á†" => "o-ye", "ᆂ" => "o-o", "ᆃ" => "o-u", + "ᆄ" => "yo-ya", "ᆅ" => "yo-yae", "ᆆ" => "yo-yeo", "ᆇ" => "yo-o", "ᆈ" => "yo-i", "ᆉ" => "u-a", + "ᆊ" => "u-ae", "ᆋ" => "u-eo-eu", "ᆌ" => "u-ye", "á†" => "u-u", "ᆎ" => "yu-a", "á†" => "yu-eo", + "á†" => "yu-e", "ᆑ" => "yu-yeo", "ᆒ" => "yu-ye", "ᆓ" => "yu-u", "ᆔ" => "yu-i", "ᆕ" => "eu-u", + "ᆖ" => "eu-eu", "ᆗ" => "yi-u", "ᆘ" => "i-a", "ᆙ" => "i-ya", "ᆚ" => "i-o", "ᆛ" => "i-u", + "ᆜ" => "i-eu", "á†" => "i-U", "ᆞ" => "U", "ᆟ" => "U-eo", "ᆠ" => "U-u", "ᆡ" => "U-i", + "ᆢ" => "UU", "ᆨ" => "g", "ᆩ" => "gg", "ᆪ" => "gs", "ᆫ" => "n", "ᆬ" => "nj", + "ᆭ" => "nh", "ᆮ" => "d", "ᆯ" => "l", "ᆰ" => "lg", "ᆱ" => "lm", "ᆲ" => "lb", + "ᆳ" => "ls", "ᆴ" => "lt", "ᆵ" => "lp", "ᆶ" => "lh", "ᆷ" => "m", "ᆸ" => "b", + "ᆹ" => "bs", "ᆺ" => "s", "ᆻ" => "ss", "ᆼ" => "ng", "ᆽ" => "j", "ᆾ" => "c", + "ᆿ" => "k", "ᇀ" => "t", "á‡" => "p", "ᇂ" => "h", "ᇃ" => "gl", "ᇄ" => "gsg", + "ᇅ" => "ng", "ᇆ" => "nd", "ᇇ" => "ns", "ᇈ" => "nZ", "ᇉ" => "nt", "ᇊ" => "dg", + "ᇋ" => "tl", "ᇌ" => "lgs", "á‡" => "ln", "ᇎ" => "ld", "á‡" => "lth", "á‡" => "ll", + "ᇑ" => "lmg", "ᇒ" => "lms", "ᇓ" => "lbs", "ᇔ" => "lbh", "ᇕ" => "rNp", "ᇖ" => "lss", + "ᇗ" => "lZ", "ᇘ" => "lk", "ᇙ" => "lQ", "ᇚ" => "mg", "ᇛ" => "ml", "ᇜ" => "mb", + "á‡" => "ms", "ᇞ" => "mss", "ᇟ" => "mZ", "ᇠ" => "mc", "ᇡ" => "mh", "ᇢ" => "mN", + "ᇣ" => "bl", "ᇤ" => "bp", "ᇥ" => "ph", "ᇦ" => "pN", "ᇧ" => "sg", "ᇨ" => "sd", + "ᇩ" => "sl", "ᇪ" => "sb", "ᇫ" => "Z", "ᇬ" => "g", "ᇭ" => "ss", "ᇯ" => "kh", + "ᇰ" => "N", "ᇱ" => "Ns", "ᇲ" => "NZ", "ᇳ" => "pb", "ᇴ" => "pN", "ᇵ" => "hn", + "ᇶ" => "hl", "ᇷ" => "hm", "ᇸ" => "hb", "ᇹ" => "Q", "áˆ" => "hu", "ሂ" => "hi", + "ሃ" => "haa", "ሄ" => "hee", "ህ" => "he", "ሆ" => "ho", "ለ" => "la", "ሉ" => "lu", + "ሊ" => "li", "ላ" => "laa", "ሌ" => "lee", "áˆ" => "le", "ሎ" => "lo", "áˆ" => "lwa", + "áˆ" => "hha", "ሑ" => "hhu", "ሒ" => "hhi", "ሓ" => "hhaa", "ሔ" => "hhee", "ሕ" => "hhe", + "ሖ" => "hho", "ሗ" => "hhwa", "መ" => "ma", "ሙ" => "mu", "ሚ" => "mi", "ማ" => "maa", + "ሜ" => "mee", "áˆ" => "me", "ሞ" => "mo", "ሟ" => "mwa", "ሠ" => "sza", "ሡ" => "szu", + "ሢ" => "szi", "ሣ" => "szaa", "ሤ" => "szee", "ሥ" => "sze", "ሦ" => "szo", "ሧ" => "szwa", + "ረ" => "ra", "ሩ" => "ru", "ሪ" => "ri", "ራ" => "raa", "ሬ" => "ree", "ር" => "re", + "ሮ" => "ro", "ሯ" => "rwa", "ሰ" => "sa", "ሱ" => "su", "ሲ" => "si", "ሳ" => "saa", + "ሴ" => "see", "ስ" => "se", "ሶ" => "so", "ሷ" => "swa", "ሸ" => "sha", "ሹ" => "shu", + "ሺ" => "shi", "ሻ" => "shaa", "ሼ" => "shee", "ሽ" => "she", "ሾ" => "sho", "ሿ" => "shwa", + "ቀ" => "qa", "á‰" => "qu", "ቂ" => "qi", "ቃ" => "qaa", "ቄ" => "qee", "ቅ" => "qe", + "ቆ" => "qo", "ቈ" => "qwa", "ቊ" => "qwi", "ቋ" => "qwaa", "ቌ" => "qwee", "á‰" => "qwe", + "á‰" => "qha", "ቑ" => "qhu", "ቒ" => "qhi", "ቓ" => "qhaa", "ቔ" => "qhee", "ቕ" => "qhe", + "ቖ" => "qho", "ቘ" => "qhwa", "ቚ" => "qhwi", "ቛ" => "qhwaa", "ቜ" => "qhwee", "á‰" => "qhwe", + "በ" => "ba", "ቡ" => "bu", "ቢ" => "bi", "ባ" => "baa", "ቤ" => "bee", "ብ" => "be", + "ቦ" => "bo", "ቧ" => "bwa", "ቨ" => "va", "ቩ" => "vu", "ቪ" => "vi", "ቫ" => "vaa", + "ቬ" => "vee", "ቭ" => "ve", "ቮ" => "vo", "ቯ" => "vwa", "ተ" => "ta", "ቱ" => "tu", + "ቲ" => "ti", "ታ" => "taa", "ቴ" => "tee", "ት" => "te", "ቶ" => "to", "ቷ" => "twa", + "ቸ" => "ca", "ቹ" => "cu", "ቺ" => "ci", "ቻ" => "caa", "ቼ" => "cee", "ች" => "ce", + "ቾ" => "co", "ቿ" => "cwa", "ኀ" => "xa", "áŠ" => "xu", "ኂ" => "xi", "ኃ" => "xaa", + "ኄ" => "xee", "ኅ" => "xe", "ኆ" => "xo", "ኈ" => "xwa", "ኊ" => "xwi", "ኋ" => "xwaa", + "ኌ" => "xwee", "áŠ" => "xwe", "áŠ" => "na", "ኑ" => "nu", "ኒ" => "ni", "ና" => "naa", + "ኔ" => "nee", "ን" => "ne", "ኖ" => "no", "ኗ" => "nwa", "ኘ" => "nya", "ኙ" => "nyu", + "ኚ" => "nyi", "ኛ" => "nyaa", "ኜ" => "nyee", "áŠ" => "nye", "ኞ" => "nyo", "ኟ" => "nywa", + "አ" => "'a", "ኡ" => "'u", "ኣ" => "'aa", "ኤ" => "'ee", "እ" => "'e", "ኦ" => "'o", + "ኧ" => "'wa", "ከ" => "ka", "ኩ" => "ku", "ኪ" => "ki", "ካ" => "kaa", "ኬ" => "kee", + "ክ" => "ke", "ኮ" => "ko", "ኰ" => "kwa", "ኲ" => "kwi", "ኳ" => "kwaa", "ኴ" => "kwee", + "ኵ" => "kwe", "ኸ" => "kxa", "ኹ" => "kxu", "ኺ" => "kxi", "ኻ" => "kxaa", "ኼ" => "kxee", + "ኽ" => "kxe", "ኾ" => "kxo", "á‹€" => "kxwa", "á‹‚" => "kxwi", "ዃ" => "kxwaa", "á‹„" => "kxwee", + "á‹…" => "kxwe", "ወ" => "wa", "ዉ" => "wu", "á‹Š" => "wi", "á‹‹" => "waa", "á‹Œ" => "wee", + "á‹" => "we", "á‹Ž" => "wo", "á‹" => "`a", "á‹‘" => "`u", "á‹’" => "`i", "á‹“" => "`aa", + "á‹”" => "`ee", "á‹•" => "`e", "á‹–" => "`o", "ዘ" => "za", "á‹™" => "zu", "á‹š" => "zi", + "á‹›" => "zaa", "á‹œ" => "zee", "á‹" => "ze", "á‹ž" => "zo", "á‹Ÿ" => "zwa", "á‹ " => "zha", + "á‹¡" => "zhu", "á‹¢" => "zhi", "á‹£" => "zhaa", "ዤ" => "zhee", "á‹¥" => "zhe", "ዦ" => "zho", + "ዧ" => "zhwa", "የ" => "ya", "á‹©" => "yu", "ዪ" => "yi", "á‹«" => "yaa", "ዬ" => "yee", + "á‹­" => "ye", "á‹®" => "yo", "á‹°" => "da", "ዱ" => "du", "ዲ" => "di", "ዳ" => "daa", + "á‹´" => "dee", "ድ" => "de", "ዶ" => "do", "á‹·" => "dwa", "ዸ" => "dda", "ዹ" => "ddu", + "ዺ" => "ddi", "á‹»" => "ddaa", "ዼ" => "ddee", "ዽ" => "dde", "ዾ" => "ddo", "á‹¿" => "ddwa", + "áŒ" => "ju", "ጂ" => "ji", "ጃ" => "jaa", "ጄ" => "jee", "ጅ" => "je", "ጆ" => "jo", + "ጇ" => "jwa", "ገ" => "ga", "ጉ" => "gu", "ጊ" => "gi", "ጋ" => "gaa", "ጌ" => "gee", + "áŒ" => "ge", "ጎ" => "go", "áŒ" => "gwa", "ጒ" => "gwi", "ጓ" => "gwaa", "ጔ" => "gwee", + "ጕ" => "gwe", "ጘ" => "gga", "ጙ" => "ggu", "ጚ" => "ggi", "ጛ" => "ggaa", "ጜ" => "ggee", + "áŒ" => "gge", "ጞ" => "ggo", "ጠ" => "tha", "ጡ" => "thu", "ጢ" => "thi", "ጣ" => "thaa", + "ጤ" => "thee", "ጥ" => "the", "ጦ" => "tho", "ጧ" => "thwa", "ጨ" => "cha", "ጩ" => "chu", + "ጪ" => "chi", "ጫ" => "chaa", "ጬ" => "chee", "ጭ" => "che", "ጮ" => "cho", "ጯ" => "chwa", + "ጰ" => "pha", "ጱ" => "phu", "ጲ" => "phi", "ጳ" => "phaa", "ጴ" => "phee", "ጵ" => "phe", + "ጶ" => "pho", "ጷ" => "phwa", "ጸ" => "tsa", "ጹ" => "tsu", "ጺ" => "tsi", "ጻ" => "tsaa", + "ጼ" => "tsee", "ጽ" => "tse", "ጾ" => "tso", "ጿ" => "tswa", "á€" => "tza", "á" => "tzu", + "á‚" => "tzi", "áƒ" => "tzaa", "á„" => "tzee", "á…" => "tze", "á†" => "tzo", "áˆ" => "fa", + "á‰" => "fu", "áŠ" => "fi", "á‹" => "faa", "áŒ" => "fee", "á" => "fe", "áŽ" => "fo", + "á" => "fwa", "á" => "pa", "á‘" => "pu", "á’" => "pi", "á“" => "paa", "á”" => "pee", + "á•" => "pe", "á–" => "po", "á—" => "pwa", "á˜" => "rya", "á™" => "mya", "áš" => "fya", + "á©" => "1", "áª" => "2", "á«" => "3", "á¬" => "4", "á­" => "5", "á®" => "6", + "á¯" => "7", "á°" => "8", "á±" => "9", "á²" => "10+", "á³" => "20+", "á´" => "30+", + "áµ" => "40+", "á¶" => "50+", "á·" => "60+", "á¸" => "70+", "á¹" => "80+", "áº" => "90+", + "á»" => "100+", "á¼" => "10,000+", "Ꭰ" => "a", "Ꭱ" => "e", "Ꭲ" => "i", "Ꭳ" => "o", + "Ꭴ" => "u", "Ꭵ" => "v", "Ꭶ" => "ga", "Ꭷ" => "ka", "Ꭸ" => "ge", "Ꭹ" => "gi", + "Ꭺ" => "go", "Ꭻ" => "gu", "Ꭼ" => "gv", "Ꭽ" => "ha", "Ꭾ" => "he", "Ꭿ" => "hi", + "Ꮀ" => "ho", "Ꮁ" => "hu", "Ꮂ" => "hv", "Ꮃ" => "la", "Ꮄ" => "le", "Ꮅ" => "li", + "Ꮆ" => "lo", "Ꮇ" => "lu", "Ꮈ" => "lv", "Ꮉ" => "ma", "Ꮊ" => "me", "Ꮋ" => "mi", + "Ꮌ" => "mo", "Ꮍ" => "mu", "Ꮎ" => "na", "Ꮏ" => "hna", "á€" => "nah", "á" => "ne", + "á‚" => "ni", "áƒ" => "no", "á„" => "nu", "á…" => "nv", "á†" => "qua", "á‡" => "que", + "áˆ" => "qui", "á‰" => "quo", "áŠ" => "quu", "á‹" => "quv", "áŒ" => "sa", "á" => "s", + "áŽ" => "se", "á" => "si", "á" => "so", "á‘" => "su", "á’" => "sv", "á“" => "da", + "á”" => "ta", "á•" => "de", "á–" => "te", "á—" => "di", "á˜" => "ti", "á™" => "do", + "áš" => "du", "á›" => "dv", "áœ" => "dla", "á" => "tla", "áž" => "tle", "áŸ" => "tli", + "á " => "tlo", "á¡" => "tlu", "á¢" => "tlv", "á£" => "tsa", "á¤" => "tse", "á¥" => "tsi", + "á¦" => "tso", "á§" => "tsu", "á¨" => "tsv", "á©" => "wa", "áª" => "we", "á«" => "wi", + "á¬" => "wo", "á­" => "wu", "á®" => "wv", "á¯" => "ya", "á°" => "ye", "á±" => "yi", + "á²" => "yo", "á³" => "yu", "á´" => "yv", "á" => "e", "á‚" => "aai", "áƒ" => "i", + "á„" => "ii", "á…" => "o", "á†" => "oo", "á‡" => "oo", "áˆ" => "ee", "á‰" => "i", + "áŠ" => "a", "á‹" => "aa", "áŒ" => "we", "á" => "we", "áŽ" => "wi", "á" => "wi", + "á" => "wii", "á‘" => "wii", "á’" => "wo", "á“" => "wo", "á”" => "woo", "á•" => "woo", + "á–" => "woo", "á—" => "wa", "á˜" => "wa", "á™" => "waa", "áš" => "waa", "á›" => "waa", + "áœ" => "ai", "á" => "w", "áŸ" => "t", "á " => "k", "á¡" => "sh", "á¢" => "s", + "á£" => "n", "á¤" => "w", "á¥" => "n", "á§" => "w", "á¨" => "c", "áª" => "l", + "á«" => "en", "á¬" => "in", "á­" => "on", "á®" => "an", "á¯" => "pe", "á°" => "paai", + "á±" => "pi", "á²" => "pii", "á³" => "po", "á´" => "poo", "áµ" => "poo", "á¶" => "hee", + "á·" => "hi", "á¸" => "pa", "á¹" => "paa", "áº" => "pwe", "á»" => "pwe", "á¼" => "pwi", + "á½" => "pwi", "á¾" => "pwii", "á¿" => "pwii", "á‘€" => "pwo", "á‘" => "pwo", "á‘‚" => "pwoo", + "ᑃ" => "pwoo", "á‘„" => "pwa", "á‘…" => "pwa", "ᑆ" => "pwaa", "ᑇ" => "pwaa", "ᑈ" => "pwaa", + "ᑉ" => "p", "á‘Š" => "p", "á‘‹" => "h", "á‘Œ" => "te", "á‘" => "taai", "á‘Ž" => "ti", + "á‘" => "tii", "á‘" => "to", "á‘‘" => "too", "á‘’" => "too", "á‘“" => "dee", "á‘”" => "di", + "á‘•" => "ta", "á‘–" => "taa", "á‘—" => "twe", "ᑘ" => "twe", "á‘™" => "twi", "á‘š" => "twi", + "á‘›" => "twii", "á‘œ" => "twii", "á‘" => "two", "á‘ž" => "two", "á‘Ÿ" => "twoo", "á‘ " => "twoo", + "á‘¡" => "twa", "á‘¢" => "twa", "á‘£" => "twaa", "ᑤ" => "twaa", "á‘¥" => "twaa", "ᑦ" => "t", + "ᑧ" => "tte", "ᑨ" => "tti", "á‘©" => "tto", "ᑪ" => "tta", "á‘«" => "ke", "ᑬ" => "kaai", + "á‘­" => "ki", "á‘®" => "kii", "ᑯ" => "ko", "á‘°" => "koo", "ᑱ" => "koo", "ᑲ" => "ka", + "ᑳ" => "kaa", "á‘´" => "kwe", "ᑵ" => "kwe", "ᑶ" => "kwi", "á‘·" => "kwi", "ᑸ" => "kwii", + "ᑹ" => "kwii", "ᑺ" => "kwo", "á‘»" => "kwo", "ᑼ" => "kwoo", "ᑽ" => "kwoo", "ᑾ" => "kwa", + "á‘¿" => "kwa", "á’€" => "kwaa", "á’" => "kwaa", "á’‚" => "kwaa", "á’ƒ" => "k", "á’„" => "kw", + "á’…" => "keh", "á’†" => "kih", "á’‡" => "koh", "á’ˆ" => "kah", "á’‰" => "ce", "á’Š" => "caai", + "á’‹" => "ci", "á’Œ" => "cii", "á’" => "co", "á’Ž" => "coo", "á’" => "coo", "á’" => "ca", + "á’‘" => "caa", "á’’" => "cwe", "á’“" => "cwe", "á’”" => "cwi", "á’•" => "cwi", "á’–" => "cwii", + "á’—" => "cwii", "á’˜" => "cwo", "á’™" => "cwo", "á’š" => "cwoo", "á’›" => "cwoo", "á’œ" => "cwa", + "á’" => "cwa", "á’ž" => "cwaa", "á’Ÿ" => "cwaa", "á’ " => "cwaa", "á’¡" => "c", "á’¢" => "th", + "á’£" => "me", "á’¤" => "maai", "á’¥" => "mi", "á’¦" => "mii", "á’§" => "mo", "á’¨" => "moo", + "á’©" => "moo", "á’ª" => "ma", "á’«" => "maa", "á’¬" => "mwe", "á’­" => "mwe", "á’®" => "mwi", + "á’¯" => "mwi", "á’°" => "mwii", "á’±" => "mwii", "á’²" => "mwo", "á’³" => "mwo", "á’´" => "mwoo", + "á’µ" => "mwoo", "á’¶" => "mwa", "á’·" => "mwa", "á’¸" => "mwaa", "á’¹" => "mwaa", "á’º" => "mwaa", + "á’»" => "m", "á’¼" => "m", "á’½" => "mh", "á’¾" => "m", "á’¿" => "m", "á“€" => "ne", + "á“" => "naai", "á“‚" => "ni", "ᓃ" => "nii", "á“„" => "no", "á“…" => "noo", "ᓆ" => "noo", + "ᓇ" => "na", "ᓈ" => "naa", "ᓉ" => "nwe", "á“Š" => "nwe", "á“‹" => "nwa", "á“Œ" => "nwa", + "á“" => "nwaa", "á“Ž" => "nwaa", "á“" => "nwaa", "á“" => "n", "á“‘" => "ng", "á“’" => "nh", + "á““" => "le", "á“”" => "laai", "á“•" => "li", "á“–" => "lii", "á“—" => "lo", "ᓘ" => "loo", + "á“™" => "loo", "á“š" => "la", "á“›" => "laa", "á“œ" => "lwe", "á“" => "lwe", "á“ž" => "lwi", + "á“Ÿ" => "lwi", "á“ " => "lwii", "á“¡" => "lwii", "á“¢" => "lwo", "á“£" => "lwo", "ᓤ" => "lwoo", + "á“¥" => "lwoo", "ᓦ" => "lwa", "ᓧ" => "lwa", "ᓨ" => "lwaa", "á“©" => "lwaa", "ᓪ" => "l", + "á“«" => "l", "ᓬ" => "l", "á“­" => "se", "á“®" => "saai", "ᓯ" => "si", "á“°" => "sii", + "ᓱ" => "so", "ᓲ" => "soo", "ᓳ" => "soo", "á“´" => "sa", "ᓵ" => "saa", "ᓶ" => "swe", + "á“·" => "swe", "ᓸ" => "swi", "ᓹ" => "swi", "ᓺ" => "swii", "á“»" => "swii", "ᓼ" => "swo", + "ᓽ" => "swo", "ᓾ" => "swoo", "á“¿" => "swoo", "á”" => "swa", "ᔂ" => "swaa", "ᔃ" => "swaa", + "ᔄ" => "swaa", "á”…" => "s", "ᔆ" => "s", "ᔇ" => "sw", "ᔈ" => "s", "ᔉ" => "sk", + "ᔊ" => "skw", "ᔋ" => "sW", "ᔌ" => "spwa", "á”" => "stwa", "ᔎ" => "skwa", "á”" => "scwa", + "á”" => "she", "ᔑ" => "shi", "á”’" => "shii", "ᔓ" => "sho", "á””" => "shoo", "ᔕ" => "sha", + "á”–" => "shaa", "á”—" => "shwe", "ᔘ" => "shwe", "á”™" => "shwi", "ᔚ" => "shwi", "á”›" => "shwii", + "ᔜ" => "shwii", "á”" => "shwo", "ᔞ" => "shwo", "ᔟ" => "shwoo", "á” " => "shwoo", "ᔡ" => "shwa", + "ᔢ" => "shwa", "ᔣ" => "shwaa", "ᔤ" => "shwaa", "ᔥ" => "sh", "ᔦ" => "ye", "ᔧ" => "yaai", + "ᔨ" => "yi", "ᔩ" => "yii", "ᔪ" => "yo", "ᔫ" => "yoo", "ᔬ" => "yoo", "á”­" => "ya", + "á”®" => "yaa", "ᔯ" => "ywe", "á”°" => "ywe", "á”±" => "ywi", "ᔲ" => "ywi", "ᔳ" => "ywii", + "á”´" => "ywii", "ᔵ" => "ywo", "ᔶ" => "ywo", "á”·" => "ywoo", "ᔸ" => "ywoo", "ᔹ" => "ywa", + "ᔺ" => "ywa", "á”»" => "ywaa", "ᔼ" => "ywaa", "ᔽ" => "ywaa", "ᔾ" => "y", "ᔿ" => "y", + "á•€" => "y", "á•" => "yi", "á•‚" => "re", "ᕃ" => "re", "á•„" => "le", "á•…" => "raai", + "ᕆ" => "ri", "ᕇ" => "rii", "ᕈ" => "ro", "ᕉ" => "roo", "á•Š" => "lo", "á•‹" => "ra", + "á•Œ" => "raa", "á•" => "la", "á•Ž" => "rwaa", "á•" => "rwaa", "á•" => "r", "á•‘" => "r", + "á•’" => "r", "á•“" => "fe", "á•”" => "faai", "á••" => "fi", "á•–" => "fii", "á•—" => "fo", + "ᕘ" => "foo", "á•™" => "fa", "á•š" => "faa", "á•›" => "fwaa", "á•œ" => "fwaa", "á•" => "f", + "á•ž" => "the", "á•Ÿ" => "the", "á• " => "thi", "á•¡" => "thi", "á•¢" => "thii", "á•£" => "thii", + "ᕤ" => "tho", "á•¥" => "thoo", "ᕦ" => "tha", "ᕧ" => "thaa", "ᕨ" => "thwaa", "á•©" => "thwaa", + "ᕪ" => "th", "á•«" => "tthe", "ᕬ" => "tthi", "á•­" => "ttho", "á•®" => "ttha", "ᕯ" => "tth", + "á•°" => "tye", "ᕱ" => "tyi", "ᕲ" => "tyo", "ᕳ" => "tya", "á•´" => "he", "ᕵ" => "hi", + "ᕶ" => "hii", "á•·" => "ho", "ᕸ" => "hoo", "ᕹ" => "ha", "ᕺ" => "haa", "á•»" => "h", + "ᕼ" => "h", "ᕽ" => "hk", "ᕾ" => "qaai", "á•¿" => "qi", "á–€" => "qii", "á–" => "qo", + "á–‚" => "qoo", "á–ƒ" => "qa", "á–„" => "qaa", "á–…" => "q", "á–†" => "tlhe", "á–‡" => "tlhi", + "á–ˆ" => "tlho", "á–‰" => "tlha", "á–Š" => "re", "á–‹" => "ri", "á–Œ" => "ro", "á–" => "ra", + "á–Ž" => "ngaai", "á–" => "ngi", "á–" => "ngii", "á–‘" => "ngo", "á–’" => "ngoo", "á–“" => "nga", + "á–”" => "ngaa", "á–•" => "ng", "á––" => "nng", "á–—" => "she", "á–˜" => "shi", "á–™" => "sho", + "á–š" => "sha", "á–›" => "the", "á–œ" => "thi", "á–" => "tho", "á–ž" => "tha", "á–Ÿ" => "th", + "á– " => "lhi", "á–¡" => "lhii", "á–¢" => "lho", "á–£" => "lhoo", "á–¤" => "lha", "á–¥" => "lhaa", + "á–¦" => "lh", "á–§" => "the", "á–¨" => "thi", "á–©" => "thii", "á–ª" => "tho", "á–«" => "thoo", + "á–¬" => "tha", "á–­" => "thaa", "á–®" => "th", "á–¯" => "b", "á–°" => "e", "á–±" => "i", + "á–²" => "o", "á–³" => "a", "á–´" => "we", "á–µ" => "wi", "á–¶" => "wo", "á–·" => "wa", + "á–¸" => "ne", "á–¹" => "ni", "á–º" => "no", "á–»" => "na", "á–¼" => "ke", "á–½" => "ki", + "á–¾" => "ko", "á–¿" => "ka", "á—€" => "he", "á—" => "hi", "á—‚" => "ho", "á—ƒ" => "ha", + "á—„" => "ghu", "á—…" => "gho", "á—†" => "ghe", "á—‡" => "ghee", "á—ˆ" => "ghi", "á—‰" => "gha", + "á—Š" => "ru", "á—‹" => "ro", "á—Œ" => "re", "á—" => "ree", "á—Ž" => "ri", "á—" => "ra", + "á—" => "wu", "á—‘" => "wo", "á—’" => "we", "á—“" => "wee", "á—”" => "wi", "á—•" => "wa", + "á—–" => "hwu", "á——" => "hwo", "á—˜" => "hwe", "á—™" => "hwee", "á—š" => "hwi", "á—›" => "hwa", + "á—œ" => "thu", "á—" => "tho", "á—ž" => "the", "á—Ÿ" => "thee", "á— " => "thi", "á—¡" => "tha", + "á—¢" => "ttu", "á—£" => "tto", "á—¤" => "tte", "á—¥" => "ttee", "á—¦" => "tti", "á—§" => "tta", + "á—¨" => "pu", "á—©" => "po", "á—ª" => "pe", "á—«" => "pee", "á—¬" => "pi", "á—­" => "pa", + "á—®" => "p", "á—¯" => "gu", "á—°" => "go", "á—±" => "ge", "á—²" => "gee", "á—³" => "gi", + "á—´" => "ga", "á—µ" => "khu", "á—¶" => "kho", "á—·" => "khe", "á—¸" => "khee", "á—¹" => "khi", + "á—º" => "kha", "á—»" => "kku", "á—¼" => "kko", "á—½" => "kke", "á—¾" => "kkee", "á—¿" => "kki", + "á˜" => "kk", "ᘂ" => "nu", "ᘃ" => "no", "ᘄ" => "ne", "ᘅ" => "nee", "ᘆ" => "ni", + "ᘇ" => "na", "ᘈ" => "mu", "ᘉ" => "mo", "ᘊ" => "me", "ᘋ" => "mee", "ᘌ" => "mi", + "á˜" => "ma", "ᘎ" => "yu", "á˜" => "yo", "á˜" => "ye", "ᘑ" => "yee", "ᘒ" => "yi", + "ᘓ" => "ya", "ᘔ" => "ju", "ᘕ" => "ju", "ᘖ" => "jo", "ᘗ" => "je", "ᘘ" => "jee", + "ᘙ" => "ji", "ᘚ" => "ji", "ᘛ" => "ja", "ᘜ" => "jju", "á˜" => "jjo", "ᘞ" => "jje", + "ᘟ" => "jjee", "ᘠ" => "jji", "ᘡ" => "jja", "ᘢ" => "lu", "ᘣ" => "lo", "ᘤ" => "le", + "ᘥ" => "lee", "ᘦ" => "li", "ᘧ" => "la", "ᘨ" => "dlu", "ᘩ" => "dlo", "ᘪ" => "dle", + "ᘫ" => "dlee", "ᘬ" => "dli", "ᘭ" => "dla", "ᘮ" => "lhu", "ᘯ" => "lho", "ᘰ" => "lhe", + "ᘱ" => "lhee", "ᘲ" => "lhi", "ᘳ" => "lha", "ᘴ" => "tlhu", "ᘵ" => "tlho", "ᘶ" => "tlhe", + "ᘷ" => "tlhee", "ᘸ" => "tlhi", "ᘹ" => "tlha", "ᘺ" => "tlu", "ᘻ" => "tlo", "ᘼ" => "tle", + "ᘽ" => "tlee", "ᘾ" => "tli", "ᘿ" => "tla", "ᙀ" => "zu", "á™" => "zo", "ᙂ" => "ze", + "ᙃ" => "zee", "ᙄ" => "zi", "á™…" => "za", "ᙆ" => "z", "ᙇ" => "z", "ᙈ" => "dzu", + "ᙉ" => "dzo", "ᙊ" => "dze", "ᙋ" => "dzee", "ᙌ" => "dzi", "á™" => "dza", "ᙎ" => "su", + "á™" => "so", "á™" => "se", "ᙑ" => "see", "á™’" => "si", "ᙓ" => "sa", "á™”" => "shu", + "ᙕ" => "sho", "á™–" => "she", "á™—" => "shee", "ᙘ" => "shi", "á™™" => "sha", "ᙚ" => "sh", + "á™›" => "tsu", "ᙜ" => "tso", "á™" => "tse", "ᙞ" => "tsee", "ᙟ" => "tsi", "á™ " => "tsa", + "ᙡ" => "chu", "ᙢ" => "cho", "ᙣ" => "che", "ᙤ" => "chee", "ᙥ" => "chi", "ᙦ" => "cha", + "ᙧ" => "ttsu", "ᙨ" => "ttso", "ᙩ" => "ttse", "ᙪ" => "ttsee", "ᙫ" => "ttsi", "ᙬ" => "ttsa", + "á™­" => "X", "ᙯ" => "qai", "á™°" => "ngai", "á™±" => "nngi", "ᙲ" => "nngii", "ᙳ" => "nngo", + "á™´" => "nngoo", "ᙵ" => "nnga", "ᙶ" => "nngaa", "áš" => "b", "áš‚" => "l", "ᚃ" => "f", + "áš„" => "s", "áš…" => "n", "ᚆ" => "h", "ᚇ" => "d", "ᚈ" => "t", "ᚉ" => "c", + "ᚊ" => "q", "áš‹" => "m", "ᚌ" => "g", "áš" => "ng", "ᚎ" => "z", "áš" => "r", + "áš" => "a", "áš‘" => "o", "áš’" => "u", "áš“" => "e", "áš”" => "i", "áš•" => "ch", + "áš–" => "th", "áš—" => "ph", "ᚘ" => "p", "áš™" => "x", "ášš" => "p", "áš " => "f", + "áš¡" => "v", "ᚢ" => "u", "ᚣ" => "yr", "ᚤ" => "y", "ᚥ" => "w", "ᚦ" => "th", + "ᚧ" => "th", "ᚨ" => "a", "áš©" => "o", "ᚪ" => "ac", "áš«" => "ae", "ᚬ" => "o", + "áš­" => "o", "áš®" => "o", "ᚯ" => "oe", "áš°" => "on", "áš±" => "r", "áš²" => "k", + "áš³" => "c", "áš´" => "k", "ášµ" => "g", "ᚶ" => "ng", "áš·" => "g", "ᚸ" => "g", + "áš¹" => "w", "ᚺ" => "h", "áš»" => "h", "áš¼" => "h", "áš½" => "h", "áš¾" => "n", + "áš¿" => "n", "ᛀ" => "n", "á›" => "i", "ᛂ" => "e", "ᛃ" => "j", "ᛄ" => "g", + "á›…" => "ae", "ᛆ" => "a", "ᛇ" => "eo", "ᛈ" => "p", "ᛉ" => "z", "ᛊ" => "s", + "ᛋ" => "s", "ᛌ" => "s", "á›" => "c", "ᛎ" => "z", "á›" => "t", "á›" => "t", + "ᛑ" => "d", "á›’" => "b", "ᛓ" => "b", "á›”" => "p", "ᛕ" => "p", "á›–" => "e", + "á›—" => "m", "ᛘ" => "m", "á›™" => "m", "ᛚ" => "l", "á››" => "l", "ᛜ" => "ng", + "á›" => "ng", "ᛞ" => "d", "ᛟ" => "o", "á› " => "ear", "ᛡ" => "ior", "ᛢ" => "qu", + "ᛣ" => "qu", "ᛤ" => "qu", "ᛥ" => "s", "ᛦ" => "yr", "ᛧ" => "yr", "ᛨ" => "yr", + "ᛩ" => "q", "ᛪ" => "x", "á›®" => "17", "ᛯ" => "18", "á›°" => "19", "ក" => "k", + "áž" => "kh", "áž‚" => "g", "ឃ" => "gh", "áž„" => "ng", "áž…" => "c", "ឆ" => "ch", + "ជ" => "j", "ឈ" => "jh", "ញ" => "ny", "ដ" => "t", "áž‹" => "tth", "ឌ" => "d", + "áž" => "ddh", "ណ" => "nn", "áž" => "t", "áž" => "th", "áž‘" => "d", "áž’" => "dh", + "áž“" => "n", "áž”" => "p", "áž•" => "ph", "áž–" => "b", "áž—" => "bh", "ម" => "m", + "áž™" => "y", "ážš" => "r", "áž›" => "l", "ážœ" => "v", "áž" => "sh", "ážž" => "ss", + "ស" => "s", "áž " => "h", "áž¡" => "l", "អ" => "q", "ឣ" => "a", "ឤ" => "aa", + "ឥ" => "i", "ឦ" => "ii", "ឧ" => "u", "ឨ" => "uk", "áž©" => "uu", "ឪ" => "uuv", + "áž«" => "ry", "ឬ" => "ryy", "áž­" => "ly", "áž®" => "lyy", "ឯ" => "e", "áž°" => "ai", + "áž±" => "oo", "áž²" => "oo", "áž³" => "au", "áž´" => "a", "ážµ" => "aa", "ា" => "aa", + "áž·" => "i", "ី" => "ii", "áž¹" => "y", "ឺ" => "yy", "áž»" => "u", "áž¼" => "uu", + "áž½" => "ua", "áž¾" => "oe", "áž¿" => "ya", "ៀ" => "ie", "áŸ" => "e", "ែ" => "ae", + "ៃ" => "ai", "ោ" => "oo", "ៅ" => "au", "ំ" => "M", "ះ" => "H", "ៈ" => "a`", + "៌" => "r", "៛" => "KR", "១" => "1", "២" => "2", "៣" => "3", "៤" => "4", + "៥" => "5", "៦" => "6", "៧" => "7", "៨" => "8", "៩" => "9", "á ‘" => "1", + "á ’" => "2", "á “" => "3", "á ”" => "4", "á •" => "5", "á –" => "6", "á —" => "7", + "á ˜" => "8", "á ™" => "9", "á  " => "a", "á ¡" => "e", "á ¢" => "i", "á £" => "o", + "á ¤" => "u", "á ¥" => "O", "á ¦" => "U", "á §" => "ee", "á ¨" => "n", "á ©" => "ng", + "á ª" => "b", "á «" => "p", "á ¬" => "q", "á ­" => "g", "á ®" => "m", "á ¯" => "l", + "á °" => "s", "á ±" => "sh", "á ²" => "t", "á ³" => "d", "á ´" => "ch", "á µ" => "j", + "á ¶" => "y", "á ·" => "r", "á ¸" => "w", "á ¹" => "f", "á º" => "k", "á »" => "kha", + "á ¼" => "ts", "á ½" => "z", "á ¾" => "h", "á ¿" => "zr", "á¡€" => "lh", "á¡" => "zh", + "á¡‚" => "ch", "á¡„" => "e", "á¡…" => "i", "ᡆ" => "o", "ᡇ" => "u", "ᡈ" => "O", + "ᡉ" => "U", "á¡Š" => "ng", "á¡‹" => "b", "á¡Œ" => "p", "á¡" => "q", "á¡Ž" => "g", + "á¡" => "m", "á¡" => "t", "á¡‘" => "d", "á¡’" => "ch", "á¡“" => "j", "á¡”" => "ts", + "á¡•" => "y", "á¡–" => "w", "á¡—" => "k", "ᡘ" => "g", "á¡™" => "h", "á¡š" => "jy", + "á¡›" => "ny", "á¡œ" => "dz", "á¡" => "e", "á¡ž" => "i", "á¡Ÿ" => "iy", "á¡ " => "U", + "á¡¡" => "u", "á¡¢" => "ng", "á¡£" => "k", "ᡤ" => "g", "á¡¥" => "h", "ᡦ" => "p", + "ᡧ" => "sh", "ᡨ" => "t", "á¡©" => "d", "ᡪ" => "j", "á¡«" => "f", "ᡬ" => "g", + "á¡­" => "h", "á¡®" => "ts", "ᡯ" => "z", "á¡°" => "r", "ᡱ" => "ch", "ᡲ" => "zh", + "ᡳ" => "i", "á¡´" => "k", "ᡵ" => "r", "ᡶ" => "f", "á¡·" => "zh", "á¢" => "H", + "ᢂ" => "X", "ᢃ" => "W", "ᢄ" => "M", "ᢅ" => "3", "ᢆ" => "333", "ᢇ" => "a", + "ᢈ" => "i", "ᢉ" => "k", "ᢊ" => "ng", "ᢋ" => "c", "ᢌ" => "tt", "á¢" => "tth", + "ᢎ" => "dd", "á¢" => "nn", "á¢" => "t", "ᢑ" => "d", "ᢒ" => "p", "ᢓ" => "ph", + "ᢔ" => "ss", "ᢕ" => "zh", "ᢖ" => "z", "ᢗ" => "a", "ᢘ" => "t", "ᢙ" => "zh", + "ᢚ" => "gh", "ᢛ" => "ng", "ᢜ" => "c", "á¢" => "jh", "ᢞ" => "tta", "ᢟ" => "ddh", + "ᢠ" => "t", "ᢡ" => "dh", "ᢢ" => "ss", "ᢣ" => "cy", "ᢤ" => "zh", "ᢥ" => "z", + "ᢦ" => "u", "ᢧ" => "y", "ᢨ" => "bh", "á¸" => "a", "Ḃ" => "B", "ḃ" => "b", + "Ḅ" => "B", "ḅ" => "b", "Ḇ" => "B", "ḇ" => "b", "Ḉ" => "C", "ḉ" => "c", + "Ḋ" => "D", "ḋ" => "d", "Ḍ" => "D", "á¸" => "d", "Ḏ" => "D", "á¸" => "d", + "á¸" => "D", "ḑ" => "d", "Ḓ" => "D", "ḓ" => "d", "Ḕ" => "E", "ḕ" => "e", + "Ḗ" => "E", "ḗ" => "e", "Ḙ" => "E", "ḙ" => "e", "Ḛ" => "E", "ḛ" => "e", + "Ḝ" => "E", "á¸" => "e", "Ḟ" => "F", "ḟ" => "f", "Ḡ" => "G", "ḡ" => "g", + "Ḣ" => "H", "ḣ" => "h", "Ḥ" => "H", "ḥ" => "h", "Ḧ" => "H", "ḧ" => "h", + "Ḩ" => "H", "ḩ" => "h", "Ḫ" => "H", "ḫ" => "h", "Ḭ" => "I", "ḭ" => "i", + "Ḯ" => "I", "ḯ" => "i", "Ḱ" => "K", "ḱ" => "k", "Ḳ" => "K", "ḳ" => "k", + "Ḵ" => "K", "ḵ" => "k", "Ḷ" => "L", "ḷ" => "l", "Ḹ" => "L", "ḹ" => "l", + "Ḻ" => "L", "ḻ" => "l", "Ḽ" => "L", "ḽ" => "l", "Ḿ" => "M", "ḿ" => "m", + "á¹€" => "M", "á¹" => "m", "Ṃ" => "M", "ṃ" => "m", "Ṅ" => "N", "á¹…" => "n", + "Ṇ" => "N", "ṇ" => "n", "Ṉ" => "N", "ṉ" => "n", "Ṋ" => "N", "ṋ" => "n", + "Ṍ" => "O", "á¹" => "o", "Ṏ" => "O", "á¹" => "o", "á¹" => "O", "ṑ" => "o", + "á¹’" => "O", "ṓ" => "o", "á¹”" => "P", "ṕ" => "p", "á¹–" => "P", "á¹—" => "p", + "Ṙ" => "R", "á¹™" => "r", "Ṛ" => "R", "á¹›" => "r", "Ṝ" => "R", "á¹" => "r", + "Ṟ" => "R", "ṟ" => "r", "á¹ " => "S", "ṡ" => "s", "á¹¢" => "S", "á¹£" => "s", + "Ṥ" => "S", "á¹¥" => "s", "Ṧ" => "S", "ṧ" => "s", "Ṩ" => "S", "ṩ" => "s", + "Ṫ" => "T", "ṫ" => "t", "Ṭ" => "T", "á¹­" => "t", "á¹®" => "T", "ṯ" => "t", + "á¹°" => "T", "á¹±" => "t", "á¹²" => "U", "á¹³" => "u", "á¹´" => "U", "á¹µ" => "u", + "Ṷ" => "U", "á¹·" => "u", "Ṹ" => "U", "á¹¹" => "u", "Ṻ" => "U", "á¹»" => "u", + "á¹¼" => "V", "á¹½" => "v", "á¹¾" => "V", "ṿ" => "v", "Ẁ" => "W", "áº" => "w", + "Ẃ" => "W", "ẃ" => "w", "Ẅ" => "W", "ẅ" => "w", "Ẇ" => "W", "ẇ" => "w", + "Ẉ" => "W", "ẉ" => "w", "Ẋ" => "X", "ẋ" => "x", "Ẍ" => "X", "áº" => "x", + "Ẏ" => "Y", "áº" => "y", "áº" => "Z", "ẑ" => "z", "Ẓ" => "Z", "ẓ" => "z", + "Ẕ" => "Z", "ẕ" => "z", "ẖ" => "h", "ẗ" => "t", "ẘ" => "w", "ẙ" => "y", + "ẚ" => "a", "ẛ" => "S", "Ạ" => "A", "ạ" => "a", "Ả" => "A", "ả" => "a", + "Ấ" => "A", "ấ" => "a", "Ầ" => "A", "ầ" => "a", "Ẩ" => "A", "ẩ" => "a", + "Ẫ" => "A", "ẫ" => "a", "Ậ" => "A", "ậ" => "a", "Ắ" => "A", "ắ" => "a", + "Ằ" => "A", "ằ" => "a", "Ẳ" => "A", "ẳ" => "a", "Ẵ" => "A", "ẵ" => "a", + "Ặ" => "A", "ặ" => "a", "Ẹ" => "E", "ẹ" => "e", "Ẻ" => "E", "ẻ" => "e", + "Ẽ" => "E", "ẽ" => "e", "Ế" => "E", "ế" => "e", "Ề" => "E", "á»" => "e", + "Ể" => "E", "ể" => "e", "Ễ" => "E", "á»…" => "e", "Ệ" => "E", "ệ" => "e", + "Ỉ" => "I", "ỉ" => "i", "Ị" => "I", "ị" => "i", "Ọ" => "O", "á»" => "o", + "Ỏ" => "O", "á»" => "o", "á»" => "O", "ố" => "o", "á»’" => "O", "ồ" => "o", + "á»”" => "O", "ổ" => "o", "á»–" => "O", "á»—" => "o", "Ộ" => "O", "á»™" => "o", + "Ớ" => "O", "á»›" => "o", "Ờ" => "O", "á»" => "o", "Ở" => "O", "ở" => "o", + "á» " => "O", "ỡ" => "o", "Ợ" => "O", "ợ" => "o", "Ụ" => "U", "ụ" => "u", + "Ủ" => "U", "ủ" => "u", "Ứ" => "U", "ứ" => "u", "Ừ" => "U", "ừ" => "u", + "Ử" => "U", "á»­" => "u", "á»®" => "U", "ữ" => "u", "á»°" => "U", "á»±" => "u", + "Ỳ" => "Y", "ỳ" => "y", "á»´" => "Y", "ỵ" => "y", "Ỷ" => "Y", "á»·" => "y", + "Ỹ" => "Y", "ỹ" => "y", "á¼" => "a", "ἂ" => "a", "ἃ" => "a", "ἄ" => "a", + "á¼…" => "a", "ἆ" => "a", "ἇ" => "a", "Ἀ" => "A", "Ἁ" => "A", "Ἂ" => "A", + "Ἃ" => "A", "Ἄ" => "A", "á¼" => "A", "Ἆ" => "A", "á¼" => "A", "á¼" => "e", + "ἑ" => "e", "á¼’" => "e", "ἓ" => "e", "á¼”" => "e", "ἕ" => "e", "Ἐ" => "E", + "á¼™" => "E", "Ἒ" => "E", "á¼›" => "E", "Ἔ" => "E", "á¼" => "E", "á¼ " => "e", + "ἡ" => "e", "á¼¢" => "e", "á¼£" => "e", "ἤ" => "e", "á¼¥" => "e", "ἦ" => "e", + "ἧ" => "e", "Ἠ" => "E", "Ἡ" => "E", "Ἢ" => "E", "Ἣ" => "E", "Ἤ" => "E", + "á¼­" => "E", "á¼®" => "E", "Ἧ" => "E", "á¼°" => "i", "á¼±" => "i", "á¼²" => "i", + "á¼³" => "i", "á¼´" => "i", "á¼µ" => "i", "ἶ" => "i", "á¼·" => "i", "Ἰ" => "I", + "á¼¹" => "I", "Ἲ" => "I", "á¼»" => "I", "á¼¼" => "I", "á¼½" => "I", "á¼¾" => "I", + "Ἷ" => "I", "á½€" => "o", "á½" => "o", "ὂ" => "o", "ὃ" => "o", "ὄ" => "o", + "á½…" => "o", "Ὀ" => "O", "Ὁ" => "O", "Ὂ" => "O", "Ὃ" => "O", "Ὄ" => "O", + "á½" => "O", "á½" => "u", "ὑ" => "u", "á½’" => "u", "ὓ" => "u", "á½”" => "u", + "ὕ" => "u", "á½–" => "u", "á½—" => "u", "á½™" => "U", "á½›" => "U", "á½" => "U", + "Ὗ" => "U", "á½ " => "o", "ὡ" => "o", "á½¢" => "o", "á½£" => "o", "ὤ" => "o", + "á½¥" => "o", "ὦ" => "o", "ὧ" => "o", "Ὠ" => "O", "Ὡ" => "O", "Ὢ" => "O", + "Ὣ" => "O", "Ὤ" => "O", "á½­" => "O", "á½®" => "O", "Ὧ" => "O", "á½°" => "a", + "á½±" => "a", "á½²" => "e", "á½³" => "e", "á½´" => "e", "á½µ" => "e", "ὶ" => "i", + "á½·" => "i", "ὸ" => "o", "á½¹" => "o", "ὺ" => "u", "á½»" => "u", "á½¼" => "o", + "á½½" => "o", "á¾€" => "a", "á¾" => "a", "ᾂ" => "a", "ᾃ" => "a", "ᾄ" => "a", + "á¾…" => "a", "ᾆ" => "a", "ᾇ" => "a", "ᾈ" => "A", "ᾉ" => "A", "ᾊ" => "A", + "ᾋ" => "A", "ᾌ" => "A", "á¾" => "A", "ᾎ" => "A", "á¾" => "A", "á¾" => "e", + "ᾑ" => "e", "á¾’" => "e", "ᾓ" => "e", "á¾”" => "e", "ᾕ" => "e", "á¾–" => "e", + "á¾—" => "e", "ᾘ" => "E", "á¾™" => "E", "ᾚ" => "E", "á¾›" => "E", "ᾜ" => "E", + "á¾" => "E", "ᾞ" => "E", "ᾟ" => "E", "á¾ " => "o", "ᾡ" => "o", "á¾¢" => "o", + "á¾£" => "o", "ᾤ" => "o", "á¾¥" => "o", "ᾦ" => "o", "ᾧ" => "o", "ᾨ" => "O", + "ᾩ" => "O", "ᾪ" => "O", "ᾫ" => "O", "ᾬ" => "O", "á¾­" => "O", "á¾®" => "O", + "ᾯ" => "O", "á¾°" => "a", "á¾±" => "a", "á¾²" => "a", "á¾³" => "a", "á¾´" => "a", + "ᾶ" => "a", "á¾·" => "a", "Ᾰ" => "A", "á¾¹" => "A", "Ὰ" => "A", "á¾»" => "A", + "á¾¼" => "A", "á¾¾" => "i", "á¿‚" => "e", "ῃ" => "e", "á¿„" => "e", "ῆ" => "e", + "ῇ" => "e", "Ὲ" => "E", "Έ" => "E", "á¿Š" => "E", "á¿‹" => "E", "á¿Œ" => "E", + "á¿" => "i", "á¿‘" => "i", "á¿’" => "i", "á¿“" => "i", "á¿–" => "i", "á¿—" => "i", + "Ῐ" => "I", "á¿™" => "I", "á¿š" => "I", "á¿›" => "I", "á¿ " => "u", "á¿¡" => "u", + "á¿¢" => "u", "á¿£" => "u", "ῤ" => "R", "á¿¥" => "R", "ῦ" => "u", "ῧ" => "u", + "Ῠ" => "U", "á¿©" => "U", "Ὺ" => "U", "á¿«" => "U", "Ῥ" => "R", "ῲ" => "o", + "ῳ" => "o", "á¿´" => "o", "ῶ" => "o", "á¿·" => "o", "Ὸ" => "O", "Ό" => "O", + "Ὼ" => "O", "á¿»" => "O", "ῼ" => "O", "‰" => "%0", "‱" => "%00", "âŠ" => "7", + "â‹" => "PP", "â´" => "4", "âµ" => "5", "â¶" => "6", "â·" => "7", "â¸" => "8", + "â¹" => "9", "â¿" => "n", "â‚" => "1", "â‚‚" => "2", "₃" => "3", "â‚„" => "4", + "â‚…" => "5", "₆" => "6", "₇" => "7", "₈" => "8", "₉" => "9", "â‚ " => "ECU", + "â‚¡" => "CL", "â‚¢" => "Cr", "â‚£" => "FF", "₤" => "L", "â‚¥" => "mil", "₦" => "N", + "₧" => "Pts", "₨" => "Rs", "â‚©" => "W", "₪" => "NS", "â‚«" => "D", "€" => "EU", + "â‚­" => "K", "â‚®" => "T", "₯" => "Dr", "â…“" => "1/3", "â…”" => "2/3", "â…•" => "1/5", + "â…–" => "2/5", "â…—" => "3/5", "â…˜" => "4/5", "â…™" => "1/6", "â…š" => "5/6", "â…›" => "1/8", + "â…œ" => "3/8", "â…" => "5/8", "â…ž" => "7/8", "â…Ÿ" => "1", "â… " => "I", "â…¡" => "II", + "â…¢" => "III", "â…£" => "IV", "â…¤" => "V", "â…¥" => "VI", "â…¦" => "VII", "â…§" => "VIII", + "â…¨" => "IX", "â…©" => "X", "â…ª" => "XI", "â…«" => "XII", "â…¬" => "L", "â…­" => "C", + "â…®" => "D", "â…¯" => "M", "â…°" => "i", "â…±" => "ii", "â…²" => "iii", "â…³" => "iv", + "â…´" => "v", "â…µ" => "vi", "â…¶" => "vii", "â…·" => "viii", "â…¸" => "ix", "â…¹" => "x", + "â…º" => "xi", "â…»" => "xii", "â…¼" => "l", "â…½" => "c", "â…¾" => "d", "â…¿" => "m", + "ↀ" => "(D", "â†" => "D)", "↷" => "V", "↺" => "V", "╳" => "X", "â–¼" => "V", + "â–½" => "V", "â–¾" => "V", "â–¿" => "V", "â—¯" => "O", "â " => "a", "â ‚" => "1", + "â ƒ" => "b", "â …" => "k", "â †" => "2", "â ‡" => "l", "â ‰" => "c", "â Š" => "i", + "â ‹" => "f", "â " => "m", "â Ž" => "s", "â " => "p", "â ‘" => "e", "â ’" => "3", + "â “" => "h", "â ”" => "9", "â •" => "o", "â –" => "6", "â —" => "r", "â ™" => "d", + "â š" => "j", "â ›" => "g", "â " => "n", "â ž" => "t", "â Ÿ" => "q", "â ¢" => "5", + "â ¥" => "u", "â ¦" => "8", "â §" => "v", "â ­" => "x", "â ²" => "4", "â µ" => "z", + "â ¶" => "7", "â º" => "w", "â ½" => "y", "â¡€" => "d7", "â¡" => "d17", "â¡‚" => "d27", + "⡃" => "d127", "â¡„" => "d37", "â¡…" => "d137", "⡆" => "d237", "⡇" => "d1237", "⡈" => "d47", + "⡉" => "d147", "â¡Š" => "d247", "â¡‹" => "d1247", "â¡Œ" => "d347", "â¡" => "d1347", "â¡Ž" => "d2347", + "â¡" => "d12347", "â¡" => "d57", "â¡‘" => "d157", "â¡’" => "d257", "â¡“" => "d1257", "â¡”" => "d357", + "â¡•" => "d1357", "â¡–" => "d2357", "â¡—" => "d12357", "⡘" => "d457", "â¡™" => "d1457", "â¡š" => "d2457", + "â¡›" => "d12457", "â¡œ" => "d3457", "â¡" => "d13457", "â¡ž" => "d23457", "â¡Ÿ" => "d123457", "â¡ " => "d67", + "â¡¡" => "d167", "â¡¢" => "d267", "â¡£" => "d1267", "⡤" => "d367", "â¡¥" => "d1367", "⡦" => "d2367", + "⡧" => "d12367", "⡨" => "d467", "â¡©" => "d1467", "⡪" => "d2467", "â¡«" => "d12467", "⡬" => "d3467", + "â¡­" => "d13467", "â¡®" => "d23467", "⡯" => "d123467", "â¡°" => "d567", "⡱" => "d1567", "⡲" => "d2567", + "⡳" => "d12567", "â¡´" => "d3567", "⡵" => "d13567", "⡶" => "d23567", "â¡·" => "d123567", "⡸" => "d4567", + "⡹" => "d14567", "⡺" => "d24567", "â¡»" => "d124567", "⡼" => "d34567", "⡽" => "d134567", "⡾" => "d234567", + "â¡¿" => "d1234567", "⢀" => "d8", "â¢" => "d18", "⢂" => "d28", "⢃" => "d128", "⢄" => "d38", + "⢅" => "d138", "⢆" => "d238", "⢇" => "d1238", "⢈" => "d48", "⢉" => "d148", "⢊" => "d248", + "⢋" => "d1248", "⢌" => "d348", "â¢" => "d1348", "⢎" => "d2348", "â¢" => "d12348", "â¢" => "d58", + "⢑" => "d158", "⢒" => "d258", "⢓" => "d1258", "⢔" => "d358", "⢕" => "d1358", "⢖" => "d2358", + "⢗" => "d12358", "⢘" => "d458", "⢙" => "d1458", "⢚" => "d2458", "⢛" => "d12458", "⢜" => "d3458", + "â¢" => "d13458", "⢞" => "d23458", "⢟" => "d123458", "⢠" => "d68", "⢡" => "d168", "⢢" => "d268", + "⢣" => "d1268", "⢤" => "d368", "⢥" => "d1368", "⢦" => "d2368", "⢧" => "d12368", "⢨" => "d468", + "⢩" => "d1468", "⢪" => "d2468", "⢫" => "d12468", "⢬" => "d3468", "⢭" => "d13468", "⢮" => "d23468", + "⢯" => "d123468", "⢰" => "d568", "⢱" => "d1568", "⢲" => "d2568", "⢳" => "d12568", "⢴" => "d3568", + "⢵" => "d13568", "⢶" => "d23568", "⢷" => "d123568", "⢸" => "d4568", "⢹" => "d14568", "⢺" => "d24568", + "⢻" => "d124568", "⢼" => "d34568", "⢽" => "d134568", "⢾" => "d234568", "⢿" => "d1234568", "⣀" => "d78", + "â£" => "d178", "⣂" => "d278", "⣃" => "d1278", "⣄" => "d378", "⣅" => "d1378", "⣆" => "d2378", + "⣇" => "d12378", "⣈" => "d478", "⣉" => "d1478", "⣊" => "d2478", "⣋" => "d12478", "⣌" => "d3478", + "â£" => "d13478", "⣎" => "d23478", "â£" => "d123478", "â£" => "d578", "⣑" => "d1578", "⣒" => "d2578", + "⣓" => "d12578", "⣔" => "d3578", "⣕" => "d13578", "⣖" => "d23578", "⣗" => "d123578", "⣘" => "d4578", + "⣙" => "d14578", "⣚" => "d24578", "⣛" => "d124578", "⣜" => "d34578", "â£" => "d134578", "⣞" => "d234578", + "⣟" => "d1234578", "⣠" => "d678", "⣡" => "d1678", "⣢" => "d2678", "⣣" => "d12678", "⣤" => "d3678", + "⣥" => "d13678", "⣦" => "d23678", "⣧" => "d123678", "⣨" => "d4678", "⣩" => "d14678", "⣪" => "d24678", + "⣫" => "d124678", "⣬" => "d34678", "⣭" => "d134678", "⣮" => "d234678", "⣯" => "d1234678", "⣰" => "d5678", + "⣱" => "d15678", "⣲" => "d25678", "⣳" => "d125678", "⣴" => "d35678", "⣵" => "d135678", "⣶" => "d235678", + "⣷" => "d1235678", "⣸" => "d45678", "⣹" => "d145678", "⣺" => "d245678", "⣻" => "d1245678", "⣼" => "d345678", + "⣽" => "d1345678", "⣾" => "d2345678", "⣿" => "d12345678", "〄" => "JIS", "〓" => "X", "〡" => "1", + "〢" => "2", "〣" => "3", "〤" => "4", "〥" => "5", "〦" => "6", "〧" => "7", + "〨" => "8", "〩" => "9", "〸" => "+10+", "〹" => "+20+", "〺" => "+30+", "ã" => "a", + "ã‚" => "a", "ãƒ" => "i", "ã„" => "i", "ã…" => "u", "ã†" => "u", "ã‡" => "e", + "ãˆ" => "e", "ã‰" => "o", "ãŠ" => "o", "ã‹" => "ka", "ãŒ" => "ga", "ã" => "ki", + "ãŽ" => "gi", "ã" => "ku", "ã" => "gu", "ã‘" => "ke", "ã’" => "ge", "ã“" => "ko", + "ã”" => "go", "ã•" => "sa", "ã–" => "za", "ã—" => "si", "ã˜" => "zi", "ã™" => "su", + "ãš" => "zu", "ã›" => "se", "ãœ" => "ze", "ã" => "so", "ãž" => "zo", "ãŸ" => "ta", + "ã " => "da", "ã¡" => "ti", "ã¢" => "di", "ã£" => "tu", "ã¤" => "tu", "ã¥" => "du", + "ã¦" => "te", "ã§" => "de", "ã¨" => "to", "ã©" => "do", "ãª" => "na", "ã«" => "ni", + "ã¬" => "nu", "ã­" => "ne", "ã®" => "no", "ã¯" => "ha", "ã°" => "ba", "ã±" => "pa", + "ã²" => "hi", "ã³" => "bi", "ã´" => "pi", "ãµ" => "hu", "ã¶" => "bu", "ã·" => "pu", + "ã¸" => "he", "ã¹" => "be", "ãº" => "pe", "ã»" => "ho", "ã¼" => "bo", "ã½" => "po", + "ã¾" => "ma", "ã¿" => "mi", "ã‚€" => "mu", "ã‚" => "me", "ã‚‚" => "mo", "ゃ" => "ya", + "ã‚„" => "ya", "ã‚…" => "yu", "ゆ" => "yu", "ょ" => "yo", "よ" => "yo", "ら" => "ra", + "ã‚Š" => "ri", "ã‚‹" => "ru", "ã‚Œ" => "re", "ã‚" => "ro", "ã‚Ž" => "wa", "ã‚" => "wa", + "ã‚" => "wi", "ã‚‘" => "we", "ã‚’" => "wo", "ã‚“" => "n", "ã‚”" => "vu", "ã‚¡" => "a", + "ã‚¢" => "a", "ã‚£" => "i", "イ" => "i", "ã‚¥" => "u", "ウ" => "u", "ェ" => "e", + "エ" => "e", "ã‚©" => "o", "オ" => "o", "ã‚«" => "ka", "ガ" => "ga", "ã‚­" => "ki", + "ã‚®" => "gi", "ク" => "ku", "ã‚°" => "gu", "ケ" => "ke", "ゲ" => "ge", "コ" => "ko", + "ã‚´" => "go", "サ" => "sa", "ザ" => "za", "ã‚·" => "si", "ジ" => "zi", "ス" => "su", + "ズ" => "zu", "ã‚»" => "se", "ゼ" => "ze", "ソ" => "so", "ゾ" => "zo", "ã‚¿" => "ta", + "ダ" => "da", "ãƒ" => "ti", "ヂ" => "di", "ッ" => "tu", "ツ" => "tu", "ヅ" => "du", + "テ" => "te", "デ" => "de", "ト" => "to", "ド" => "do", "ナ" => "na", "ニ" => "ni", + "ヌ" => "nu", "ãƒ" => "ne", "ノ" => "no", "ãƒ" => "ha", "ãƒ" => "ba", "パ" => "pa", + "ヒ" => "hi", "ビ" => "bi", "ピ" => "pi", "フ" => "hu", "ブ" => "bu", "プ" => "pu", + "ヘ" => "he", "ベ" => "be", "ペ" => "pe", "ホ" => "ho", "ボ" => "bo", "ãƒ" => "po", + "マ" => "ma", "ミ" => "mi", "ム" => "mu", "メ" => "me", "モ" => "mo", "ャ" => "ya", + "ヤ" => "ya", "ュ" => "yu", "ユ" => "yu", "ョ" => "yo", "ヨ" => "yo", "ラ" => "ra", + "リ" => "ri", "ル" => "ru", "レ" => "re", "ロ" => "ro", "ヮ" => "wa", "ワ" => "wa", + "ヰ" => "wi", "ヱ" => "we", "ヲ" => "wo", "ン" => "n", "ヴ" => "vu", "ヵ" => "ka", + "ヶ" => "ke", "ヷ" => "va", "ヸ" => "vi", "ヹ" => "ve", "ヺ" => "vo", "ã„…" => "B", + "ㄆ" => "P", "ㄇ" => "M", "ㄈ" => "F", "ㄉ" => "D", "ã„Š" => "T", "ã„‹" => "N", + "ã„Œ" => "L", "ã„" => "G", "ã„Ž" => "K", "ã„" => "H", "ã„" => "J", "ã„‘" => "Q", + "ã„’" => "X", "ã„“" => "ZH", "ã„”" => "CH", "ã„•" => "SH", "ã„–" => "R", "ã„—" => "Z", + "ㄘ" => "C", "ã„™" => "S", "ã„š" => "A", "ã„›" => "O", "ã„œ" => "E", "ã„" => "EH", + "ã„ž" => "AI", "ã„Ÿ" => "EI", "ã„ " => "AU", "ã„¡" => "OU", "ã„¢" => "AN", "ã„£" => "EN", + "ㄤ" => "ANG", "ã„¥" => "ENG", "ㄦ" => "ER", "ㄧ" => "I", "ㄨ" => "U", "ã„©" => "IU", + "ㄪ" => "V", "ã„«" => "NG", "ㄬ" => "GN", "ㄱ" => "g", "ㄲ" => "gg", "ㄳ" => "gs", + "ã„´" => "n", "ㄵ" => "nj", "ㄶ" => "nh", "ã„·" => "d", "ㄸ" => "dd", "ㄹ" => "r", + "ㄺ" => "lg", "ã„»" => "lm", "ㄼ" => "lb", "ㄽ" => "ls", "ㄾ" => "lt", "ã„¿" => "lp", + "ã…€" => "rh", "ã…" => "m", "ã…‚" => "b", "ã…ƒ" => "bb", "ã…„" => "bs", "ã……" => "s", + "ã…†" => "ss", "ã…ˆ" => "j", "ã…‰" => "jj", "ã…Š" => "c", "ã…‹" => "k", "ã…Œ" => "t", + "ã…" => "p", "ã…Ž" => "h", "ã…" => "a", "ã…" => "ae", "ã…‘" => "ya", "ã…’" => "yae", + "ã…“" => "eo", "ã…”" => "e", "ã…•" => "yeo", "ã…–" => "ye", "ã…—" => "o", "ã…˜" => "wa", + "ã…™" => "wae", "ã…š" => "oe", "ã…›" => "yo", "ã…œ" => "u", "ã…" => "weo", "ã…ž" => "we", + "ã…Ÿ" => "wi", "ã… " => "yu", "ã…¡" => "eu", "ã…¢" => "yi", "ã…£" => "i", "ã…¥" => "nn", + "ã…¦" => "nd", "ã…§" => "ns", "ã…¨" => "nZ", "ã…©" => "lgs", "ã…ª" => "ld", "ã…«" => "lbs", + "ã…¬" => "lZ", "ã…­" => "lQ", "ã…®" => "mb", "ã…¯" => "ms", "ã…°" => "mZ", "ã…±" => "mN", + "ã…²" => "bg", "ã…´" => "bsg", "ã…µ" => "bst", "ã…¶" => "bj", "ã…·" => "bt", "ã…¸" => "bN", + "ã…¹" => "bbN", "ã…º" => "sg", "ã…»" => "sn", "ã…¼" => "sd", "ã…½" => "sb", "ã…¾" => "sj", + "ã…¿" => "Z", "ã†" => "N", "ㆂ" => "Ns", "ㆃ" => "NZ", "ㆄ" => "pN", "ㆅ" => "hh", + "ㆆ" => "Q", "ㆇ" => "yo-ya", "ㆈ" => "yo-yae", "ㆉ" => "yo-i", "ㆊ" => "yu-yeo", "ㆋ" => "yu-ye", + "ㆌ" => "yu-i", "ã†" => "U", "ㆎ" => "U-i", "ㆠ" => "BU", "ㆡ" => "ZI", "ㆢ" => "JI", + "ㆣ" => "GU", "ㆤ" => "EE", "ㆥ" => "ENN", "ㆦ" => "OO", "ㆧ" => "ONN", "ㆨ" => "IR", + "ㆩ" => "ANN", "ㆪ" => "INN", "ㆫ" => "UNN", "ㆬ" => "IM", "ㆭ" => "NGG", "ㆮ" => "AINN", + "ㆯ" => "AUNN", "ㆰ" => "AM", "ㆱ" => "OM", "ㆲ" => "ONG", "ㆳ" => "INNN", "ㆴ" => "P", + "ㆵ" => "T", "ㆶ" => "K", "ㆷ" => "H", "ãˆ" => "(n)", "㈂" => "(d)", "㈃" => "(r)", + "㈄" => "(m)", "㈅" => "(b)", "㈆" => "(s)", "㈈" => "(j)", "㈉" => "(c)", "㈊" => "(k)", + "㈋" => "(t)", "㈌" => "(p)", "ãˆ" => "(h)", "㈎" => "(ga)", "ãˆ" => "(na)", "ãˆ" => "(da)", + "㈑" => "(ra)", "㈒" => "(ma)", "㈓" => "(ba)", "㈔" => "(sa)", "㈕" => "(a)", "㈖" => "(ja)", + "㈗" => "(ca)", "㈘" => "(ka)", "㈙" => "(ta)", "㈚" => "(pa)", "㈛" => "(ha)", "㈜" => "(ju)", + "㈠" => "(1)", "㈡" => "(2)", "㈢" => "(3)", "㈣" => "(4)", "㈤" => "(5)", "㈥" => "(6)", + "㈦" => "(7)", "㈧" => "(8)", "㈨" => "(9)", "㈩" => "(10)", "㈪" => "(Yue)", "㈫" => "(Huo)", + "㈬" => "(Shui)", "㈭" => "(Mu)", "㈮" => "(Jin)", "㈯" => "(Tu)", "㈰" => "(Ri)", "㈱" => "(Zhu)", + "㈲" => "(You)", "㈳" => "(She)", "㈴" => "(Ming)", "㈵" => "(Te)", "㈶" => "(Cai)", "㈷" => "(Zhu)", + "㈸" => "(Lao)", "㈹" => "(Dai)", "㈺" => "(Hu)", "㈻" => "(Xue)", "㈼" => "(Jian)", "㈽" => "(Qi)", + "㈾" => "(Zi)", "㈿" => "(Xie)", "㉀" => "(Ji)", "ã‰" => "(Xiu)", "㉠" => "(g)", "㉡" => "(n)", + "㉢" => "(d)", "㉣" => "(r)", "㉤" => "(m)", "㉥" => "(b)", "㉦" => "(s)", "㉨" => "(j)", + "㉩" => "(c)", "㉪" => "(k)", "㉫" => "(t)", "㉬" => "(p)", "㉭" => "(h)", "㉮" => "(ga)", + "㉯" => "(na)", "㉰" => "(da)", "㉱" => "(ra)", "㉲" => "(ma)", "㉳" => "(ba)", "㉴" => "(sa)", + "㉵" => "(a)", "㉶" => "(ja)", "㉷" => "(ca)", "㉸" => "(ka)", "㉹" => "(ta)", "㉺" => "(pa)", + "㉻" => "(ha)", "㉿" => "KIS", "㊀" => "(1)", "ãŠ" => "(2)", "㊂" => "(3)", "㊃" => "(4)", + "㊄" => "(5)", "㊅" => "(6)", "㊆" => "(7)", "㊇" => "(8)", "㊈" => "(9)", "㊉" => "(10)", + "㊊" => "(Yue)", "㊋" => "(Huo)", "㊌" => "(Shui)", "ãŠ" => "(Mu)", "㊎" => "(Jin)", "ãŠ" => "(Tu)", + "ãŠ" => "(Ri)", "㊑" => "(Zhu)", "㊒" => "(You)", "㊓" => "(She)", "㊔" => "(Ming)", "㊕" => "(Te)", + "㊖" => "(Cai)", "㊗" => "(Zhu)", "㊘" => "(Lao)", "㊙" => "(Mi)", "㊚" => "(Nan)", "㊛" => "(Nu)", + "㊜" => "(Shi)", "ãŠ" => "(You)", "㊞" => "(Yin)", "㊟" => "(Zhu)", "㊠" => "(Xiang)", "㊡" => "(Xiu)", + "㊢" => "(Xie)", "㊣" => "(Zheng)", "㊤" => "(Shang)", "㊥" => "(Zhong)", "㊦" => "(Xia)", "㊧" => "(Zuo)", + "㊨" => "(You)", "㊩" => "(Yi)", "㊪" => "(Zong)", "㊫" => "(Xue)", "㊬" => "(Jian)", "㊭" => "(Qi)", + "㊮" => "(Zi)", "㊯" => "(Xie)", "㊰" => "(Ye)", "ã‹€" => "1M", "ã‹" => "2M", "ã‹‚" => "3M", + "㋃" => "4M", "ã‹„" => "5M", "ã‹…" => "6M", "㋆" => "7M", "㋇" => "8M", "㋈" => "9M", + "㋉" => "10M", "ã‹Š" => "11M", "ã‹‹" => "12M", "ã‹" => "a", "ã‹‘" => "i", "ã‹’" => "u", + "ã‹“" => "u", "ã‹”" => "o", "ã‹•" => "ka", "ã‹–" => "ki", "ã‹—" => "ku", "㋘" => "ke", + "ã‹™" => "ko", "ã‹š" => "sa", "ã‹›" => "si", "ã‹œ" => "su", "ã‹" => "se", "ã‹ž" => "so", + "ã‹Ÿ" => "ta", "ã‹ " => "ti", "ã‹¡" => "tu", "ã‹¢" => "te", "ã‹£" => "to", "㋤" => "na", + "ã‹¥" => "ni", "㋦" => "nu", "㋧" => "ne", "㋨" => "no", "ã‹©" => "ha", "㋪" => "hi", + "ã‹«" => "hu", "㋬" => "he", "ã‹­" => "ho", "ã‹®" => "ma", "㋯" => "mi", "ã‹°" => "mu", + "㋱" => "me", "㋲" => "mo", "㋳" => "ya", "ã‹´" => "yu", "㋵" => "yo", "㋶" => "ra", + "ã‹·" => "ri", "㋸" => "ru", "㋹" => "re", "㋺" => "ro", "ã‹»" => "wa", "㋼" => "wi", + "㋽" => "we", "㋾" => "wo", "ãŒ" => "alpha", "㌂" => "ampere", "㌃" => "are", "㌄" => "inning", + "㌅" => "inch", "㌆" => "won", "㌇" => "escudo", "㌈" => "acre", "㌉" => "ounce", "㌊" => "ohm", + "㌋" => "kai-ri", "㌌" => "carat", "ãŒ" => "calorie", "㌎" => "gallon", "ãŒ" => "gamma", "ãŒ" => "giga", + "㌑" => "guinea", "㌒" => "curie", "㌓" => "guilder", "㌔" => "kilo", "㌕" => "kilogram", "㌖" => "kilometer", + "㌗" => "kilowatt", "㌘" => "gram", "㌚" => "cruzeiro", "㌛" => "krone", "㌜" => "case", "ãŒ" => "koruna", + "㌞" => "co-op", "㌟" => "cycle", "㌠" => "centime", "㌡" => "shilling", "㌢" => "centi", "㌣" => "cent", + "㌤" => "dozen", "㌥" => "desi", "㌦" => "dollar", "㌧" => "ton", "㌨" => "nano", "㌩" => "knot", + "㌪" => "heights", "㌫" => "percent", "㌬" => "parts", "㌭" => "barrel", "㌮" => "piaster", "㌯" => "picul", + "㌰" => "pico", "㌱" => "building", "㌲" => "farad", "㌳" => "feet", "㌴" => "bushel", "㌵" => "franc", + "㌶" => "hectare", "㌷" => "peso", "㌸" => "pfennig", "㌹" => "hertz", "㌺" => "pence", "㌻" => "page", + "㌼" => "beta", "㌽" => "point", "㌾" => "volt", "㌿" => "hon", "ã€" => "pound", "ã" => "hall", + "ã‚" => "horn", "ãƒ" => "micro", "ã„" => "mile", "ã…" => "mach", "ã†" => "mark", "ã‡" => "mansion", + "ãˆ" => "micron", "ã‰" => "milli", "ãŠ" => "millibar", "ã‹" => "mega", "ãŒ" => "megaton", "ã" => "meter", + "ãŽ" => "yard", "ã" => "yard", "ã" => "yuan", "ã‘" => "liter", "ã’" => "lira", "ã“" => "rupee", + "ã”" => "ruble", "ã•" => "rem", "ã–" => "roentgen", "ã—" => "watt", "ã˜" => "0h", "ã™" => "1h", + "ãš" => "2h", "ã›" => "3h", "ãœ" => "4h", "ã" => "5h", "ãž" => "6h", "ãŸ" => "7h", + "ã " => "8h", "ã¡" => "9h", "ã¢" => "10h", "ã£" => "11h", "ã¤" => "12h", "ã¥" => "13h", + "ã¦" => "14h", "ã§" => "15h", "ã¨" => "16h", "ã©" => "17h", "ãª" => "18h", "ã«" => "19h", + "ã¬" => "20h", "ã­" => "21h", "ã®" => "22h", "ã¯" => "23h", "ã°" => "24h", "ã±" => "HPA", + "ã²" => "da", "ã³" => "AU", "ã´" => "bar", "ãµ" => "oV", "ã¶" => "pc", "ã»" => "Heisei", + "ã¼" => "Syouwa", "ã½" => "Taisyou", "ã¾" => "Meiji", "ã¿" => "Inc.", "㎀" => "pA", "ãŽ" => "nA", + "㎂" => "microamp", "㎃" => "mA", "㎄" => "kA", "㎅" => "kB", "㎆" => "MB", "㎇" => "GB", + "㎈" => "cal", "㎉" => "kcal", "㎊" => "pF", "㎋" => "nF", "㎌" => "microFarad", "ãŽ" => "microgram", + "㎎" => "mg", "ãŽ" => "kg", "ãŽ" => "Hz", "㎑" => "kHz", "㎒" => "MHz", "㎓" => "GHz", + "㎔" => "THz", "㎕" => "microliter", "㎖" => "ml", "㎗" => "dl", "㎘" => "kl", "㎙" => "fm", + "㎚" => "nm", "㎛" => "micrometer", "㎜" => "mm", "ãŽ" => "cm", "㎞" => "km", "㎟" => "mm^2", + "㎠" => "cm^2", "㎡" => "m^2", "㎢" => "km^2", "㎣" => "mm^4", "㎤" => "cm^3", "㎥" => "m^3", + "㎦" => "km^3", "㎧" => "m/s", "㎨" => "m/s^2", "㎩" => "Pa", "㎪" => "kPa", "㎫" => "MPa", + "㎬" => "GPa", "㎭" => "rad", "㎮" => "rad/s", "㎯" => "rad/s^2", "㎰" => "ps", "㎱" => "ns", + "㎲" => "microsecond", "㎳" => "ms", "㎴" => "pV", "㎵" => "nV", "㎶" => "microvolt", "㎷" => "mV", + "㎸" => "kV", "㎹" => "MV", "㎺" => "pW", "㎻" => "nW", "㎼" => "microwatt", "㎽" => "mW", + "㎾" => "kW", "㎿" => "MW", "ã€" => "kOhm", "ã" => "MOhm", "ã‚" => "a.m.", "ãƒ" => "Bq", + "ã„" => "cc", "ã…" => "cd", "ã†" => "C/kg", "ã‡" => "Co.", "ãˆ" => "dB", "ã‰" => "Gy", + "ãŠ" => "ha", "ã‹" => "HP", "ãŒ" => "in", "ã" => "K.K.", "ãŽ" => "KM", "ã" => "kt", + "ã" => "lm", "ã‘" => "ln", "ã’" => "log", "ã“" => "lx", "ã”" => "mb", "ã•" => "mil", + "ã–" => "mol", "ã—" => "pH", "ã˜" => "p.m.", "ã™" => "PPM", "ãš" => "PR", "ã›" => "sr", + "ãœ" => "Sv", "ã" => "Wb", "ã " => "1d", "ã¡" => "2d", "ã¢" => "3d", "ã£" => "4d", + "ã¤" => "5d", "ã¥" => "6d", "ã¦" => "7d", "ã§" => "8d", "ã¨" => "9d", "ã©" => "10d", + "ãª" => "11d", "ã«" => "12d", "ã¬" => "13d", "ã­" => "14d", "ã®" => "15d", "ã¯" => "16d", + "ã°" => "17d", "ã±" => "18d", "ã²" => "19d", "ã³" => "20d", "ã´" => "21d", "ãµ" => "22d", + "ã¶" => "23d", "ã·" => "24d", "ã¸" => "25d", "ã¹" => "26d", "ãº" => "27d", "ã»" => "28d", + "ã¼" => "29d", "ã½" => "30d", "ã¾" => "31d", "ä¸" => "Ding", "丂" => "Kao", "七" => "Qi", + "丄" => "Shang", "丅" => "Xia", "万" => "Mo", "丈" => "Zhang", "三" => "San", "上" => "Shang", + "下" => "Xia", "丌" => "Ji", "ä¸" => "Bu", "与" => "Yu", "ä¸" => "Mian", "ä¸" => "Gai", + "丑" => "Chou", "丒" => "Chou", "专" => "Zhuan", "且" => "Qie", "丕" => "Pi", "世" => "Shi", + "丗" => "Shi", "丘" => "Qiu", "丙" => "Bing", "业" => "Ye", "丛" => "Cong", "东" => "Dong", + "ä¸" => "Si", "丞" => "Cheng", "丟" => "Diu", "丠" => "Qiu", "両" => "Liang", "丢" => "Diu", + "丣" => "You", "两" => "Liang", "严" => "Yan", "並" => "Bing", "丧" => "Sang", "丨" => "Gun", + "丩" => "Jiu", "个" => "Ge", "丫" => "Ya", "丬" => "Qiang", "中" => "Zhong", "丮" => "Ji", + "丯" => "Jie", "丰" => "Feng", "丱" => "Guan", "串" => "Chuan", "丳" => "Chan", "临" => "Lin", + "丵" => "Zhuo", "丶" => "Zhu", "丷" => "Ha", "丸" => "Wan", "丹" => "Dan", "为" => "Wei", + "主" => "Zhu", "丼" => "Jing", "丽" => "Li", "举" => "Ju", "丿" => "Pie", "ä¹€" => "Fu", + "ä¹" => "Yi", "乂" => "Yi", "乃" => "Nai", "乄" => "Shime", "ä¹…" => "Jiu", "乆" => "Jiu", + "乇" => "Zhe", "么" => "Yao", "义" => "Yi", "之" => "Zhi", "乌" => "Wu", "ä¹" => "Zha", + "乎" => "Hu", "ä¹" => "Fa", "ä¹" => "Le", "乑" => "Zhong", "ä¹’" => "Ping", "乓" => "Pang", + "ä¹”" => "Qiao", "乕" => "Hu", "ä¹–" => "Guai", "ä¹—" => "Cheng", "乘" => "Cheng", "ä¹™" => "Yi", + "乚" => "Yin", "乜" => "Mie", "ä¹" => "Jiu", "乞" => "Qi", "也" => "Ye", "ä¹ " => "Xi", + "乡" => "Xiang", "ä¹¢" => "Gai", "ä¹£" => "Diu", "乤" => "Hal", "书" => "Shu", "乧" => "Twul", + "乨" => "Shi", "乩" => "Ji", "乪" => "Nang", "乫" => "Jia", "乬" => "Kel", "ä¹­" => "Shi", + "乯" => "Ol", "ä¹°" => "Mai", "ä¹±" => "Luan", "ä¹²" => "Cal", "ä¹³" => "Ru", "ä¹´" => "Xue", + "ä¹µ" => "Yan", "乶" => "Fu", "ä¹·" => "Sha", "乸" => "Na", "ä¹¹" => "Gan", "乺" => "Sol", + "ä¹»" => "El", "ä¹¼" => "Cwul", "ä¹¾" => "Gan", "乿" => "Chi", "亀" => "Gui", "äº" => "Gan", + "亂" => "Luan", "亃" => "Lin", "亄" => "Yi", "亅" => "Jue", "了" => "Liao", "亇" => "Ma", + "予" => "Yu", "争" => "Zheng", "亊" => "Shi", "事" => "Shi", "二" => "Er", "äº" => "Chu", + "于" => "Yu", "äº" => "Yu", "äº" => "Yu", "云" => "Yun", "互" => "Hu", "亓" => "Qi", + "五" => "Wu", "井" => "Jing", "亖" => "Si", "亗" => "Sui", "亘" => "Gen", "亙" => "Gen", + "亚" => "Ya", "些" => "Xie", "亜" => "Ya", "äº" => "Qi", "亞" => "Ya", "亟" => "Ji", + "亠" => "Tou", "亡" => "Wang", "亢" => "Kang", "亣" => "Ta", "交" => "Jiao", "亥" => "Hai", + "亦" => "Yi", "产" => "Chan", "亨" => "Heng", "亩" => "Mu", "享" => "Xiang", "京" => "Jing", + "亭" => "Ting", "亮" => "Liang", "亯" => "Xiang", "亰" => "Jing", "亱" => "Ye", "亲" => "Qin", + "亳" => "Bo", "亴" => "You", "亵" => "Xie", "亶" => "Dan", "亷" => "Lian", "亸" => "Duo", + "亹" => "Wei", "人" => "Ren", "亻" => "Ren", "亼" => "Ji", "亽" => "La", "亾" => "Wang", + "亿" => "Yi", "什" => "Shi", "ä»" => "Ren", "仂" => "Le", "仃" => "Ding", "仄" => "Ze", + "ä»…" => "Jin", "仆" => "Pu", "仇" => "Chou", "仈" => "Ba", "仉" => "Zhang", "今" => "Jin", + "介" => "Jie", "仌" => "Bing", "ä»" => "Reng", "从" => "Cong", "ä»" => "Fo", "ä»" => "San", + "仑" => "Lun", "ä»’" => "Sya", "仓" => "Cang", "ä»”" => "Zi", "仕" => "Shi", "ä»–" => "Ta", + "ä»—" => "Zhang", "付" => "Fu", "ä»™" => "Xian", "仚" => "Xian", "ä»›" => "Tuo", "仜" => "Hong", + "ä»" => "Tong", "仞" => "Ren", "仟" => "Qian", "ä» " => "Gan", "仡" => "Yi", "仢" => "Di", + "代" => "Dai", "令" => "Ling", "以" => "Yi", "仦" => "Chao", "仧" => "Chang", "仨" => "Sa", + "仪" => "Yi", "仫" => "Mu", "们" => "Men", "ä»­" => "Ren", "ä»®" => "Jia", "仯" => "Chao", + "ä»°" => "Yang", "ä»±" => "Qian", "仲" => "Zhong", "仳" => "Pi", "ä»´" => "Wan", "仵" => "Wu", + "件" => "Jian", "ä»·" => "Jie", "仸" => "Yao", "仹" => "Feng", "仺" => "Cang", "ä»»" => "Ren", + "仼" => "Wang", "份" => "Fen", "仾" => "Di", "仿" => "Fang", "ä¼" => "Qi", "伂" => "Pei", + "伃" => "Yu", "伄" => "Diao", "ä¼…" => "Dun", "伆" => "Wen", "伇" => "Yi", "伈" => "Xin", + "伉" => "Kang", "伊" => "Yi", "伋" => "Ji", "伌" => "Ai", "ä¼" => "Wu", "伎" => "Ji", + "ä¼" => "Fu", "ä¼" => "Fa", "休" => "Xiu", "ä¼’" => "Jin", "伓" => "Bei", "ä¼”" => "Dan", + "伕" => "Fu", "ä¼–" => "Tang", "ä¼—" => "Zhong", "优" => "You", "ä¼™" => "Huo", "会" => "Hui", + "ä¼›" => "Yu", "伜" => "Cui", "ä¼" => "Chuan", "伞" => "San", "伟" => "Wei", "ä¼ " => "Chuan", + "伡" => "Che", "ä¼¢" => "Ya", "ä¼£" => "Xian", "伤" => "Shang", "ä¼¥" => "Chang", "伦" => "Lun", + "伧" => "Cang", "伨" => "Xun", "伩" => "Xin", "伪" => "Wei", "伫" => "Zhu", "ä¼­" => "Xuan", + "ä¼®" => "Nu", "伯" => "Bo", "ä¼°" => "Gu", "ä¼±" => "Ni", "ä¼²" => "Ni", "ä¼³" => "Xie", + "ä¼´" => "Ban", "ä¼µ" => "Xu", "伶" => "Ling", "ä¼·" => "Zhou", "伸" => "Shen", "ä¼¹" => "Qu", + "伺" => "Si", "ä¼»" => "Beng", "ä¼¼" => "Si", "ä¼½" => "Jia", "ä¼¾" => "Pi", "伿" => "Yi", + "ä½€" => "Si", "ä½" => "Ai", "佂" => "Zheng", "佃" => "Dian", "佄" => "Han", "ä½…" => "Mai", + "但" => "Dan", "佇" => "Zhu", "佈" => "Bu", "佉" => "Qu", "佊" => "Bi", "佋" => "Shao", + "佌" => "Ci", "ä½" => "Wei", "低" => "Di", "ä½" => "Zhu", "ä½" => "Zuo", "佑" => "You", + "ä½’" => "Yang", "体" => "Ti", "ä½”" => "Zhan", "何" => "He", "ä½–" => "Bi", "ä½—" => "Tuo", + "佘" => "She", "ä½™" => "Yu", "佚" => "Yi", "ä½›" => "Fo", "作" => "Zuo", "ä½" => "Kou", + "佞" => "Ning", "佟" => "Tong", "ä½ " => "Ni", "佡" => "Xuan", "ä½¢" => "Qu", "ä½£" => "Yong", + "佤" => "Wa", "ä½¥" => "Qian", "佧" => "Ka", "佩" => "Pei", "佪" => "Huai", "佫" => "He", + "佬" => "Lao", "ä½­" => "Xiang", "ä½®" => "Ge", "佯" => "Yang", "ä½°" => "Bai", "ä½±" => "Fa", + "ä½²" => "Ming", "ä½³" => "Jia", "ä½´" => "Er", "ä½µ" => "Bing", "佶" => "Ji", "ä½·" => "Hen", + "佸" => "Huo", "ä½¹" => "Gui", "佺" => "Quan", "ä½»" => "Tiao", "ä½¼" => "Jiao", "ä½½" => "Ci", + "ä½¾" => "Yi", "使" => "Shi", "ä¾€" => "Xing", "ä¾" => "Shen", "侂" => "Tuo", "侃" => "Kan", + "侄" => "Zhi", "ä¾…" => "Gai", "來" => "Lai", "侇" => "Yi", "侈" => "Chi", "侉" => "Kua", + "侊" => "Guang", "例" => "Li", "侌" => "Yin", "ä¾" => "Shi", "侎" => "Mi", "ä¾" => "Zhu", + "ä¾" => "Xu", "侑" => "You", "ä¾’" => "An", "侓" => "Lu", "ä¾”" => "Mou", "侕" => "Er", + "ä¾–" => "Lun", "ä¾—" => "Tong", "侘" => "Cha", "ä¾™" => "Chi", "侚" => "Xun", "ä¾›" => "Gong", + "侜" => "Zhou", "ä¾" => "Yi", "侞" => "Ru", "侟" => "Jian", "ä¾ " => "Xia", "価" => "Jia", + "ä¾¢" => "Zai", "ä¾£" => "Lu", "侤" => "Ko", "ä¾¥" => "Jiao", "侦" => "Zhen", "侧" => "Ce", + "侨" => "Qiao", "侩" => "Kuai", "侪" => "Chai", "侫" => "Ning", "侬" => "Nong", "ä¾­" => "Jin", + "ä¾®" => "Wu", "侯" => "Hou", "ä¾°" => "Jiong", "ä¾±" => "Cheng", "ä¾²" => "Zhen", "ä¾³" => "Zuo", + "ä¾´" => "Chou", "ä¾µ" => "Qin", "侶" => "Lu", "ä¾·" => "Ju", "侸" => "Shu", "ä¾¹" => "Ting", + "侺" => "Shen", "ä¾»" => "Tuo", "ä¾¼" => "Bo", "ä¾½" => "Nan", "ä¾¾" => "Hao", "便" => "Bian", + "ä¿€" => "Tui", "ä¿" => "Yu", "ä¿‚" => "Xi", "促" => "Cu", "ä¿„" => "E", "ä¿…" => "Qiu", + "俆" => "Xu", "俇" => "Kuang", "俈" => "Ku", "俉" => "Wu", "ä¿Š" => "Jun", "ä¿‹" => "Yi", + "ä¿Œ" => "Fu", "ä¿" => "Lang", "ä¿Ž" => "Zu", "ä¿" => "Qiao", "ä¿" => "Li", "ä¿‘" => "Yong", + "ä¿’" => "Hun", "ä¿“" => "Jing", "ä¿”" => "Xian", "ä¿•" => "San", "ä¿–" => "Pai", "ä¿—" => "Su", + "俘" => "Fu", "ä¿™" => "Xi", "ä¿š" => "Li", "ä¿›" => "Fu", "ä¿œ" => "Ping", "ä¿" => "Bao", + "ä¿ž" => "Yu", "ä¿Ÿ" => "Si", "ä¿ " => "Xia", "ä¿¡" => "Xin", "ä¿¢" => "Xiu", "ä¿£" => "Yu", + "俤" => "Ti", "ä¿¥" => "Che", "俦" => "Chou", "俨" => "Yan", "ä¿©" => "Lia", "俪" => "Li", + "ä¿«" => "Lai", "ä¿­" => "Jian", "ä¿®" => "Xiu", "俯" => "Fu", "ä¿°" => "He", "俱" => "Ju", + "俲" => "Xiao", "俳" => "Pai", "ä¿´" => "Jian", "俵" => "Biao", "俶" => "Chu", "ä¿·" => "Fei", + "俸" => "Feng", "俹" => "Ya", "俺" => "An", "ä¿»" => "Bei", "俼" => "Yu", "俽" => "Xin", + "俾" => "Bi", "ä¿¿" => "Jian", "å€" => "Chi", "倂" => "Bing", "倃" => "Zan", "倄" => "Yao", + "倅" => "Cui", "倆" => "Lia", "倇" => "Wan", "倈" => "Lai", "倉" => "Cang", "倊" => "Zong", + "個" => "Ge", "倌" => "Guan", "å€" => "Bei", "倎" => "Tian", "å€" => "Shu", "å€" => "Shu", + "們" => "Men", "倒" => "Dao", "倓" => "Tan", "倔" => "Jue", "倕" => "Chui", "倖" => "Xing", + "倗" => "Peng", "倘" => "Tang", "候" => "Hou", "倚" => "Yi", "倛" => "Qi", "倜" => "Ti", + "å€" => "Gan", "倞" => "Jing", "借" => "Jie", "倠" => "Sui", "倡" => "Chang", "倢" => "Jie", + "倣" => "Fang", "値" => "Zhi", "倥" => "Kong", "倦" => "Juan", "倧" => "Zong", "倨" => "Ju", + "倩" => "Qian", "倪" => "Ni", "倫" => "Lun", "倬" => "Zhuo", "倭" => "Wei", "倮" => "Luo", + "倯" => "Song", "倰" => "Leng", "倱" => "Hun", "倲" => "Dong", "倳" => "Zi", "倴" => "Ben", + "倵" => "Wu", "倶" => "Ju", "倷" => "Nai", "倸" => "Cai", "倹" => "Jian", "债" => "Zhai", + "倻" => "Ye", "值" => "Zhi", "倽" => "Sha", "倾" => "Qing", "å€" => "Ying", "å" => "Cheng", + "å‚" => "Jian", "åƒ" => "Yan", "å„" => "Nuan", "å…" => "Zhong", "å†" => "Chun", "å‡" => "Jia", + "åˆ" => "Jie", "å‰" => "Wei", "åŠ" => "Yu", "å‹" => "Bing", "åŒ" => "Ruo", "å" => "Ti", + "åŽ" => "Wei", "å" => "Pian", "å" => "Yan", "å‘" => "Feng", "å’" => "Tang", "å“" => "Wo", + "å”" => "E", "å•" => "Xie", "å–" => "Che", "å—" => "Sheng", "å˜" => "Kan", "å™" => "Di", + "åš" => "Zuo", "å›" => "Cha", "åœ" => "Ting", "å" => "Bei", "åž" => "Ye", "åŸ" => "Huang", + "å " => "Yao", "å¡" => "Zhan", "å¢" => "Chou", "å£" => "Yan", "å¤" => "You", "å¥" => "Jian", + "å¦" => "Xu", "å§" => "Zha", "å¨" => "Ci", "å©" => "Fu", "åª" => "Bi", "å«" => "Zhi", + "å¬" => "Zong", "å­" => "Mian", "å®" => "Ji", "å¯" => "Yi", "å°" => "Xie", "å±" => "Xun", + "å²" => "Si", "å³" => "Duan", "å´" => "Ce", "åµ" => "Zhen", "å¶" => "Ou", "å·" => "Tou", + "å¸" => "Tou", "å¹" => "Bei", "åº" => "Za", "å»" => "Lu", "å¼" => "Jie", "å½" => "Wei", + "å¾" => "Fen", "å¿" => "Chang", "å‚€" => "Gui", "å‚" => "Sou", "å‚‚" => "Zhi", "傃" => "Su", + "å‚„" => "Xia", "å‚…" => "Fu", "傆" => "Yuan", "傇" => "Rong", "傈" => "Li", "傉" => "Ru", + "å‚Š" => "Yun", "å‚‹" => "Gou", "å‚Œ" => "Ma", "å‚" => "Bang", "å‚Ž" => "Dian", "å‚" => "Tang", + "å‚" => "Hao", "å‚‘" => "Jie", "å‚’" => "Xi", "å‚“" => "Shan", "å‚”" => "Qian", "å‚•" => "Jue", + "å‚–" => "Cang", "å‚—" => "Chu", "傘" => "San", "å‚™" => "Bei", "å‚š" => "Xiao", "å‚›" => "Yong", + "å‚œ" => "Yao", "å‚" => "Tan", "å‚ž" => "Suo", "å‚Ÿ" => "Yang", "å‚ " => "Fa", "å‚¡" => "Bing", + "å‚¢" => "Jia", "å‚£" => "Dai", "傤" => "Zai", "å‚¥" => "Tang", "傧" => "Bin", "储" => "Chu", + "å‚©" => "Nuo", "傪" => "Can", "å‚«" => "Lei", "催" => "Cui", "å‚­" => "Yong", "å‚®" => "Zao", + "傯" => "Zong", "å‚°" => "Peng", "傱" => "Song", "傲" => "Ao", "傳" => "Chuan", "å‚´" => "Yu", + "債" => "Zhai", "傶" => "Cou", "å‚·" => "Shang", "傸" => "Qiang", "傹" => "Jing", "傺" => "Chi", + "å‚»" => "Sha", "傼" => "Han", "傽" => "Zhang", "傾" => "Qing", "å‚¿" => "Yan", "僀" => "Di", + "åƒ" => "Xi", "僂" => "Lu", "僃" => "Bei", "僄" => "Piao", "僅" => "Jin", "僆" => "Lian", + "僇" => "Lu", "僈" => "Man", "僉" => "Qian", "僊" => "Xian", "僋" => "Tan", "僌" => "Ying", + "åƒ" => "Dong", "僎" => "Zhuan", "åƒ" => "Xiang", "åƒ" => "Shan", "僑" => "Qiao", "僒" => "Jiong", + "僓" => "Tui", "僔" => "Zun", "僕" => "Pu", "僖" => "Xi", "僗" => "Lao", "僘" => "Chang", + "僙" => "Guang", "僚" => "Liao", "僛" => "Qi", "僜" => "Deng", "åƒ" => "Chan", "僞" => "Wei", + "僟" => "Ji", "僠" => "Fan", "僡" => "Hui", "僢" => "Chuan", "僣" => "Jian", "僤" => "Dan", + "僥" => "Jiao", "僦" => "Jiu", "僧" => "Seng", "僨" => "Fen", "僩" => "Xian", "僪" => "Jue", + "僫" => "E", "僬" => "Jiao", "僭" => "Jian", "僮" => "Tong", "僯" => "Lin", "僰" => "Bo", + "僱" => "Gu", "僳" => "Su", "僴" => "Xian", "僵" => "Jiang", "僶" => "Min", "僷" => "Ye", + "僸" => "Jin", "價" => "Jia", "僺" => "Qiao", "僻" => "Pi", "僼" => "Feng", "僽" => "Zhou", + "僾" => "Ai", "僿" => "Sai", "å„" => "Jun", "å„‚" => "Nong", "儃" => "Chan", "å„„" => "Yi", + "å„…" => "Dang", "儆" => "Jing", "儇" => "Xuan", "儈" => "Kuai", "儉" => "Jian", "å„Š" => "Chu", + "å„‹" => "Dan", "å„Œ" => "Jiao", "å„" => "Sha", "å„Ž" => "Zai", "å„" => "Bin", "å„‘" => "An", + "å„’" => "Ru", "å„“" => "Tai", "å„”" => "Chou", "å„•" => "Chai", "å„–" => "Lan", "å„—" => "Ni", + "儘" => "Jin", "å„™" => "Qian", "å„š" => "Meng", "å„›" => "Wu", "å„œ" => "Ning", "å„" => "Qiong", + "å„ž" => "Ni", "å„Ÿ" => "Chang", "å„ " => "Lie", "å„¡" => "Lei", "å„¢" => "Lu", "å„£" => "Kuang", + "儤" => "Bao", "å„¥" => "Du", "儦" => "Biao", "儧" => "Zan", "儨" => "Zhi", "å„©" => "Si", + "優" => "You", "å„«" => "Hao", "儬" => "Chen", "å„­" => "Chen", "å„®" => "Li", "儯" => "Teng", + "å„°" => "Wei", "儱" => "Long", "儲" => "Chu", "儳" => "Chan", "å„´" => "Rang", "儵" => "Shu", + "儶" => "Hui", "å„·" => "Li", "儸" => "Luo", "儹" => "Zan", "儺" => "Nuo", "å„»" => "Tang", + "儼" => "Yan", "儽" => "Lei", "儾" => "Nang", "å„¿" => "Er", "å…€" => "Wu", "å…" => "Yun", + "å…‚" => "Zan", "å…ƒ" => "Yuan", "å…„" => "Xiong", "å……" => "Chong", "å…†" => "Zhao", "å…‡" => "Xiong", + "å…ˆ" => "Xian", "å…‰" => "Guang", "å…Š" => "Dui", "å…‹" => "Ke", "å…Œ" => "Dui", "å…" => "Mian", + "å…Ž" => "Tu", "å…" => "Chang", "å…" => "Er", "å…‘" => "Dui", "å…’" => "Er", "å…“" => "Xin", + "å…”" => "Tu", "å…•" => "Si", "å…–" => "Yan", "å…—" => "Yan", "å…˜" => "Shi", "å…™" => "Shi", + "å…š" => "Dang", "å…›" => "Qian", "å…œ" => "Dou", "å…" => "Fen", "å…ž" => "Mao", "å…Ÿ" => "Shen", + "å… " => "Dou", "å…¡" => "Bai", "å…¢" => "Jing", "å…£" => "Li", "å…¤" => "Huang", "å…¥" => "Ru", + "å…¦" => "Wang", "å…§" => "Nei", "å…¨" => "Quan", "å…©" => "Liang", "å…ª" => "Yu", "å…«" => "Ba", + "å…¬" => "Gong", "å…­" => "Liu", "å…®" => "Xi", "å…°" => "Lan", "å…±" => "Gong", "å…²" => "Tian", + "å…³" => "Guan", "å…´" => "Xing", "å…µ" => "Bing", "å…¶" => "Qi", "å…·" => "Ju", "å…¸" => "Dian", + "å…¹" => "Zi", "å…º" => "Ppwun", "å…»" => "Yang", "å…¼" => "Jian", "å…½" => "Shou", "å…¾" => "Ji", + "å…¿" => "Yi", "冀" => "Ji", "å†" => "Chan", "冂" => "Jiong", "冃" => "Mao", "冄" => "Ran", + "内" => "Nei", "円" => "Yuan", "冇" => "Mao", "冈" => "Gang", "冉" => "Ran", "冊" => "Ce", + "冋" => "Jiong", "册" => "Ce", "å†" => "Zai", "冎" => "Gua", "å†" => "Jiong", "å†" => "Mao", + "冑" => "Zhou", "冒" => "Mou", "冓" => "Gou", "冔" => "Xu", "冕" => "Mian", "冖" => "Mi", + "冗" => "Rong", "冘" => "Yin", "写" => "Xie", "冚" => "Kan", "军" => "Jun", "农" => "Nong", + "å†" => "Yi", "冞" => "Mi", "冟" => "Shi", "冠" => "Guan", "冡" => "Meng", "冢" => "Zhong", + "冣" => "Ju", "冤" => "Yuan", "冥" => "Ming", "冦" => "Kou", "冧" => "Lam", "冨" => "Fu", + "冩" => "Xie", "冪" => "Mi", "冫" => "Bing", "冬" => "Dong", "冭" => "Tai", "冮" => "Gang", + "冯" => "Feng", "冰" => "Bing", "冱" => "Hu", "冲" => "Chong", "决" => "Jue", "冴" => "Hu", + "况" => "Kuang", "冶" => "Ye", "冷" => "Leng", "冸" => "Pan", "冹" => "Fu", "冺" => "Min", + "冻" => "Dong", "冼" => "Xian", "冽" => "Lie", "冾" => "Xia", "冿" => "Jian", "净" => "Jing", + "å‡" => "Shu", "凂" => "Mei", "凃" => "Tu", "凄" => "Qi", "凅" => "Gu", "准" => "Zhun", + "凇" => "Song", "凈" => "Jing", "凉" => "Liang", "凊" => "Qing", "凋" => "Diao", "凌" => "Ling", + "å‡" => "Dong", "凎" => "Gan", "å‡" => "Jian", "å‡" => "Yin", "凑" => "Cou", "凒" => "Yi", + "凓" => "Li", "凔" => "Cang", "凕" => "Ming", "凖" => "Zhuen", "凗" => "Cui", "凘" => "Si", + "凙" => "Duo", "凚" => "Jin", "凛" => "Lin", "凜" => "Lin", "å‡" => "Ning", "凞" => "Xi", + "凟" => "Du", "几" => "Ji", "凡" => "Fan", "凢" => "Fan", "凣" => "Fan", "凤" => "Feng", + "凥" => "Ju", "処" => "Chu", "凧" => "Tako", "凨" => "Feng", "凩" => "Mok", "凪" => "Ci", + "凫" => "Fu", "凬" => "Feng", "凭" => "Ping", "凮" => "Feng", "凯" => "Kai", "凰" => "Huang", + "凱" => "Kai", "凲" => "Gan", "凳" => "Deng", "凴" => "Ping", "凵" => "Qu", "凶" => "Xiong", + "凷" => "Kuai", "凸" => "Tu", "凹" => "Ao", "出" => "Chu", "击" => "Ji", "凼" => "Dang", + "函" => "Han", "凾" => "Han", "凿" => "Zao", "åˆ" => "Diao", "刂" => "Dao", "刃" => "Ren", + "刄" => "Ren", "刅" => "Chuang", "分" => "Fen", "切" => "Qie", "刈" => "Yi", "刉" => "Ji", + "刊" => "Kan", "刋" => "Qian", "刌" => "Cun", "åˆ" => "Chu", "刎" => "Wen", "åˆ" => "Ji", + "åˆ" => "Dan", "刑" => "Xing", "划" => "Hua", "刓" => "Wan", "刔" => "Jue", "刕" => "Li", + "刖" => "Yue", "列" => "Lie", "刘" => "Liu", "则" => "Ze", "刚" => "Gang", "创" => "Chuang", + "刜" => "Fu", "åˆ" => "Chu", "刞" => "Qu", "刟" => "Ju", "删" => "Shan", "刡" => "Min", + "刢" => "Ling", "刣" => "Zhong", "判" => "Pan", "別" => "Bie", "刦" => "Jie", "刧" => "Jie", + "刨" => "Bao", "利" => "Li", "刪" => "Shan", "别" => "Bie", "刬" => "Chan", "刭" => "Jing", + "刮" => "Gua", "刯" => "Gen", "到" => "Dao", "刱" => "Chuang", "刲" => "Kui", "刳" => "Ku", + "刴" => "Duo", "刵" => "Er", "制" => "Zhi", "刷" => "Shua", "券" => "Quan", "刹" => "Cha", + "刺" => "Ci", "刻" => "Ke", "刼" => "Jie", "刽" => "Gui", "刾" => "Ci", "刿" => "Gui", + "剀" => "Kai", "å‰" => "Duo", "剂" => "Ji", "剃" => "Ti", "剄" => "Jing", "剅" => "Lou", + "剆" => "Gen", "則" => "Ze", "剈" => "Yuan", "剉" => "Cuo", "削" => "Xue", "剋" => "Ke", + "剌" => "La", "å‰" => "Qian", "剎" => "Cha", "å‰" => "Chuang", "å‰" => "Gua", "剑" => "Jian", + "剒" => "Cuo", "剓" => "Li", "剔" => "Ti", "剕" => "Fei", "剖" => "Pou", "剗" => "Chan", + "剘" => "Qi", "剙" => "Chuang", "剚" => "Zi", "剛" => "Gang", "剜" => "Wan", "å‰" => "Bo", + "剞" => "Ji", "剟" => "Duo", "剠" => "Qing", "剡" => "Yan", "剢" => "Zhuo", "剣" => "Jian", + "剤" => "Ji", "剥" => "Bo", "剦" => "Yan", "剧" => "Ju", "剨" => "Huo", "剩" => "Sheng", + "剪" => "Jian", "剫" => "Duo", "剬" => "Duan", "剭" => "Wu", "剮" => "Gua", "副" => "Fu", + "剰" => "Sheng", "剱" => "Jian", "割" => "Ge", "剳" => "Zha", "剴" => "Kai", "創" => "Chuang", + "剶" => "Juan", "剷" => "Chan", "剸" => "Tuan", "剹" => "Lu", "剺" => "Li", "剻" => "Fou", + "剼" => "Shan", "剽" => "Piao", "剾" => "Kou", "剿" => "Jiao", "劀" => "Gua", "åŠ" => "Qiao", + "劂" => "Jue", "劃" => "Hua", "劄" => "Zha", "劅" => "Zhuo", "劆" => "Lian", "劇" => "Ju", + "劈" => "Pi", "劉" => "Liu", "劊" => "Gui", "劋" => "Jiao", "劌" => "Gui", "åŠ" => "Jian", + "劎" => "Jian", "åŠ" => "Tang", "åŠ" => "Huo", "劑" => "Ji", "劒" => "Jian", "劓" => "Yi", + "劔" => "Jian", "劕" => "Zhi", "劖" => "Chan", "劗" => "Cuan", "劘" => "Mo", "劙" => "Li", + "劚" => "Zhu", "力" => "Li", "劜" => "Ya", "åŠ" => "Quan", "办" => "Ban", "功" => "Gong", + "加" => "Jia", "务" => "Wu", "劢" => "Mai", "劣" => "Lie", "劤" => "Jin", "劥" => "Keng", + "劦" => "Xie", "劧" => "Zhi", "动" => "Dong", "助" => "Zhu", "努" => "Nu", "劫" => "Jie", + "劬" => "Qu", "劭" => "Shao", "劮" => "Yi", "劯" => "Zhu", "劰" => "Miao", "励" => "Li", + "劲" => "Jing", "劳" => "Lao", "労" => "Lao", "劵" => "Juan", "劶" => "Kou", "劷" => "Yang", + "劸" => "Wa", "効" => "Xiao", "劺" => "Mou", "劻" => "Kuang", "劼" => "Jie", "劽" => "Lie", + "劾" => "He", "势" => "Shi", "å‹€" => "Ke", "å‹" => "Jing", "å‹‚" => "Hao", "勃" => "Bo", + "å‹„" => "Min", "å‹…" => "Chi", "勆" => "Lang", "勇" => "Yong", "勈" => "Yong", "勉" => "Mian", + "å‹Š" => "Ke", "å‹‹" => "Xun", "å‹Œ" => "Juan", "å‹" => "Qing", "å‹Ž" => "Lu", "å‹" => "Pou", + "å‹" => "Meng", "å‹‘" => "Lai", "å‹’" => "Le", "å‹“" => "Kai", "å‹”" => "Mian", "å‹•" => "Dong", + "å‹–" => "Xu", "å‹—" => "Xu", "勘" => "Kan", "å‹™" => "Wu", "å‹š" => "Yi", "å‹›" => "Xun", + "å‹œ" => "Weng", "å‹" => "Sheng", "å‹ž" => "Lao", "å‹Ÿ" => "Mu", "å‹ " => "Lu", "å‹¡" => "Piao", + "å‹¢" => "Shi", "å‹£" => "Ji", "勤" => "Qin", "å‹¥" => "Qiang", "勦" => "Jiao", "勧" => "Quan", + "勨" => "Yang", "å‹©" => "Yi", "勪" => "Jue", "å‹«" => "Fan", "勬" => "Juan", "å‹­" => "Tong", + "å‹®" => "Ju", "勯" => "Dan", "å‹°" => "Xie", "勱" => "Mai", "勲" => "Xun", "勳" => "Xun", + "å‹´" => "Lu", "勵" => "Li", "勶" => "Che", "å‹·" => "Rang", "勸" => "Quan", "勹" => "Bao", + "勺" => "Shao", "å‹»" => "Yun", "勼" => "Jiu", "勽" => "Bao", "勾" => "Gou", "å‹¿" => "Wu", + "åŒ" => "Mwun", "匂" => "Nay", "匃" => "Gai", "匄" => "Gai", "包" => "Bao", "匆" => "Cong", + "匈" => "Xiong", "匉" => "Peng", "匊" => "Ju", "匋" => "Tao", "匌" => "Ge", "åŒ" => "Pu", + "匎" => "An", "åŒ" => "Pao", "åŒ" => "Fu", "匑" => "Gong", "匒" => "Da", "匓" => "Jiu", + "匔" => "Qiong", "匕" => "Bi", "化" => "Hua", "北" => "Bei", "匘" => "Nao", "匙" => "Chi", + "匚" => "Fang", "匛" => "Jiu", "匜" => "Yi", "åŒ" => "Za", "匞" => "Jiang", "匟" => "Kang", + "匠" => "Jiang", "匡" => "Kuang", "匢" => "Hu", "匣" => "Xia", "匤" => "Qu", "匥" => "Bian", + "匦" => "Gui", "匧" => "Qie", "匨" => "Zang", "匩" => "Kuang", "匪" => "Fei", "匫" => "Hu", + "匬" => "Tou", "匭" => "Gui", "匮" => "Gui", "匯" => "Hui", "匰" => "Dan", "匱" => "Gui", + "匲" => "Lian", "匳" => "Lian", "匴" => "Suan", "匵" => "Du", "匶" => "Jiu", "匷" => "Qu", + "匸" => "Xi", "匹" => "Pi", "区" => "Qu", "医" => "Yi", "匼" => "Qia", "匽" => "Yan", + "匾" => "Bian", "匿" => "Ni", "å€" => "Qu", "å" => "Shi", "å‚" => "Xin", "åƒ" => "Qian", + "å„" => "Nian", "å…" => "Sa", "å†" => "Zu", "å‡" => "Sheng", "åˆ" => "Wu", "å‰" => "Hui", + "åŠ" => "Ban", "å‹" => "Shi", "åŒ" => "Xi", "å" => "Wan", "åŽ" => "Hua", "å" => "Xie", + "å" => "Wan", "å‘" => "Bei", "å’" => "Zu", "å“" => "Zhuo", "å”" => "Xie", "å•" => "Dan", + "å–" => "Mai", "å—" => "Nan", "å˜" => "Dan", "å™" => "Ji", "åš" => "Bo", "å›" => "Shuai", + "åœ" => "Bu", "å" => "Kuang", "åž" => "Bian", "åŸ" => "Bu", "å " => "Zhan", "å¡" => "Qia", + "å¢" => "Lu", "å£" => "You", "å¤" => "Lu", "å¥" => "Xi", "å¦" => "Gua", "å§" => "Wo", + "å¨" => "Xie", "å©" => "Jie", "åª" => "Jie", "å«" => "Wei", "å¬" => "Ang", "å­" => "Qiong", + "å®" => "Zhi", "å¯" => "Mao", "å°" => "Yin", "å±" => "Wei", "å²" => "Shao", "å³" => "Ji", + "å´" => "Que", "åµ" => "Luan", "å¶" => "Shi", "å·" => "Juan", "å¸" => "Xie", "å¹" => "Xu", + "åº" => "Jin", "å»" => "Que", "å¼" => "Wu", "å½" => "Ji", "å¾" => "E", "å¿" => "Qing", + "厀" => "Xi", "厂" => "Han", "厃" => "Zhan", "厄" => "E", "厅" => "Ting", "历" => "Li", + "厇" => "Zhe", "厈" => "Han", "厉" => "Li", "厊" => "Ya", "压" => "Ya", "厌" => "Yan", + "åŽ" => "She", "厎" => "Zhi", "åŽ" => "Zha", "åŽ" => "Pang", "厒" => "He", "厓" => "Ya", + "厔" => "Zhi", "厕" => "Ce", "厖" => "Pang", "厗" => "Ti", "厘" => "Li", "厙" => "She", + "厚" => "Hou", "厛" => "Ting", "厜" => "Zui", "åŽ" => "Cuo", "厞" => "Fei", "原" => "Yuan", + "厠" => "Ce", "厡" => "Yuan", "厢" => "Xiang", "厣" => "Yan", "厤" => "Li", "厥" => "Jue", + "厦" => "Sha", "厧" => "Dian", "厨" => "Chu", "厩" => "Jiu", "厪" => "Qin", "厫" => "Ao", + "厬" => "Gui", "厭" => "Yan", "厮" => "Si", "厯" => "Li", "厰" => "Chang", "厱" => "Lan", + "厲" => "Li", "厳" => "Yan", "厴" => "Yan", "厵" => "Yuan", "厶" => "Si", "厷" => "Gong", + "厸" => "Lin", "厹" => "Qiu", "厺" => "Qu", "去" => "Qu", "厼" => "Uk", "厽" => "Lei", + "厾" => "Du", "县" => "Xian", "å€" => "Zhuan", "å" => "San", "å‚" => "Can", "åƒ" => "Can", + "å„" => "Can", "å…" => "Can", "å†" => "Ai", "å‡" => "Dai", "åˆ" => "You", "å‰" => "Cha", + "åŠ" => "Ji", "å‹" => "You", "åŒ" => "Shuang", "å" => "Fan", "åŽ" => "Shou", "å" => "Guai", + "å" => "Ba", "å‘" => "Fa", "å’" => "Ruo", "å“" => "Shi", "å”" => "Shu", "å•" => "Zhuo", + "å–" => "Qu", "å—" => "Shou", "å˜" => "Bian", "å™" => "Xu", "åš" => "Jia", "å›" => "Pan", + "åœ" => "Sou", "å" => "Gao", "åž" => "Wei", "åŸ" => "Sou", "å " => "Die", "å¡" => "Rui", + "å¢" => "Cong", "å£" => "Kou", "å¤" => "Gu", "å¥" => "Ju", "å¦" => "Ling", "å§" => "Gua", + "å¨" => "Tao", "å©" => "Kou", "åª" => "Zhi", "å«" => "Jiao", "å¬" => "Zhao", "å­" => "Ba", + "å®" => "Ding", "å¯" => "Ke", "å°" => "Tai", "å±" => "Chi", "å²" => "Shi", "å³" => "You", + "å´" => "Qiu", "åµ" => "Po", "å¶" => "Xie", "å·" => "Hao", "å¸" => "Si", "å¹" => "Tan", + "åº" => "Chi", "å»" => "Le", "å¼" => "Diao", "å½" => "Ji", "å¿" => "Hong", "å" => "Xu", + "å‚" => "Mang", "åƒ" => "Chi", "å„" => "Ge", "å…" => "Xuan", "å†" => "Yao", "å‡" => "Zi", + "åˆ" => "He", "å‰" => "Ji", "åŠ" => "Diao", "å‹" => "Cun", "åŒ" => "Tong", "å" => "Ming", + "åŽ" => "Hou", "å" => "Li", "å" => "Tu", "å‘" => "Xiang", "å’" => "Zha", "å“" => "Xia", + "å”" => "Ye", "å•" => "Lu", "å–" => "A", "å—" => "Ma", "å˜" => "Ou", "å™" => "Xue", + "åš" => "Yi", "å›" => "Jun", "åœ" => "Chou", "å" => "Lin", "åž" => "Tun", "åŸ" => "Yin", + "å " => "Fei", "å¡" => "Bi", "å¢" => "Qin", "å£" => "Qin", "å¤" => "Jie", "å¥" => "Bu", + "å¦" => "Fou", "å§" => "Ba", "å¨" => "Dun", "å©" => "Fen", "åª" => "E", "å«" => "Han", + "å¬" => "Ting", "å­" => "Hang", "å®" => "Shun", "å¯" => "Qi", "å°" => "Hong", "å±" => "Zhi", + "å²" => "Shen", "å³" => "Wu", "å´" => "Wu", "åµ" => "Chao", "å¶" => "Ne", "å·" => "Xue", + "å¸" => "Xi", "å¹" => "Chui", "åº" => "Dou", "å»" => "Wen", "å¼" => "Hou", "å½" => "Ou", + "å¾" => "Wu", "å¿" => "Gao", "å‘€" => "Ya", "å‘" => "Jun", "å‘‚" => "Lu", "呃" => "E", + "å‘„" => "Ge", "å‘…" => "Mei", "呆" => "Ai", "呇" => "Qi", "呈" => "Cheng", "呉" => "Wu", + "å‘Š" => "Gao", "å‘‹" => "Fu", "å‘Œ" => "Jiao", "å‘" => "Hong", "å‘Ž" => "Chi", "å‘" => "Sheng", + "å‘" => "Ne", "å‘‘" => "Tun", "å‘’" => "Fu", "å‘“" => "Yi", "å‘”" => "Dai", "å‘•" => "Ou", + "å‘–" => "Li", "å‘—" => "Bai", "员" => "Yuan", "å‘™" => "Kuai", "å‘›" => "Qiang", "å‘œ" => "Wu", + "å‘" => "E", "å‘ž" => "Shi", "å‘Ÿ" => "Quan", "å‘ " => "Pen", "å‘¡" => "Wen", "å‘¢" => "Ni", + "å‘£" => "M", "呤" => "Ling", "å‘¥" => "Ran", "呦" => "You", "呧" => "Di", "周" => "Zhou", + "å‘©" => "Shi", "呪" => "Zhou", "å‘«" => "Tie", "呬" => "Xi", "å‘­" => "Yi", "å‘®" => "Qi", + "呯" => "Ping", "å‘°" => "Zi", "呱" => "Gu", "呲" => "Zi", "味" => "Wei", "å‘´" => "Xu", + "呵" => "He", "呶" => "Nao", "å‘·" => "Xia", "呸" => "Pei", "呹" => "Yi", "呺" => "Xiao", + "å‘»" => "Shen", "呼" => "Hu", "命" => "Ming", "呾" => "Da", "å‘¿" => "Qu", "å’€" => "Ju", + "å’" => "Gem", "å’‚" => "Za", "å’ƒ" => "Tuo", "å’„" => "Duo", "å’…" => "Pou", "å’†" => "Pao", + "å’‡" => "Bi", "å’ˆ" => "Fu", "å’‰" => "Yang", "å’Š" => "He", "å’‹" => "Zha", "å’Œ" => "He", + "å’" => "Hai", "å’Ž" => "Jiu", "å’" => "Yong", "å’" => "Fu", "å’‘" => "Que", "å’’" => "Zhou", + "å’“" => "Wa", "å’”" => "Ka", "å’•" => "Gu", "å’–" => "Ka", "å’—" => "Zuo", "å’˜" => "Bu", + "å’™" => "Long", "å’š" => "Dong", "å’›" => "Ning", "å’œ" => "Tha", "å’" => "Si", "å’ž" => "Xian", + "å’Ÿ" => "Huo", "å’ " => "Qi", "å’¡" => "Er", "å’¢" => "E", "å’£" => "Guang", "å’¤" => "Zha", + "å’¥" => "Xi", "å’¦" => "Yi", "å’§" => "Lie", "å’¨" => "Zi", "å’©" => "Mie", "å’ª" => "Mi", + "å’«" => "Zhi", "å’¬" => "Yao", "å’­" => "Ji", "å’®" => "Zhou", "å’¯" => "Ge", "å’°" => "Shuai", + "å’±" => "Zan", "å’²" => "Xiao", "å’³" => "Ke", "å’´" => "Hui", "å’µ" => "Kua", "å’¶" => "Huai", + "å’·" => "Tao", "å’¸" => "Xian", "å’¹" => "E", "å’º" => "Xuan", "å’»" => "Xiu", "å’¼" => "Wai", + "å’½" => "Yan", "å’¾" => "Lao", "å’¿" => "Yi", "å“€" => "Ai", "å“" => "Pin", "å“‚" => "Shen", + "哃" => "Tong", "å“„" => "Hong", "å“…" => "Xiong", "哆" => "Chi", "哇" => "Wa", "哈" => "Ha", + "哉" => "Zai", "å“Š" => "Yu", "å“‹" => "Di", "å“Œ" => "Pai", "å“" => "Xiang", "å“Ž" => "Ai", + "å“" => "Hen", "å“" => "Kuang", "å“‘" => "Ya", "å“’" => "Da", "å““" => "Xiao", "å“”" => "Bi", + "å“•" => "Yue", "å“—" => "Hua", "哘" => "Sasou", "å“™" => "Kuai", "å“š" => "Duo", "å“œ" => "Ji", + "å“" => "Nong", "å“ž" => "Mou", "å“Ÿ" => "Yo", "å“ " => "Hao", "å“¡" => "Yuan", "å“¢" => "Long", + "å“£" => "Pou", "哤" => "Mang", "å“¥" => "Ge", "哦" => "E", "哧" => "Chi", "哨" => "Shao", + "å“©" => "Li", "哪" => "Na", "å“«" => "Zu", "哬" => "He", "å“­" => "Ku", "å“®" => "Xiao", + "哯" => "Xian", "å“°" => "Lao", "哱" => "Bo", "哲" => "Zhe", "哳" => "Zha", "å“´" => "Liang", + "哵" => "Ba", "哶" => "Mie", "å“·" => "Le", "哸" => "Sui", "哹" => "Fou", "哺" => "Bu", + "å“»" => "Han", "哼" => "Heng", "哽" => "Geng", "哾" => "Shuo", "å“¿" => "Ge", "å”" => "Yan", + "唂" => "Gu", "唃" => "Gu", "唄" => "Bai", "å”…" => "Han", "唆" => "Suo", "唇" => "Chun", + "唈" => "Yi", "唉" => "Ai", "唊" => "Jia", "唋" => "Tu", "唌" => "Xian", "å”" => "Huan", + "唎" => "Li", "å”" => "Xi", "å”" => "Tang", "唑" => "Zuo", "å”’" => "Qiu", "唓" => "Che", + "å””" => "Wu", "唕" => "Zao", "å”–" => "Ya", "å”—" => "Dou", "唘" => "Qi", "å”™" => "Di", + "唚" => "Qin", "å”›" => "Ma", "唜" => "Mal", "å”" => "Hong", "唞" => "Dou", "唟" => "Kes", + "å” " => "Lao", "唡" => "Liang", "唢" => "Suo", "唣" => "Zao", "唤" => "Huan", "唥" => "Lang", + "唦" => "Sha", "唧" => "Ji", "唨" => "Zuo", "唩" => "Wo", "唪" => "Feng", "唫" => "Yin", + "唬" => "Hu", "å”­" => "Qi", "å”®" => "Shou", "唯" => "Wei", "å”°" => "Shua", "å”±" => "Chang", + "唲" => "Er", "唳" => "Li", "å”´" => "Qiang", "唵" => "An", "唶" => "Jie", "å”·" => "Yo", + "唸" => "Nian", "唹" => "Yu", "唺" => "Tian", "å”»" => "Lai", "唼" => "Sha", "唽" => "Xi", + "唾" => "Tuo", "唿" => "Hu", "å•€" => "Ai", "å•" => "Zhou", "å•‚" => "Nou", "啃" => "Ken", + "å•„" => "Zhuo", "å•…" => "Zhuo", "商" => "Shang", "啇" => "Di", "啈" => "Heng", "啉" => "Lan", + "å•Š" => "A", "å•‹" => "Xiao", "å•Œ" => "Xiang", "å•" => "Tun", "å•Ž" => "Wu", "å•" => "Wen", + "å•" => "Cui", "å•‘" => "Sha", "å•’" => "Hu", "å•“" => "Qi", "å•”" => "Qi", "å••" => "Tao", + "å•–" => "Dan", "å•—" => "Dan", "啘" => "Ye", "å•™" => "Zi", "å•š" => "Bi", "å•›" => "Cui", + "å•œ" => "Chuo", "å•" => "He", "å•ž" => "Ya", "å•Ÿ" => "Qi", "å• " => "Zhe", "å•¡" => "Pei", + "å•¢" => "Liang", "å•£" => "Xian", "啤" => "Pi", "å•¥" => "Sha", "啦" => "La", "啧" => "Ze", + "啨" => "Qing", "å•©" => "Gua", "啪" => "Pa", "å•«" => "Zhe", "啬" => "Se", "å•­" => "Zhuan", + "å•®" => "Nie", "啯" => "Guo", "å•°" => "Luo", "啱" => "Yan", "啲" => "Di", "啳" => "Quan", + "å•´" => "Tan", "啵" => "Bo", "啶" => "Ding", "å•·" => "Lang", "啸" => "Xiao", "啺" => "Tang", + "å•»" => "Chi", "啼" => "Ti", "啽" => "An", "啾" => "Jiu", "å•¿" => "Dan", "å–€" => "Ke", + "å–" => "Yong", "å–‚" => "Wei", "å–ƒ" => "Nan", "å–„" => "Shan", "å–…" => "Yu", "å–†" => "Zhe", + "å–‡" => "La", "å–ˆ" => "Jie", "å–‰" => "Hou", "å–Š" => "Han", "å–‹" => "Die", "å–Œ" => "Zhou", + "å–" => "Chai", "å–Ž" => "Wai", "å–" => "Re", "å–" => "Yu", "å–‘" => "Yin", "å–’" => "Zan", + "å–“" => "Yao", "å–”" => "Wo", "å–•" => "Mian", "å––" => "Hu", "å–—" => "Yun", "å–˜" => "Chuan", + "å–™" => "Hui", "å–š" => "Huan", "å–›" => "Huan", "å–œ" => "Xi", "å–" => "He", "å–ž" => "Ji", + "å–Ÿ" => "Kui", "å– " => "Zhong", "å–¡" => "Wei", "å–¢" => "Sha", "å–£" => "Xu", "å–¤" => "Huang", + "å–¥" => "Du", "å–¦" => "Nie", "å–§" => "Xuan", "å–¨" => "Liang", "å–©" => "Yu", "å–ª" => "Sang", + "å–«" => "Chi", "å–¬" => "Qiao", "å–­" => "Yan", "å–®" => "Dan", "å–¯" => "Pen", "å–°" => "Can", + "å–±" => "Li", "å–²" => "Yo", "å–³" => "Zha", "å–´" => "Wei", "å–µ" => "Miao", "å–¶" => "Ying", + "å–·" => "Pen", "å–¸" => "Phos", "å–¹" => "Kui", "å–º" => "Xi", "å–»" => "Yu", "å–¼" => "Jie", + "å–½" => "Lou", "å–¾" => "Ku", "å–¿" => "Sao", "å—€" => "Huo", "å—" => "Ti", "å—‚" => "Yao", + "å—ƒ" => "He", "å—„" => "A", "å—…" => "Xiu", "å—†" => "Qiang", "å—‡" => "Se", "å—ˆ" => "Yong", + "å—‰" => "Su", "å—Š" => "Hong", "å—‹" => "Xie", "å—Œ" => "Yi", "å—" => "Suo", "å—Ž" => "Ma", + "å—" => "Cha", "å—" => "Hai", "å—‘" => "Ke", "å—’" => "Ta", "å—“" => "Sang", "å—”" => "Tian", + "å—•" => "Ru", "å—–" => "Sou", "å——" => "Wa", "å—˜" => "Ji", "å—™" => "Pang", "å—š" => "Wu", + "å—›" => "Xian", "å—œ" => "Shi", "å—" => "Ge", "å—ž" => "Zi", "å—Ÿ" => "Jie", "å— " => "Luo", + "å—¡" => "Weng", "å—¢" => "Wa", "å—£" => "Si", "å—¤" => "Chi", "å—¥" => "Hao", "å—¦" => "Suo", + "å—§" => "Jia", "å—¨" => "Hai", "å—©" => "Suo", "å—ª" => "Qin", "å—«" => "Nie", "å—¬" => "He", + "å—­" => "Cis", "å—®" => "Sai", "å—¯" => "Ng", "å—°" => "Ge", "å—±" => "Na", "å—²" => "Dia", + "å—³" => "Ai", "å—µ" => "Tong", "å—¶" => "Bi", "å—·" => "Ao", "å—¸" => "Ao", "å—¹" => "Lian", + "å—º" => "Cui", "å—»" => "Zhe", "å—¼" => "Mo", "å—½" => "Sou", "å—¾" => "Sou", "å—¿" => "Tan", + "å˜" => "Qi", "嘂" => "Jiao", "嘃" => "Chong", "嘄" => "Jiao", "嘅" => "Kai", "嘆" => "Tan", + "嘇" => "San", "嘈" => "Cao", "嘉" => "Jia", "嘊" => "Ai", "嘋" => "Xiao", "嘌" => "Piao", + "å˜" => "Lou", "嘎" => "Ga", "å˜" => "Gu", "å˜" => "Xiao", "嘑" => "Hu", "嘒" => "Hui", + "嘓" => "Guo", "嘔" => "Ou", "嘕" => "Xian", "嘖" => "Ze", "嘗" => "Chang", "嘘" => "Xu", + "嘙" => "Po", "嘚" => "De", "嘛" => "Ma", "嘜" => "Ma", "å˜" => "Hu", "嘞" => "Lei", + "嘟" => "Du", "嘠" => "Ga", "嘡" => "Tang", "嘢" => "Ye", "嘣" => "Beng", "嘤" => "Ying", + "嘥" => "Saai", "嘦" => "Jiao", "嘧" => "Mi", "嘨" => "Xiao", "嘩" => "Hua", "嘪" => "Mai", + "嘫" => "Ran", "嘬" => "Zuo", "嘭" => "Peng", "嘮" => "Lao", "嘯" => "Xiao", "嘰" => "Ji", + "嘱" => "Zhu", "嘲" => "Chao", "嘳" => "Kui", "嘴" => "Zui", "嘵" => "Xiao", "嘶" => "Si", + "嘷" => "Hao", "嘸" => "Fu", "嘹" => "Liao", "嘺" => "Qiao", "嘻" => "Xi", "嘼" => "Xiu", + "嘽" => "Tan", "嘾" => "Tan", "嘿" => "Mo", "噀" => "Xun", "å™" => "E", "噂" => "Zun", + "噃" => "Fan", "噄" => "Chi", "å™…" => "Hui", "噆" => "Zan", "噇" => "Chuang", "噈" => "Cu", + "噉" => "Dan", "噊" => "Yu", "噋" => "Tun", "噌" => "Cheng", "å™" => "Jiao", "噎" => "Ye", + "å™" => "Xi", "å™" => "Qi", "噑" => "Hao", "å™’" => "Lian", "噓" => "Xu", "å™”" => "Deng", + "噕" => "Hui", "å™–" => "Yin", "å™—" => "Pu", "噘" => "Jue", "å™™" => "Qin", "噚" => "Xun", + "å™›" => "Nie", "噜" => "Lu", "å™" => "Si", "噞" => "Yan", "噟" => "Ying", "å™ " => "Da", + "噡" => "Dan", "噢" => "Yu", "噣" => "Zhou", "噤" => "Jin", "噥" => "Nong", "噦" => "Yue", + "噧" => "Hui", "器" => "Qi", "噩" => "E", "噪" => "Zao", "噫" => "Yi", "噬" => "Shi", + "å™­" => "Jiao", "å™®" => "Yuan", "噯" => "Ai", "å™°" => "Yong", "å™±" => "Jue", "噲" => "Kuai", + "噳" => "Yu", "å™´" => "Pen", "噵" => "Dao", "噶" => "Ge", "å™·" => "Xin", "噸" => "Dun", + "噹" => "Dang", "噺" => "Sin", "å™»" => "Sai", "噼" => "Pi", "噽" => "Pi", "噾" => "Yin", + "噿" => "Zui", "嚀" => "Ning", "åš" => "Di", "åš‚" => "Lan", "嚃" => "Ta", "åš„" => "Huo", + "åš…" => "Ru", "嚆" => "Hao", "嚇" => "Xia", "嚈" => "Ya", "嚉" => "Duo", "嚊" => "Xi", + "åš‹" => "Chou", "嚌" => "Ji", "åš" => "Jin", "嚎" => "Hao", "åš" => "Ti", "åš" => "Chang", + "åš“" => "Ca", "åš”" => "Ti", "åš•" => "Lu", "åš–" => "Hui", "åš—" => "Bo", "嚘" => "You", + "åš™" => "Nie", "åšš" => "Yin", "åš›" => "Hu", "åšœ" => "Mo", "åš" => "Huang", "åšž" => "Zhe", + "嚟" => "Li", "åš " => "Liu", "åš¡" => "Haai", "嚢" => "Nang", "嚣" => "Xiao", "嚤" => "Mo", + "嚥" => "Yan", "嚦" => "Li", "嚧" => "Lu", "嚨" => "Long", "åš©" => "Fu", "嚪" => "Dan", + "åš«" => "Chen", "嚬" => "Pin", "åš­" => "Pi", "åš®" => "Xiang", "嚯" => "Huo", "åš°" => "Mo", + "åš±" => "Xi", "åš²" => "Duo", "åš³" => "Ku", "åš´" => "Yan", "åšµ" => "Chan", "嚶" => "Ying", + "åš·" => "Rang", "嚸" => "Dian", "åš¹" => "La", "嚺" => "Ta", "åš»" => "Xiao", "åš¼" => "Jiao", + "åš½" => "Chuo", "åš¾" => "Huan", "åš¿" => "Huo", "囀" => "Zhuan", "å›" => "Nie", "囂" => "Xiao", + "囃" => "Ca", "囄" => "Li", "å›…" => "Chan", "囆" => "Chai", "囇" => "Li", "囈" => "Yi", + "囉" => "Luo", "囊" => "Nang", "囋" => "Zan", "囌" => "Su", "å›" => "Xi", "囎" => "So", + "å›" => "Jian", "å›" => "Za", "囑" => "Zhu", "å›’" => "Lan", "囓" => "Nie", "å›”" => "Nang", + "å›—" => "Wei", "囘" => "Hui", "å›™" => "Yin", "囚" => "Qiu", "å››" => "Si", "囜" => "Nin", + "å›" => "Jian", "回" => "Hui", "囟" => "Xin", "å› " => "Yin", "囡" => "Nan", "团" => "Tuan", + "団" => "Tuan", "囤" => "Dun", "囥" => "Kang", "囦" => "Yuan", "囧" => "Jiong", "囨" => "Pian", + "囩" => "Yun", "囪" => "Cong", "囫" => "Hu", "囬" => "Hui", "å›­" => "Yuan", "å›®" => "You", + "囯" => "Guo", "å›°" => "Kun", "å›±" => "Cong", "囲" => "Wei", "図" => "Tu", "å›´" => "Wei", + "囵" => "Lun", "囶" => "Guo", "å›·" => "Qun", "囸" => "Ri", "囹" => "Ling", "固" => "Gu", + "å›»" => "Guo", "囼" => "Tai", "国" => "Guo", "图" => "Tu", "囿" => "You", "åœ" => "Yin", + "圂" => "Hun", "圃" => "Pu", "圄" => "Yu", "圅" => "Han", "圆" => "Yuan", "圇" => "Lun", + "圈" => "Quan", "圉" => "Yu", "圊" => "Qing", "國" => "Guo", "圌" => "Chuan", "åœ" => "Wei", + "圎" => "Yuan", "åœ" => "Quan", "åœ" => "Ku", "圑" => "Fu", "園" => "Yuan", "圓" => "Yuan", + "圔" => "E", "圕" => "Tu", "圖" => "Tu", "圗" => "Tu", "團" => "Tuan", "圙" => "Lue", + "圚" => "Hui", "圛" => "Yi", "圜" => "Yuan", "åœ" => "Luan", "圞" => "Luan", "土" => "Tu", + "圠" => "Ya", "圡" => "Tu", "圢" => "Ting", "圣" => "Sheng", "圤" => "Pu", "圥" => "Lu", + "圦" => "Iri", "圧" => "Ya", "在" => "Zai", "圩" => "Wei", "圪" => "Ge", "圫" => "Yu", + "圬" => "Wu", "圭" => "Gui", "圮" => "Pi", "圯" => "Yi", "地" => "Di", "圱" => "Qian", + "圲" => "Qian", "圳" => "Zhen", "圴" => "Zhuo", "圵" => "Dang", "圶" => "Qia", "圷" => "Akutsu", + "圸" => "Yama", "圹" => "Kuang", "场" => "Chang", "圻" => "Qi", "圼" => "Nie", "圽" => "Mo", + "圾" => "Ji", "圿" => "Jia", "å€" => "Zhi", "å" => "Zhi", "å‚" => "Ban", "åƒ" => "Xun", + "å„" => "Tou", "å…" => "Qin", "å†" => "Fen", "å‡" => "Jun", "åˆ" => "Keng", "å‰" => "Tun", + "åŠ" => "Fang", "å‹" => "Fen", "åŒ" => "Ben", "å" => "Tan", "åŽ" => "Kan", "å" => "Pi", + "å" => "Zuo", "å‘" => "Keng", "å’" => "Bi", "å“" => "Xing", "å”" => "Di", "å•" => "Jing", + "å–" => "Ji", "å—" => "Kuai", "å˜" => "Di", "å™" => "Jing", "åš" => "Jian", "å›" => "Tan", + "åœ" => "Li", "å" => "Ba", "åž" => "Wu", "åŸ" => "Fen", "å " => "Zhui", "å¡" => "Po", + "å¢" => "Pan", "å£" => "Tang", "å¤" => "Kun", "å¥" => "Qu", "å¦" => "Tan", "å§" => "Zhi", + "å¨" => "Tuo", "å©" => "Gan", "åª" => "Ping", "å«" => "Dian", "å¬" => "Gua", "å­" => "Ni", + "å®" => "Tai", "å¯" => "Pi", "å°" => "Jiong", "å±" => "Yang", "å²" => "Fo", "å³" => "Ao", + "å´" => "Liu", "åµ" => "Qiu", "å¶" => "Mu", "å·" => "Ke", "å¸" => "Gou", "å¹" => "Xue", + "åº" => "Ba", "å»" => "Chi", "å¼" => "Che", "å½" => "Ling", "å¾" => "Zhu", "å¿" => "Fu", + "垀" => "Hu", "åž" => "Zhi", "åž‚" => "Chui", "垃" => "La", "åž„" => "Long", "åž…" => "Long", + "垆" => "Lu", "垇" => "Ao", "垈" => "Tay", "垉" => "Pao", "åž‹" => "Xing", "垌" => "Dong", + "åž" => "Ji", "垎" => "Ke", "åž" => "Lu", "åž" => "Ci", "åž‘" => "Chi", "åž’" => "Lei", + "åž“" => "Gai", "åž”" => "Yin", "åž•" => "Hou", "åž–" => "Dui", "åž—" => "Zhao", "垘" => "Fu", + "åž™" => "Guang", "åžš" => "Yao", "åž›" => "Duo", "åžœ" => "Duo", "åž" => "Gui", "åžž" => "Cha", + "垟" => "Yang", "åž " => "Yin", "åž¡" => "Fa", "垢" => "Gou", "垣" => "Yuan", "垤" => "Die", + "垥" => "Xie", "垦" => "Ken", "垧" => "Jiong", "垨" => "Shou", "åž©" => "E", "垪" => "Ha", + "åž«" => "Dian", "垬" => "Hong", "åž­" => "Wu", "åž®" => "Kua", "åž°" => "Tao", "åž±" => "Dang", + "åž²" => "Kai", "åž³" => "Gake", "åž´" => "Nao", "åžµ" => "An", "垶" => "Xing", "åž·" => "Xian", + "垸" => "Huan", "åž¹" => "Bang", "垺" => "Pei", "åž»" => "Ba", "åž¼" => "Yi", "åž½" => "Yin", + "åž¾" => "Han", "åž¿" => "Xu", "埀" => "Chui", "åŸ" => "Cen", "埂" => "Geng", "埃" => "Ai", + "埄" => "Peng", "埅" => "Fang", "埆" => "Que", "埇" => "Yong", "埈" => "Xun", "埉" => "Jia", + "埊" => "Di", "埋" => "Mai", "埌" => "Lang", "åŸ" => "Xuan", "城" => "Cheng", "åŸ" => "Yan", + "åŸ" => "Jin", "埑" => "Zhe", "埒" => "Lei", "埓" => "Lie", "埔" => "Bu", "埕" => "Cheng", + "埖" => "Gomi", "埗" => "Bu", "埘" => "Shi", "埙" => "Xun", "埚" => "Guo", "埛" => "Jiong", + "埜" => "Ye", "åŸ" => "Nian", "埞" => "Di", "域" => "Yu", "埠" => "Bu", "埡" => "Ya", + "埢" => "Juan", "埣" => "Sui", "埤" => "Pi", "埥" => "Cheng", "埦" => "Wan", "埧" => "Ju", + "埨" => "Lun", "埩" => "Zheng", "埪" => "Kong", "埫" => "Chong", "埬" => "Dong", "埭" => "Dai", + "埮" => "Tan", "埯" => "An", "埰" => "Cai", "埱" => "Shu", "埲" => "Beng", "埳" => "Kan", + "埴" => "Zhi", "埵" => "Duo", "埶" => "Yi", "執" => "Zhi", "埸" => "Yi", "培" => "Pei", + "基" => "Ji", "埻" => "Zhun", "埼" => "Qi", "埽" => "Sao", "埾" => "Ju", "埿" => "Ni", + "å " => "Ke", "å ‚" => "Tang", "å ƒ" => "Kun", "å „" => "Ni", "å …" => "Jian", "å †" => "Dui", + "å ‡" => "Jin", "å ˆ" => "Gang", "å ‰" => "Yu", "å Š" => "E", "å ‹" => "Peng", "å Œ" => "Gu", + "å " => "Tu", "å Ž" => "Leng", "å " => "Ya", "å ‘" => "Qian", "å “" => "An", "å •" => "Duo", + "å –" => "Nao", "å —" => "Tu", "å ˜" => "Cheng", "å ™" => "Yin", "å š" => "Hun", "å ›" => "Bi", + "å œ" => "Lian", "å " => "Guo", "å ž" => "Die", "å Ÿ" => "Zhuan", "å  " => "Hou", "å ¡" => "Bao", + "å ¢" => "Bao", "å £" => "Yu", "å ¤" => "Di", "å ¥" => "Mao", "å ¦" => "Jie", "å §" => "Ruan", + "å ¨" => "E", "å ©" => "Geng", "å ª" => "Kan", "å «" => "Zong", "å ¬" => "Yu", "å ­" => "Huang", + "å ®" => "E", "å ¯" => "Yao", "å °" => "Yan", "å ±" => "Bao", "å ²" => "Ji", "å ³" => "Mei", + "å ´" => "Chang", "å µ" => "Du", "å ¶" => "Tuo", "å ·" => "Yin", "å ¸" => "Feng", "å ¹" => "Zhong", + "å º" => "Jie", "å »" => "Zhen", "å ¼" => "Feng", "å ½" => "Gang", "å ¾" => "Chuan", "å ¿" => "Jian", + "å¡€" => "Pyeng", "å¡" => "Toride", "å¡‚" => "Xiang", "塃" => "Huang", "å¡„" => "Leng", "å¡…" => "Duan", + "塇" => "Xuan", "塈" => "Ji", "塉" => "Ji", "å¡Š" => "Kuai", "å¡‹" => "Ying", "å¡Œ" => "Ta", + "å¡" => "Cheng", "å¡Ž" => "Yong", "å¡" => "Kai", "å¡" => "Su", "å¡‘" => "Su", "å¡’" => "Shi", + "å¡“" => "Mi", "å¡”" => "Ta", "å¡•" => "Weng", "å¡–" => "Cheng", "å¡—" => "Tu", "塘" => "Tang", + "å¡™" => "Que", "å¡š" => "Zhong", "å¡›" => "Li", "å¡œ" => "Peng", "å¡" => "Bang", "å¡ž" => "Sai", + "å¡Ÿ" => "Zang", "å¡ " => "Dui", "å¡¡" => "Tian", "å¡¢" => "Wu", "å¡£" => "Cheng", "塤" => "Xun", + "å¡¥" => "Ge", "塦" => "Zhen", "塧" => "Ai", "塨" => "Gong", "å¡©" => "Yan", "塪" => "Kan", + "å¡«" => "Tian", "塬" => "Yuan", "å¡­" => "Wen", "å¡®" => "Xie", "塯" => "Liu", "å¡°" => "Ama", + "塱" => "Lang", "塲" => "Chang", "塳" => "Peng", "å¡´" => "Beng", "塵" => "Chen", "塶" => "Cu", + "å¡·" => "Lu", "塸" => "Ou", "塹" => "Qian", "塺" => "Mei", "å¡»" => "Mo", "塼" => "Zhuan", + "塽" => "Shuang", "塾" => "Shu", "å¡¿" => "Lou", "墀" => "Chi", "å¢" => "Man", "墂" => "Biao", + "境" => "Jing", "墄" => "Qi", "墅" => "Shu", "墆" => "Di", "墇" => "Zhang", "墈" => "Kan", + "墉" => "Yong", "墊" => "Dian", "墋" => "Chen", "墌" => "Zhi", "å¢" => "Xi", "墎" => "Guo", + "å¢" => "Qiang", "å¢" => "Jin", "墑" => "Di", "墒" => "Shang", "墓" => "Mu", "墔" => "Cui", + "墕" => "Yan", "墖" => "Ta", "増" => "Zeng", "墘" => "Qi", "墙" => "Qiang", "墚" => "Liang", + "墜" => "Zhui", "å¢" => "Qiao", "增" => "Zeng", "墟" => "Xu", "墠" => "Shan", "墡" => "Shan", + "墢" => "Ba", "墣" => "Pu", "墤" => "Kuai", "墥" => "Dong", "墦" => "Fan", "墧" => "Que", + "墨" => "Mo", "墩" => "Dun", "墪" => "Dun", "墫" => "Dun", "墬" => "Di", "墭" => "Sheng", + "墮" => "Duo", "墯" => "Duo", "墰" => "Tan", "墱" => "Deng", "墲" => "Wu", "墳" => "Fen", + "墴" => "Huang", "墵" => "Tan", "墶" => "Da", "墷" => "Ye", "墸" => "Sho", "墹" => "Mama", + "墺" => "Yu", "墻" => "Qiang", "墼" => "Ji", "墽" => "Qiao", "墾" => "Ken", "墿" => "Yi", + "壀" => "Pi", "å£" => "Bi", "壂" => "Dian", "壃" => "Jiang", "壄" => "Ye", "壅" => "Yong", + "壆" => "Bo", "壇" => "Tan", "壈" => "Lan", "壉" => "Ju", "壊" => "Huai", "壋" => "Dang", + "壌" => "Rang", "å£" => "Qian", "壎" => "Xun", "å£" => "Lan", "å£" => "Xi", "壑" => "He", + "壒" => "Ai", "壓" => "Ya", "壔" => "Dao", "壕" => "Hao", "壖" => "Ruan", "壗" => "Mama", + "壘" => "Lei", "壙" => "Kuang", "壚" => "Lu", "壛" => "Yan", "壜" => "Tan", "å£" => "Wei", + "壞" => "Huai", "壟" => "Long", "壠" => "Long", "壡" => "Rui", "壢" => "Li", "壣" => "Lin", + "壤" => "Rang", "壥" => "Ten", "壦" => "Xun", "壧" => "Yan", "壨" => "Lei", "壩" => "Ba", + "士" => "Shi", "壬" => "Ren", "壮" => "Zhuang", "壯" => "Zhuang", "声" => "Sheng", "壱" => "Yi", + "売" => "Mai", "壳" => "Ke", "壴" => "Zhu", "壵" => "Zhuang", "壶" => "Hu", "壷" => "Hu", + "壸" => "Kun", "壹" => "Yi", "壺" => "Hu", "壻" => "Xu", "壼" => "Kun", "壽" => "Shou", + "壾" => "Mang", "壿" => "Zun", "å¤" => "Yi", "夂" => "Zhi", "夃" => "Gu", "处" => "Chu", + "夅" => "Jiang", "夆" => "Feng", "备" => "Bei", "夈" => "Cay", "変" => "Bian", "夊" => "Sui", + "夋" => "Qun", "夌" => "Ling", "å¤" => "Fu", "夎" => "Zuo", "å¤" => "Xia", "å¤" => "Xiong", + "夒" => "Nao", "夓" => "Xia", "夔" => "Kui", "夕" => "Xi", "外" => "Wai", "夗" => "Yuan", + "夘" => "Mao", "夙" => "Su", "多" => "Duo", "夛" => "Duo", "夜" => "Ye", "å¤" => "Qing", + "夞" => "Uys", "够" => "Gou", "夠" => "Gou", "夡" => "Qi", "夢" => "Meng", "夣" => "Meng", + "夤" => "Yin", "夥" => "Huo", "夦" => "Chen", "大" => "Da", "夨" => "Ze", "天" => "Tian", + "太" => "Tai", "夫" => "Fu", "夬" => "Guai", "夭" => "Yao", "央" => "Yang", "夯" => "Hang", + "夰" => "Gao", "失" => "Shi", "夲" => "Ben", "夳" => "Tai", "头" => "Tou", "夵" => "Yan", + "夶" => "Bi", "夷" => "Yi", "夸" => "Kua", "夹" => "Jia", "夺" => "Duo", "夻" => "Kwu", + "夼" => "Kuang", "夽" => "Yun", "夾" => "Jia", "夿" => "Pa", "奀" => "En", "å¥" => "Lian", + "奂" => "Huan", "奃" => "Di", "奄" => "Yan", "奅" => "Pao", "奆" => "Quan", "奇" => "Qi", + "奈" => "Nai", "奉" => "Feng", "奊" => "Xie", "奋" => "Fen", "奌" => "Dian", "奎" => "Kui", + "å¥" => "Zou", "å¥" => "Huan", "契" => "Qi", "奒" => "Kai", "奓" => "Zha", "奔" => "Ben", + "奕" => "Yi", "奖" => "Jiang", "套" => "Tao", "奘" => "Zang", "奙" => "Ben", "奚" => "Xi", + "奛" => "Xiang", "奜" => "Fei", "å¥" => "Diao", "奞" => "Xun", "奟" => "Keng", "奠" => "Dian", + "奡" => "Ao", "奢" => "She", "奣" => "Weng", "奤" => "Pan", "奥" => "Ao", "奦" => "Wu", + "奧" => "Ao", "奨" => "Jiang", "奩" => "Lian", "奪" => "Duo", "奫" => "Yun", "奬" => "Jiang", + "奭" => "Shi", "奮" => "Fen", "奯" => "Huo", "奰" => "Bi", "奱" => "Lian", "奲" => "Duo", + "女" => "Nu", "奴" => "Nu", "奵" => "Ding", "奶" => "Nai", "奷" => "Qian", "奸" => "Jian", + "她" => "Ta", "奺" => "Jiu", "奻" => "Nan", "奼" => "Cha", "好" => "Hao", "奾" => "Xian", + "奿" => "Fan", "妀" => "Ji", "å¦" => "Shuo", "如" => "Ru", "妃" => "Fei", "妄" => "Wang", + "妅" => "Hong", "妆" => "Zhuang", "妇" => "Fu", "妈" => "Ma", "妉" => "Dan", "妊" => "Ren", + "妋" => "Fu", "妌" => "Jing", "å¦" => "Yan", "妎" => "Xie", "å¦" => "Wen", "å¦" => "Zhong", + "妑" => "Pa", "妒" => "Du", "妓" => "Ji", "妔" => "Keng", "妕" => "Zhong", "妖" => "Yao", + "妗" => "Jin", "妘" => "Yun", "妙" => "Miao", "妚" => "Pei", "妛" => "Shi", "妜" => "Yue", + "å¦" => "Zhuang", "妞" => "Niu", "妟" => "Yan", "妠" => "Na", "妡" => "Xin", "妢" => "Fen", + "妣" => "Bi", "妤" => "Yu", "妥" => "Tuo", "妦" => "Feng", "妧" => "Yuan", "妨" => "Fang", + "妩" => "Wu", "妪" => "Yu", "妫" => "Gui", "妬" => "Du", "妭" => "Ba", "妮" => "Ni", + "妯" => "Zhou", "妰" => "Zhuo", "妱" => "Zhao", "妲" => "Da", "妳" => "Nai", "妴" => "Yuan", + "妵" => "Tou", "妶" => "Xuan", "妷" => "Zhi", "妸" => "E", "妹" => "Mei", "妺" => "Mo", + "妻" => "Qi", "妼" => "Bi", "妽" => "Shen", "妾" => "Qie", "妿" => "E", "姀" => "He", + "å§" => "Xu", "姂" => "Fa", "姃" => "Zheng", "姄" => "Min", "姅" => "Ban", "姆" => "Mu", + "姇" => "Fu", "姈" => "Ling", "姉" => "Zi", "姊" => "Zi", "始" => "Shi", "姌" => "Ran", + "å§" => "Shan", "姎" => "Yang", "å§" => "Man", "å§" => "Jie", "姑" => "Gu", "姒" => "Si", + "姓" => "Xing", "委" => "Wei", "姕" => "Zi", "姖" => "Ju", "姗" => "Shan", "姘" => "Pin", + "姙" => "Ren", "姚" => "Yao", "姛" => "Tong", "姜" => "Jiang", "å§" => "Shu", "姞" => "Ji", + "姟" => "Gai", "姠" => "Shang", "姡" => "Kuo", "姢" => "Juan", "姣" => "Jiao", "姤" => "Gou", + "姥" => "Mu", "姦" => "Jian", "姧" => "Jian", "姨" => "Yi", "姩" => "Nian", "姪" => "Zhi", + "姫" => "Ji", "姬" => "Ji", "姭" => "Xian", "姮" => "Heng", "姯" => "Guang", "姰" => "Jun", + "姱" => "Kua", "姲" => "Yan", "姳" => "Ming", "姴" => "Lie", "姵" => "Pei", "姶" => "Yan", + "姷" => "You", "姸" => "Yan", "姹" => "Cha", "姺" => "Shen", "姻" => "Yin", "姼" => "Chi", + "姽" => "Gui", "姾" => "Quan", "姿" => "Zi", "å¨" => "Wei", "娂" => "Hong", "娃" => "Wa", + "娄" => "Lou", "娅" => "Ya", "娆" => "Rao", "娇" => "Jiao", "娈" => "Luan", "娉" => "Ping", + "娊" => "Xian", "娋" => "Shao", "娌" => "Li", "å¨" => "Cheng", "娎" => "Xiao", "å¨" => "Mang", + "å¨" => "Fu", "娑" => "Suo", "娒" => "Wu", "娓" => "Wei", "娔" => "Ke", "娕" => "Lai", + "娖" => "Chuo", "娗" => "Ding", "娘" => "Niang", "娙" => "Xing", "娚" => "Nan", "娛" => "Yu", + "娜" => "Nuo", "å¨" => "Pei", "娞" => "Nei", "娟" => "Juan", "娠" => "Shen", "娡" => "Zhi", + "娢" => "Han", "娣" => "Di", "娤" => "Zhuang", "娥" => "E", "娦" => "Pin", "娧" => "Tui", + "娨" => "Han", "娩" => "Mian", "娪" => "Wu", "娫" => "Yan", "娬" => "Wu", "娭" => "Xi", + "娮" => "Yan", "娯" => "Yu", "娰" => "Si", "娱" => "Yu", "娲" => "Wa", "娴" => "Xian", + "娵" => "Ju", "娶" => "Qu", "娷" => "Shui", "娸" => "Qi", "娹" => "Xian", "娺" => "Zhui", + "娻" => "Dong", "娼" => "Chang", "娽" => "Lu", "娾" => "Ai", "娿" => "E", "å©€" => "E", + "å©" => "Lou", "å©‚" => "Mian", "婃" => "Cong", "å©„" => "Pou", "å©…" => "Ju", "婆" => "Po", + "婇" => "Cai", "婈" => "Ding", "婉" => "Wan", "å©Š" => "Biao", "å©‹" => "Xiao", "å©Œ" => "Shu", + "å©" => "Qi", "å©Ž" => "Hui", "å©" => "Fu", "å©" => "E", "å©‘" => "Wo", "å©’" => "Tan", + "å©“" => "Fei", "å©”" => "Wei", "å©•" => "Jie", "å©–" => "Tian", "å©—" => "Ni", "婘" => "Quan", + "å©™" => "Jing", "å©š" => "Hun", "å©›" => "Jing", "å©œ" => "Qian", "å©" => "Dian", "å©ž" => "Xing", + "å©Ÿ" => "Hu", "å© " => "Wa", "å©¡" => "Lai", "å©¢" => "Bi", "å©£" => "Yin", "婤" => "Chou", + "å©¥" => "Chuo", "婦" => "Fu", "婧" => "Jing", "婨" => "Lun", "å©©" => "Yan", "婪" => "Lan", + "å©«" => "Kun", "婬" => "Yin", "å©­" => "Ya", "å©®" => "Ju", "婯" => "Li", "å©°" => "Dian", + "婱" => "Xian", "婲" => "Hwa", "婳" => "Hua", "å©´" => "Ying", "婵" => "Chan", "婶" => "Shen", + "å©·" => "Ting", "婸" => "Dang", "婹" => "Yao", "婺" => "Wu", "å©»" => "Nan", "婼" => "Ruo", + "婽" => "Jia", "婾" => "Tou", "å©¿" => "Xu", "媀" => "Yu", "åª" => "Wei", "媂" => "Ti", + "媃" => "Rou", "媄" => "Mei", "媅" => "Dan", "媆" => "Ruan", "媇" => "Qin", "媈" => "Hui", + "媉" => "Wu", "媊" => "Qian", "媋" => "Chun", "媌" => "Mao", "åª" => "Fu", "媎" => "Jie", + "åª" => "Duan", "åª" => "Xi", "媑" => "Zhong", "媒" => "Mei", "媓" => "Huang", "媔" => "Mian", + "媕" => "An", "媖" => "Ying", "媗" => "Xuan", "媘" => "Jie", "媙" => "Wei", "媚" => "Mei", + "媛" => "Yuan", "媜" => "Zhen", "åª" => "Qiu", "媞" => "Ti", "媟" => "Xie", "媠" => "Tuo", + "媡" => "Lian", "媢" => "Mao", "媣" => "Ran", "媤" => "Si", "媥" => "Pian", "媦" => "Wei", + "媧" => "Wa", "媨" => "Jiu", "媩" => "Hu", "媪" => "Ao", "媬" => "Bou", "媭" => "Xu", + "媮" => "Tou", "媯" => "Gui", "媰" => "Zou", "媱" => "Yao", "媲" => "Pi", "媳" => "Xi", + "媴" => "Yuan", "媵" => "Ying", "媶" => "Rong", "媷" => "Ru", "媸" => "Chi", "媹" => "Liu", + "媺" => "Mei", "媻" => "Pan", "媼" => "Ao", "媽" => "Ma", "媾" => "Gou", "媿" => "Kui", + "å«€" => "Qin", "å«" => "Jia", "å«‚" => "Sao", "嫃" => "Zhen", "å«„" => "Yuan", "å«…" => "Cha", + "嫆" => "Yong", "嫇" => "Ming", "嫈" => "Ying", "嫉" => "Ji", "å«Š" => "Su", "å«‹" => "Niao", + "å«Œ" => "Xian", "å«" => "Tao", "å«Ž" => "Pang", "å«" => "Lang", "å«" => "Nao", "å«‘" => "Bao", + "å«’" => "Ai", "å«“" => "Pi", "å«”" => "Pin", "å«•" => "Yi", "å«–" => "Piao", "å«—" => "Yu", + "嫘" => "Lei", "å«™" => "Xuan", "å«š" => "Man", "å«›" => "Yi", "å«œ" => "Zhang", "å«" => "Kang", + "å«ž" => "Yong", "å«Ÿ" => "Ni", "å« " => "Li", "å«¡" => "Di", "å«¢" => "Gui", "å«£" => "Yan", + "嫤" => "Jin", "å«¥" => "Zhuan", "嫦" => "Chang", "嫧" => "Ce", "嫨" => "Han", "å«©" => "Nen", + "嫪" => "Lao", "å««" => "Mo", "嫬" => "Zhe", "å«­" => "Hu", "å«®" => "Hu", "嫯" => "Ao", + "å«°" => "Nen", "嫱" => "Qiang", "嫲" => "Ma", "嫳" => "Pie", "å«´" => "Gu", "嫵" => "Wu", + "嫶" => "Jiao", "å«·" => "Tuo", "嫸" => "Zhan", "嫹" => "Mao", "嫺" => "Xian", "å«»" => "Xian", + "嫼" => "Mo", "嫽" => "Liao", "嫾" => "Lian", "å«¿" => "Hua", "å¬" => "Deng", "嬂" => "Zhi", + "嬃" => "Xu", "嬄" => "Yi", "嬅" => "Hua", "嬆" => "Xi", "嬇" => "Hui", "嬈" => "Rao", + "嬉" => "Xi", "嬊" => "Yan", "嬋" => "Chan", "嬌" => "Jiao", "å¬" => "Mei", "嬎" => "Fan", + "å¬" => "Fan", "å¬" => "Xian", "嬑" => "Yi", "嬒" => "Wei", "嬓" => "Jiao", "嬔" => "Fu", + "嬕" => "Shi", "嬖" => "Bi", "嬗" => "Shan", "嬘" => "Sui", "嬙" => "Qiang", "嬚" => "Lian", + "嬛" => "Huan", "嬜" => "Xin", "å¬" => "Niao", "嬞" => "Dong", "嬟" => "Yi", "嬠" => "Can", + "嬡" => "Ai", "嬢" => "Niang", "嬣" => "Neng", "嬤" => "Ma", "嬥" => "Tiao", "嬦" => "Chou", + "嬧" => "Jin", "嬨" => "Ci", "嬩" => "Yu", "嬪" => "Pin", "嬫" => "Yong", "嬬" => "Xu", + "嬭" => "Nai", "嬮" => "Yan", "嬯" => "Tai", "嬰" => "Ying", "嬱" => "Can", "嬲" => "Niao", + "嬳" => "Wo", "嬴" => "Ying", "嬵" => "Mian", "嬶" => "Kaka", "嬷" => "Ma", "嬸" => "Shen", + "嬹" => "Xing", "嬺" => "Ni", "嬻" => "Du", "嬼" => "Liu", "嬽" => "Yuan", "嬾" => "Lan", + "嬿" => "Yan", "å­€" => "Shuang", "å­" => "Ling", "å­‚" => "Jiao", "å­ƒ" => "Niang", "å­„" => "Lan", + "å­…" => "Xian", "å­†" => "Ying", "å­‡" => "Shuang", "å­ˆ" => "Shuai", "å­‰" => "Quan", "å­Š" => "Mi", + "å­‹" => "Li", "å­Œ" => "Luan", "å­" => "Yan", "å­Ž" => "Zhu", "å­" => "Lan", "å­" => "Zi", + "å­‘" => "Jie", "å­’" => "Jue", "å­“" => "Jue", "å­”" => "Kong", "å­•" => "Yun", "å­–" => "Zi", + "å­—" => "Zi", "å­˜" => "Cun", "å­™" => "Sun", "å­š" => "Fu", "å­›" => "Bei", "å­œ" => "Zi", + "å­" => "Xiao", "å­ž" => "Xin", "å­Ÿ" => "Meng", "å­ " => "Si", "å­¡" => "Tai", "å­¢" => "Bao", + "å­£" => "Ji", "å­¤" => "Gu", "å­¥" => "Nu", "å­¦" => "Xue", "å­¨" => "Zhuan", "å­©" => "Hai", + "å­ª" => "Luan", "å­«" => "Sun", "å­¬" => "Huai", "å­­" => "Mie", "å­®" => "Cong", "å­¯" => "Qian", + "å­°" => "Shu", "å­±" => "Chan", "å­²" => "Ya", "å­³" => "Zi", "å­´" => "Ni", "å­µ" => "Fu", + "å­¶" => "Zi", "å­·" => "Li", "å­¸" => "Xue", "å­¹" => "Bo", "å­º" => "Ru", "å­»" => "Lai", + "å­¼" => "Nie", "å­½" => "Nie", "å­¾" => "Ying", "å­¿" => "Luan", "宀" => "Mian", "å®" => "Zhu", + "宂" => "Rong", "它" => "Ta", "宄" => "Gui", "å®…" => "Zhai", "宆" => "Qiong", "宇" => "Yu", + "守" => "Shou", "安" => "An", "宊" => "Tu", "宋" => "Song", "完" => "Wan", "å®" => "Rou", + "宎" => "Yao", "å®" => "Hong", "å®" => "Yi", "宑" => "Jing", "å®’" => "Zhun", "宓" => "Mi", + "å®”" => "Zhu", "宕" => "Dang", "å®–" => "Hong", "å®—" => "Zong", "官" => "Guan", "å®™" => "Zhou", + "定" => "Ding", "å®›" => "Wan", "宜" => "Yi", "å®" => "Bao", "实" => "Shi", "実" => "Shi", + "å® " => "Chong", "审" => "Shen", "客" => "Ke", "宣" => "Xuan", "室" => "Shi", "宥" => "You", + "宦" => "Huan", "宧" => "Yi", "宨" => "Tiao", "宩" => "Shi", "宪" => "Xian", "宫" => "Gong", + "宬" => "Cheng", "å®­" => "Qun", "å®®" => "Gong", "宯" => "Xiao", "å®°" => "Zai", "å®±" => "Zha", + "宲" => "Bao", "害" => "Hai", "å®´" => "Yan", "宵" => "Xiao", "家" => "Jia", "å®·" => "Shen", + "宸" => "Chen", "容" => "Rong", "宺" => "Huang", "å®»" => "Mi", "宼" => "Kou", "宽" => "Kuan", + "宾" => "Bin", "宿" => "Su", "寀" => "Cai", "å¯" => "Zan", "寂" => "Ji", "寃" => "Yuan", + "寄" => "Ji", "寅" => "Yin", "密" => "Mi", "寇" => "Kou", "寈" => "Qing", "寉" => "Que", + "寊" => "Zhen", "寋" => "Jian", "富" => "Fu", "å¯" => "Ning", "寎" => "Bing", "å¯" => "Huan", + "å¯" => "Mei", "寑" => "Qin", "寒" => "Han", "寓" => "Yu", "寔" => "Shi", "寕" => "Ning", + "寖" => "Qin", "寗" => "Ning", "寘" => "Zhi", "寙" => "Yu", "寚" => "Bao", "寛" => "Kuan", + "寜" => "Ning", "å¯" => "Qin", "寞" => "Mo", "察" => "Cha", "寠" => "Ju", "寡" => "Gua", + "寢" => "Qin", "寣" => "Hu", "寤" => "Wu", "寥" => "Liao", "實" => "Shi", "寧" => "Zhu", + "寨" => "Zhai", "審" => "Shen", "寪" => "Wei", "寫" => "Xie", "寬" => "Kuan", "寭" => "Hui", + "寮" => "Liao", "寯" => "Jun", "寰" => "Huan", "寱" => "Yi", "寲" => "Yi", "寳" => "Bao", + "寴" => "Qin", "寵" => "Chong", "寶" => "Bao", "寷" => "Feng", "寸" => "Cun", "对" => "Dui", + "寺" => "Si", "寻" => "Xun", "导" => "Dao", "寽" => "Lu", "対" => "Dui", "寿" => "Shou", + "å°" => "Feng", "å°‚" => "Zhuan", "å°ƒ" => "Fu", "å°„" => "She", "å°…" => "Ke", "å°†" => "Jiang", + "å°‡" => "Jiang", "å°ˆ" => "Zhuan", "å°‰" => "Wei", "å°Š" => "Zun", "å°‹" => "Xun", "å°Œ" => "Shu", + "å°" => "Dui", "å°Ž" => "Dao", "å°" => "Xiao", "å°" => "Ji", "å°‘" => "Shao", "å°’" => "Er", + "å°“" => "Er", "å°”" => "Er", "å°•" => "Ga", "å°–" => "Jian", "å°—" => "Shu", "å°˜" => "Chen", + "å°™" => "Shang", "å°š" => "Shang", "å°›" => "Mo", "å°œ" => "Ga", "å°" => "Chang", "å°ž" => "Liao", + "å°Ÿ" => "Xian", "å° " => "Xian", "å°¢" => "Wang", "å°£" => "Wang", "å°¤" => "You", "å°¥" => "Liao", + "å°¦" => "Liao", "å°§" => "Yao", "å°¨" => "Mang", "å°©" => "Wang", "å°ª" => "Wang", "å°«" => "Wang", + "å°¬" => "Ga", "å°­" => "Yao", "å°®" => "Duo", "å°¯" => "Kui", "å°°" => "Zhong", "å°±" => "Jiu", + "å°²" => "Gan", "å°³" => "Gu", "å°´" => "Gan", "å°µ" => "Tui", "å°¶" => "Gan", "å°·" => "Gan", + "å°¸" => "Shi", "å°¹" => "Yin", "å°º" => "Chi", "å°»" => "Kao", "å°¼" => "Ni", "å°½" => "Jin", + "å°¾" => "Wei", "å°¿" => "Niao", "å±€" => "Ju", "å±" => "Pi", "层" => "Ceng", "屃" => "Xi", + "屄" => "Bi", "å±…" => "Ju", "屆" => "Jie", "屇" => "Tian", "屈" => "Qu", "屉" => "Ti", + "届" => "Jie", "屋" => "Wu", "屌" => "Diao", "å±" => "Shi", "屎" => "Shi", "å±" => "Ping", + "å±" => "Ji", "屑" => "Xie", "å±’" => "Chen", "屓" => "Xi", "å±”" => "Ni", "展" => "Zhan", + "å±–" => "Xi", "屘" => "Man", "å±™" => "E", "屚" => "Lou", "å±›" => "Ping", "屜" => "Ti", + "å±" => "Fei", "属" => "Shu", "屟" => "Xie", "å± " => "Tu", "屡" => "Lu", "å±¢" => "Lu", + "å±£" => "Xi", "層" => "Ceng", "å±¥" => "Lu", "屦" => "Ju", "屧" => "Xie", "屨" => "Ju", + "屩" => "Jue", "屪" => "Liao", "屫" => "Jue", "屬" => "Shu", "å±­" => "Xi", "å±®" => "Che", + "屯" => "Tun", "å±°" => "Ni", "å±±" => "Shan", "å±³" => "Xian", "å±´" => "Li", "å±µ" => "Xue", + "屶" => "Nata", "屸" => "Long", "å±¹" => "Yi", "屺" => "Qi", "å±»" => "Ren", "å±¼" => "Wu", + "å±½" => "Han", "å±¾" => "Shen", "屿" => "Yu", "å²€" => "Chu", "å²" => "Sui", "岂" => "Qi", + "岄" => "Yue", "å²…" => "Ban", "岆" => "Yao", "岇" => "Ang", "岈" => "Ya", "岉" => "Wu", + "岊" => "Jie", "岋" => "E", "岌" => "Ji", "å²" => "Qian", "岎" => "Fen", "å²" => "Yuan", + "å²" => "Qi", "岑" => "Cen", "å²’" => "Qian", "岓" => "Qi", "å²”" => "Cha", "岕" => "Jie", + "å²–" => "Qu", "å²—" => "Gang", "岘" => "Xian", "å²™" => "Ao", "岚" => "Lan", "å²›" => "Dao", + "岜" => "Ba", "å²" => "Zuo", "岞" => "Zuo", "岟" => "Yang", "å² " => "Ju", "岡" => "Gang", + "å²¢" => "Ke", "å²£" => "Gou", "岤" => "Xue", "å²¥" => "Bei", "岦" => "Li", "岧" => "Tiao", + "岨" => "Ju", "岩" => "Yan", "岪" => "Fu", "岫" => "Xiu", "岬" => "Jia", "å²­" => "Ling", + "å²®" => "Tuo", "岯" => "Pei", "å²°" => "You", "å²±" => "Dai", "å²²" => "Kuang", "å²³" => "Yue", + "å²´" => "Qu", "å²µ" => "Hu", "岶" => "Po", "å²·" => "Min", "岸" => "An", "å²¹" => "Tiao", + "岺" => "Ling", "å²»" => "Chi", "å²¼" => "Yuri", "å²½" => "Dong", "å²¾" => "Cem", "岿" => "Kui", + "å³€" => "Xiu", "å³" => "Mao", "峂" => "Tong", "峃" => "Xue", "峄" => "Yi", "å³…" => "Kura", + "峆" => "He", "峇" => "Ke", "峈" => "Luo", "峉" => "E", "峊" => "Fu", "峋" => "Xun", + "峌" => "Die", "å³" => "Lu", "峎" => "An", "å³" => "Er", "å³" => "Gai", "峑" => "Quan", + "å³’" => "Tong", "峓" => "Yi", "å³”" => "Mu", "峕" => "Shi", "å³–" => "An", "å³—" => "Wei", + "峘" => "Hu", "å³™" => "Zhi", "峚" => "Mi", "å³›" => "Li", "峜" => "Ji", "å³" => "Tong", + "峞" => "Wei", "峟" => "You", "å³ " => "Sang", "峡" => "Xia", "å³¢" => "Li", "å³£" => "Yao", + "峤" => "Jiao", "å³¥" => "Zheng", "峦" => "Luan", "峧" => "Jiao", "峨" => "E", "峩" => "E", + "峪" => "Yu", "峫" => "Ye", "峬" => "Bu", "å³­" => "Qiao", "å³®" => "Qun", "峯" => "Feng", + "å³°" => "Feng", "å³±" => "Nao", "å³²" => "Li", "å³³" => "You", "å³´" => "Xian", "å³µ" => "Hong", + "島" => "Dao", "å³·" => "Shen", "峸" => "Cheng", "å³¹" => "Tu", "峺" => "Geng", "å³»" => "Jun", + "å³¼" => "Hao", "å³½" => "Xia", "å³¾" => "Yin", "峿" => "Yu", "å´" => "Kan", "å´‚" => "Lao", + "å´ƒ" => "Lai", "å´„" => "Xian", "å´…" => "Que", "å´†" => "Kong", "å´‡" => "Chong", "å´ˆ" => "Chong", + "å´‰" => "Ta", "å´Š" => "Lin", "å´‹" => "Hua", "å´Œ" => "Ju", "å´" => "Lai", "å´Ž" => "Qi", + "å´" => "Min", "å´" => "Kun", "å´‘" => "Kun", "å´’" => "Zu", "å´“" => "Gu", "å´”" => "Cui", + "å´•" => "Ya", "å´–" => "Ya", "å´—" => "Gang", "å´˜" => "Lun", "å´™" => "Lun", "å´š" => "Leng", + "å´›" => "Jue", "å´œ" => "Duo", "å´" => "Zheng", "å´ž" => "Guo", "å´Ÿ" => "Yin", "å´ " => "Dong", + "å´¡" => "Han", "å´¢" => "Zheng", "å´£" => "Wei", "å´¤" => "Yao", "å´¥" => "Pi", "å´¦" => "Yan", + "å´§" => "Song", "å´¨" => "Jie", "å´©" => "Beng", "å´ª" => "Zu", "å´«" => "Jue", "å´¬" => "Dong", + "å´­" => "Zhan", "å´®" => "Gu", "å´¯" => "Yin", "å´±" => "Ze", "å´²" => "Huang", "å´³" => "Yu", + "å´´" => "Wei", "å´µ" => "Yang", "å´¶" => "Feng", "å´·" => "Qiu", "å´¸" => "Dun", "å´¹" => "Ti", + "å´º" => "Yi", "å´»" => "Zhi", "å´¼" => "Shi", "å´½" => "Zai", "å´¾" => "Yao", "å´¿" => "E", + "åµ€" => "Zhu", "åµ" => "Kan", "嵂" => "Lu", "嵃" => "Yan", "嵄" => "Mei", "åµ…" => "Gan", + "嵆" => "Ji", "嵇" => "Ji", "嵈" => "Huan", "嵉" => "Ting", "嵊" => "Sheng", "嵋" => "Mei", + "嵌" => "Qian", "åµ" => "Wu", "嵎" => "Yu", "åµ" => "Zong", "åµ" => "Lan", "嵑" => "Jue", + "åµ’" => "Yan", "嵓" => "Yan", "åµ”" => "Wei", "嵕" => "Zong", "åµ–" => "Cha", "åµ—" => "Sui", + "嵘" => "Rong", "åµ™" => "Yamashina", "嵚" => "Qin", "åµ›" => "Yu", "嵜" => "Kewashii", "åµ" => "Lou", + "嵞" => "Tu", "嵟" => "Dui", "åµ " => "Xi", "嵡" => "Weng", "åµ¢" => "Cang", "åµ£" => "Dang", + "嵤" => "Hong", "åµ¥" => "Jie", "嵦" => "Ai", "嵧" => "Liu", "嵨" => "Wu", "嵩" => "Song", + "嵪" => "Qiao", "嵫" => "Zi", "嵬" => "Wei", "åµ­" => "Beng", "åµ®" => "Dian", "嵯" => "Cuo", + "åµ°" => "Qian", "åµ±" => "Yong", "åµ²" => "Nie", "åµ³" => "Cuo", "åµ´" => "Ji", "嵶" => "Tao", + "åµ·" => "Song", "嵸" => "Zong", "åµ¹" => "Jiang", "嵺" => "Liao", "åµ»" => "Kang", "åµ¼" => "Chan", + "åµ½" => "Die", "åµ¾" => "Cen", "嵿" => "Ding", "嶀" => "Tu", "å¶" => "Lou", "嶂" => "Zhang", + "嶃" => "Zhan", "嶄" => "Zhan", "嶅" => "Ao", "嶆" => "Cao", "嶇" => "Qu", "嶈" => "Qiang", + "嶉" => "Zui", "嶊" => "Zui", "嶋" => "Dao", "嶌" => "Dao", "å¶" => "Xi", "嶎" => "Yu", + "å¶" => "Bo", "å¶" => "Long", "嶑" => "Xiang", "嶒" => "Ceng", "嶓" => "Bo", "嶔" => "Qin", + "嶕" => "Jiao", "嶖" => "Yan", "嶗" => "Lao", "嶘" => "Zhan", "嶙" => "Lin", "嶚" => "Liao", + "嶛" => "Liao", "嶜" => "Jin", "å¶" => "Deng", "嶞" => "Duo", "嶟" => "Zun", "嶠" => "Jiao", + "嶡" => "Gui", "嶢" => "Yao", "嶣" => "Qiao", "嶤" => "Yao", "嶥" => "Jue", "嶦" => "Zhan", + "嶧" => "Yi", "嶨" => "Xue", "嶩" => "Nao", "嶪" => "Ye", "嶫" => "Ye", "嶬" => "Yi", + "嶭" => "E", "嶮" => "Xian", "嶯" => "Ji", "嶰" => "Xie", "嶱" => "Ke", "嶲" => "Xi", + "嶳" => "Di", "嶴" => "Ao", "嶵" => "Zui", "嶷" => "Ni", "嶸" => "Rong", "嶹" => "Dao", + "嶺" => "Ling", "嶻" => "Za", "嶼" => "Yu", "嶽" => "Yue", "嶾" => "Yin", "å·€" => "Jie", + "å·" => "Li", "å·‚" => "Sui", "å·ƒ" => "Long", "å·„" => "Long", "å·…" => "Dian", "å·†" => "Ying", + "å·‡" => "Xi", "å·ˆ" => "Ju", "å·‰" => "Chan", "å·Š" => "Ying", "å·‹" => "Kui", "å·Œ" => "Yan", + "å·" => "Wei", "å·Ž" => "Nao", "å·" => "Quan", "å·" => "Chao", "å·‘" => "Cuan", "å·’" => "Luan", + "å·“" => "Dian", "å·”" => "Dian", "å·–" => "Yan", "å·—" => "Yan", "å·˜" => "Yan", "å·™" => "Nao", + "å·š" => "Yan", "å·›" => "Chuan", "å·œ" => "Gui", "å·" => "Chuan", "å·ž" => "Zhou", "å·Ÿ" => "Huang", + "å· " => "Jing", "å·¡" => "Xun", "å·¢" => "Chao", "å·£" => "Chao", "å·¤" => "Lie", "å·¥" => "Gong", + "å·¦" => "Zuo", "å·§" => "Qiao", "å·¨" => "Ju", "å·©" => "Gong", "å·ª" => "Kek", "å·«" => "Wu", + "å·¬" => "Pwu", "å·­" => "Pwu", "å·®" => "Chai", "å·¯" => "Qiu", "å·°" => "Qiu", "å·±" => "Ji", + "å·²" => "Yi", "å·³" => "Si", "å·´" => "Ba", "å·µ" => "Zhi", "å·¶" => "Zhao", "å··" => "Xiang", + "å·¸" => "Yi", "å·¹" => "Jin", "å·º" => "Xun", "å·»" => "Juan", "å·¼" => "Phas", "å·½" => "Xun", + "å·¾" => "Jin", "å·¿" => "Fu", "å¸" => "Bi", "市" => "Shi", "布" => "Bu", "帄" => "Ding", + "帅" => "Shuai", "帆" => "Fan", "帇" => "Nie", "师" => "Shi", "帉" => "Fen", "帊" => "Pa", + "帋" => "Zhi", "希" => "Xi", "å¸" => "Hu", "帎" => "Dan", "å¸" => "Wei", "å¸" => "Zhang", + "帑" => "Tang", "帒" => "Dai", "帓" => "Ma", "帔" => "Pei", "帕" => "Pa", "帖" => "Tie", + "帗" => "Fu", "帘" => "Lian", "帙" => "Zhi", "帚" => "Zhou", "帛" => "Bo", "帜" => "Zhi", + "å¸" => "Di", "帞" => "Mo", "帟" => "Yi", "帠" => "Yi", "帡" => "Ping", "帢" => "Qia", + "帣" => "Juan", "帤" => "Ru", "帥" => "Shuai", "带" => "Dai", "帧" => "Zheng", "帨" => "Shui", + "帩" => "Qiao", "帪" => "Zhen", "師" => "Shi", "帬" => "Qun", "席" => "Xi", "帮" => "Bang", + "帯" => "Dai", "帰" => "Gui", "帱" => "Chou", "帲" => "Ping", "帳" => "Zhang", "帴" => "Sha", + "帵" => "Wan", "帶" => "Dai", "帷" => "Wei", "常" => "Chang", "帹" => "Sha", "帺" => "Qi", + "帻" => "Ze", "帼" => "Guo", "帽" => "Mao", "帾" => "Du", "帿" => "Hou", "å¹€" => "Zheng", + "å¹" => "Xu", "幂" => "Mi", "幃" => "Wei", "幄" => "Wo", "å¹…" => "Fu", "幆" => "Yi", + "幇" => "Bang", "幈" => "Ping", "幉" => "Tazuna", "幊" => "Gong", "幋" => "Pan", "幌" => "Huang", + "å¹" => "Dao", "幎" => "Mi", "å¹" => "Jia", "å¹" => "Teng", "幑" => "Hui", "å¹’" => "Zhong", + "幓" => "Shan", "å¹”" => "Man", "幕" => "Mu", "å¹–" => "Biao", "å¹—" => "Guo", "幘" => "Ze", + "å¹™" => "Mu", "幚" => "Bang", "å¹›" => "Zhang", "幜" => "Jiong", "å¹" => "Chan", "幞" => "Fu", + "幟" => "Zhi", "å¹ " => "Hu", "幡" => "Fan", "å¹¢" => "Chuang", "å¹£" => "Bi", "幤" => "Hei", + "幦" => "Mi", "幧" => "Qiao", "幨" => "Chan", "幩" => "Fen", "幪" => "Meng", "幫" => "Bang", + "幬" => "Chou", "å¹­" => "Mie", "å¹®" => "Chu", "幯" => "Jie", "å¹°" => "Xian", "å¹±" => "Lan", + "å¹²" => "Gan", "å¹³" => "Ping", "å¹´" => "Nian", "å¹µ" => "Qian", "并" => "Bing", "å¹·" => "Bing", + "幸" => "Xing", "å¹¹" => "Gan", "幺" => "Yao", "å¹»" => "Huan", "å¹¼" => "You", "å¹½" => "You", + "å¹¾" => "Ji", "广" => "Yan", "庀" => "Pi", "åº" => "Ting", "庂" => "Ze", "広" => "Guang", + "庄" => "Zhuang", "庅" => "Mo", "庆" => "Qing", "庇" => "Bi", "庈" => "Qin", "庉" => "Dun", + "床" => "Chuang", "庋" => "Gui", "庌" => "Ya", "åº" => "Bai", "庎" => "Jie", "åº" => "Xu", + "åº" => "Lu", "庑" => "Wu", "库" => "Ku", "应" => "Ying", "底" => "Di", "庖" => "Pao", + "店" => "Dian", "庘" => "Ya", "庙" => "Miao", "庚" => "Geng", "庛" => "Ci", "府" => "Fu", + "åº" => "Tong", "庞" => "Pang", "废" => "Fei", "庠" => "Xiang", "庡" => "Yi", "庢" => "Zhi", + "庣" => "Tiao", "庤" => "Zhi", "庥" => "Xiu", "度" => "Du", "座" => "Zuo", "庨" => "Xiao", + "庩" => "Tu", "庪" => "Gui", "庫" => "Ku", "庬" => "Pang", "庭" => "Ting", "庮" => "You", + "庯" => "Bu", "庰" => "Ding", "庱" => "Cheng", "庲" => "Lai", "庳" => "Bei", "庴" => "Ji", + "庵" => "An", "庶" => "Shu", "康" => "Kang", "庸" => "Yong", "庹" => "Tuo", "庺" => "Song", + "庻" => "Shu", "庼" => "Qing", "庽" => "Yu", "庾" => "Yu", "庿" => "Miao", "廀" => "Sou", + "å»" => "Ce", "廂" => "Xiang", "廃" => "Fei", "廄" => "Jiu", "å»…" => "He", "廆" => "Hui", + "廇" => "Liu", "廈" => "Sha", "廉" => "Lian", "廊" => "Lang", "廋" => "Sou", "廌" => "Jian", + "å»" => "Pou", "廎" => "Qing", "å»" => "Jiu", "å»" => "Jiu", "廑" => "Qin", "å»’" => "Ao", + "廓" => "Kuo", "å»”" => "Lou", "廕" => "Yin", "å»–" => "Liao", "å»—" => "Dai", "廘" => "Lu", + "å»™" => "Yi", "廚" => "Chu", "å»›" => "Chan", "廜" => "Tu", "å»" => "Si", "廞" => "Xin", + "廟" => "Miao", "å» " => "Chang", "廡" => "Wu", "廢" => "Fei", "廣" => "Guang", "廤" => "Koc", + "廥" => "Kuai", "廦" => "Bi", "廧" => "Qiang", "廨" => "Xie", "廩" => "Lin", "廪" => "Lin", + "廫" => "Liao", "廬" => "Lu", "å»®" => "Ying", "廯" => "Xian", "å»°" => "Ting", "å»±" => "Yong", + "廲" => "Li", "廳" => "Ting", "å»´" => "Yin", "廵" => "Xun", "延" => "Yan", "å»·" => "Ting", + "廸" => "Di", "廹" => "Po", "建" => "Jian", "å»»" => "Hui", "廼" => "Nai", "廽" => "Hui", + "廾" => "Gong", "廿" => "Nian", "å¼" => "Bian", "异" => "Yi", "弃" => "Qi", "弄" => "Nong", + "å¼…" => "Fen", "弆" => "Ju", "弇" => "Yan", "弈" => "Yi", "弉" => "Zang", "弊" => "Bi", + "弋" => "Yi", "弌" => "Yi", "å¼" => "Er", "弎" => "San", "å¼" => "Shi", "å¼" => "Er", + "弑" => "Shi", "å¼’" => "Shi", "弓" => "Gong", "å¼”" => "Diao", "引" => "Yin", "å¼–" => "Hu", + "å¼—" => "Fu", "弘" => "Hong", "å¼™" => "Wu", "弚" => "Tui", "å¼›" => "Chi", "弜" => "Jiang", + "å¼" => "Ba", "弞" => "Shen", "弟" => "Di", "å¼ " => "Zhang", "弡" => "Jue", "å¼¢" => "Tao", + "å¼£" => "Fu", "弤" => "Di", "å¼¥" => "Mi", "弦" => "Xian", "弧" => "Hu", "弨" => "Chao", + "弩" => "Nu", "弪" => "Jing", "弫" => "Zhen", "弬" => "Yi", "å¼­" => "Mi", "å¼®" => "Quan", + "弯" => "Wan", "å¼°" => "Shao", "å¼±" => "Ruo", "å¼²" => "Xuan", "å¼³" => "Jing", "å¼´" => "Dun", + "å¼µ" => "Zhang", "弶" => "Jiang", "å¼·" => "Qiang", "弸" => "Peng", "å¼¹" => "Dan", "强" => "Qiang", + "å¼»" => "Bi", "å¼¼" => "Bi", "å¼½" => "She", "å¼¾" => "Dan", "弿" => "Jian", "å½€" => "Gou", + "å½" => "Sei", "彂" => "Fa", "彃" => "Bi", "彄" => "Kou", "å½…" => "Nagi", "彆" => "Bie", + "彇" => "Xiao", "彈" => "Dan", "彉" => "Kuo", "彊" => "Qiang", "彋" => "Hong", "彌" => "Mi", + "å½" => "Kuo", "彎" => "Wan", "å½" => "Jue", "å½" => "Ji", "彑" => "Ji", "å½’" => "Gui", + "当" => "Dang", "å½”" => "Lu", "录" => "Lu", "å½–" => "Tuan", "å½—" => "Hui", "彘" => "Zhi", + "å½™" => "Hui", "彚" => "Hui", "å½›" => "Yi", "彜" => "Yi", "å½" => "Yi", "彞" => "Yi", + "彟" => "Huo", "å½ " => "Huo", "彡" => "Shan", "å½¢" => "Xing", "å½£" => "Wen", "彤" => "Tong", + "å½¥" => "Yan", "彦" => "Yan", "彧" => "Yu", "彨" => "Chi", "彩" => "Cai", "彪" => "Biao", + "彫" => "Diao", "彬" => "Bin", "å½­" => "Peng", "å½®" => "Yong", "彯" => "Piao", "å½°" => "Zhang", + "å½±" => "Ying", "å½²" => "Chi", "å½³" => "Chi", "å½´" => "Zhuo", "å½µ" => "Tuo", "彶" => "Ji", + "å½·" => "Pang", "彸" => "Zhong", "å½¹" => "Yi", "彺" => "Wang", "å½»" => "Che", "å½¼" => "Bi", + "å½½" => "Chi", "å½¾" => "Ling", "彿" => "Fu", "å¾€" => "Wang", "å¾" => "Zheng", "徂" => "Cu", + "徃" => "Wang", "径" => "Jing", "å¾…" => "Dai", "徆" => "Xi", "徇" => "Xun", "很" => "Hen", + "徉" => "Yang", "徊" => "Huai", "律" => "Lu", "後" => "Hou", "å¾" => "Wa", "徎" => "Cheng", + "å¾" => "Zhi", "å¾" => "Xu", "徑" => "Jing", "å¾’" => "Tu", "従" => "Cong", "徕" => "Lai", + "å¾–" => "Cong", "å¾—" => "De", "徘" => "Pai", "å¾™" => "Xi", "å¾›" => "Qi", "徜" => "Chang", + "å¾" => "Zhi", "從" => "Cong", "徟" => "Zhou", "å¾ " => "Lai", "御" => "Yu", "å¾¢" => "Xie", + "å¾£" => "Jie", "徤" => "Jian", "å¾¥" => "Chi", "徦" => "Jia", "徧" => "Bian", "徨" => "Huang", + "復" => "Fu", "循" => "Xun", "徫" => "Wei", "徬" => "Pang", "å¾­" => "Yao", "å¾®" => "Wei", + "徯" => "Xi", "å¾°" => "Zheng", "å¾±" => "Piao", "å¾²" => "Chi", "å¾³" => "De", "å¾´" => "Zheng", + "å¾µ" => "Zheng", "徶" => "Bie", "å¾·" => "De", "徸" => "Chong", "å¾¹" => "Che", "徺" => "Jiao", + "å¾»" => "Wei", "å¾¼" => "Jiao", "å¾½" => "Hui", "å¾¾" => "Mei", "徿" => "Long", "å¿€" => "Xiang", + "å¿" => "Bao", "å¿‚" => "Qu", "心" => "Xin", "å¿„" => "Shu", "å¿…" => "Bi", "忆" => "Yi", + "忇" => "Le", "忈" => "Ren", "忉" => "Dao", "å¿Š" => "Ding", "å¿‹" => "Gai", "å¿Œ" => "Ji", + "å¿" => "Ren", "å¿Ž" => "Ren", "å¿" => "Chan", "å¿" => "Tan", "å¿‘" => "Te", "å¿’" => "Te", + "å¿“" => "Gan", "å¿”" => "Qi", "å¿•" => "Shi", "å¿–" => "Cun", "å¿—" => "Zhi", "忘" => "Wang", + "å¿™" => "Mang", "å¿š" => "Xi", "å¿›" => "Fan", "å¿œ" => "Ying", "å¿" => "Tian", "å¿ž" => "Min", + "å¿Ÿ" => "Min", "å¿ " => "Zhong", "å¿¡" => "Chong", "å¿¢" => "Wu", "å¿£" => "Ji", "忤" => "Wu", + "å¿¥" => "Xi", "忦" => "Ye", "忧" => "You", "忨" => "Wan", "å¿©" => "Cong", "忪" => "Zhong", + "å¿«" => "Kuai", "忬" => "Yu", "å¿­" => "Bian", "å¿®" => "Zhi", "忯" => "Qi", "å¿°" => "Cui", + "忱" => "Chen", "忲" => "Tai", "忳" => "Tun", "å¿´" => "Qian", "念" => "Nian", "忶" => "Hun", + "å¿·" => "Xiong", "忸" => "Niu", "忹" => "Wang", "忺" => "Xian", "å¿»" => "Xin", "忼" => "Kang", + "忽" => "Hu", "忾" => "Kai", "å¿¿" => "Fen", "æ€" => "Tai", "怂" => "Song", "怃" => "Wu", + "怄" => "Ou", "怅" => "Chang", "怆" => "Chuang", "怇" => "Ju", "怈" => "Yi", "怉" => "Bao", + "怊" => "Chao", "怋" => "Min", "怌" => "Pei", "æ€" => "Zuo", "怎" => "Zen", "æ€" => "Yang", + "æ€" => "Kou", "怑" => "Ban", "怒" => "Nu", "怓" => "Nao", "怔" => "Zheng", "怕" => "Pa", + "怖" => "Bu", "怗" => "Tie", "怘" => "Gu", "怙" => "Hu", "怚" => "Ju", "怛" => "Da", + "怜" => "Lian", "æ€" => "Si", "怞" => "Chou", "怟" => "Di", "怠" => "Dai", "怡" => "Yi", + "怢" => "Tu", "怣" => "You", "怤" => "Fu", "急" => "Ji", "怦" => "Peng", "性" => "Xing", + "怨" => "Yuan", "怩" => "Ni", "怪" => "Guai", "怫" => "Fu", "怬" => "Xi", "怭" => "Bi", + "怮" => "You", "怯" => "Qie", "怰" => "Xuan", "怱" => "Cong", "怲" => "Bing", "怳" => "Huang", + "怴" => "Xu", "怵" => "Chu", "怶" => "Pi", "怷" => "Xi", "怸" => "Xi", "怹" => "Tan", + "怺" => "Koraeru", "总" => "Zong", "怼" => "Dui", "怾" => "Ki", "怿" => "Yi", "æ€" => "Chi", + "æ" => "Ren", "æ‚" => "Xun", "æƒ" => "Shi", "æ„" => "Xi", "æ…" => "Lao", "æ†" => "Heng", + "æ‡" => "Kuang", "æˆ" => "Mu", "æ‰" => "Zhi", "æŠ" => "Xie", "æ‹" => "Lian", "æŒ" => "Tiao", + "æ" => "Huang", "æŽ" => "Die", "æ" => "Hao", "æ" => "Kong", "æ‘" => "Gui", "æ’" => "Heng", + "æ“" => "Xi", "æ”" => "Xiao", "æ•" => "Shu", "æ–" => "S", "æ—" => "Kua", "æ˜" => "Qiu", + "æ™" => "Yang", "æš" => "Hui", "æ›" => "Hui", "æœ" => "Chi", "æ" => "Jia", "æž" => "Yi", + "æŸ" => "Xiong", "æ " => "Guai", "æ¡" => "Lin", "æ¢" => "Hui", "æ£" => "Zi", "æ¤" => "Xu", + "æ¥" => "Chi", "æ¦" => "Xiang", "æ§" => "Nu", "æ¨" => "Hen", "æ©" => "En", "æª" => "Ke", + "æ«" => "Tong", "æ¬" => "Tian", "æ­" => "Gong", "æ®" => "Quan", "æ¯" => "Xi", "æ°" => "Qia", + "æ±" => "Yue", "æ²" => "Peng", "æ³" => "Ken", "æ´" => "De", "æµ" => "Hui", "æ¶" => "E", + "æ·" => "Kyuu", "æ¸" => "Tong", "æ¹" => "Yan", "æº" => "Kai", "æ»" => "Ce", "æ¼" => "Nao", + "æ½" => "Yun", "æ¾" => "Mang", "æ¿" => "Yong", "æ‚€" => "Yong", "æ‚" => "Yuan", "æ‚‚" => "Pi", + "悃" => "Kun", "æ‚„" => "Qiao", "æ‚…" => "Yue", "悆" => "Yu", "悇" => "Yu", "悈" => "Jie", + "悉" => "Xi", "æ‚Š" => "Zhe", "æ‚‹" => "Lin", "æ‚Œ" => "Ti", "æ‚" => "Han", "æ‚Ž" => "Hao", + "æ‚" => "Qie", "æ‚" => "Ti", "æ‚‘" => "Bu", "æ‚’" => "Yi", "æ‚“" => "Qian", "æ‚”" => "Hui", + "æ‚•" => "Xi", "æ‚–" => "Bei", "æ‚—" => "Man", "悘" => "Yi", "æ‚™" => "Heng", "æ‚š" => "Song", + "æ‚›" => "Quan", "æ‚œ" => "Cheng", "æ‚" => "Hui", "æ‚ž" => "Wu", "æ‚Ÿ" => "Wu", "æ‚ " => "You", + "æ‚¡" => "Li", "æ‚¢" => "Liang", "æ‚£" => "Huan", "悤" => "Cong", "æ‚¥" => "Yi", "悦" => "Yue", + "悧" => "Li", "您" => "Nin", "æ‚©" => "Nao", "悪" => "E", "æ‚«" => "Que", "悬" => "Xuan", + "æ‚­" => "Qian", "æ‚®" => "Wu", "悯" => "Min", "æ‚°" => "Cong", "悱" => "Fei", "悲" => "Bei", + "悳" => "Duo", "æ‚´" => "Cui", "悵" => "Chang", "悶" => "Men", "æ‚·" => "Li", "悸" => "Ji", + "悹" => "Guan", "悺" => "Guan", "æ‚»" => "Xing", "悼" => "Dao", "悽" => "Qi", "悾" => "Kong", + "æ‚¿" => "Tian", "惀" => "Lun", "æƒ" => "Xi", "惂" => "Kan", "惃" => "Kun", "惄" => "Ni", + "情" => "Qing", "惆" => "Chou", "惇" => "Dun", "惈" => "Guo", "惉" => "Chan", "惊" => "Liang", + "惋" => "Wan", "惌" => "Yuan", "æƒ" => "Jin", "惎" => "Ji", "æƒ" => "Lin", "æƒ" => "Yu", + "惑" => "Huo", "惒" => "He", "惓" => "Quan", "惔" => "Tan", "惕" => "Ti", "惖" => "Ti", + "惗" => "Nie", "惘" => "Wang", "惙" => "Chuo", "惚" => "Bu", "惛" => "Hun", "惜" => "Xi", + "æƒ" => "Tang", "惞" => "Xin", "惟" => "Wei", "惠" => "Hui", "惡" => "E", "惢" => "Rui", + "惣" => "Zong", "惤" => "Jian", "惥" => "Yong", "惦" => "Dian", "惧" => "Ju", "惨" => "Can", + "惩" => "Cheng", "惪" => "De", "惫" => "Bei", "惬" => "Qie", "惭" => "Can", "惮" => "Dan", + "惯" => "Guan", "惰" => "Duo", "惱" => "Nao", "惲" => "Yun", "想" => "Xiang", "惴" => "Zhui", + "惵" => "Die", "惶" => "Huang", "惷" => "Chun", "惸" => "Qiong", "惹" => "Re", "惺" => "Xing", + "惻" => "Ce", "惼" => "Bian", "惽" => "Hun", "惾" => "Zong", "惿" => "Ti", "æ„" => "Chou", + "æ„‚" => "Bei", "愃" => "Xuan", "æ„„" => "Wei", "æ„…" => "Ge", "愆" => "Qian", "愇" => "Wei", + "愈" => "Yu", "愉" => "Yu", "æ„Š" => "Bi", "æ„‹" => "Xuan", "æ„Œ" => "Huan", "æ„" => "Min", + "æ„Ž" => "Bi", "æ„" => "Yi", "æ„" => "Mian", "æ„‘" => "Yong", "æ„’" => "Kai", "æ„“" => "Dang", + "æ„”" => "Yin", "æ„•" => "E", "æ„–" => "Chen", "æ„—" => "Mou", "愘" => "Ke", "æ„™" => "Ke", + "æ„š" => "Yu", "æ„›" => "Ai", "æ„œ" => "Qie", "æ„" => "Yan", "æ„ž" => "Nuo", "æ„Ÿ" => "Gan", + "æ„ " => "Yun", "æ„¡" => "Zong", "æ„¢" => "Sai", "æ„£" => "Leng", "愤" => "Fen", "愦" => "Kui", + "愧" => "Kui", "愨" => "Que", "æ„©" => "Gong", "愪" => "Yun", "æ„«" => "Su", "愬" => "Su", + "æ„­" => "Qi", "æ„®" => "Yao", "愯" => "Song", "æ„°" => "Huang", "愱" => "Ji", "愲" => "Gu", + "愳" => "Ju", "æ„´" => "Chuang", "愵" => "Ni", "愶" => "Xie", "æ„·" => "Kai", "愸" => "Zheng", + "愹" => "Yong", "愺" => "Cao", "æ„»" => "Sun", "愼" => "Shen", "愽" => "Bo", "愾" => "Kai", + "æ„¿" => "Yuan", "æ…€" => "Xie", "æ…" => "Hun", "æ…‚" => "Yong", "æ…ƒ" => "Yang", "æ…„" => "Li", + "æ……" => "Sao", "æ…†" => "Tao", "æ…‡" => "Yin", "æ…ˆ" => "Ci", "æ…‰" => "Xu", "æ…Š" => "Qian", + "æ…‹" => "Tai", "æ…Œ" => "Huang", "æ…" => "Yun", "æ…Ž" => "Shen", "æ…" => "Ming", "æ…‘" => "She", + "æ…’" => "Cong", "æ…“" => "Piao", "æ…”" => "Mo", "æ…•" => "Mu", "æ…–" => "Guo", "æ…—" => "Chi", + "æ…˜" => "Can", "æ…™" => "Can", "æ…š" => "Can", "æ…›" => "Cui", "æ…œ" => "Min", "æ…" => "Te", + "æ…ž" => "Zhang", "æ…Ÿ" => "Tong", "æ… " => "Ao", "æ…¡" => "Shuang", "æ…¢" => "Man", "æ…£" => "Guan", + "æ…¤" => "Que", "æ…¥" => "Zao", "æ…¦" => "Jiu", "æ…§" => "Hui", "æ…¨" => "Kai", "æ…©" => "Lian", + "æ…ª" => "Ou", "æ…«" => "Song", "æ…¬" => "Jin", "æ…­" => "Yin", "æ…®" => "Lu", "æ…¯" => "Shang", + "æ…°" => "Wei", "æ…±" => "Tuan", "æ…²" => "Man", "æ…³" => "Qian", "æ…´" => "She", "æ…µ" => "Yong", + "æ…¶" => "Qing", "æ…·" => "Kang", "æ…¸" => "Di", "æ…¹" => "Zhi", "æ…º" => "Lou", "æ…»" => "Juan", + "æ…¼" => "Qi", "æ…½" => "Qi", "æ…¾" => "Yu", "æ…¿" => "Ping", "憀" => "Liao", "æ†" => "Cong", + "憂" => "You", "憃" => "Chong", "憄" => "Zhi", "憅" => "Tong", "憆" => "Cheng", "憇" => "Qi", + "憈" => "Qu", "憉" => "Peng", "憊" => "Bei", "憋" => "Bie", "憌" => "Chun", "æ†" => "Jiao", + "憎" => "Zeng", "æ†" => "Chi", "æ†" => "Lian", "憑" => "Ping", "憒" => "Kui", "憓" => "Hui", + "憔" => "Qiao", "憕" => "Cheng", "憖" => "Yin", "憗" => "Yin", "憘" => "Xi", "憙" => "Xi", + "憚" => "Dan", "憛" => "Tan", "憜" => "Duo", "æ†" => "Dui", "憞" => "Dui", "憟" => "Su", + "憠" => "Jue", "憡" => "Ce", "憢" => "Xiao", "憣" => "Fan", "憤" => "Fen", "憥" => "Lao", + "憦" => "Lao", "憧" => "Chong", "憨" => "Han", "憩" => "Qi", "憪" => "Xian", "憫" => "Min", + "憬" => "Jing", "憭" => "Liao", "憮" => "Wu", "憯" => "Can", "憰" => "Jue", "憱" => "Cu", + "憲" => "Xian", "憳" => "Tan", "憴" => "Sheng", "憵" => "Pi", "憶" => "Yi", "憷" => "Chu", + "憸" => "Xian", "憹" => "Nao", "憺" => "Dan", "憻" => "Tan", "憼" => "Jing", "憽" => "Song", + "憾" => "Han", "憿" => "Jiao", "懀" => "Wai", "æ‡" => "Huan", "懂" => "Dong", "懃" => "Qin", + "懄" => "Qin", "懅" => "Qu", "懆" => "Cao", "懇" => "Ken", "懈" => "Xie", "應" => "Ying", + "懊" => "Ao", "懋" => "Mao", "懌" => "Yi", "æ‡" => "Lin", "懎" => "Se", "æ‡" => "Jun", + "æ‡" => "Huai", "懑" => "Men", "懒" => "Lan", "懓" => "Ai", "懔" => "Lin", "懕" => "Yan", + "懖" => "Gua", "懗" => "Xia", "懘" => "Chi", "懙" => "Yu", "懚" => "Yin", "懛" => "Dai", + "懜" => "Meng", "æ‡" => "Ai", "懞" => "Meng", "懟" => "Dui", "懠" => "Qi", "懡" => "Mo", + "懢" => "Lan", "懣" => "Men", "懤" => "Chou", "懥" => "Zhi", "懦" => "Nuo", "懧" => "Nuo", + "懨" => "Yan", "懩" => "Yang", "懪" => "Bo", "懫" => "Zhi", "懬" => "Kuang", "懭" => "Kuang", + "懮" => "You", "懯" => "Fu", "懰" => "Liu", "懱" => "Mie", "懲" => "Cheng", "懴" => "Chan", + "懵" => "Meng", "懶" => "Lan", "懷" => "Huai", "懸" => "Xuan", "懹" => "Rang", "懺" => "Chan", + "懻" => "Ji", "懼" => "Ju", "懽" => "Huan", "懾" => "She", "懿" => "Yi", "æˆ" => "Nan", + "戂" => "Mi", "戃" => "Tang", "戄" => "Jue", "戅" => "Gang", "戆" => "Gang", "戇" => "Gang", + "戈" => "Ge", "戉" => "Yue", "戊" => "Wu", "戋" => "Jian", "戌" => "Xu", "æˆ" => "Shu", + "戎" => "Rong", "æˆ" => "Xi", "æˆ" => "Cheng", "我" => "Wo", "戒" => "Jie", "戓" => "Ge", + "戔" => "Jian", "戕" => "Qiang", "或" => "Huo", "戗" => "Qiang", "战" => "Zhan", "戙" => "Dong", + "戚" => "Qi", "戛" => "Jia", "戜" => "Die", "æˆ" => "Zei", "戞" => "Jia", "戟" => "Ji", + "戠" => "Shi", "戡" => "Kan", "戢" => "Ji", "戣" => "Kui", "戤" => "Gai", "戥" => "Deng", + "戦" => "Zhan", "戧" => "Chuang", "戨" => "Ge", "戩" => "Jian", "截" => "Jie", "戫" => "Yu", + "戬" => "Jian", "戭" => "Yan", "戮" => "Lu", "戯" => "Xi", "戰" => "Zhan", "戱" => "Xi", + "戲" => "Xi", "戳" => "Chuo", "戴" => "Dai", "戵" => "Qu", "戶" => "Hu", "户" => "Hu", + "戸" => "Hu", "戹" => "E", "戺" => "Shi", "戻" => "Li", "戼" => "Mao", "戽" => "Hu", + "戾" => "Li", "房" => "Fang", "所" => "Suo", "æ‰" => "Bian", "扂" => "Dian", "扃" => "Jiong", + "扄" => "Shang", "扅" => "Yi", "扆" => "Yi", "扇" => "Shan", "扈" => "Hu", "扉" => "Fei", + "扊" => "Yan", "手" => "Shou", "扌" => "T", "æ‰" => "Cai", "扎" => "Zha", "æ‰" => "Qiu", + "æ‰" => "Le", "扑" => "Bu", "扒" => "Ba", "打" => "Da", "扔" => "Reng", "払" => "Fu", + "扖" => "Hameru", "扗" => "Zai", "托" => "Tuo", "扙" => "Zhang", "扚" => "Diao", "扛" => "Kang", + "扜" => "Yu", "æ‰" => "Ku", "扞" => "Han", "扟" => "Shen", "扠" => "Cha", "扡" => "Yi", + "扢" => "Gu", "扣" => "Kou", "扤" => "Wu", "扥" => "Tuo", "扦" => "Qian", "执" => "Zhi", + "扨" => "Ren", "扩" => "Kuo", "扪" => "Men", "扫" => "Sao", "扬" => "Yang", "扭" => "Niu", + "扮" => "Ban", "扯" => "Che", "扰" => "Rao", "扱" => "Xi", "扲" => "Qian", "扳" => "Ban", + "扴" => "Jia", "扵" => "Yu", "扶" => "Fu", "扷" => "Ao", "扸" => "Xi", "批" => "Pi", + "扺" => "Zhi", "扻" => "Zi", "扼" => "E", "扽" => "Dun", "找" => "Zhao", "承" => "Cheng", + "技" => "Ji", "æŠ" => "Yan", "抂" => "Kuang", "抃" => "Bian", "抄" => "Chao", "抅" => "Ju", + "抆" => "Wen", "抇" => "Hu", "抈" => "Yue", "抉" => "Jue", "把" => "Ba", "抋" => "Qin", + "抌" => "Zhen", "æŠ" => "Zheng", "抎" => "Yun", "æŠ" => "Wan", "æŠ" => "Nu", "抑" => "Yi", + "抒" => "Shu", "抓" => "Zhua", "抔" => "Pou", "投" => "Tou", "抖" => "Dou", "抗" => "Kang", + "折" => "Zhe", "抙" => "Pou", "抚" => "Fu", "抛" => "Pao", "抜" => "Ba", "æŠ" => "Ao", + "択" => "Ze", "抟" => "Tuan", "抠" => "Kou", "抡" => "Lun", "抢" => "Qiang", "护" => "Hu", + "报" => "Bao", "抦" => "Bing", "抧" => "Zhi", "抨" => "Peng", "抩" => "Tan", "抪" => "Pu", + "披" => "Pi", "抬" => "Tai", "抭" => "Yao", "抮" => "Zhen", "抯" => "Zha", "抰" => "Yang", + "抱" => "Bao", "抲" => "He", "抳" => "Ni", "抴" => "Yi", "抵" => "Di", "抶" => "Chi", + "抷" => "Pi", "抸" => "Za", "抹" => "Mo", "抺" => "Mo", "抻" => "Shen", "押" => "Ya", + "抽" => "Chou", "抾" => "Qu", "抿" => "Min", "æ‹€" => "Chu", "æ‹" => "Jia", "æ‹‚" => "Fu", + "拃" => "Zhan", "æ‹„" => "Zhu", "æ‹…" => "Dan", "拆" => "Chai", "拇" => "Mu", "拈" => "Nian", + "拉" => "La", "æ‹Š" => "Fu", "æ‹‹" => "Pao", "æ‹Œ" => "Ban", "æ‹" => "Pai", "æ‹Ž" => "Ling", + "æ‹" => "Na", "æ‹" => "Guai", "æ‹‘" => "Qian", "æ‹’" => "Ju", "æ‹“" => "Tuo", "æ‹”" => "Ba", + "æ‹•" => "Tuo", "æ‹–" => "Tuo", "æ‹—" => "Ao", "拘" => "Ju", "æ‹™" => "Zhuo", "æ‹š" => "Pan", + "æ‹›" => "Zhao", "æ‹œ" => "Bai", "æ‹" => "Bai", "æ‹ž" => "Di", "æ‹Ÿ" => "Ni", "æ‹ " => "Ju", + "æ‹¡" => "Kuo", "æ‹¢" => "Long", "æ‹£" => "Jian", "æ‹¥" => "Yong", "拦" => "Lan", "拧" => "Ning", + "拨" => "Bo", "æ‹©" => "Ze", "拪" => "Qian", "æ‹«" => "Hen", "括" => "Gua", "æ‹­" => "Shi", + "æ‹®" => "Jie", "拯" => "Zheng", "æ‹°" => "Nin", "拱" => "Gong", "拲" => "Gong", "拳" => "Quan", + "æ‹´" => "Shuan", "拵" => "Cun", "拶" => "Zan", "æ‹·" => "Kao", "拸" => "Chi", "拹" => "Xie", + "拺" => "Ce", "æ‹»" => "Hui", "拼" => "Pin", "拽" => "Zhuai", "拾" => "Shi", "æ‹¿" => "Na", + "æŒ" => "Chi", "挂" => "Gua", "挃" => "Zhi", "挄" => "Kuo", "挅" => "Duo", "挆" => "Duo", + "指" => "Zhi", "挈" => "Qie", "按" => "An", "挊" => "Nong", "挋" => "Zhen", "挌" => "Ge", + "æŒ" => "Jiao", "挎" => "Ku", "æŒ" => "Dong", "æŒ" => "Ru", "挑" => "Tiao", "挒" => "Lie", + "挓" => "Zha", "挔" => "Lu", "挕" => "Die", "挖" => "Wa", "挗" => "Jue", "挘" => "Mushiru", + "挙" => "Ju", "挚" => "Zhi", "挛" => "Luan", "挜" => "Ya", "æŒ" => "Zhua", "挞" => "Ta", + "挟" => "Xie", "挠" => "Nao", "挡" => "Dang", "挢" => "Jiao", "挣" => "Zheng", "挤" => "Ji", + "挥" => "Hui", "挦" => "Xun", "挧" => "Ku", "挨" => "Ai", "挩" => "Tuo", "挪" => "Nuo", + "挫" => "Cuo", "挬" => "Bo", "挭" => "Geng", "挮" => "Ti", "振" => "Zhen", "挰" => "Cheng", + "挱" => "Suo", "挲" => "Suo", "挳" => "Keng", "挴" => "Mei", "挵" => "Long", "挶" => "Ju", + "挷" => "Peng", "挸" => "Jian", "挹" => "Yi", "挺" => "Ting", "挻" => "Shan", "挼" => "Nuo", + "挽" => "Wan", "挾" => "Xie", "挿" => "Cha", "æ€" => "Feng", "æ" => "Jiao", "æ‚" => "Wu", + "æƒ" => "Jun", "æ„" => "Jiu", "æ…" => "Tong", "æ†" => "Kun", "æ‡" => "Huo", "æˆ" => "Tu", + "æ‰" => "Zhuo", "æŠ" => "Pou", "æ‹" => "Le", "æŒ" => "Ba", "æ" => "Han", "æŽ" => "Shao", + "æ" => "Nie", "æ" => "Juan", "æ‘" => "Ze", "æ’" => "Song", "æ“" => "Ye", "æ”" => "Jue", + "æ•" => "Bu", "æ–" => "Huan", "æ—" => "Bu", "æ˜" => "Zun", "æ™" => "Yi", "æš" => "Zhai", + "æ›" => "Lu", "æœ" => "Sou", "æ" => "Tuo", "æž" => "Lao", "æŸ" => "Sun", "æ " => "Bang", + "æ¡" => "Jian", "æ¢" => "Huan", "æ£" => "Dao", "æ¥" => "Wan", "æ¦" => "Qin", "æ§" => "Peng", + "æ¨" => "She", "æ©" => "Lie", "æª" => "Min", "æ«" => "Men", "æ¬" => "Fu", "æ­" => "Bai", + "æ®" => "Ju", "æ¯" => "Dao", "æ°" => "Wo", "æ±" => "Ai", "æ²" => "Juan", "æ³" => "Yue", + "æ´" => "Zong", "æµ" => "Chen", "æ¶" => "Chui", "æ·" => "Jie", "æ¸" => "Tu", "æ¹" => "Ben", + "æº" => "Na", "æ»" => "Nian", "æ¼" => "Nuo", "æ½" => "Zu", "æ¾" => "Wo", "æ¿" => "Xi", + "掀" => "Xian", "æŽ" => "Cheng", "掂" => "Dian", "掃" => "Sao", "掄" => "Lun", "掅" => "Qing", + "掆" => "Gang", "掇" => "Duo", "授" => "Shou", "掉" => "Diao", "掊" => "Pou", "掋" => "Di", + "掌" => "Zhang", "æŽ" => "Gun", "掎" => "Ji", "æŽ" => "Tao", "æŽ" => "Qia", "掑" => "Qi", + "排" => "Pai", "掓" => "Shu", "掔" => "Qian", "掕" => "Ling", "掖" => "Yi", "掗" => "Ya", + "掘" => "Jue", "掙" => "Zheng", "掚" => "Liang", "掛" => "Gua", "掜" => "Yi", "æŽ" => "Huo", + "掞" => "Shan", "掟" => "Zheng", "掠" => "Lue", "採" => "Cai", "探" => "Tan", "掣" => "Che", + "掤" => "Bing", "接" => "Jie", "掦" => "Ti", "控" => "Kong", "推" => "Tui", "掩" => "Yan", + "措" => "Cuo", "掫" => "Zou", "掬" => "Ju", "掭" => "Tian", "掮" => "Qian", "掯" => "Ken", + "掰" => "Bai", "掱" => "Shou", "掲" => "Jie", "掳" => "Lu", "掴" => "Guo", "掵" => "Haba", + "掷" => "Zhi", "掸" => "Dan", "掹" => "Mang", "掺" => "Xian", "掻" => "Sao", "掼" => "Guan", + "掽" => "Peng", "掾" => "Yuan", "掿" => "Nuo", "æ€" => "Jian", "æ" => "Zhen", "æ‚" => "Jiu", + "æƒ" => "Jian", "æ„" => "Yu", "æ…" => "Yan", "æ†" => "Kui", "æ‡" => "Nan", "æˆ" => "Hong", + "æ‰" => "Rou", "æŠ" => "Pi", "æ‹" => "Wei", "æŒ" => "Sai", "æ" => "Zou", "æŽ" => "Xuan", + "æ" => "Miao", "æ" => "Ti", "æ‘" => "Nie", "æ’" => "Cha", "æ“" => "Shi", "æ”" => "Zong", + "æ•" => "Zhen", "æ–" => "Yi", "æ—" => "Shun", "æ˜" => "Heng", "æ™" => "Bian", "æš" => "Yang", + "æ›" => "Huan", "æœ" => "Yan", "æ" => "Zuan", "æž" => "An", "æŸ" => "Xu", "æ " => "Ya", + "æ¡" => "Wo", "æ¢" => "Ke", "æ£" => "Chuai", "æ¤" => "Ji", "æ¥" => "Ti", "æ¦" => "La", + "æ§" => "La", "æ¨" => "Cheng", "æ©" => "Kai", "æª" => "Jiu", "æ«" => "Jiu", "æ¬" => "Tu", + "æ­" => "Jie", "æ®" => "Hui", "æ¯" => "Geng", "æ°" => "Chong", "æ±" => "Shuo", "æ²" => "She", + "æ³" => "Xie", "æ´" => "Yuan", "æµ" => "Qian", "æ¶" => "Ye", "æ·" => "Cha", "æ¸" => "Zha", + "æ¹" => "Bei", "æº" => "Yao", "æ½" => "Lan", "æ¾" => "Wen", "æ¿" => "Qin", "æ" => "Ge", + "æ‚" => "Lou", "æƒ" => "Zong", "æ„" => "Geng", "æ…" => "Jiao", "æ†" => "Gou", "æ‡" => "Qin", + "æˆ" => "Yong", "æ‰" => "Que", "æŠ" => "Chou", "æ‹" => "Chi", "æŒ" => "Zhan", "æ" => "Sun", + "æŽ" => "Sun", "æ" => "Bo", "æ" => "Chu", "æ‘" => "Rong", "æ’" => "Beng", "æ“" => "Cuo", + "æ”" => "Sao", "æ•" => "Ke", "æ–" => "Yao", "æ—" => "Dao", "æ˜" => "Zhi", "æ™" => "Nu", + "æš" => "Xie", "æ›" => "Jian", "æœ" => "Sou", "æ" => "Qiu", "æž" => "Gao", "æŸ" => "Xian", + "æ " => "Shuo", "æ¡" => "Sang", "æ¢" => "Jin", "æ£" => "Mie", "æ¤" => "E", "æ¥" => "Chui", + "æ¦" => "Nuo", "æ§" => "Shan", "æ¨" => "Ta", "æ©" => "Jie", "æª" => "Tang", "æ«" => "Pan", + "æ¬" => "Ban", "æ­" => "Da", "æ®" => "Li", "æ¯" => "Tao", "æ°" => "Hu", "æ±" => "Zhi", + "æ²" => "Wa", "æ³" => "Xia", "æ´" => "Qian", "æµ" => "Wen", "æ¶" => "Qiang", "æ·" => "Tian", + "æ¸" => "Zhen", "æ¹" => "E", "æº" => "Xi", "æ»" => "Nuo", "æ¼" => "Quan", "æ½" => "Cha", + "æ¾" => "Zha", "æ¿" => "Ge", "æ‘€" => "Wu", "æ‘" => "En", "æ‘‚" => "She", "摃" => "Kang", + "æ‘„" => "She", "æ‘…" => "Shu", "摆" => "Bai", "摇" => "Yao", "摈" => "Bin", "摉" => "Sou", + "æ‘Š" => "Tan", "æ‘‹" => "Sa", "æ‘Œ" => "Chan", "æ‘" => "Suo", "æ‘Ž" => "Liao", "æ‘" => "Chong", + "æ‘" => "Chuang", "æ‘‘" => "Guo", "æ‘’" => "Bing", "æ‘“" => "Feng", "æ‘”" => "Shuai", "æ‘•" => "Di", + "æ‘–" => "Qi", "æ‘—" => "Sou", "摘" => "Zhai", "æ‘™" => "Lian", "æ‘š" => "Tang", "æ‘›" => "Chi", + "æ‘œ" => "Guan", "æ‘" => "Lu", "æ‘ž" => "Luo", "æ‘Ÿ" => "Lou", "æ‘ " => "Zong", "æ‘¡" => "Gai", + "æ‘¢" => "Hu", "æ‘£" => "Zha", "摤" => "Chuang", "æ‘¥" => "Tang", "摦" => "Hua", "摧" => "Cui", + "摨" => "Nai", "æ‘©" => "Mo", "摪" => "Jiang", "æ‘«" => "Gui", "摬" => "Ying", "æ‘­" => "Zhi", + "æ‘®" => "Ao", "摯" => "Zhi", "æ‘°" => "Nie", "摱" => "Man", "摲" => "Shan", "摳" => "Kou", + "æ‘´" => "Shu", "摵" => "Suo", "摶" => "Tuan", "æ‘·" => "Jiao", "摸" => "Mo", "摹" => "Mo", + "摺" => "Zhe", "æ‘»" => "Xian", "摼" => "Keng", "摽" => "Piao", "摾" => "Jiang", "æ‘¿" => "Yin", + "æ’€" => "Gou", "æ’" => "Qian", "æ’‚" => "Lue", "æ’ƒ" => "Ji", "æ’„" => "Ying", "æ’…" => "Jue", + "æ’†" => "Pie", "æ’‡" => "Pie", "æ’ˆ" => "Lao", "æ’‰" => "Dun", "æ’Š" => "Xian", "æ’‹" => "Ruan", + "æ’Œ" => "Kui", "æ’" => "Zan", "æ’Ž" => "Yi", "æ’" => "Xun", "æ’" => "Cheng", "æ’‘" => "Cheng", + "æ’’" => "Sa", "æ’“" => "Nao", "æ’”" => "Heng", "æ’•" => "Si", "æ’–" => "Qian", "æ’—" => "Huang", + "æ’˜" => "Da", "æ’™" => "Zun", "æ’š" => "Nian", "æ’›" => "Lin", "æ’œ" => "Zheng", "æ’" => "Hui", + "æ’ž" => "Zhuang", "æ’Ÿ" => "Jiao", "æ’ " => "Ji", "æ’¡" => "Cao", "æ’¢" => "Dan", "æ’£" => "Dan", + "æ’¤" => "Che", "æ’¥" => "Bo", "æ’¦" => "Che", "æ’§" => "Jue", "æ’¨" => "Xiao", "æ’©" => "Liao", + "æ’ª" => "Ben", "æ’«" => "Fu", "æ’¬" => "Qiao", "æ’­" => "Bo", "æ’®" => "Cuo", "æ’¯" => "Zhuo", + "æ’°" => "Zhuan", "æ’±" => "Tuo", "æ’²" => "Pu", "æ’³" => "Qin", "æ’´" => "Dun", "æ’µ" => "Nian", + "æ’·" => "Xie", "æ’¸" => "Lu", "æ’¹" => "Jiao", "æ’º" => "Cuan", "æ’»" => "Ta", "æ’¼" => "Han", + "æ’½" => "Qiao", "æ’¾" => "Zhua", "æ’¿" => "Jian", "æ“€" => "Gan", "æ“" => "Yong", "æ“‚" => "Lei", + "擃" => "Kuo", "æ“„" => "Lu", "æ“…" => "Shan", "擆" => "Zhuo", "擇" => "Ze", "擈" => "Pu", + "擉" => "Chuo", "æ“Š" => "Ji", "æ“‹" => "Dang", "æ“Œ" => "Suo", "æ“" => "Cao", "æ“Ž" => "Qing", + "æ“" => "Jing", "æ“" => "Huan", "æ“‘" => "Jie", "æ“’" => "Qin", "æ““" => "Kuai", "æ“”" => "Dan", + "æ“•" => "Xi", "æ“–" => "Ge", "æ“—" => "Pi", "擘" => "Bo", "æ“™" => "Ao", "æ“š" => "Ju", + "æ“›" => "Ye", "æ“" => "Mang", "æ“ž" => "Sou", "æ“Ÿ" => "Mi", "æ“ " => "Ji", "æ“¡" => "Tai", + "æ“¢" => "Zhuo", "æ“£" => "Dao", "擤" => "Xing", "æ“¥" => "Lan", "擦" => "Ca", "擧" => "Ju", + "擨" => "Ye", "æ“©" => "Ru", "擪" => "Ye", "æ“«" => "Ye", "擬" => "Ni", "æ“­" => "Hu", + "æ“®" => "Ji", "擯" => "Bin", "æ“°" => "Ning", "擱" => "Ge", "擲" => "Zhi", "擳" => "Jie", + "æ“´" => "Kuo", "擵" => "Mo", "擶" => "Jian", "æ“·" => "Xie", "擸" => "Lie", "擹" => "Tan", + "擺" => "Bai", "æ“»" => "Sou", "擼" => "Lu", "擽" => "Lue", "擾" => "Rao", "æ“¿" => "Zhi", + "æ”" => "Yang", "攂" => "Lei", "攃" => "Sa", "攄" => "Shu", "æ”…" => "Zan", "攆" => "Nian", + "攇" => "Xian", "攈" => "Jun", "攉" => "Huo", "攊" => "Li", "攋" => "La", "攌" => "Han", + "æ”" => "Ying", "攎" => "Lu", "æ”" => "Long", "æ”" => "Qian", "攑" => "Qian", "æ”’" => "Zan", + "攓" => "Qian", "æ””" => "Lan", "攕" => "San", "æ”–" => "Ying", "æ”—" => "Mei", "攘" => "Rang", + "æ”™" => "Chan", "æ”›" => "Cuan", "攜" => "Xi", "æ”" => "She", "攞" => "Luo", "攟" => "Jun", + "æ” " => "Mi", "攡" => "Li", "攢" => "Zan", "攣" => "Luan", "攤" => "Tan", "攥" => "Zuan", + "攦" => "Li", "攧" => "Dian", "攨" => "Wa", "攩" => "Dang", "攪" => "Jiao", "攫" => "Jue", + "攬" => "Lan", "æ”­" => "Li", "æ”®" => "Nang", "支" => "Zhi", "æ”°" => "Gui", "æ”±" => "Gui", + "攲" => "Qi", "攳" => "Xin", "æ”´" => "Pu", "攵" => "Sui", "收" => "Shou", "æ”·" => "Kao", + "攸" => "You", "改" => "Gai", "攺" => "Yi", "æ”»" => "Gong", "攼" => "Gan", "攽" => "Ban", + "放" => "Fang", "政" => "Zheng", "æ•€" => "Bo", "æ•" => "Dian", "æ•‚" => "Kou", "敃" => "Min", + "æ•„" => "Wu", "æ•…" => "Gu", "敆" => "He", "敇" => "Ce", "效" => "Xiao", "敉" => "Mi", + "æ•Š" => "Chu", "æ•‹" => "Ge", "æ•Œ" => "Di", "æ•" => "Xu", "æ•Ž" => "Jiao", "æ•" => "Min", + "æ•" => "Chen", "æ•‘" => "Jiu", "æ•’" => "Zhen", "æ•“" => "Duo", "æ•”" => "Yu", "æ••" => "Chi", + "æ•–" => "Ao", "æ•—" => "Bai", "敘" => "Xu", "æ•™" => "Jiao", "æ•š" => "Duo", "æ•›" => "Lian", + "æ•œ" => "Nie", "æ•" => "Bi", "æ•ž" => "Chang", "æ•Ÿ" => "Dian", "æ• " => "Duo", "æ•¡" => "Yi", + "æ•¢" => "Gan", "æ•£" => "San", "敤" => "Ke", "æ•¥" => "Yan", "敦" => "Dun", "敧" => "Qi", + "敨" => "Dou", "æ•©" => "Xiao", "敪" => "Duo", "æ•«" => "Jiao", "敬" => "Jing", "æ•­" => "Yang", + "æ•®" => "Xia", "敯" => "Min", "æ•°" => "Shu", "敱" => "Ai", "敲" => "Qiao", "敳" => "Ai", + "æ•´" => "Zheng", "敵" => "Di", "敶" => "Zhen", "æ•·" => "Fu", "數" => "Shu", "敹" => "Liao", + "敺" => "Qu", "æ•»" => "Xiong", "敼" => "Xi", "敽" => "Jiao", "敾" => "Sen", "æ•¿" => "Jiao", + "æ–€" => "Zhuo", "æ–" => "Yi", "æ–‚" => "Lian", "æ–ƒ" => "Bi", "æ–„" => "Li", "æ–…" => "Xiao", + "æ–†" => "Xiao", "æ–‡" => "Wen", "æ–ˆ" => "Xue", "æ–‰" => "Qi", "æ–Š" => "Qi", "æ–‹" => "Zhai", + "æ–Œ" => "Bin", "æ–" => "Jue", "æ–Ž" => "Zhai", "æ–" => "Fei", "æ–‘" => "Ban", "æ–’" => "Ban", + "æ–“" => "Lan", "æ–”" => "Yu", "æ–•" => "Lan", "æ––" => "Wei", "æ–—" => "Dou", "æ–˜" => "Sheng", + "æ–™" => "Liao", "æ–š" => "Jia", "æ–›" => "Hu", "æ–œ" => "Xie", "æ–" => "Jia", "æ–ž" => "Yu", + "æ–Ÿ" => "Zhen", "æ– " => "Jiao", "æ–¡" => "Wo", "æ–¢" => "Tou", "æ–£" => "Chu", "æ–¤" => "Jin", + "æ–¥" => "Chi", "æ–¦" => "Yin", "æ–§" => "Fu", "æ–¨" => "Qiang", "æ–©" => "Zhan", "æ–ª" => "Qu", + "æ–«" => "Zhuo", "æ–¬" => "Zhan", "æ–­" => "Duan", "æ–®" => "Zhuo", "æ–¯" => "Si", "æ–°" => "Xin", + "æ–±" => "Zhuo", "æ–²" => "Zhuo", "æ–³" => "Qin", "æ–´" => "Lin", "æ–µ" => "Zhuo", "æ–¶" => "Chu", + "æ–·" => "Duan", "æ–¸" => "Zhu", "æ–¹" => "Fang", "æ–º" => "Xie", "æ–»" => "Hang", "æ–¼" => "Yu", + "æ–½" => "Shi", "æ–¾" => "Pei", "æ–¿" => "You", "æ—€" => "Mye", "æ—" => "Pang", "æ—‚" => "Qi", + "æ—ƒ" => "Zhan", "æ—„" => "Mao", "æ—…" => "Lu", "æ—†" => "Pei", "æ—‡" => "Pi", "æ—ˆ" => "Liu", + "æ—‰" => "Fu", "æ—Š" => "Fang", "æ—‹" => "Xuan", "æ—Œ" => "Jing", "æ—" => "Jing", "æ—Ž" => "Ni", + "æ—" => "Zu", "æ—" => "Zhao", "æ—‘" => "Yi", "æ—’" => "Liu", "æ—“" => "Shao", "æ—”" => "Jian", + "æ—•" => "Es", "æ—–" => "Yi", "æ——" => "Qi", "æ—˜" => "Zhi", "æ—™" => "Fan", "æ—š" => "Piao", + "æ—›" => "Fan", "æ—œ" => "Zhan", "æ—" => "Guai", "æ—ž" => "Sui", "æ—Ÿ" => "Yu", "æ— " => "Wu", + "æ—¡" => "Ji", "æ—¢" => "Ji", "æ—£" => "Ji", "æ—¤" => "Huo", "æ—¥" => "Ri", "æ—¦" => "Dan", + "æ—§" => "Jiu", "æ—¨" => "Zhi", "æ—©" => "Zao", "æ—ª" => "Xie", "æ—«" => "Tiao", "æ—¬" => "Xun", + "æ—­" => "Xu", "æ—®" => "Xu", "æ—¯" => "Xu", "æ—°" => "Gan", "æ—±" => "Han", "æ—²" => "Tai", + "æ—³" => "Di", "æ—´" => "Xu", "æ—µ" => "Chan", "æ—¶" => "Shi", "æ—·" => "Kuang", "æ—¸" => "Yang", + "æ—¹" => "Shi", "æ—º" => "Wang", "æ—»" => "Min", "æ—¼" => "Min", "æ—½" => "Tun", "æ—¾" => "Chun", + "æ—¿" => "Wu", "æ˜" => "Bei", "昂" => "Ang", "昃" => "Ze", "昄" => "Ban", "昅" => "Jie", + "昆" => "Kun", "昇" => "Sheng", "昈" => "Hu", "昉" => "Fang", "昊" => "Hao", "昋" => "Gui", + "昌" => "Chang", "æ˜" => "Xuan", "明" => "Ming", "æ˜" => "Hun", "æ˜" => "Fen", "昑" => "Qin", + "昒" => "Hu", "易" => "Yi", "昔" => "Xi", "昕" => "Xin", "昖" => "Yan", "昗" => "Ze", + "昘" => "Fang", "昙" => "Tan", "昚" => "Shen", "昛" => "Ju", "昜" => "Yang", "æ˜" => "Zan", + "昞" => "Bing", "星" => "Xing", "映" => "Ying", "昡" => "Xuan", "昢" => "Pei", "昣" => "Zhen", + "昤" => "Ling", "春" => "Chun", "昦" => "Hao", "昧" => "Mei", "昨" => "Zuo", "昩" => "Mo", + "昪" => "Bian", "昫" => "Xu", "昬" => "Hun", "昭" => "Zhao", "昮" => "Zong", "是" => "Shi", + "昰" => "Shi", "昱" => "Yu", "昲" => "Fei", "昳" => "Die", "昴" => "Mao", "昵" => "Ni", + "昶" => "Chang", "昷" => "Wen", "昸" => "Dong", "昹" => "Ai", "昺" => "Bing", "昻" => "Ang", + "昼" => "Zhou", "昽" => "Long", "显" => "Xian", "昿" => "Kuang", "晀" => "Tiao", "æ™" => "Chao", + "時" => "Shi", "晃" => "Huang", "晄" => "Huang", "æ™…" => "Xuan", "晆" => "Kui", "晇" => "Xu", + "晈" => "Jiao", "晉" => "Jin", "晊" => "Zhi", "晋" => "Jin", "晌" => "Shang", "æ™" => "Tong", + "晎" => "Hong", "æ™" => "Yan", "æ™" => "Gai", "晑" => "Xiang", "æ™’" => "Shai", "晓" => "Xiao", + "æ™”" => "Ye", "晕" => "Yun", "æ™–" => "Hui", "æ™—" => "Han", "晘" => "Han", "æ™™" => "Jun", + "晚" => "Wan", "æ™›" => "Xian", "晜" => "Kun", "æ™" => "Zhou", "晞" => "Xi", "晟" => "Cheng", + "æ™ " => "Sheng", "晡" => "Bu", "晢" => "Zhe", "晣" => "Zhe", "晤" => "Wu", "晥" => "Han", + "晦" => "Hui", "晧" => "Hao", "晨" => "Chen", "晩" => "Wan", "晪" => "Tian", "晫" => "Zhuo", + "晬" => "Zui", "æ™­" => "Zhou", "æ™®" => "Pu", "景" => "Jing", "æ™°" => "Xi", "æ™±" => "Shan", + "晲" => "Yi", "晳" => "Xi", "æ™´" => "Qing", "晵" => "Qi", "晶" => "Jing", "æ™·" => "Gui", + "晸" => "Zhen", "晹" => "Yi", "智" => "Zhi", "æ™»" => "An", "晼" => "Wan", "晽" => "Lin", + "晾" => "Liang", "晿" => "Chang", "暀" => "Wang", "æš" => "Xiao", "æš‚" => "Zan", "暃" => "Hi", + "æš„" => "Xuan", "æš…" => "Xuan", "暆" => "Yi", "暇" => "Xia", "暈" => "Yun", "暉" => "Hui", + "暊" => "Fu", "æš‹" => "Min", "暌" => "Kui", "æš" => "He", "暎" => "Ying", "æš" => "Du", + "æš" => "Wei", "æš‘" => "Shu", "æš’" => "Qing", "æš“" => "Mao", "æš”" => "Nan", "æš•" => "Jian", + "æš–" => "Nuan", "æš—" => "An", "暘" => "Yang", "æš™" => "Chun", "æšš" => "Yao", "æš›" => "Suo", + "æšœ" => "Jin", "æš" => "Ming", "æšž" => "Jiao", "暟" => "Kai", "æš " => "Gao", "æš¡" => "Weng", + "暢" => "Chang", "暣" => "Qi", "暤" => "Hao", "暥" => "Yan", "暦" => "Li", "暧" => "Ai", + "暨" => "Ji", "æš©" => "Gui", "暪" => "Men", "æš«" => "Zan", "暬" => "Xie", "æš­" => "Hao", + "æš®" => "Mu", "暯" => "Mo", "æš°" => "Cong", "æš±" => "Ni", "æš²" => "Zhang", "æš³" => "Hui", + "æš´" => "Bao", "æšµ" => "Han", "暶" => "Xuan", "æš·" => "Chuan", "暸" => "Liao", "æš¹" => "Xian", + "暺" => "Dan", "æš»" => "Jing", "æš¼" => "Pie", "æš½" => "Lin", "æš¾" => "Tun", "æš¿" => "Xi", + "曀" => "Yi", "æ›" => "Ji", "曂" => "Huang", "曃" => "Tai", "曄" => "Ye", "æ›…" => "Ye", + "曆" => "Li", "曇" => "Tan", "曈" => "Tong", "曉" => "Xiao", "曊" => "Fei", "曋" => "Qin", + "曌" => "Zhao", "æ›" => "Hao", "曎" => "Yi", "æ›" => "Xiang", "æ›" => "Xing", "曑" => "Sen", + "æ›’" => "Jiao", "曓" => "Bao", "æ›”" => "Jing", "曕" => "Yian", "æ›–" => "Ai", "æ›—" => "Ye", + "曘" => "Ru", "æ›™" => "Shu", "曚" => "Meng", "æ››" => "Xun", "曜" => "Yao", "æ›" => "Pu", + "曞" => "Li", "曟" => "Chen", "æ› " => "Kuang", "曡" => "Die", "曣" => "Yan", "曤" => "Huo", + "曥" => "Lu", "曦" => "Xi", "曧" => "Rong", "曨" => "Long", "曩" => "Nang", "曪" => "Luo", + "曫" => "Luan", "曬" => "Shai", "æ›­" => "Tang", "æ›®" => "Yan", "曯" => "Chu", "æ›°" => "Yue", + "æ›±" => "Yue", "曲" => "Qu", "曳" => "Yi", "æ›´" => "Geng", "曵" => "Ye", "曶" => "Hu", + "æ›·" => "He", "書" => "Shu", "曹" => "Cao", "曺" => "Cao", "æ›»" => "Noboru", "曼" => "Man", + "曽" => "Ceng", "曾" => "Ceng", "替" => "Ti", "æœ" => "Can", "朂" => "Xu", "會" => "Hui", + "朄" => "Yin", "朅" => "Qie", "朆" => "Fen", "朇" => "Pi", "月" => "Yue", "有" => "You", + "朊" => "Ruan", "朋" => "Peng", "朌" => "Ban", "æœ" => "Fu", "朎" => "Ling", "æœ" => "Fei", + "æœ" => "Qu", "朒" => "Nu", "朓" => "Tiao", "朔" => "Shuo", "朕" => "Zhen", "朖" => "Lang", + "朗" => "Lang", "朘" => "Juan", "朙" => "Ming", "朚" => "Huang", "望" => "Wang", "朜" => "Tun", + "æœ" => "Zhao", "朞" => "Ji", "期" => "Qi", "朠" => "Ying", "朡" => "Zong", "朢" => "Wang", + "朣" => "Tong", "朤" => "Lang", "朦" => "Meng", "朧" => "Long", "木" => "Mu", "朩" => "Deng", + "未" => "Wei", "末" => "Mo", "本" => "Ben", "札" => "Zha", "朮" => "Zhu", "术" => "Zhu", + "朱" => "Zhu", "朲" => "Ren", "朳" => "Ba", "朴" => "Po", "朵" => "Duo", "朶" => "Duo", + "朷" => "Dao", "朸" => "Li", "朹" => "Qiu", "机" => "Ji", "朻" => "Jiu", "朼" => "Bi", + "朽" => "Xiu", "朾" => "Ting", "朿" => "Ci", "æ€" => "Sha", "æ" => "Eburi", "æ‚" => "Za", + "æƒ" => "Quan", "æ„" => "Qian", "æ…" => "Yu", "æ†" => "Gan", "æ‡" => "Wu", "æˆ" => "Cha", + "æ‰" => "Shan", "æŠ" => "Xun", "æ‹" => "Fan", "æŒ" => "Wu", "æ" => "Zi", "æŽ" => "Li", + "æ" => "Xing", "æ" => "Cai", "æ‘" => "Cun", "æ’" => "Ren", "æ“" => "Shao", "æ”" => "Tuo", + "æ•" => "Di", "æ–" => "Zhang", "æ—" => "Mang", "æ˜" => "Chi", "æ™" => "Yi", "æš" => "Gu", + "æ›" => "Gong", "æœ" => "Du", "æ" => "Yi", "æž" => "Qi", "æŸ" => "Shu", "æ " => "Gang", + "æ¡" => "Tiao", "æ¢" => "Moku", "æ£" => "Soma", "æ¤" => "Tochi", "æ¥" => "Lai", "æ¦" => "Sugi", + "æ§" => "Mang", "æ¨" => "Yang", "æ©" => "Ma", "æª" => "Miao", "æ«" => "Si", "æ¬" => "Yuan", + "æ­" => "Hang", "æ®" => "Fei", "æ¯" => "Bei", "æ°" => "Jie", "æ±" => "Dong", "æ²" => "Gao", + "æ³" => "Yao", "æ´" => "Xian", "æµ" => "Chu", "æ¶" => "Qun", "æ·" => "Pa", "æ¸" => "Shu", + "æ¹" => "Hua", "æº" => "Xin", "æ»" => "Chou", "æ¼" => "Zhu", "æ½" => "Chou", "æ¾" => "Song", + "æ¿" => "Ban", "枀" => "Song", "æž" => "Ji", "æž‚" => "Yue", "枃" => "Jin", "æž„" => "Gou", + "æž…" => "Ji", "枆" => "Mao", "枇" => "Pi", "枈" => "Bi", "枉" => "Wang", "枊" => "Ang", + "æž‹" => "Fang", "枌" => "Fen", "æž" => "Yi", "枎" => "Fu", "æž" => "Nan", "æž" => "Xi", + "æž‘" => "Hu", "æž’" => "Ya", "æž“" => "Dou", "æž”" => "Xun", "æž•" => "Zhen", "æž–" => "Yao", + "æž—" => "Lin", "枘" => "Rui", "æž™" => "E", "æžš" => "Mei", "æž›" => "Zhao", "æžœ" => "Guo", + "æž" => "Zhi", "æžž" => "Cong", "枟" => "Yun", "æž " => "Waku", "æž¡" => "Dou", "枢" => "Shu", + "枣" => "Zao", "枥" => "Li", "枦" => "Haze", "枧" => "Jian", "枨" => "Cheng", "æž©" => "Matsu", + "枪" => "Qiang", "æž«" => "Feng", "枬" => "Nan", "æž­" => "Xiao", "æž®" => "Xian", "枯" => "Ku", + "æž°" => "Ping", "æž±" => "Yi", "æž²" => "Xi", "æž³" => "Zhi", "æž´" => "Guai", "æžµ" => "Xiao", + "架" => "Jia", "æž·" => "Jia", "枸" => "Gou", "æž¹" => "Fu", "枺" => "Mo", "æž»" => "Yi", + "æž¼" => "Ye", "æž½" => "Ye", "æž¾" => "Shi", "æž¿" => "Nie", "柀" => "Bi", "æŸ" => "Duo", + "柂" => "Yi", "柃" => "Ling", "柄" => "Bing", "柅" => "Ni", "柆" => "La", "柇" => "He", + "柈" => "Pan", "柉" => "Fan", "柊" => "Zhong", "柋" => "Dai", "柌" => "Ci", "æŸ" => "Yang", + "柎" => "Fu", "æŸ" => "Bo", "æŸ" => "Mou", "柑" => "Gan", "柒" => "Qi", "染" => "Ran", + "柔" => "Rou", "柕" => "Mao", "柖" => "Zhao", "柗" => "Song", "柘" => "Zhe", "柙" => "Xia", + "柚" => "You", "柛" => "Shen", "柜" => "Ju", "æŸ" => "Tuo", "柞" => "Zuo", "柟" => "Nan", + "柠" => "Ning", "柡" => "Yong", "柢" => "Di", "柣" => "Zhi", "柤" => "Zha", "查" => "Cha", + "柦" => "Dan", "柧" => "Gu", "柨" => "Pu", "柩" => "Jiu", "柪" => "Ao", "柫" => "Fu", + "柬" => "Jian", "柭" => "Bo", "柮" => "Duo", "柯" => "Ke", "柰" => "Nai", "柱" => "Zhu", + "柲" => "Bi", "柳" => "Liu", "柴" => "Chai", "柵" => "Zha", "柶" => "Si", "柷" => "Zhu", + "柸" => "Pei", "柹" => "Shi", "柺" => "Guai", "査" => "Cha", "柼" => "Yao", "柽" => "Jue", + "柾" => "Jiu", "柿" => "Shi", "æ " => "Liu", "æ ‚" => "Mei", "æ ƒ" => "Hoy", "æ „" => "Rong", + "æ …" => "Zha", "æ ‡" => "Biao", "æ ˆ" => "Zhan", "æ ‰" => "Jie", "æ Š" => "Long", "æ ‹" => "Dong", + "æ Œ" => "Lu", "æ " => "Sayng", "æ Ž" => "Li", "æ " => "Lan", "æ " => "Yong", "æ ‘" => "Shu", + "æ ’" => "Xun", "æ “" => "Shuan", "æ ”" => "Qi", "æ •" => "Zhen", "æ –" => "Qi", "æ —" => "Li", + "æ ˜" => "Yi", "æ ™" => "Xiang", "æ š" => "Zhen", "æ ›" => "Li", "æ œ" => "Su", "æ " => "Gua", + "æ ž" => "Kan", "æ Ÿ" => "Bing", "æ  " => "Ren", "æ ¡" => "Xiao", "æ ¢" => "Bo", "æ £" => "Ren", + "æ ¤" => "Bing", "æ ¥" => "Zi", "æ ¦" => "Chou", "æ §" => "Yi", "æ ¨" => "Jie", "æ ©" => "Xu", + "æ ª" => "Zhu", "æ «" => "Jian", "æ ¬" => "Zui", "æ ­" => "Er", "æ ®" => "Er", "æ ¯" => "You", + "æ °" => "Fa", "æ ±" => "Gong", "æ ²" => "Kao", "æ ³" => "Lao", "æ ´" => "Zhan", "æ µ" => "Li", + "æ ¶" => "Yin", "æ ·" => "Yang", "æ ¸" => "He", "æ ¹" => "Gen", "æ º" => "Zhi", "æ »" => "Chi", + "æ ¼" => "Ge", "æ ½" => "Zai", "æ ¾" => "Luan", "æ ¿" => "Fu", "æ¡€" => "Jie", "æ¡" => "Hang", + "æ¡‚" => "Gui", "桃" => "Tao", "æ¡„" => "Guang", "æ¡…" => "Wei", "框" => "Kuang", "桇" => "Ru", + "案" => "An", "桉" => "An", "æ¡Š" => "Juan", "æ¡‹" => "Yi", "æ¡Œ" => "Zhuo", "æ¡" => "Ku", + "æ¡Ž" => "Zhi", "æ¡" => "Qiong", "æ¡" => "Tong", "æ¡‘" => "Sang", "æ¡’" => "Sang", "æ¡“" => "Huan", + "æ¡”" => "Jie", "æ¡•" => "Jiu", "æ¡–" => "Xue", "æ¡—" => "Duo", "桘" => "Zhui", "æ¡™" => "Yu", + "æ¡š" => "Zan", "æ¡›" => "Kasei", "æ¡œ" => "Ying", "æ¡" => "Masu", "æ¡Ÿ" => "Zhan", "æ¡ " => "Ya", + "æ¡¡" => "Nao", "æ¡¢" => "Zhen", "æ¡£" => "Dang", "桤" => "Qi", "æ¡¥" => "Qiao", "桦" => "Hua", + "桧" => "Kuai", "桨" => "Jiang", "æ¡©" => "Zhuang", "桪" => "Xun", "æ¡«" => "Suo", "桬" => "Sha", + "æ¡­" => "Zhen", "æ¡®" => "Bei", "桯" => "Ting", "æ¡°" => "Gua", "桱" => "Jing", "桲" => "Bo", + "桳" => "Ben", "æ¡´" => "Fu", "桵" => "Rui", "桶" => "Tong", "æ¡·" => "Jue", "桸" => "Xi", + "桹" => "Lang", "桺" => "Liu", "æ¡»" => "Feng", "桼" => "Qi", "桽" => "Wen", "桾" => "Jun", + "æ¡¿" => "Gan", "梀" => "Cu", "æ¢" => "Liang", "梂" => "Qiu", "梃" => "Ting", "梄" => "You", + "梅" => "Mei", "梆" => "Bang", "梇" => "Long", "梈" => "Peng", "梉" => "Zhuang", "梊" => "Di", + "梋" => "Xuan", "梌" => "Tu", "æ¢" => "Zao", "梎" => "Ao", "æ¢" => "Gu", "æ¢" => "Bi", + "梑" => "Di", "梒" => "Han", "梓" => "Zi", "梔" => "Zhi", "梕" => "Ren", "梖" => "Bei", + "梗" => "Geng", "梘" => "Jian", "梙" => "Huan", "梚" => "Wan", "梛" => "Nuo", "梜" => "Jia", + "æ¢" => "Tiao", "梞" => "Ji", "梟" => "Xiao", "梠" => "Lu", "梡" => "Huan", "梢" => "Shao", + "梣" => "Cen", "梤" => "Fen", "梥" => "Song", "梦" => "Meng", "梧" => "Wu", "梨" => "Li", + "梩" => "Li", "梪" => "Dou", "梫" => "Cen", "梬" => "Ying", "梭" => "Suo", "梮" => "Ju", + "梯" => "Ti", "械" => "Jie", "梱" => "Kun", "梲" => "Zhuo", "梳" => "Shu", "梴" => "Chan", + "梵" => "Fan", "梶" => "Wei", "梷" => "Jing", "梸" => "Li", "梹" => "Bing", "梺" => "Fumoto", + "梻" => "Shikimi", "梼" => "Tao", "梽" => "Zhi", "梾" => "Lai", "梿" => "Lian", "检" => "Jian", + "æ£" => "Zhuo", "棂" => "Ling", "棃" => "Li", "棄" => "Qi", "棅" => "Bing", "棆" => "Zhun", + "棇" => "Cong", "棈" => "Qian", "棉" => "Mian", "棊" => "Qi", "棋" => "Qi", "棌" => "Cai", + "æ£" => "Gun", "棎" => "Chan", "æ£" => "Te", "æ£" => "Fei", "棑" => "Pai", "棒" => "Bang", + "棓" => "Pou", "棔" => "Hun", "棕" => "Zong", "棖" => "Cheng", "棗" => "Zao", "棘" => "Ji", + "棙" => "Li", "棚" => "Peng", "棛" => "Yu", "棜" => "Yu", "æ£" => "Gu", "棞" => "Hun", + "棟" => "Dong", "棠" => "Tang", "棡" => "Gang", "棢" => "Wang", "棣" => "Di", "棤" => "Xi", + "棥" => "Fan", "棦" => "Cheng", "棧" => "Zhan", "棨" => "Qi", "棩" => "Yuan", "棪" => "Yan", + "棫" => "Yu", "棬" => "Quan", "棭" => "Yi", "森" => "Sen", "棯" => "Ren", "棰" => "Chui", + "棱" => "Leng", "棲" => "Qi", "棳" => "Zhuo", "棴" => "Fu", "棵" => "Ke", "棶" => "Lai", + "棷" => "Zou", "棸" => "Zou", "棹" => "Zhuo", "棺" => "Guan", "棻" => "Fen", "棼" => "Fen", + "棽" => "Chen", "棾" => "Qiong", "棿" => "Nie", "æ¤" => "Guo", "椂" => "Lu", "椃" => "Hao", + "椄" => "Jie", "椅" => "Yi", "椆" => "Chou", "椇" => "Ju", "椈" => "Ju", "椉" => "Cheng", + "椊" => "Zuo", "椋" => "Liang", "椌" => "Qiang", "æ¤" => "Zhi", "椎" => "Zhui", "æ¤" => "Ya", + "æ¤" => "Ju", "椑" => "Bei", "椒" => "Jiao", "椓" => "Zhuo", "椔" => "Zi", "椕" => "Bin", + "椖" => "Peng", "椗" => "Ding", "椘" => "Chu", "椙" => "Chang", "椚" => "Kunugi", "椛" => "Momiji", + "検" => "Jian", "æ¤" => "Gui", "椞" => "Xi", "椟" => "Du", "椠" => "Qian", "椡" => "Kunugi", + "椢" => "Soko", "椣" => "Shide", "椤" => "Luo", "椥" => "Zhi", "椦" => "Ken", "椧" => "Myeng", + "椨" => "Tafu", "椪" => "Peng", "椫" => "Zhan", "椭" => "Tuo", "椮" => "Sen", "椯" => "Duo", + "椰" => "Ye", "椱" => "Fou", "椲" => "Wei", "椳" => "Wei", "椴" => "Duan", "椵" => "Jia", + "椶" => "Zong", "椷" => "Jian", "椸" => "Yi", "椹" => "Shen", "椺" => "Xi", "椻" => "Yan", + "椼" => "Yan", "椽" => "Chuan", "椾" => "Zhan", "椿" => "Chun", "楀" => "Yu", "æ¥" => "He", + "楂" => "Zha", "楃" => "Wo", "楄" => "Pian", "楅" => "Bi", "楆" => "Yao", "楇" => "Huo", + "楈" => "Xu", "楉" => "Ruo", "楊" => "Yang", "楋" => "La", "楌" => "Yan", "æ¥" => "Ben", + "楎" => "Hun", "æ¥" => "Kui", "æ¥" => "Jie", "楑" => "Kui", "楒" => "Si", "楓" => "Feng", + "楔" => "Xie", "楕" => "Tuo", "楖" => "Zhi", "楗" => "Jian", "楘" => "Mu", "楙" => "Mao", + "楚" => "Chu", "楛" => "Hu", "楜" => "Hu", "æ¥" => "Lian", "楞" => "Leng", "楟" => "Ting", + "楠" => "Nan", "楡" => "Yu", "楢" => "You", "楣" => "Mei", "楤" => "Song", "楥" => "Xuan", + "楦" => "Xuan", "楧" => "Ying", "楨" => "Zhen", "楩" => "Pian", "楪" => "Ye", "楫" => "Ji", + "楬" => "Jie", "業" => "Ye", "楮" => "Chu", "楯" => "Shun", "楰" => "Yu", "楱" => "Cou", + "楲" => "Wei", "楳" => "Mei", "楴" => "Di", "極" => "Ji", "楶" => "Jie", "楷" => "Kai", + "楸" => "Qiu", "楹" => "Ying", "楺" => "Rou", "楻" => "Heng", "楼" => "Lou", "楽" => "Le", + "楾" => "Hazou", "楿" => "Katsura", "榀" => "Pin", "æ¦" => "Muro", "概" => "Gai", "榃" => "Tan", + "榄" => "Lan", "榅" => "Yun", "榆" => "Yu", "榇" => "Chen", "榈" => "Lu", "榉" => "Ju", + "榊" => "Sakaki", "榌" => "Pi", "æ¦" => "Xie", "榎" => "Jia", "æ¦" => "Yi", "æ¦" => "Zhan", + "榑" => "Fu", "榒" => "Nai", "榓" => "Mi", "榔" => "Lang", "榕" => "Rong", "榖" => "Gu", + "榗" => "Jian", "榘" => "Ju", "榙" => "Ta", "榚" => "Yao", "榛" => "Zhen", "榜" => "Bang", + "æ¦" => "Sha", "榞" => "Yuan", "榟" => "Zi", "榠" => "Ming", "榡" => "Su", "榢" => "Jia", + "榣" => "Yao", "榤" => "Jie", "榥" => "Huang", "榦" => "Gan", "榧" => "Fei", "榨" => "Zha", + "榩" => "Qian", "榪" => "Ma", "榫" => "Sun", "榬" => "Yuan", "榭" => "Xie", "榮" => "Rong", + "榯" => "Shi", "榰" => "Zhi", "榱" => "Cui", "榲" => "Yun", "榳" => "Ting", "榴" => "Liu", + "榵" => "Rong", "榶" => "Tang", "榷" => "Que", "榸" => "Zhai", "榹" => "Si", "榺" => "Sheng", + "榻" => "Ta", "榼" => "Ke", "榽" => "Xi", "榾" => "Gu", "榿" => "Qi", "槀" => "Kao", + "æ§" => "Gao", "槂" => "Sun", "槃" => "Pan", "槄" => "Tao", "槅" => "Ge", "槆" => "Xun", + "槇" => "Dian", "槈" => "Nou", "槉" => "Ji", "槊" => "Shuo", "構" => "Gou", "槌" => "Chui", + "æ§" => "Qiang", "槎" => "Cha", "æ§" => "Qian", "æ§" => "Huai", "槑" => "Mei", "槒" => "Xu", + "槓" => "Gang", "槔" => "Gao", "槕" => "Zhuo", "槖" => "Tuo", "槗" => "Hashi", "様" => "Yang", + "槙" => "Dian", "槚" => "Jia", "槛" => "Jian", "槜" => "Zui", "æ§" => "Kashi", "槞" => "Ori", + "槟" => "Bin", "槠" => "Zhu", "槢" => "Xi", "槣" => "Qi", "槤" => "Lian", "槥" => "Hui", + "槦" => "Yong", "槧" => "Qian", "槨" => "Guo", "槩" => "Gai", "槪" => "Gai", "槫" => "Tuan", + "槬" => "Hua", "槭" => "Cu", "槮" => "Sen", "槯" => "Cui", "槰" => "Beng", "槱" => "You", + "槲" => "Hu", "槳" => "Jiang", "槴" => "Hu", "槵" => "Huan", "槶" => "Kui", "槷" => "Yi", + "槸" => "Nie", "槹" => "Gao", "槺" => "Kang", "槻" => "Gui", "槼" => "Gui", "槽" => "Cao", + "槾" => "Man", "槿" => "Jin", "æ¨" => "Zhuang", "樂" => "Le", "樃" => "Lang", "樄" => "Chen", + "樅" => "Cong", "樆" => "Li", "樇" => "Xiu", "樈" => "Qing", "樉" => "Shuang", "樊" => "Fan", + "樋" => "Tong", "樌" => "Guan", "æ¨" => "Ji", "樎" => "Suo", "æ¨" => "Lei", "æ¨" => "Lu", + "樑" => "Liang", "樒" => "Mi", "樓" => "Lou", "樔" => "Chao", "樕" => "Su", "樖" => "Ke", + "樗" => "Shu", "樘" => "Tang", "標" => "Biao", "樚" => "Lu", "樛" => "Jiu", "樜" => "Shu", + "æ¨" => "Zha", "樞" => "Shu", "樟" => "Zhang", "樠" => "Men", "模" => "Mo", "樢" => "Niao", + "樣" => "Yang", "樤" => "Tiao", "樥" => "Peng", "樦" => "Zhu", "樧" => "Sha", "樨" => "Xi", + "権" => "Quan", "横" => "Heng", "樫" => "Jian", "樬" => "Cong", "樮" => "Hokuso", "樯" => "Qiang", + "樰" => "Tara", "樱" => "Ying", "樲" => "Er", "樳" => "Xin", "樴" => "Zhi", "樵" => "Qiao", + "樶" => "Zui", "樷" => "Cong", "樸" => "Pu", "樹" => "Shu", "樺" => "Hua", "樻" => "Kui", + "樼" => "Zhen", "樽" => "Zun", "樾" => "Yue", "樿" => "Zhan", "æ©€" => "Xi", "æ©" => "Xun", + "æ©‚" => "Dian", "橃" => "Fa", "æ©„" => "Gan", "æ©…" => "Mo", "橆" => "Wu", "橇" => "Qiao", + "橈" => "Nao", "橉" => "Lin", "æ©Š" => "Liu", "æ©‹" => "Qiao", "æ©Œ" => "Xian", "æ©" => "Run", + "æ©Ž" => "Fan", "æ©" => "Zhan", "æ©" => "Tuo", "æ©‘" => "Lao", "æ©’" => "Yun", "æ©“" => "Shun", + "æ©”" => "Tui", "æ©•" => "Cheng", "æ©–" => "Tang", "æ©—" => "Meng", "橘" => "Ju", "æ©™" => "Cheng", + "æ©š" => "Su", "æ©›" => "Jue", "æ©œ" => "Jue", "æ©" => "Tan", "æ©ž" => "Hui", "æ©Ÿ" => "Ji", + "æ© " => "Nuo", "æ©¡" => "Xiang", "æ©¢" => "Tuo", "æ©£" => "Ning", "橤" => "Rui", "æ©¥" => "Zhu", + "橦" => "Chuang", "橧" => "Zeng", "橨" => "Fen", "æ©©" => "Qiong", "橪" => "Ran", "æ©«" => "Heng", + "橬" => "Cen", "æ©­" => "Gu", "æ©®" => "Liu", "橯" => "Lao", "æ©°" => "Gao", "橱" => "Chu", + "橲" => "Zusa", "橳" => "Nude", "æ©´" => "Ca", "橵" => "San", "橶" => "Ji", "æ©·" => "Dou", + "橸" => "Shou", "橹" => "Lu", "橼" => "Yuan", "橽" => "Ta", "橾" => "Shu", "æ©¿" => "Jiang", + "檀" => "Tan", "æª" => "Lin", "檂" => "Nong", "檃" => "Yin", "檄" => "Xi", "檅" => "Sui", + "檆" => "Shan", "檇" => "Zui", "檈" => "Xuan", "檉" => "Cheng", "檊" => "Gan", "檋" => "Ju", + "檌" => "Zui", "æª" => "Yi", "檎" => "Qin", "æª" => "Pu", "æª" => "Yan", "檑" => "Lei", + "檒" => "Feng", "檓" => "Hui", "檔" => "Dang", "檕" => "Ji", "檖" => "Sui", "檗" => "Bo", + "檘" => "Bi", "檙" => "Ding", "檚" => "Chu", "檛" => "Zhua", "檜" => "Kuai", "æª" => "Ji", + "檞" => "Jie", "檟" => "Jia", "檠" => "Qing", "檡" => "Zhe", "檢" => "Jian", "檣" => "Qiang", + "檤" => "Dao", "檥" => "Yi", "檦" => "Biao", "檧" => "Song", "檨" => "She", "檩" => "Lin", + "檪" => "Kunugi", "檫" => "Cha", "檬" => "Meng", "檭" => "Yin", "檮" => "Tao", "檯" => "Tai", + "檰" => "Mian", "檱" => "Qi", "檲" => "Toan", "檳" => "Bin", "檴" => "Huo", "檵" => "Ji", + "檶" => "Qian", "檷" => "Mi", "檸" => "Ning", "檹" => "Yi", "檺" => "Gao", "檻" => "Jian", + "檼" => "Yin", "檽" => "Er", "檾" => "Qing", "檿" => "Yan", "æ«€" => "Qi", "æ«" => "Mi", + "æ«‚" => "Zhao", "櫃" => "Gui", "æ«„" => "Chun", "æ«…" => "Ji", "櫆" => "Kui", "櫇" => "Po", + "櫈" => "Deng", "櫉" => "Chu", "æ«‹" => "Mian", "æ«Œ" => "You", "æ«" => "Zhi", "æ«Ž" => "Guang", + "æ«" => "Qian", "æ«" => "Lei", "æ«‘" => "Lei", "æ«’" => "Sa", "æ«“" => "Lu", "æ«”" => "Li", + "æ«•" => "Cuan", "æ«–" => "Lu", "æ«—" => "Mie", "櫘" => "Hui", "æ«™" => "Ou", "æ«š" => "Lu", + "æ«›" => "Jie", "æ«œ" => "Gao", "æ«" => "Du", "æ«ž" => "Yuan", "æ«Ÿ" => "Li", "æ« " => "Fei", + "æ«¡" => "Zhuo", "æ«¢" => "Sou", "æ«£" => "Lian", "櫤" => "Tamo", "æ«¥" => "Chu", "櫧" => "Zhu", + "櫨" => "Lu", "æ«©" => "Yan", "櫪" => "Li", "æ««" => "Zhu", "櫬" => "Chen", "æ«­" => "Jie", + "æ«®" => "E", "櫯" => "Su", "æ«°" => "Huai", "櫱" => "Nie", "櫲" => "Yu", "櫳" => "Long", + "æ«´" => "Lai", "櫶" => "Xian", "æ«·" => "Kwi", "櫸" => "Ju", "櫹" => "Xiao", "櫺" => "Ling", + "æ«»" => "Ying", "櫼" => "Jian", "櫽" => "Yin", "櫾" => "You", "æ«¿" => "Ying", "æ¬" => "Nong", + "欂" => "Bo", "欃" => "Chan", "欄" => "Lan", "欅" => "Ju", "欆" => "Shuang", "欇" => "She", + "欈" => "Wei", "欉" => "Cong", "權" => "Quan", "欋" => "Qu", "欌" => "Cang", "欎" => "Yu", + "æ¬" => "Luo", "æ¬" => "Li", "欑" => "Zan", "欒" => "Luan", "欓" => "Dang", "欔" => "Jue", + "欕" => "Em", "欖" => "Lan", "欗" => "Lan", "欘" => "Zhu", "欙" => "Lei", "欚" => "Li", + "欛" => "Ba", "欜" => "Nang", "æ¬" => "Yu", "欞" => "Ling", "欟" => "Tsuki", "欠" => "Qian", + "次" => "Ci", "欢" => "Huan", "欣" => "Xin", "欤" => "Yu", "欥" => "Yu", "欦" => "Qian", + "欧" => "Ou", "欨" => "Xu", "欩" => "Chao", "欪" => "Chu", "欫" => "Chi", "欬" => "Kai", + "欭" => "Yi", "欮" => "Jue", "欯" => "Xi", "欰" => "Xu", "欱" => "Xia", "欲" => "Yu", + "欳" => "Kuai", "欴" => "Lang", "欵" => "Kuan", "欶" => "Shuo", "欷" => "Xi", "欸" => "Ai", + "欹" => "Yi", "欺" => "Qi", "欻" => "Hu", "欼" => "Chi", "欽" => "Qin", "款" => "Kuan", + "欿" => "Kan", "æ­€" => "Kuan", "æ­" => "Kan", "æ­‚" => "Chuan", "æ­ƒ" => "Sha", "æ­„" => "Gua", + "æ­…" => "Yin", "æ­†" => "Xin", "æ­‡" => "Xie", "æ­ˆ" => "Yu", "æ­‰" => "Qian", "æ­Š" => "Xiao", + "æ­‹" => "Yi", "æ­Œ" => "Ge", "æ­" => "Wu", "æ­Ž" => "Tan", "æ­" => "Jin", "æ­" => "Ou", + "æ­‘" => "Hu", "æ­’" => "Ti", "æ­“" => "Huan", "æ­”" => "Xu", "æ­•" => "Pen", "æ­–" => "Xi", + "æ­—" => "Xiao", "æ­˜" => "Xu", "æ­™" => "Xi", "æ­š" => "Sen", "æ­›" => "Lian", "æ­œ" => "Chu", + "æ­" => "Yi", "æ­ž" => "Kan", "æ­Ÿ" => "Yu", "æ­ " => "Chuo", "æ­¡" => "Huan", "æ­¢" => "Zhi", + "æ­£" => "Zheng", "æ­¤" => "Ci", "æ­¥" => "Bu", "æ­¦" => "Wu", "æ­§" => "Qi", "æ­¨" => "Bu", + "æ­©" => "Bu", "æ­ª" => "Wai", "æ­«" => "Ju", "æ­¬" => "Qian", "æ­­" => "Chi", "æ­®" => "Se", + "æ­¯" => "Chi", "æ­°" => "Se", "æ­±" => "Zhong", "æ­²" => "Sui", "æ­³" => "Sui", "æ­´" => "Li", + "æ­µ" => "Cuo", "æ­¶" => "Yu", "æ­·" => "Li", "æ­¸" => "Gui", "æ­¹" => "Dai", "æ­º" => "Dai", + "æ­»" => "Si", "æ­¼" => "Jian", "æ­½" => "Zhe", "æ­¾" => "Mo", "æ­¿" => "Mo", "殀" => "Yao", + "æ®" => "Mo", "殂" => "Cu", "殃" => "Yang", "殄" => "Tian", "æ®…" => "Sheng", "殆" => "Dai", + "殇" => "Shang", "殈" => "Xu", "殉" => "Xun", "殊" => "Shu", "残" => "Can", "殌" => "Jue", + "æ®" => "Piao", "殎" => "Qia", "æ®" => "Qiu", "æ®" => "Su", "殑" => "Qing", "æ®’" => "Yun", + "殓" => "Lian", "æ®”" => "Yi", "殕" => "Fou", "æ®–" => "Zhi", "æ®—" => "Ye", "殘" => "Can", + "æ®™" => "Hun", "殚" => "Dan", "æ®›" => "Ji", "殜" => "Ye", "æ®" => "Zhen", "殞" => "Yun", + "殟" => "Wen", "æ® " => "Chou", "殡" => "Bin", "殢" => "Ti", "殣" => "Jin", "殤" => "Shang", + "殥" => "Yin", "殦" => "Diao", "殧" => "Cu", "殨" => "Hui", "殩" => "Cuan", "殪" => "Yi", + "殫" => "Dan", "殬" => "Du", "æ®­" => "Jiang", "æ®®" => "Lian", "殯" => "Bin", "æ®°" => "Du", + "æ®±" => "Tsukusu", "殲" => "Jian", "殳" => "Shu", "æ®´" => "Ou", "段" => "Duan", "殶" => "Zhu", + "æ®·" => "Yin", "殸" => "Qing", "殹" => "Yi", "殺" => "Sha", "æ®»" => "Que", "殼" => "Ke", + "殽" => "Yao", "殾" => "Jun", "殿" => "Dian", "毀" => "Hui", "æ¯" => "Hui", "毂" => "Gu", + "毃" => "Que", "毄" => "Ji", "毅" => "Yi", "毆" => "Ou", "毇" => "Hui", "毈" => "Duan", + "毉" => "Yi", "毊" => "Xiao", "毋" => "Wu", "毌" => "Guan", "æ¯" => "Mu", "毎" => "Mei", + "æ¯" => "Mei", "æ¯" => "Ai", "毑" => "Zuo", "毒" => "Du", "毓" => "Yu", "比" => "Bi", + "毕" => "Bi", "毖" => "Bi", "毗" => "Pi", "毘" => "Pi", "毙" => "Bi", "毚" => "Chan", + "毛" => "Mao", "毞" => "Pu", "毟" => "Mushiru", "毠" => "Jia", "毡" => "Zhan", "毢" => "Sai", + "毣" => "Mu", "毤" => "Tuo", "毥" => "Xun", "毦" => "Er", "毧" => "Rong", "毨" => "Xian", + "毩" => "Ju", "毪" => "Mu", "毫" => "Hao", "毬" => "Qiu", "毭" => "Dou", "毮" => "Mushiru", + "毯" => "Tan", "毰" => "Pei", "毱" => "Ju", "毲" => "Duo", "毳" => "Cui", "毴" => "Bi", + "毵" => "San", "毷" => "Mao", "毸" => "Sui", "毹" => "Yu", "毺" => "Yu", "毻" => "Tuo", + "毼" => "He", "毽" => "Jian", "毾" => "Ta", "毿" => "San", "æ°" => "Mu", "æ°‚" => "Li", + "æ°ƒ" => "Tong", "æ°„" => "Rong", "æ°…" => "Chang", "æ°†" => "Pu", "æ°‡" => "Luo", "æ°ˆ" => "Zhan", + "æ°‰" => "Sao", "æ°Š" => "Zhan", "æ°‹" => "Meng", "æ°Œ" => "Luo", "æ°" => "Qu", "æ°Ž" => "Die", + "æ°" => "Shi", "æ°" => "Di", "æ°‘" => "Min", "æ°’" => "Jue", "æ°“" => "Mang", "æ°”" => "Qi", + "æ°•" => "Pie", "æ°–" => "Nai", "æ°—" => "Qi", "æ°˜" => "Dao", "æ°™" => "Xian", "æ°š" => "Chuan", + "æ°›" => "Fen", "æ°œ" => "Ri", "æ°" => "Nei", "æ°Ÿ" => "Fu", "æ° " => "Shen", "æ°¡" => "Dong", + "æ°¢" => "Qing", "æ°£" => "Qi", "æ°¤" => "Yin", "æ°¥" => "Xi", "æ°¦" => "Hai", "æ°§" => "Yang", + "æ°¨" => "An", "æ°©" => "Ya", "æ°ª" => "Ke", "æ°«" => "Qing", "æ°¬" => "Ya", "æ°­" => "Dong", + "æ°®" => "Dan", "æ°¯" => "Lu", "æ°°" => "Qing", "æ°±" => "Yang", "æ°²" => "Yun", "æ°³" => "Yun", + "æ°´" => "Shui", "æ°µ" => "San", "æ°¶" => "Zheng", "æ°·" => "Bing", "æ°¸" => "Yong", "æ°¹" => "Dang", + "æ°º" => "Shitamizu", "æ°»" => "Le", "æ°¼" => "Ni", "æ°½" => "Tun", "æ°¾" => "Fan", "æ°¿" => "Gui", + "æ±€" => "Ting", "æ±" => "Zhi", "求" => "Qiu", "汃" => "Bin", "汄" => "Ze", "æ±…" => "Mian", + "汆" => "Cuan", "汇" => "Hui", "汈" => "Diao", "汉" => "Yi", "汊" => "Cha", "汋" => "Zhuo", + "汌" => "Chuan", "æ±" => "Wan", "汎" => "Fan", "æ±" => "Dai", "æ±" => "Xi", "汑" => "Tuo", + "æ±’" => "Mang", "汓" => "Qiu", "æ±”" => "Qi", "汕" => "Shan", "æ±–" => "Pai", "æ±—" => "Han", + "汘" => "Qian", "æ±™" => "Wu", "汚" => "Wu", "æ±›" => "Xun", "汜" => "Si", "æ±" => "Ru", + "汞" => "Gong", "江" => "Jiang", "æ± " => "Chi", "污" => "Wu", "æ±¢" => "Tsuchi", "汤" => "Tang", + "æ±¥" => "Zhi", "汦" => "Chi", "汧" => "Qian", "汨" => "Mi", "汩" => "Yu", "汪" => "Wang", + "汫" => "Qing", "汬" => "Jing", "æ±­" => "Rui", "æ±®" => "Jun", "汯" => "Hong", "æ±°" => "Tai", + "æ±±" => "Quan", "æ±²" => "Ji", "æ±³" => "Bian", "æ±´" => "Bian", "æ±µ" => "Gan", "汶" => "Wen", + "æ±·" => "Zhong", "汸" => "Fang", "æ±¹" => "Xiong", "決" => "Jue", "æ±»" => "Hang", "æ±¼" => "Niou", + "æ±½" => "Qi", "æ±¾" => "Fen", "汿" => "Xu", "æ²€" => "Xu", "æ²" => "Qin", "沂" => "Yi", + "沃" => "Wo", "沄" => "Yun", "æ²…" => "Yuan", "沆" => "Hang", "沇" => "Yan", "沈" => "Chen", + "沉" => "Chen", "沊" => "Dan", "沋" => "You", "沌" => "Dun", "æ²" => "Hu", "沎" => "Huo", + "æ²" => "Qie", "æ²" => "Mu", "沑" => "Rou", "æ²’" => "Mei", "沓" => "Ta", "æ²”" => "Mian", + "沕" => "Wu", "æ²–" => "Chong", "æ²—" => "Tian", "沘" => "Bi", "æ²™" => "Sha", "沚" => "Zhi", + "æ²›" => "Pei", "沜" => "Pan", "æ²" => "Zhui", "沞" => "Za", "沟" => "Gou", "æ² " => "Liu", + "没" => "Mei", "æ²¢" => "Ze", "æ²£" => "Feng", "沤" => "Ou", "æ²¥" => "Li", "沦" => "Lun", + "沧" => "Cang", "沨" => "Feng", "沩" => "Wei", "沪" => "Hu", "沫" => "Mo", "沬" => "Mei", + "æ²­" => "Shu", "æ²®" => "Ju", "沯" => "Zan", "æ²°" => "Tuo", "æ²±" => "Tuo", "æ²²" => "Tuo", + "æ²³" => "He", "æ²´" => "Li", "æ²µ" => "Mi", "沶" => "Yi", "æ²·" => "Fa", "沸" => "Fei", + "æ²¹" => "You", "沺" => "Tian", "æ²»" => "Zhi", "æ²¼" => "Zhao", "æ²½" => "Gu", "æ²¾" => "Zhan", + "沿" => "Yan", "æ³€" => "Si", "æ³" => "Kuang", "泂" => "Jiong", "泃" => "Ju", "泄" => "Xie", + "æ³…" => "Qiu", "泆" => "Yi", "泇" => "Jia", "泈" => "Zhong", "泉" => "Quan", "泊" => "Bo", + "泋" => "Hui", "泌" => "Mi", "æ³" => "Ben", "泎" => "Zhuo", "æ³" => "Chu", "æ³" => "Le", + "泑" => "You", "æ³’" => "Gu", "泓" => "Hong", "æ³”" => "Gan", "法" => "Fa", "æ³–" => "Mao", + "æ³—" => "Si", "泘" => "Hu", "æ³™" => "Ping", "泚" => "Ci", "æ³›" => "Fan", "泜" => "Chi", + "æ³" => "Su", "泞" => "Ning", "泟" => "Cheng", "æ³ " => "Ling", "泡" => "Pao", "æ³¢" => "Bo", + "æ³£" => "Qi", "泤" => "Si", "æ³¥" => "Ni", "泦" => "Ju", "泧" => "Yue", "注" => "Zhu", + "泩" => "Sheng", "泪" => "Lei", "泫" => "Xuan", "泬" => "Xue", "æ³­" => "Fu", "æ³®" => "Pan", + "泯" => "Min", "æ³°" => "Tai", "æ³±" => "Yang", "æ³²" => "Ji", "æ³³" => "Yong", "æ³´" => "Guan", + "æ³µ" => "Beng", "泶" => "Xue", "æ³·" => "Long", "泸" => "Lu", "泺" => "Bo", "æ³»" => "Xie", + "æ³¼" => "Po", "æ³½" => "Ze", "æ³¾" => "Jing", "泿" => "Yin", "æ´" => "Ji", "æ´‚" => "Yi", + "æ´ƒ" => "Hui", "æ´„" => "Hui", "æ´…" => "Zui", "æ´†" => "Cheng", "æ´‡" => "Yin", "æ´ˆ" => "Wei", + "æ´‰" => "Hou", "æ´Š" => "Jian", "æ´‹" => "Yang", "æ´Œ" => "Lie", "æ´" => "Si", "æ´Ž" => "Ji", + "æ´" => "Er", "æ´" => "Xing", "æ´‘" => "Fu", "æ´’" => "Sa", "æ´“" => "Suo", "æ´”" => "Zhi", + "æ´•" => "Yin", "æ´–" => "Wu", "æ´—" => "Xi", "æ´˜" => "Kao", "æ´™" => "Zhu", "æ´š" => "Jiang", + "æ´›" => "Luo", "æ´" => "An", "æ´ž" => "Dong", "æ´Ÿ" => "Yi", "æ´ " => "Mou", "æ´¡" => "Lei", + "æ´¢" => "Yi", "æ´£" => "Mi", "æ´¤" => "Quan", "æ´¥" => "Jin", "æ´¦" => "Mo", "æ´§" => "Wei", + "æ´¨" => "Xiao", "æ´©" => "Xie", "æ´ª" => "Hong", "æ´«" => "Xu", "æ´¬" => "Shuo", "æ´­" => "Kuang", + "æ´®" => "Tao", "æ´¯" => "Qie", "æ´°" => "Ju", "æ´±" => "Er", "æ´²" => "Zhou", "æ´³" => "Ru", + "æ´´" => "Ping", "æ´µ" => "Xun", "æ´¶" => "Xiong", "æ´·" => "Zhi", "æ´¸" => "Guang", "æ´¹" => "Huan", + "æ´º" => "Ming", "æ´»" => "Huo", "æ´¼" => "Wa", "æ´½" => "Qia", "æ´¾" => "Pai", "æ´¿" => "Wu", + "æµ€" => "Qu", "æµ" => "Liu", "浂" => "Yi", "浃" => "Jia", "浄" => "Jing", "æµ…" => "Qian", + "浆" => "Jiang", "浇" => "Jiao", "浈" => "Cheng", "浉" => "Shi", "浊" => "Zhuo", "测" => "Ce", + "浌" => "Pal", "æµ" => "Kuai", "济" => "Ji", "æµ" => "Liu", "æµ" => "Chan", "浑" => "Hun", + "æµ’" => "Hu", "浓" => "Nong", "æµ”" => "Xun", "浕" => "Jin", "æµ–" => "Lie", "æµ—" => "Qiu", + "浘" => "Wei", "æµ™" => "Zhe", "浚" => "Jun", "æµ›" => "Han", "浜" => "Bang", "æµ" => "Mang", + "浞" => "Zhuo", "浟" => "You", "æµ " => "Xi", "浡" => "Bo", "æµ¢" => "Dou", "æµ£" => "Wan", + "浤" => "Hong", "æµ¥" => "Yi", "浦" => "Pu", "浧" => "Ying", "浨" => "Lan", "浩" => "Hao", + "浪" => "Lang", "浫" => "Han", "浬" => "Li", "æµ­" => "Geng", "æµ®" => "Fu", "浯" => "Wu", + "æµ°" => "Lian", "æµ±" => "Chun", "æµ²" => "Feng", "æµ³" => "Yi", "æµ´" => "Yu", "æµµ" => "Tong", + "浶" => "Lao", "æµ·" => "Hai", "浸" => "Jin", "æµ¹" => "Jia", "浺" => "Chong", "æµ»" => "Weng", + "æµ¼" => "Mei", "æµ½" => "Sui", "æµ¾" => "Cheng", "浿" => "Pei", "涀" => "Xian", "æ¶" => "Shen", + "涂" => "Tu", "涃" => "Kun", "涄" => "Pin", "涅" => "Nie", "涆" => "Han", "涇" => "Jing", + "消" => "Xiao", "涉" => "She", "涊" => "Nian", "涋" => "Tu", "涌" => "Yong", "æ¶" => "Xiao", + "涎" => "Xian", "æ¶" => "Ting", "æ¶" => "E", "涑" => "Su", "涒" => "Tun", "涓" => "Juan", + "涔" => "Cen", "涕" => "Ti", "涖" => "Li", "涗" => "Shui", "涘" => "Si", "涙" => "Lei", + "涚" => "Shui", "涛" => "Tao", "涜" => "Du", "æ¶" => "Lao", "涞" => "Lai", "涟" => "Lian", + "涠" => "Wei", "涡" => "Wo", "涢" => "Yun", "涣" => "Huan", "涤" => "Di", "润" => "Run", + "涧" => "Jian", "涨" => "Zhang", "涩" => "Se", "涪" => "Fu", "涫" => "Guan", "涬" => "Xing", + "涭" => "Shou", "涮" => "Shuan", "涯" => "Ya", "涰" => "Chuo", "涱" => "Zhang", "液" => "Ye", + "涳" => "Kong", "涴" => "Wo", "涵" => "Han", "涶" => "Tuo", "涷" => "Dong", "涸" => "He", + "涹" => "Wo", "涺" => "Ju", "涻" => "Gan", "涼" => "Liang", "涽" => "Hun", "涾" => "Ta", + "涿" => "Zhuo", "æ·€" => "Dian", "æ·" => "Qie", "æ·‚" => "De", "æ·ƒ" => "Juan", "æ·„" => "Zi", + "æ·…" => "Xi", "æ·†" => "Yao", "æ·‡" => "Qi", "æ·ˆ" => "Gu", "æ·‰" => "Guo", "æ·Š" => "Han", + "æ·‹" => "Lin", "æ·Œ" => "Tang", "æ·" => "Zhou", "æ·Ž" => "Peng", "æ·" => "Hao", "æ·" => "Chang", + "æ·‘" => "Shu", "æ·’" => "Qi", "æ·“" => "Fang", "æ·”" => "Chi", "æ·•" => "Lu", "æ·–" => "Nao", + "æ·—" => "Ju", "æ·˜" => "Tao", "æ·™" => "Cong", "æ·š" => "Lei", "æ·›" => "Zhi", "æ·œ" => "Peng", + "æ·" => "Fei", "æ·ž" => "Song", "æ·Ÿ" => "Tian", "æ· " => "Pi", "æ·¡" => "Dan", "æ·¢" => "Yu", + "æ·£" => "Ni", "æ·¤" => "Yu", "æ·¥" => "Lu", "æ·¦" => "Gan", "æ·§" => "Mi", "æ·¨" => "Jing", + "æ·©" => "Ling", "æ·ª" => "Lun", "æ·«" => "Yin", "æ·¬" => "Cui", "æ·­" => "Qu", "æ·®" => "Huai", + "æ·¯" => "Yu", "æ·°" => "Nian", "æ·±" => "Shen", "æ·²" => "Piao", "æ·³" => "Chun", "æ·´" => "Wa", + "æ·µ" => "Yuan", "æ·¶" => "Lai", "æ··" => "Hun", "æ·¸" => "Qing", "æ·¹" => "Yan", "æ·º" => "Qian", + "æ·»" => "Tian", "æ·¼" => "Miao", "æ·½" => "Zhi", "æ·¾" => "Yin", "æ·¿" => "Mi", "æ¸" => "Yuan", + "渂" => "Wen", "渃" => "Re", "渄" => "Fei", "清" => "Qing", "渆" => "Yuan", "渇" => "Ke", + "済" => "Ji", "渉" => "She", "渊" => "Yuan", "渋" => "Shibui", "渌" => "Lu", "æ¸" => "Zi", + "渎" => "Du", "æ¸" => "Jian", "渑" => "Min", "渒" => "Pi", "渓" => "Tani", "渔" => "Yu", + "渕" => "Yuan", "渖" => "Shen", "渗" => "Shen", "渘" => "Rou", "渙" => "Huan", "渚" => "Zhu", + "減" => "Jian", "渜" => "Nuan", "æ¸" => "Yu", "渞" => "Qiu", "渟" => "Ting", "渠" => "Qu", + "渡" => "Du", "渢" => "Feng", "渣" => "Zha", "渤" => "Bo", "渥" => "Wo", "渦" => "Wo", + "渧" => "Di", "渨" => "Wei", "温" => "Wen", "渪" => "Ru", "渫" => "Xie", "測" => "Ce", + "渭" => "Wei", "渮" => "Ge", "港" => "Gang", "渰" => "Yan", "渱" => "Hong", "渲" => "Xuan", + "渳" => "Mi", "渴" => "Ke", "渵" => "Mao", "渶" => "Ying", "渷" => "Yan", "游" => "You", + "渹" => "Hong", "渺" => "Miao", "渻" => "Xing", "渼" => "Mei", "渽" => "Zai", "渾" => "Hun", + "渿" => "Nai", "æ¹€" => "Kui", "æ¹" => "Shi", "湂" => "E", "湃" => "Pai", "湄" => "Mei", + "æ¹…" => "Lian", "湆" => "Qi", "湇" => "Qi", "湈" => "Mei", "湉" => "Tian", "湊" => "Cou", + "湋" => "Wei", "湌" => "Can", "æ¹" => "Tuan", "湎" => "Mian", "æ¹" => "Hui", "æ¹" => "Mo", + "湑" => "Xu", "æ¹’" => "Ji", "湓" => "Pen", "æ¹”" => "Jian", "湕" => "Jian", "æ¹–" => "Hu", + "æ¹—" => "Feng", "湘" => "Xiang", "æ¹™" => "Yi", "湚" => "Yin", "æ¹›" => "Zhan", "湜" => "Shi", + "æ¹" => "Jie", "湞" => "Cheng", "湟" => "Huang", "æ¹ " => "Tan", "湡" => "Yu", "æ¹¢" => "Bi", + "æ¹£" => "Min", "湤" => "Shi", "æ¹¥" => "Tu", "湦" => "Sheng", "湧" => "Yong", "湨" => "Qu", + "湩" => "Zhong", "湪" => "Suei", "湫" => "Jiu", "湬" => "Jiao", "æ¹­" => "Qiou", "æ¹®" => "Yin", + "湯" => "Tang", "æ¹°" => "Long", "æ¹±" => "Huo", "æ¹²" => "Yuan", "æ¹³" => "Nan", "æ¹´" => "Ban", + "æ¹µ" => "You", "湶" => "Quan", "æ¹·" => "Chui", "湸" => "Liang", "æ¹¹" => "Chan", "湺" => "Yan", + "æ¹»" => "Chun", "æ¹¼" => "Nie", "æ¹½" => "Zi", "æ¹¾" => "Wan", "湿" => "Shi", "満" => "Man", + "æº" => "Ying", "溂" => "Ratsu", "溃" => "Kui", "溅" => "Jian", "溆" => "Xu", "溇" => "Lu", + "溈" => "Gui", "溉" => "Gai", "溌" => "Po", "æº" => "Jin", "溎" => "Gui", "æº" => "Tang", + "æº" => "Yuan", "溑" => "Suo", "溒" => "Yuan", "溓" => "Lian", "溔" => "Yao", "溕" => "Meng", + "準" => "Zhun", "溗" => "Sheng", "溘" => "Ke", "溙" => "Tai", "溚" => "Da", "溛" => "Wa", + "溜" => "Liu", "æº" => "Gou", "溞" => "Sao", "溟" => "Ming", "溠" => "Zha", "溡" => "Shi", + "溢" => "Yi", "溣" => "Lun", "溤" => "Ma", "溥" => "Pu", "溦" => "Wei", "溧" => "Li", + "溨" => "Cai", "溩" => "Wu", "溪" => "Xi", "溫" => "Wen", "溬" => "Qiang", "溭" => "Ze", + "溮" => "Shi", "溯" => "Su", "溰" => "Yi", "溱" => "Zhen", "溲" => "Sou", "溳" => "Yun", + "溴" => "Xiu", "溵" => "Yin", "溶" => "Rong", "溷" => "Hun", "溸" => "Su", "溹" => "Su", + "溺" => "Ni", "溻" => "Ta", "溼" => "Shi", "溽" => "Ru", "溾" => "Wei", "溿" => "Pan", + "滀" => "Chu", "æ»" => "Chu", "滂" => "Pang", "滃" => "Weng", "滄" => "Cang", "æ»…" => "Mie", + "滆" => "He", "滇" => "Dian", "滈" => "Hao", "滉" => "Huang", "滊" => "Xi", "滋" => "Zi", + "滌" => "Di", "æ»" => "Zhi", "滎" => "Ying", "æ»" => "Fu", "æ»" => "Jie", "滑" => "Hua", + "æ»’" => "Ge", "滓" => "Zi", "æ»”" => "Tao", "滕" => "Teng", "æ»–" => "Sui", "æ»—" => "Bi", + "滘" => "Jiao", "æ»™" => "Hui", "滚" => "Gun", "æ»›" => "Yin", "滜" => "Gao", "æ»" => "Long", + "滞" => "Zhi", "滟" => "Yan", "æ» " => "She", "满" => "Man", "滢" => "Ying", "滣" => "Chun", + "滤" => "Lu", "滥" => "Lan", "滦" => "Luan", "滨" => "Bin", "滩" => "Tan", "滪" => "Yu", + "滫" => "Sou", "滬" => "Hu", "æ»­" => "Bi", "æ»®" => "Biao", "滯" => "Zhi", "æ»°" => "Jiang", + "æ»±" => "Kou", "滲" => "Shen", "滳" => "Shang", "æ»´" => "Di", "滵" => "Mi", "滶" => "Ao", + "æ»·" => "Lu", "滸" => "Hu", "滹" => "Hu", "滺" => "You", "æ»»" => "Chan", "滼" => "Fan", + "滽" => "Yong", "滾" => "Gun", "滿" => "Man", "æ¼" => "Yu", "漂" => "Piao", "漃" => "Ji", + "漄" => "Ya", "æ¼…" => "Jiao", "漆" => "Qi", "漇" => "Xi", "漈" => "Ji", "漉" => "Lu", + "漊" => "Lu", "漋" => "Long", "漌" => "Jin", "æ¼" => "Guo", "漎" => "Cong", "æ¼" => "Lou", + "æ¼" => "Zhi", "漑" => "Gai", "æ¼’" => "Qiang", "漓" => "Li", "æ¼”" => "Yan", "漕" => "Cao", + "æ¼–" => "Jiao", "æ¼—" => "Cong", "漘" => "Qun", "æ¼™" => "Tuan", "漚" => "Ou", "æ¼›" => "Teng", + "漜" => "Ye", "æ¼" => "Xi", "漞" => "Mi", "漟" => "Tang", "æ¼ " => "Mo", "漡" => "Shang", + "æ¼¢" => "Han", "æ¼£" => "Lian", "漤" => "Lan", "æ¼¥" => "Wa", "漦" => "Li", "漧" => "Qian", + "漨" => "Feng", "漩" => "Xuan", "漪" => "Yi", "漫" => "Man", "漬" => "Zi", "æ¼­" => "Mang", + "æ¼®" => "Kang", "漯" => "Lei", "æ¼°" => "Peng", "æ¼±" => "Shu", "æ¼²" => "Zhang", "æ¼³" => "Zhang", + "æ¼´" => "Chong", "æ¼µ" => "Xu", "漶" => "Huan", "æ¼·" => "Kuo", "漸" => "Jian", "æ¼¹" => "Yan", + "漺" => "Chuang", "æ¼»" => "Liao", "æ¼¼" => "Cui", "æ¼½" => "Ti", "æ¼¾" => "Yang", "漿" => "Jiang", + "æ½€" => "Cong", "æ½" => "Ying", "潂" => "Hong", "潃" => "Xun", "潄" => "Shu", "æ½…" => "Guan", + "潆" => "Ying", "潇" => "Xiao", "潊" => "Xu", "潋" => "Lian", "潌" => "Zhi", "æ½" => "Wei", + "潎" => "Pi", "æ½" => "Jue", "æ½" => "Jiao", "潑" => "Po", "æ½’" => "Dang", "潓" => "Hui", + "æ½”" => "Jie", "潕" => "Wu", "æ½–" => "Pa", "æ½—" => "Ji", "潘" => "Pan", "æ½™" => "Gui", + "潚" => "Xiao", "æ½›" => "Qian", "潜" => "Qian", "æ½" => "Xi", "潞" => "Lu", "潟" => "Xi", + "æ½ " => "Xuan", "潡" => "Dun", "æ½¢" => "Huang", "æ½£" => "Min", "潤" => "Run", "æ½¥" => "Su", + "潦" => "Liao", "潧" => "Zhen", "潨" => "Zhong", "潩" => "Yi", "潪" => "Di", "潫" => "Wan", + "潬" => "Dan", "æ½­" => "Tan", "æ½®" => "Chao", "潯" => "Xun", "æ½°" => "Kui", "æ½±" => "Yie", + "æ½²" => "Shao", "æ½³" => "Tu", "æ½´" => "Zhu", "æ½µ" => "San", "潶" => "Hei", "æ½·" => "Bi", + "潸" => "Shan", "æ½¹" => "Chan", "潺" => "Chan", "æ½»" => "Shu", "æ½¼" => "Tong", "æ½½" => "Pu", + "æ½¾" => "Lin", "潿" => "Wei", "æ¾€" => "Se", "æ¾" => "Se", "澂" => "Cheng", "澃" => "Jiong", + "澄" => "Cheng", "æ¾…" => "Hua", "澆" => "Jiao", "澇" => "Lao", "澈" => "Che", "澉" => "Gan", + "澊" => "Cun", "澋" => "Heng", "澌" => "Si", "æ¾" => "Shu", "澎" => "Peng", "æ¾" => "Han", + "æ¾" => "Yun", "澑" => "Liu", "æ¾’" => "Hong", "澓" => "Fu", "æ¾”" => "Hao", "澕" => "He", + "æ¾–" => "Xian", "æ¾—" => "Jian", "澘" => "Shan", "æ¾™" => "Xi", "澚" => "Oki", "澜" => "Lan", + "澞" => "Yu", "澟" => "Lin", "æ¾ " => "Min", "澡" => "Zao", "æ¾¢" => "Dang", "æ¾£" => "Wan", + "澤" => "Ze", "æ¾¥" => "Xie", "澦" => "Yu", "澧" => "Li", "澨" => "Shi", "澩" => "Xue", + "澪" => "Ling", "澫" => "Man", "澬" => "Zi", "æ¾­" => "Yong", "æ¾®" => "Kuai", "澯" => "Can", + "æ¾°" => "Lian", "æ¾±" => "Dian", "æ¾²" => "Ye", "æ¾³" => "Ao", "æ¾´" => "Huan", "æ¾µ" => "Zhen", + "澶" => "Chan", "æ¾·" => "Man", "澸" => "Dan", "æ¾¹" => "Dan", "澺" => "Yi", "æ¾»" => "Sui", + "æ¾¼" => "Pi", "æ¾½" => "Ju", "æ¾¾" => "Ta", "澿" => "Qin", "æ¿€" => "Ji", "æ¿" => "Zhuo", + "æ¿‚" => "Lian", "濃" => "Nong", "æ¿„" => "Guo", "æ¿…" => "Jin", "濆" => "Fen", "濇" => "Se", + "濈" => "Ji", "濉" => "Sui", "æ¿Š" => "Hui", "æ¿‹" => "Chu", "æ¿Œ" => "Ta", "æ¿" => "Song", + "æ¿Ž" => "Ding", "æ¿" => "Zhu", "æ¿‘" => "Lai", "æ¿’" => "Bin", "æ¿“" => "Lian", "æ¿”" => "Mi", + "æ¿•" => "Shi", "æ¿–" => "Shu", "æ¿—" => "Mi", "濘" => "Ning", "æ¿™" => "Ying", "æ¿š" => "Ying", + "æ¿›" => "Meng", "æ¿œ" => "Jin", "æ¿" => "Qi", "æ¿ž" => "Pi", "æ¿Ÿ" => "Ji", "æ¿ " => "Hao", + "æ¿¡" => "Ru", "æ¿¢" => "Zui", "æ¿£" => "Wo", "濤" => "Tao", "æ¿¥" => "Yin", "濦" => "Yin", + "濧" => "Dui", "濨" => "Ci", "æ¿©" => "Huo", "濪" => "Jing", "æ¿«" => "Lan", "濬" => "Jun", + "æ¿­" => "Ai", "æ¿®" => "Pu", "濯" => "Zhuo", "æ¿°" => "Wei", "濱" => "Bin", "濲" => "Gu", + "濳" => "Qian", "æ¿´" => "Xing", "濵" => "Hama", "濶" => "Kuo", "æ¿·" => "Fei", "濹" => "Boku", + "濺" => "Jian", "æ¿»" => "Wei", "濼" => "Luo", "濽" => "Zan", "濾" => "Lu", "æ¿¿" => "Li", + "ç€" => "Yang", "瀂" => "Lu", "瀃" => "Si", "瀄" => "Jie", "瀅" => "Ying", "瀆" => "Du", + "瀇" => "Wang", "瀈" => "Hui", "瀉" => "Xie", "瀊" => "Pan", "瀋" => "Shen", "瀌" => "Biao", + "ç€" => "Chan", "瀎" => "Mo", "ç€" => "Liu", "ç€" => "Jian", "瀑" => "Pu", "瀒" => "Se", + "瀓" => "Cheng", "瀔" => "Gu", "瀕" => "Bin", "瀖" => "Huo", "瀗" => "Xian", "瀘" => "Lu", + "瀙" => "Qin", "瀚" => "Han", "瀛" => "Ying", "瀜" => "Yong", "ç€" => "Li", "瀞" => "Jing", + "瀟" => "Xiao", "瀠" => "Ying", "瀡" => "Sui", "瀢" => "Wei", "瀣" => "Xie", "瀤" => "Huai", + "瀥" => "Hao", "瀦" => "Zhu", "瀧" => "Long", "瀨" => "Lai", "瀩" => "Dui", "瀪" => "Fan", + "瀫" => "Hu", "瀬" => "Lai", "瀯" => "Ying", "瀰" => "Mi", "瀱" => "Ji", "瀲" => "Lian", + "瀳" => "Jian", "瀴" => "Ying", "瀵" => "Fen", "瀶" => "Lin", "瀷" => "Yi", "瀸" => "Jian", + "瀹" => "Yue", "瀺" => "Chan", "瀻" => "Dai", "瀼" => "Rang", "瀽" => "Jian", "瀾" => "Lan", + "瀿" => "Fan", "ç€" => "Shuang", "ç" => "Yuan", "ç‚" => "Zhuo", "çƒ" => "Feng", "ç„" => "She", + "ç…" => "Lei", "ç†" => "Lan", "ç‡" => "Cong", "çˆ" => "Qu", "ç‰" => "Yong", "çŠ" => "Qian", + "ç‹" => "Fa", "çŒ" => "Guan", "ç" => "Que", "çŽ" => "Yan", "ç" => "Hao", "ç" => "Hyeng", + "ç‘" => "Sa", "ç’" => "Zan", "ç“" => "Luan", "ç”" => "Yan", "ç•" => "Li", "ç–" => "Mi", + "ç—" => "Shan", "ç˜" => "Tan", "ç™" => "Dang", "çš" => "Jiao", "ç›" => "Chan", "ç" => "Hao", + "çž" => "Ba", "çŸ" => "Zhu", "ç " => "Lan", "ç¡" => "Lan", "ç¢" => "Nang", "ç£" => "Wan", + "ç¤" => "Luan", "ç¥" => "Xun", "ç¦" => "Xian", "ç§" => "Yan", "ç¨" => "Gan", "ç©" => "Yan", + "çª" => "Yu", "ç«" => "Huo", "ç¬" => "Si", "ç­" => "Mie", "ç®" => "Guang", "ç¯" => "Deng", + "ç°" => "Hui", "ç±" => "Xiao", "ç²" => "Xiao", "ç³" => "Hu", "ç´" => "Hong", "çµ" => "Ling", + "ç¶" => "Zao", "ç·" => "Zhuan", "ç¸" => "Jiu", "ç¹" => "Zha", "çº" => "Xie", "ç»" => "Chi", + "ç¼" => "Zhuo", "ç½" => "Zai", "ç¾" => "Zai", "ç¿" => "Can", "ç‚€" => "Yang", "ç‚" => "Qi", + "ç‚‚" => "Zhong", "炃" => "Fen", "ç‚„" => "Niu", "ç‚…" => "Jiong", "炆" => "Wen", "炇" => "Po", + "炈" => "Yi", "炉" => "Lu", "ç‚Š" => "Chui", "ç‚‹" => "Pi", "ç‚Œ" => "Kai", "ç‚" => "Pan", + "ç‚Ž" => "Yan", "ç‚" => "Kai", "ç‚" => "Pang", "ç‚‘" => "Mu", "ç‚’" => "Chao", "ç‚“" => "Liao", + "ç‚”" => "Gui", "ç‚•" => "Kang", "ç‚–" => "Tun", "ç‚—" => "Guang", "炘" => "Xin", "ç‚™" => "Zhi", + "ç‚š" => "Guang", "ç‚›" => "Guang", "ç‚œ" => "Wei", "ç‚" => "Qiang", "ç‚Ÿ" => "Da", "ç‚ " => "Xia", + "ç‚¡" => "Zheng", "ç‚¢" => "Zhu", "ç‚£" => "Ke", "炤" => "Zhao", "ç‚¥" => "Fu", "炦" => "Ba", + "炧" => "Duo", "炨" => "Duo", "ç‚©" => "Ling", "炪" => "Zhuo", "ç‚«" => "Xuan", "炬" => "Ju", + "ç‚­" => "Tan", "ç‚®" => "Pao", "炯" => "Jiong", "ç‚°" => "Pao", "炱" => "Tai", "炲" => "Tai", + "炳" => "Bing", "ç‚´" => "Yang", "炵" => "Tong", "炶" => "Han", "ç‚·" => "Zhu", "炸" => "Zha", + "点" => "Dian", "為" => "Wei", "ç‚»" => "Shi", "炼" => "Lian", "炽" => "Chi", "炾" => "Huang", + "烀" => "Hu", "çƒ" => "Shuo", "烂" => "Lan", "烃" => "Jing", "烄" => "Jiao", "烅" => "Xu", + "烆" => "Xing", "烇" => "Quan", "烈" => "Lie", "烉" => "Huan", "烊" => "Yang", "烋" => "Xiao", + "烌" => "Xiu", "çƒ" => "Xian", "烎" => "Yin", "çƒ" => "Wu", "çƒ" => "Zhou", "烑" => "Yao", + "烒" => "Shi", "烓" => "Wei", "烔" => "Tong", "烕" => "Xue", "烖" => "Zai", "烗" => "Kai", + "烘" => "Hong", "烙" => "Luo", "烚" => "Xia", "烛" => "Zhu", "烜" => "Xuan", "çƒ" => "Zheng", + "烞" => "Po", "烟" => "Yan", "烠" => "Hui", "烡" => "Guang", "烢" => "Zhe", "烣" => "Hui", + "烤" => "Kao", "烦" => "Fan", "烧" => "Shao", "烨" => "Ye", "烩" => "Hui", "烫" => "Tang", + "烬" => "Jin", "热" => "Re", "烯" => "Xi", "烰" => "Fu", "烱" => "Jiong", "烲" => "Che", + "烳" => "Pu", "烴" => "Jing", "烵" => "Zhuo", "烶" => "Ting", "烷" => "Wan", "烸" => "Hai", + "烹" => "Peng", "烺" => "Lang", "烻" => "Shan", "烼" => "Hu", "烽" => "Feng", "烾" => "Chi", + "烿" => "Rong", "ç„" => "Xi", "ç„‚" => "Shu", "焃" => "He", "ç„„" => "Xun", "ç„…" => "Ku", + "焆" => "Jue", "焇" => "Xiao", "焈" => "Xi", "焉" => "Yan", "ç„Š" => "Han", "ç„‹" => "Zhuang", + "ç„Œ" => "Jun", "ç„" => "Di", "ç„Ž" => "Xie", "ç„" => "Ji", "ç„" => "Wu", "ç„“" => "Han", + "ç„”" => "Yan", "ç„•" => "Huan", "ç„–" => "Men", "ç„—" => "Ju", "焘" => "Chou", "ç„™" => "Bei", + "ç„š" => "Fen", "ç„›" => "Lin", "ç„œ" => "Kun", "ç„" => "Hun", "ç„ž" => "Tun", "ç„Ÿ" => "Xi", + "ç„ " => "Cui", "ç„¡" => "Wu", "ç„¢" => "Hong", "ç„£" => "Ju", "焤" => "Fu", "ç„¥" => "Wo", + "焦" => "Jiao", "焧" => "Cong", "焨" => "Feng", "ç„©" => "Ping", "焪" => "Qiong", "ç„«" => "Ruo", + "焬" => "Xi", "ç„­" => "Qiong", "ç„®" => "Xin", "焯" => "Zhuo", "ç„°" => "Yan", "焱" => "Yan", + "焲" => "Yi", "焳" => "Jue", "ç„´" => "Yu", "焵" => "Gang", "然" => "Ran", "ç„·" => "Pi", + "焸" => "Gu", "焺" => "Sheng", "ç„»" => "Chang", "焼" => "Shao", "ç…" => "Chen", "ç…‚" => "He", + "ç…ƒ" => "Kui", "ç…„" => "Zhong", "ç……" => "Duan", "ç…†" => "Xia", "ç…‡" => "Hui", "ç…ˆ" => "Feng", + "ç…‰" => "Lian", "ç…Š" => "Xuan", "ç…‹" => "Xing", "ç…Œ" => "Huang", "ç…" => "Jiao", "ç…Ž" => "Jian", + "ç…" => "Bi", "ç…" => "Ying", "ç…‘" => "Zhu", "ç…’" => "Wei", "ç…“" => "Tuan", "ç…”" => "Tian", + "ç…•" => "Xi", "ç…–" => "Nuan", "ç…—" => "Nuan", "ç…˜" => "Chan", "ç…™" => "Yan", "ç…š" => "Jiong", + "ç…›" => "Jiong", "ç…œ" => "Yu", "ç…" => "Mei", "ç…ž" => "Sha", "ç…Ÿ" => "Wei", "ç… " => "Ye", + "ç…¡" => "Xin", "ç…¢" => "Qiong", "ç…£" => "Rou", "ç…¤" => "Mei", "ç…¥" => "Huan", "ç…¦" => "Xu", + "ç…§" => "Zhao", "ç…¨" => "Wei", "ç…©" => "Fan", "ç…ª" => "Qiu", "ç…«" => "Sui", "ç…¬" => "Yang", + "ç…­" => "Lie", "ç…®" => "Zhu", "ç…¯" => "Jie", "ç…°" => "Gao", "ç…±" => "Gua", "ç…²" => "Bao", + "ç…³" => "Hu", "ç…´" => "Yun", "ç…µ" => "Xia", "ç…¸" => "Bian", "ç…¹" => "Gou", "ç…º" => "Tui", + "ç…»" => "Tang", "ç…¼" => "Chao", "ç…½" => "Shan", "ç…¾" => "N", "ç…¿" => "Bo", "熀" => "Huang", + "ç†" => "Xie", "熂" => "Xi", "熃" => "Wu", "熄" => "Xi", "熅" => "Yun", "熆" => "He", + "熇" => "He", "熈" => "Xi", "熉" => "Yun", "熊" => "Xiong", "熋" => "Nai", "熌" => "Shan", + "ç†" => "Qiong", "熎" => "Yao", "ç†" => "Xun", "ç†" => "Mi", "熑" => "Lian", "熒" => "Ying", + "熓" => "Wen", "熔" => "Rong", "熕" => "Oozutsu", "熗" => "Qiang", "熘" => "Liu", "熙" => "Xi", + "熚" => "Bi", "熛" => "Biao", "熜" => "Zong", "ç†" => "Lu", "熞" => "Jian", "熟" => "Shou", + "熠" => "Yi", "熡" => "Lou", "熢" => "Feng", "熣" => "Sui", "熤" => "Yi", "熥" => "Tong", + "熦" => "Jue", "熧" => "Zong", "熨" => "Yun", "熩" => "Hu", "熪" => "Yi", "熫" => "Zhi", + "熬" => "Ao", "熭" => "Wei", "熮" => "Liao", "熯" => "Han", "熰" => "Ou", "熱" => "Re", + "熲" => "Jiong", "熳" => "Man", "熵" => "Shang", "熶" => "Cuan", "熷" => "Zeng", "熸" => "Jian", + "熹" => "Xi", "熺" => "Xi", "熻" => "Xi", "熼" => "Yi", "熽" => "Xiao", "熾" => "Chi", + "熿" => "Huang", "燀" => "Chan", "ç‡" => "Ye", "燂" => "Qian", "燃" => "Ran", "燄" => "Yan", + "燅" => "Xian", "燆" => "Qiao", "燇" => "Zun", "燈" => "Deng", "燉" => "Dun", "燊" => "Shen", + "燋" => "Jiao", "燌" => "Fen", "ç‡" => "Si", "燎" => "Liao", "ç‡" => "Yu", "ç‡" => "Lin", + "燑" => "Tong", "燒" => "Shao", "燓" => "Fen", "燔" => "Fan", "燕" => "Yan", "燖" => "Xun", + "燗" => "Lan", "燘" => "Mei", "燙" => "Tang", "燚" => "Yi", "燛" => "Jing", "燜" => "Men", + "營" => "Ying", "燠" => "Yu", "燡" => "Yi", "燢" => "Xue", "燣" => "Lan", "燤" => "Tai", + "燥" => "Zao", "燦" => "Can", "燧" => "Sui", "燨" => "Xi", "燩" => "Que", "燪" => "Cong", + "燫" => "Lian", "燬" => "Hui", "燭" => "Zhu", "燮" => "Xie", "燯" => "Ling", "燰" => "Wei", + "燱" => "Yi", "燲" => "Xie", "燳" => "Zhao", "燴" => "Hui", "燵" => "Tatsu", "燶" => "Nung", + "燷" => "Lan", "燸" => "Ru", "燹" => "Xian", "燺" => "Kao", "燻" => "Xun", "燼" => "Jin", + "燽" => "Chou", "燾" => "Chou", "燿" => "Yao", "çˆ" => "Lan", "爂" => "Biao", "爃" => "Rong", + "爄" => "Li", "爅" => "Mo", "爆" => "Bao", "爇" => "Ruo", "爈" => "Lu", "爉" => "La", + "爊" => "Ao", "爋" => "Xun", "爌" => "Kuang", "çˆ" => "Shuo", "çˆ" => "Li", "çˆ" => "Lu", + "爑" => "Jue", "爒" => "Liao", "爓" => "Yan", "爔" => "Xi", "爕" => "Xie", "爖" => "Long", + "爗" => "Ye", "爙" => "Rang", "爚" => "Yue", "爛" => "Lan", "爜" => "Cong", "çˆ" => "Jue", + "爞" => "Tong", "爟" => "Guan", "爡" => "Che", "爢" => "Mi", "爣" => "Tang", "爤" => "Lan", + "爥" => "Zhu", "爧" => "Ling", "爨" => "Cuan", "爩" => "Yu", "爪" => "Zhua", "爫" => "Tsumekanmuri", + "爬" => "Pa", "爭" => "Zheng", "爮" => "Pao", "爯" => "Cheng", "爰" => "Yuan", "爱" => "Ai", + "爲" => "Wei", "爴" => "Jue", "爵" => "Jue", "父" => "Fu", "爷" => "Ye", "爸" => "Ba", + "爹" => "Die", "爺" => "Ye", "爻" => "Yao", "爼" => "Zu", "爽" => "Shuang", "爾" => "Er", + "爿" => "Qiang", "牀" => "Chuang", "ç‰" => "Ge", "牂" => "Zang", "牃" => "Die", "牄" => "Qiang", + "牅" => "Yong", "牆" => "Qiang", "片" => "Pian", "版" => "Ban", "牉" => "Pan", "牊" => "Shao", + "牋" => "Jian", "牌" => "Pai", "ç‰" => "Du", "牎" => "Chuang", "ç‰" => "Tou", "ç‰" => "Zha", + "牑" => "Bian", "牒" => "Die", "牓" => "Bang", "牔" => "Bo", "牕" => "Chuang", "牖" => "You", + "牘" => "Du", "牙" => "Ya", "牚" => "Cheng", "牛" => "Niu", "牜" => "Ushihen", "ç‰" => "Pin", + "牞" => "Jiu", "牟" => "Mou", "牠" => "Tuo", "牡" => "Mu", "牢" => "Lao", "牣" => "Ren", + "牤" => "Mang", "牥" => "Fang", "牦" => "Mao", "牧" => "Mu", "牨" => "Gang", "物" => "Wu", + "牪" => "Yan", "牫" => "Ge", "牬" => "Bei", "牭" => "Si", "牮" => "Jian", "牯" => "Gu", + "牰" => "You", "牱" => "Ge", "牲" => "Sheng", "牳" => "Mu", "牴" => "Di", "牵" => "Qian", + "牶" => "Quan", "牷" => "Quan", "牸" => "Zi", "特" => "Te", "牺" => "Xi", "牻" => "Mang", + "牼" => "Keng", "牽" => "Qian", "牾" => "Wu", "牿" => "Gu", "犀" => "Xi", "çŠ" => "Li", + "犂" => "Li", "犃" => "Pou", "犄" => "Ji", "犅" => "Gang", "犆" => "Zhi", "犇" => "Ben", + "犈" => "Quan", "犉" => "Run", "犊" => "Du", "犋" => "Ju", "犌" => "Jia", "çŠ" => "Jian", + "犎" => "Feng", "çŠ" => "Pian", "çŠ" => "Ke", "犑" => "Ju", "犒" => "Kao", "犓" => "Chu", + "犔" => "Xi", "犕" => "Bei", "犖" => "Luo", "犗" => "Jie", "犘" => "Ma", "犙" => "San", + "犚" => "Wei", "犛" => "Li", "犜" => "Dun", "çŠ" => "Tong", "犟" => "Jiang", "犠" => "Ikenie", + "犡" => "Li", "犢" => "Du", "犣" => "Lie", "犤" => "Pi", "犥" => "Piao", "犦" => "Bao", + "犧" => "Xi", "犨" => "Chou", "犩" => "Wei", "犪" => "Kui", "犫" => "Chou", "犬" => "Quan", + "犭" => "Fan", "犮" => "Ba", "犯" => "Fan", "犰" => "Qiu", "犱" => "Ji", "犲" => "Cai", + "犳" => "Chuo", "犴" => "An", "犵" => "Jie", "状" => "Zhuang", "犷" => "Guang", "犸" => "Ma", + "犹" => "You", "犺" => "Kang", "犻" => "Bo", "犼" => "Hou", "犽" => "Ya", "犾" => "Yin", + "犿" => "Huan", "ç‹€" => "Zhuang", "ç‹" => "Yun", "ç‹‚" => "Kuang", "狃" => "Niu", "ç‹„" => "Di", + "ç‹…" => "Qing", "狆" => "Zhong", "狇" => "Mu", "狈" => "Bei", "狉" => "Pi", "ç‹Š" => "Ju", + "ç‹‹" => "Ni", "ç‹Œ" => "Sheng", "ç‹" => "Pao", "ç‹Ž" => "Xia", "ç‹" => "Tuo", "ç‹" => "Hu", + "ç‹‘" => "Ling", "ç‹’" => "Fei", "ç‹“" => "Pi", "ç‹”" => "Ni", "ç‹•" => "Ao", "ç‹–" => "You", + "ç‹—" => "Gou", "狘" => "Yue", "ç‹™" => "Ju", "ç‹š" => "Dan", "ç‹›" => "Po", "ç‹œ" => "Gu", + "ç‹" => "Xian", "ç‹ž" => "Ning", "ç‹Ÿ" => "Huan", "ç‹ " => "Hen", "ç‹¡" => "Jiao", "ç‹¢" => "He", + "ç‹£" => "Zhao", "狤" => "Ji", "ç‹¥" => "Xun", "狦" => "Shan", "狧" => "Ta", "狨" => "Rong", + "ç‹©" => "Shou", "狪" => "Tong", "ç‹«" => "Lao", "独" => "Du", "ç‹­" => "Xia", "ç‹®" => "Shi", + "狯" => "Hua", "ç‹°" => "Zheng", "狱" => "Yu", "狲" => "Sun", "狳" => "Yu", "ç‹´" => "Bi", + "狵" => "Mang", "狶" => "Xi", "ç‹·" => "Juan", "狸" => "Li", "狹" => "Xia", "狺" => "Yin", + "ç‹»" => "Suan", "狼" => "Lang", "狽" => "Bei", "狾" => "Zhi", "ç‹¿" => "Yan", "çŒ" => "Li", + "猂" => "Han", "猃" => "Xian", "猄" => "Jing", "猅" => "Pai", "猆" => "Fei", "猇" => "Yao", + "猈" => "Ba", "猉" => "Qi", "猊" => "Ni", "猋" => "Biao", "猌" => "Yin", "çŒ" => "Lai", + "猎" => "Xi", "çŒ" => "Jian", "çŒ" => "Qiang", "猑" => "Kun", "猒" => "Yan", "猓" => "Guo", + "猔" => "Zong", "猕" => "Mi", "猖" => "Chang", "猗" => "Yi", "猘" => "Zhi", "猙" => "Zheng", + "猚" => "Ya", "猛" => "Meng", "猜" => "Cai", "çŒ" => "Cu", "猞" => "She", "猟" => "Kari", + "猠" => "Cen", "猡" => "Luo", "猢" => "Hu", "猣" => "Zong", "猤" => "Ji", "猥" => "Wei", + "猦" => "Feng", "猧" => "Wo", "猨" => "Yuan", "猩" => "Xing", "猪" => "Zhu", "猫" => "Mao", + "猬" => "Wei", "猭" => "Yuan", "献" => "Xian", "猯" => "Tuan", "猰" => "Ya", "猱" => "Nao", + "猲" => "Xie", "猳" => "Jia", "猴" => "Hou", "猵" => "Bian", "猶" => "You", "猷" => "You", + "猸" => "Mei", "猹" => "Zha", "猺" => "Yao", "猻" => "Sun", "猼" => "Bo", "猽" => "Ming", + "猾" => "Hua", "猿" => "Yuan", "ç€" => "Sou", "ç" => "Ma", "ç‚" => "Yuan", "çƒ" => "Dai", + "ç„" => "Yu", "ç…" => "Shi", "ç†" => "Hao", "çˆ" => "Yi", "ç‰" => "Zhen", "çŠ" => "Chuang", + "ç‹" => "Hao", "çŒ" => "Man", "ç" => "Jing", "çŽ" => "Jiang", "ç" => "Mu", "ç" => "Zhang", + "ç‘" => "Chan", "ç’" => "Ao", "ç“" => "Ao", "ç”" => "Hao", "ç•" => "Cui", "ç–" => "Fen", + "ç—" => "Jue", "ç˜" => "Bi", "ç™" => "Bi", "çš" => "Huang", "ç›" => "Pu", "çœ" => "Lin", + "ç" => "Yu", "çž" => "Tong", "çŸ" => "Yao", "ç " => "Liao", "ç¡" => "Shuo", "ç¢" => "Xiao", + "ç£" => "Swu", "ç¤" => "Ton", "ç¥" => "Xi", "ç¦" => "Ge", "ç§" => "Juan", "ç¨" => "Du", + "ç©" => "Hui", "çª" => "Kuai", "ç«" => "Xian", "ç¬" => "Xie", "ç­" => "Ta", "ç®" => "Xian", + "ç¯" => "Xun", "ç°" => "Ning", "ç±" => "Pin", "ç²" => "Huo", "ç³" => "Nou", "ç´" => "Meng", + "çµ" => "Lie", "ç¶" => "Nao", "ç·" => "Guang", "ç¸" => "Shou", "ç¹" => "Lu", "çº" => "Ta", + "ç»" => "Xian", "ç¼" => "Mi", "ç½" => "Rang", "ç¾" => "Huan", "ç¿" => "Nao", "玀" => "Luo", + "çŽ" => "Xian", "玂" => "Qi", "玃" => "Jue", "玄" => "Xuan", "玅" => "Miao", "玆" => "Zi", + "率" => "Lu", "玈" => "Lu", "玉" => "Yu", "玊" => "Su", "王" => "Wang", "玌" => "Qiu", + "çŽ" => "Ga", "玎" => "Ding", "çŽ" => "Le", "çŽ" => "Ba", "玑" => "Ji", "玒" => "Hong", + "玓" => "Di", "玔" => "Quan", "玕" => "Gan", "玖" => "Jiu", "玗" => "Yu", "玘" => "Ji", + "玙" => "Yu", "玚" => "Yang", "玛" => "Ma", "玜" => "Gong", "çŽ" => "Wu", "玞" => "Fu", + "玟" => "Wen", "玠" => "Jie", "玡" => "Ya", "玢" => "Fen", "玣" => "Bian", "玤" => "Beng", + "玥" => "Yue", "玦" => "Jue", "玧" => "Yun", "玨" => "Jue", "玩" => "Wan", "玪" => "Jian", + "玫" => "Mei", "玬" => "Dan", "玭" => "Pi", "玮" => "Wei", "环" => "Huan", "现" => "Xian", + "玱" => "Qiang", "玲" => "Ling", "玳" => "Dai", "玴" => "Yi", "玵" => "An", "玶" => "Ping", + "玷" => "Dian", "玸" => "Fu", "玹" => "Xuan", "玺" => "Xi", "玻" => "Bo", "玼" => "Ci", + "玽" => "Gou", "玾" => "Jia", "玿" => "Shao", "ç€" => "Po", "ç" => "Ci", "ç‚" => "Ke", + "çƒ" => "Ran", "ç„" => "Sheng", "ç…" => "Shen", "ç†" => "Yi", "ç‡" => "Zu", "çˆ" => "Jia", + "ç‰" => "Min", "çŠ" => "Shan", "ç‹" => "Liu", "çŒ" => "Bi", "ç" => "Zhen", "çŽ" => "Zhen", + "ç" => "Jue", "ç" => "Fa", "ç‘" => "Long", "ç’" => "Jin", "ç“" => "Jiao", "ç”" => "Jian", + "ç•" => "Li", "ç–" => "Guang", "ç—" => "Xian", "ç˜" => "Zhou", "ç™" => "Gong", "çš" => "Yan", + "ç›" => "Xiu", "çœ" => "Yang", "ç" => "Xu", "çž" => "Luo", "çŸ" => "Su", "ç " => "Zhu", + "ç¡" => "Qin", "ç¢" => "Ken", "ç£" => "Xun", "ç¤" => "Bao", "ç¥" => "Er", "ç¦" => "Xiang", + "ç§" => "Yao", "ç¨" => "Xia", "ç©" => "Heng", "çª" => "Gui", "ç«" => "Chong", "ç¬" => "Xu", + "ç­" => "Ban", "ç®" => "Pei", "ç°" => "Dang", "ç±" => "Ei", "ç²" => "Hun", "ç³" => "Wen", + "ç´" => "E", "çµ" => "Cheng", "ç¶" => "Ti", "ç·" => "Wu", "ç¸" => "Wu", "ç¹" => "Cheng", + "çº" => "Jun", "ç»" => "Mei", "ç¼" => "Bei", "ç½" => "Ting", "ç¾" => "Xian", "ç¿" => "Chuo", + "ç" => "Xuan", "ç‚" => "Yan", "çƒ" => "Qiu", "ç„" => "Quan", "ç…" => "Lang", "ç†" => "Li", + "ç‡" => "Xiu", "çˆ" => "Fu", "ç‰" => "Liu", "çŠ" => "Ye", "ç‹" => "Xi", "çŒ" => "Ling", + "ç" => "Li", "çŽ" => "Jin", "ç" => "Lian", "ç" => "Suo", "ç‘" => "Chiisai", "ç“" => "Wan", + "ç”" => "Dian", "ç•" => "Pin", "ç–" => "Zhan", "ç—" => "Cui", "ç˜" => "Min", "ç™" => "Yu", + "çš" => "Ju", "ç›" => "Chen", "çœ" => "Lai", "ç" => "Wen", "çž" => "Sheng", "çŸ" => "Wei", + "ç " => "Dian", "ç¡" => "Chu", "ç¢" => "Zhuo", "ç£" => "Pei", "ç¤" => "Cheng", "ç¥" => "Hu", + "ç¦" => "Qi", "ç§" => "E", "ç¨" => "Kun", "ç©" => "Chang", "çª" => "Qi", "ç«" => "Beng", + "ç¬" => "Wan", "ç­" => "Lu", "ç®" => "Cong", "ç¯" => "Guan", "ç°" => "Yan", "ç±" => "Diao", + "ç²" => "Bei", "ç³" => "Lin", "ç´" => "Qin", "çµ" => "Pi", "ç¶" => "Pa", "ç·" => "Que", + "ç¸" => "Zhuo", "ç¹" => "Qin", "çº" => "Fa", "ç¼" => "Qiong", "ç½" => "Du", "ç¾" => "Jie", + "ç¿" => "Hun", "ç‘€" => "Yu", "ç‘" => "Mao", "ç‘‚" => "Mei", "瑃" => "Chun", "ç‘„" => "Xuan", + "ç‘…" => "Ti", "瑆" => "Xing", "瑇" => "Dai", "瑈" => "Rou", "瑉" => "Min", "ç‘Š" => "Zhen", + "ç‘‹" => "Wei", "ç‘Œ" => "Ruan", "ç‘" => "Huan", "ç‘Ž" => "Jie", "ç‘" => "Chuan", "ç‘" => "Jian", + "ç‘‘" => "Zhuan", "ç‘’" => "Yang", "ç‘“" => "Lian", "ç‘”" => "Quan", "ç‘•" => "Xia", "ç‘–" => "Duan", + "ç‘—" => "Yuan", "瑘" => "Ye", "ç‘™" => "Nao", "ç‘š" => "Hu", "ç‘›" => "Ying", "ç‘œ" => "Yu", + "ç‘" => "Huang", "ç‘ž" => "Rui", "ç‘Ÿ" => "Se", "ç‘ " => "Liu", "ç‘¡" => "Shi", "ç‘¢" => "Rong", + "ç‘£" => "Suo", "瑤" => "Yao", "ç‘¥" => "Wen", "瑦" => "Wu", "瑧" => "Jin", "瑨" => "Jin", + "ç‘©" => "Ying", "瑪" => "Ma", "ç‘«" => "Tao", "瑬" => "Liu", "ç‘­" => "Tang", "ç‘®" => "Li", + "瑯" => "Lang", "ç‘°" => "Gui", "瑱" => "Zhen", "瑲" => "Qiang", "瑳" => "Cuo", "ç‘´" => "Jue", + "瑵" => "Zhao", "瑶" => "Yao", "ç‘·" => "Ai", "瑸" => "Bin", "瑹" => "Tu", "瑺" => "Chang", + "ç‘»" => "Kun", "瑼" => "Zhuan", "瑽" => "Cong", "瑾" => "Jin", "ç‘¿" => "Yi", "ç’€" => "Cui", + "ç’" => "Cong", "ç’‚" => "Qi", "ç’ƒ" => "Li", "ç’„" => "Ying", "ç’…" => "Suo", "ç’†" => "Qiu", + "ç’‡" => "Xuan", "ç’ˆ" => "Ao", "ç’‰" => "Lian", "ç’Š" => "Man", "ç’‹" => "Zhang", "ç’Œ" => "Yin", + "ç’Ž" => "Ying", "ç’" => "Zhi", "ç’" => "Lu", "ç’‘" => "Wu", "ç’’" => "Deng", "ç’“" => "Xiou", + "ç’”" => "Zeng", "ç’•" => "Xun", "ç’–" => "Qu", "ç’—" => "Dang", "ç’˜" => "Lin", "ç’™" => "Liao", + "ç’š" => "Qiong", "ç’›" => "Su", "ç’œ" => "Huang", "ç’" => "Gui", "ç’ž" => "Pu", "ç’Ÿ" => "Jing", + "ç’ " => "Fan", "ç’¡" => "Jin", "ç’¢" => "Liu", "ç’£" => "Ji", "ç’¥" => "Jing", "ç’¦" => "Ai", + "ç’§" => "Bi", "ç’¨" => "Can", "ç’©" => "Qu", "ç’ª" => "Zao", "ç’«" => "Dang", "ç’¬" => "Jiao", + "ç’­" => "Gun", "ç’®" => "Tan", "ç’¯" => "Hui", "ç’°" => "Huan", "ç’±" => "Se", "ç’²" => "Sui", + "ç’³" => "Tian", "ç’µ" => "Yu", "ç’¶" => "Jin", "ç’·" => "Lu", "ç’¸" => "Bin", "ç’¹" => "Shou", + "ç’º" => "Wen", "ç’»" => "Zui", "ç’¼" => "Lan", "ç’½" => "Xi", "ç’¾" => "Ji", "ç’¿" => "Xuan", + "ç“€" => "Ruan", "ç“" => "Huo", "ç“‚" => "Gai", "瓃" => "Lei", "ç“„" => "Du", "ç“…" => "Li", + "瓆" => "Zhi", "瓇" => "Rou", "瓈" => "Li", "瓉" => "Zan", "ç“Š" => "Qiong", "ç“‹" => "Zhe", + "ç“Œ" => "Gui", "ç“" => "Sui", "ç“Ž" => "La", "ç“" => "Long", "ç“" => "Lu", "ç“‘" => "Li", + "ç“’" => "Zan", "ç““" => "Lan", "ç“”" => "Ying", "ç“•" => "Mi", "ç“–" => "Xiang", "ç“—" => "Xi", + "瓘" => "Guan", "ç“™" => "Dao", "ç“š" => "Zan", "ç“›" => "Huan", "ç“œ" => "Gua", "ç“" => "Bo", + "ç“ž" => "Die", "ç“Ÿ" => "Bao", "ç“ " => "Hu", "ç“¡" => "Zhi", "ç“¢" => "Piao", "ç“£" => "Ban", + "瓤" => "Rang", "ç“¥" => "Li", "瓦" => "Wa", "瓧" => "Dekaguramu", "瓨" => "Jiang", "ç“©" => "Qian", + "瓪" => "Fan", "ç“«" => "Pen", "瓬" => "Fang", "ç“­" => "Dan", "ç“®" => "Weng", "瓯" => "Ou", + "ç“°" => "Deshiguramu", "瓱" => "Miriguramu", "瓲" => "Thon", "瓳" => "Hu", "ç“´" => "Ling", "瓵" => "Yi", + "瓶" => "Ping", "ç“·" => "Ci", "瓸" => "Hekutogura", "瓹" => "Juan", "瓺" => "Chang", "ç“»" => "Chi", + "瓼" => "Sarake", "瓽" => "Dang", "瓾" => "Meng", "ç“¿" => "Pou", "ç”" => "Ping", "甂" => "Bian", + "甃" => "Zhou", "甄" => "Zhen", "ç”…" => "Senchigura", "甆" => "Ci", "甇" => "Ying", "甈" => "Qi", + "甉" => "Xian", "甊" => "Lou", "甋" => "Di", "甌" => "Ou", "ç”" => "Meng", "甎" => "Zhuan", + "ç”" => "Peng", "ç”" => "Lin", "甑" => "Zeng", "ç”’" => "Wu", "甓" => "Pi", "ç””" => "Dan", + "甕" => "Weng", "ç”–" => "Ying", "ç”—" => "Yan", "甘" => "Gan", "ç”™" => "Dai", "甚" => "Shen", + "ç”›" => "Tian", "甜" => "Tian", "ç”" => "Han", "甞" => "Chang", "生" => "Sheng", "ç” " => "Qing", + "甡" => "Sheng", "產" => "Chan", "産" => "Chan", "甤" => "Rui", "甥" => "Sheng", "甦" => "Su", + "甧" => "Sen", "用" => "Yong", "甩" => "Shuai", "甪" => "Lu", "甫" => "Fu", "甬" => "Yong", + "ç”­" => "Beng", "ç”®" => "Feng", "甯" => "Ning", "ç”°" => "Tian", "ç”±" => "You", "甲" => "Jia", + "申" => "Shen", "ç”´" => "Zha", "电" => "Dian", "甶" => "Fu", "ç”·" => "Nan", "甸" => "Dian", + "甹" => "Ping", "町" => "Ting", "ç”»" => "Hua", "甼" => "Ting", "甽" => "Quan", "甾" => "Zi", + "甿" => "Meng", "ç•€" => "Bi", "ç•" => "Qi", "ç•‚" => "Liu", "畃" => "Xun", "ç•„" => "Liu", + "ç•…" => "Chang", "畆" => "Mu", "畇" => "Yun", "畈" => "Fan", "畉" => "Fu", "ç•Š" => "Geng", + "ç•‹" => "Tian", "ç•Œ" => "Jie", "ç•" => "Jie", "ç•Ž" => "Quan", "ç•" => "Wei", "ç•" => "Fu", + "ç•‘" => "Tian", "ç•’" => "Mu", "ç•“" => "Tap", "ç•”" => "Pan", "ç••" => "Jiang", "ç•–" => "Wa", + "ç•—" => "Da", "畘" => "Nan", "ç•™" => "Liu", "ç•š" => "Ben", "ç•›" => "Zhen", "ç•œ" => "Chu", + "ç•" => "Mu", "ç•ž" => "Mu", "ç•Ÿ" => "Ce", "ç• " => "Cen", "ç•¡" => "Gai", "ç•¢" => "Bi", + "ç•£" => "Da", "畤" => "Zhi", "ç•¥" => "Lue", "畦" => "Qi", "畧" => "Lue", "畨" => "Pan", + "ç•©" => "Kesa", "番" => "Fan", "ç•«" => "Hua", "畬" => "Yu", "ç•­" => "Yu", "ç•®" => "Mu", + "畯" => "Jun", "ç•°" => "Yi", "畱" => "Liu", "畲" => "Yu", "畳" => "Die", "ç•´" => "Chou", + "畵" => "Hua", "當" => "Dang", "ç•·" => "Chuo", "畸" => "Ji", "畹" => "Wan", "畺" => "Jiang", + "ç•»" => "Sheng", "畼" => "Chang", "畽" => "Tuan", "畾" => "Lei", "ç•¿" => "Ji", "ç–€" => "Cha", + "ç–" => "Liu", "ç–‚" => "Tatamu", "ç–ƒ" => "Tuan", "ç–„" => "Lin", "ç–…" => "Jiang", "ç–†" => "Jiang", + "ç–‡" => "Chou", "ç–ˆ" => "Bo", "ç–‰" => "Die", "ç–Š" => "Die", "ç–‹" => "Pi", "ç–Œ" => "Nie", + "ç–" => "Dan", "ç–Ž" => "Shu", "ç–" => "Shu", "ç–" => "Zhi", "ç–‘" => "Yi", "ç–’" => "Chuang", + "ç–“" => "Nai", "ç–”" => "Ding", "ç–•" => "Bi", "ç––" => "Jie", "ç–—" => "Liao", "ç–˜" => "Gong", + "ç–™" => "Ge", "ç–š" => "Jiu", "ç–›" => "Zhou", "ç–œ" => "Xia", "ç–" => "Shan", "ç–ž" => "Xu", + "ç–Ÿ" => "Nue", "ç– " => "Li", "ç–¡" => "Yang", "ç–¢" => "Chen", "ç–£" => "You", "ç–¤" => "Ba", + "ç–¥" => "Jie", "ç–¦" => "Jue", "ç–§" => "Zhi", "ç–¨" => "Xia", "ç–©" => "Cui", "ç–ª" => "Bi", + "ç–«" => "Yi", "ç–¬" => "Li", "ç–­" => "Zong", "ç–®" => "Chuang", "ç–¯" => "Feng", "ç–°" => "Zhu", + "ç–±" => "Pao", "ç–²" => "Pi", "ç–³" => "Gan", "ç–´" => "Ke", "ç–µ" => "Ci", "ç–¶" => "Xie", + "ç–·" => "Qi", "ç–¸" => "Dan", "ç–¹" => "Zhen", "ç–º" => "Fa", "ç–»" => "Zhi", "ç–¼" => "Teng", + "ç–½" => "Ju", "ç–¾" => "Ji", "ç–¿" => "Fei", "ç—€" => "Qu", "ç—" => "Dian", "ç—‚" => "Jia", + "ç—ƒ" => "Xian", "ç—„" => "Cha", "ç—…" => "Bing", "ç—†" => "Ni", "ç—‡" => "Zheng", "ç—ˆ" => "Yong", + "ç—‰" => "Jing", "ç—Š" => "Quan", "ç—‹" => "Chong", "ç—Œ" => "Tong", "ç—" => "Yi", "ç—Ž" => "Kai", + "ç—" => "Wei", "ç—" => "Hui", "ç—‘" => "Duo", "ç—’" => "Yang", "ç—“" => "Chi", "ç—”" => "Zhi", + "ç—•" => "Hen", "ç—–" => "Ya", "ç——" => "Mei", "ç—˜" => "Dou", "ç—™" => "Jing", "ç—š" => "Xiao", + "ç—›" => "Tong", "ç—œ" => "Tu", "ç—" => "Mang", "ç—ž" => "Pi", "ç—Ÿ" => "Xiao", "ç— " => "Suan", + "ç—¡" => "Pu", "ç—¢" => "Li", "ç—£" => "Zhi", "ç—¤" => "Cuo", "ç—¥" => "Duo", "ç—¦" => "Wu", + "ç—§" => "Sha", "ç—¨" => "Lao", "ç—©" => "Shou", "ç—ª" => "Huan", "ç—«" => "Xian", "ç—¬" => "Yi", + "ç—­" => "Peng", "ç—®" => "Zhang", "ç—¯" => "Guan", "ç—°" => "Tan", "ç—±" => "Fei", "ç—²" => "Ma", + "ç—³" => "Lin", "ç—´" => "Chi", "ç—µ" => "Ji", "ç—¶" => "Dian", "ç—·" => "An", "ç—¸" => "Chi", + "ç—¹" => "Bi", "ç—º" => "Bei", "ç—»" => "Min", "ç—¼" => "Gu", "ç—½" => "Dui", "ç—¾" => "E", + "ç—¿" => "Wei", "ç˜" => "Cui", "瘂" => "Ya", "瘃" => "Zhu", "瘄" => "Cu", "瘅" => "Dan", + "瘆" => "Shen", "瘇" => "Zhung", "瘈" => "Ji", "瘉" => "Yu", "瘊" => "Hou", "瘋" => "Feng", + "瘌" => "La", "ç˜" => "Yang", "瘎" => "Shen", "ç˜" => "Tu", "ç˜" => "Yu", "瘑" => "Gua", + "瘒" => "Wen", "瘓" => "Huan", "瘔" => "Ku", "瘕" => "Jia", "瘖" => "Yin", "瘗" => "Yi", + "瘘" => "Lu", "瘙" => "Sao", "瘚" => "Jue", "瘛" => "Chi", "瘜" => "Xi", "ç˜" => "Guan", + "瘞" => "Yi", "瘟" => "Wen", "瘠" => "Ji", "瘡" => "Chuang", "瘢" => "Ban", "瘣" => "Lei", + "瘤" => "Liu", "瘥" => "Chai", "瘦" => "Shou", "瘧" => "Nue", "瘨" => "Dian", "瘩" => "Da", + "瘪" => "Pie", "瘫" => "Tan", "瘬" => "Zhang", "瘭" => "Biao", "瘮" => "Shen", "瘯" => "Cu", + "瘰" => "Luo", "瘱" => "Yi", "瘲" => "Zong", "瘳" => "Chou", "瘴" => "Zhang", "瘵" => "Zhai", + "瘶" => "Sou", "瘷" => "Suo", "瘸" => "Que", "瘹" => "Diao", "瘺" => "Lou", "瘻" => "Lu", + "瘼" => "Mo", "瘽" => "Jin", "瘾" => "Yin", "瘿" => "Ying", "癀" => "Huang", "ç™" => "Fu", + "療" => "Liao", "癃" => "Long", "癄" => "Qiao", "ç™…" => "Liu", "癆" => "Lao", "癇" => "Xian", + "癈" => "Fei", "癉" => "Dan", "癊" => "Yin", "癋" => "He", "癌" => "Yan", "ç™" => "Ban", + "癎" => "Xian", "ç™" => "Guan", "ç™" => "Guai", "癑" => "Nong", "ç™’" => "Yu", "癓" => "Wei", + "ç™”" => "Yi", "癕" => "Yong", "ç™–" => "Pi", "ç™—" => "Lei", "癘" => "Li", "ç™™" => "Shu", + "癚" => "Dan", "ç™›" => "Lin", "癜" => "Dian", "ç™" => "Lin", "癞" => "Lai", "癟" => "Pie", + "ç™ " => "Ji", "癡" => "Chi", "癢" => "Yang", "癣" => "Xian", "癤" => "Jie", "癥" => "Zheng", + "癧" => "Li", "癨" => "Huo", "癩" => "Lai", "癪" => "Shaku", "癫" => "Dian", "癬" => "Xian", + "ç™­" => "Ying", "ç™®" => "Yin", "癯" => "Qu", "ç™°" => "Yong", "ç™±" => "Tan", "癲" => "Dian", + "癳" => "Luo", "ç™´" => "Luan", "癵" => "Luan", "癶" => "Bo", "癸" => "Gui", "癹" => "Po", + "発" => "Fa", "ç™»" => "Deng", "發" => "Fa", "白" => "Bai", "百" => "Bai", "癿" => "Qie", + "皀" => "Bi", "çš" => "Zao", "çš‚" => "Zao", "皃" => "Mao", "çš„" => "De", "çš…" => "Pa", + "皆" => "Jie", "皇" => "Huang", "皈" => "Gui", "皉" => "Ci", "皊" => "Ling", "çš‹" => "Gao", + "皌" => "Mo", "çš" => "Ji", "皎" => "Jiao", "çš" => "Peng", "çš" => "Gao", "çš‘" => "Ai", + "çš’" => "E", "çš“" => "Hao", "çš”" => "Han", "çš•" => "Bi", "çš–" => "Wan", "çš—" => "Chou", + "皘" => "Qian", "çš™" => "Xi", "çšš" => "Ai", "çš›" => "Jiong", "çšœ" => "Hao", "çš" => "Huang", + "çšž" => "Hao", "皟" => "Ze", "çš " => "Cui", "çš¡" => "Hao", "皢" => "Xiao", "皣" => "Ye", + "皤" => "Po", "皥" => "Hao", "皦" => "Jiao", "皧" => "Ai", "皨" => "Xing", "çš©" => "Huang", + "皪" => "Li", "çš«" => "Piao", "皬" => "He", "çš­" => "Jiao", "çš®" => "Pi", "皯" => "Gan", + "çš°" => "Pao", "çš±" => "Zhou", "çš²" => "Jun", "çš³" => "Qiu", "çš´" => "Cun", "çšµ" => "Que", + "皶" => "Zha", "çš·" => "Gu", "皸" => "Jun", "çš¹" => "Jun", "皺" => "Zhou", "çš»" => "Zha", + "çš¼" => "Gu", "çš½" => "Zhan", "çš¾" => "Du", "çš¿" => "Min", "盀" => "Qi", "ç›" => "Ying", + "盂" => "Yu", "盃" => "Bei", "盄" => "Zhao", "ç›…" => "Zhong", "盆" => "Pen", "盇" => "He", + "盈" => "Ying", "盉" => "He", "益" => "Yi", "盋" => "Bo", "盌" => "Wan", "ç›" => "He", + "盎" => "Ang", "ç›" => "Zhan", "ç›" => "Yan", "监" => "Jian", "ç›’" => "He", "盓" => "Yu", + "ç›”" => "Kui", "盕" => "Fan", "ç›–" => "Gai", "ç›—" => "Dao", "盘" => "Pan", "ç›™" => "Fu", + "盚" => "Qiu", "ç››" => "Sheng", "盜" => "Dao", "ç›" => "Lu", "盞" => "Zhan", "盟" => "Meng", + "ç› " => "Li", "盡" => "Jin", "盢" => "Xu", "監" => "Jian", "盤" => "Pan", "盥" => "Guan", + "盦" => "An", "盧" => "Lu", "盨" => "Shu", "盩" => "Zhou", "盪" => "Dang", "盫" => "An", + "盬" => "Gu", "ç›­" => "Li", "ç›®" => "Mu", "盯" => "Cheng", "ç›°" => "Gan", "ç›±" => "Xu", + "盲" => "Mang", "盳" => "Mang", "ç›´" => "Zhi", "盵" => "Qi", "盶" => "Ruan", "ç›·" => "Tian", + "相" => "Xiang", "盹" => "Dun", "盺" => "Xin", "ç›»" => "Xi", "盼" => "Pan", "盽" => "Feng", + "盾" => "Dun", "盿" => "Min", "çœ" => "Sheng", "眂" => "Shi", "眃" => "Yun", "眄" => "Mian", + "眅" => "Pan", "眆" => "Fang", "眇" => "Miao", "眈" => "Dan", "眉" => "Mei", "眊" => "Mao", + "看" => "Kan", "県" => "Xian", "çœ" => "Ou", "眎" => "Shi", "çœ" => "Yang", "çœ" => "Zheng", + "眑" => "Yao", "眒" => "Shen", "眓" => "Huo", "眔" => "Da", "眕" => "Zhen", "眖" => "Kuang", + "眗" => "Ju", "眘" => "Shen", "眙" => "Chi", "眚" => "Sheng", "眛" => "Mei", "眜" => "Mo", + "çœ" => "Zhu", "眞" => "Zhen", "真" => "Zhen", "眠" => "Mian", "眡" => "Di", "眢" => "Yuan", + "眣" => "Die", "眤" => "Yi", "眥" => "Zi", "眦" => "Zi", "眧" => "Chao", "眨" => "Zha", + "眩" => "Xuan", "眪" => "Bing", "眫" => "Mi", "眬" => "Long", "眭" => "Sui", "眮" => "Dong", + "眯" => "Mi", "眰" => "Die", "眱" => "Yi", "眲" => "Er", "眳" => "Ming", "眴" => "Xuan", + "眵" => "Chi", "眶" => "Kuang", "眷" => "Juan", "眸" => "Mou", "眹" => "Zhen", "眺" => "Tiao", + "眻" => "Yang", "眼" => "Yan", "眽" => "Mo", "眾" => "Zhong", "眿" => "Mai", "ç€" => "Zhao", + "ç" => "Zheng", "ç‚" => "Mei", "çƒ" => "Jun", "ç„" => "Shao", "ç…" => "Han", "ç†" => "Huan", + "ç‡" => "Di", "çˆ" => "Cheng", "ç‰" => "Cuo", "çŠ" => "Juan", "ç‹" => "E", "çŒ" => "Wan", + "ç" => "Xian", "çŽ" => "Xi", "ç" => "Kun", "ç" => "Lai", "ç‘" => "Jian", "ç’" => "Shan", + "ç“" => "Tian", "ç”" => "Hun", "ç•" => "Wan", "ç–" => "Ling", "ç—" => "Shi", "ç˜" => "Qiong", + "ç™" => "Lie", "çš" => "Yai", "ç›" => "Jing", "çœ" => "Zheng", "ç" => "Li", "çž" => "Lai", + "çŸ" => "Sui", "ç " => "Juan", "ç¡" => "Shui", "ç¢" => "Sui", "ç£" => "Du", "ç¤" => "Bi", + "ç¥" => "Bi", "ç¦" => "Mu", "ç§" => "Hun", "ç¨" => "Ni", "ç©" => "Lu", "çª" => "Yi", + "ç«" => "Jie", "ç¬" => "Cai", "ç­" => "Zhou", "ç®" => "Yu", "ç¯" => "Hun", "ç°" => "Ma", + "ç±" => "Xia", "ç²" => "Xing", "ç³" => "Xi", "ç´" => "Gun", "çµ" => "Cai", "ç¶" => "Chun", + "ç·" => "Jian", "ç¸" => "Mei", "ç¹" => "Du", "çº" => "Hou", "ç»" => "Xuan", "ç¼" => "Ti", + "ç½" => "Kui", "ç¾" => "Gao", "ç¿" => "Rui", "瞀" => "Mou", "çž" => "Xu", "çž‚" => "Fa", + "瞃" => "Wen", "çž„" => "Miao", "çž…" => "Chou", "瞆" => "Kui", "瞇" => "Mi", "瞈" => "Weng", + "瞉" => "Kou", "瞊" => "Dang", "çž‹" => "Chen", "瞌" => "Ke", "çž" => "Sou", "瞎" => "Xia", + "çž" => "Qiong", "çž" => "Mao", "çž‘" => "Ming", "çž’" => "Man", "çž“" => "Shui", "çž”" => "Ze", + "çž•" => "Zhang", "çž–" => "Yi", "çž—" => "Diao", "瞘" => "Ou", "çž™" => "Mo", "çžš" => "Shun", + "çž›" => "Cong", "çžœ" => "Lou", "çž" => "Chi", "çžž" => "Man", "瞟" => "Piao", "çž " => "Cheng", + "çž¡" => "Ji", "瞢" => "Meng", "瞤" => "Run", "瞥" => "Pie", "瞦" => "Xi", "瞧" => "Qiao", + "瞨" => "Pu", "çž©" => "Zhu", "瞪" => "Deng", "çž«" => "Shen", "瞬" => "Shun", "çž­" => "Liao", + "çž®" => "Che", "瞯" => "Xian", "çž°" => "Kan", "çž±" => "Ye", "çž²" => "Xu", "çž³" => "Tong", + "çž´" => "Mou", "çžµ" => "Lin", "瞶" => "Kui", "çž·" => "Xian", "瞸" => "Ye", "çž¹" => "Ai", + "瞺" => "Hui", "çž»" => "Zhan", "çž¼" => "Jian", "çž½" => "Gu", "çž¾" => "Zhao", "çž¿" => "Qu", + "矀" => "Wei", "çŸ" => "Chou", "矂" => "Sao", "矃" => "Ning", "矄" => "Xun", "矅" => "Yao", + "矆" => "Huo", "矇" => "Meng", "矈" => "Mian", "矉" => "Bin", "矊" => "Mian", "矋" => "Li", + "矌" => "Kuang", "çŸ" => "Jue", "矎" => "Xuan", "çŸ" => "Mian", "çŸ" => "Huo", "矑" => "Lu", + "矒" => "Meng", "矓" => "Long", "矔" => "Guan", "矕" => "Man", "矖" => "Xi", "矗" => "Chu", + "矘" => "Tang", "矙" => "Kan", "矚" => "Zhu", "矛" => "Mao", "矜" => "Jin", "çŸ" => "Lin", + "矞" => "Yu", "矟" => "Shuo", "矠" => "Ce", "矡" => "Jue", "矢" => "Shi", "矣" => "Yi", + "矤" => "Shen", "知" => "Zhi", "矦" => "Hou", "矧" => "Shen", "矨" => "Ying", "矩" => "Ju", + "矪" => "Zhou", "矫" => "Jiao", "矬" => "Cuo", "短" => "Duan", "矮" => "Ai", "矯" => "Jiao", + "矰" => "Zeng", "矱" => "Huo", "矲" => "Bai", "石" => "Shi", "矴" => "Ding", "矵" => "Qi", + "矶" => "Ji", "矷" => "Zi", "矸" => "Gan", "矹" => "Wu", "矺" => "Tuo", "矻" => "Ku", + "矼" => "Qiang", "矽" => "Xi", "矾" => "Fan", "矿" => "Kuang", "ç " => "Ma", "ç ‚" => "Sha", + "ç ƒ" => "Dan", "ç „" => "Jue", "ç …" => "Li", "ç †" => "Fu", "ç ‡" => "Min", "ç ˆ" => "Nuo", + "ç ‰" => "Huo", "ç Š" => "Kang", "ç ‹" => "Zhi", "ç Œ" => "Qi", "ç " => "Kan", "ç Ž" => "Jie", + "ç " => "Fen", "ç " => "E", "ç ‘" => "Ya", "ç ’" => "Pi", "ç “" => "Zhe", "ç ”" => "Yan", + "ç •" => "Sui", "ç –" => "Zhuan", "ç —" => "Che", "ç ˜" => "Dun", "ç ™" => "Pan", "ç š" => "Yan", + "ç œ" => "Feng", "ç " => "Fa", "ç ž" => "Mo", "ç Ÿ" => "Zha", "ç  " => "Qu", "ç ¡" => "Yu", + "ç ¢" => "Luo", "ç £" => "Tuo", "ç ¤" => "Tuo", "ç ¥" => "Di", "ç ¦" => "Zhai", "ç §" => "Zhen", + "ç ¨" => "Ai", "ç ©" => "Fei", "ç ª" => "Mu", "ç «" => "Zhu", "ç ¬" => "Li", "ç ­" => "Bian", + "ç ®" => "Nu", "ç ¯" => "Ping", "ç °" => "Peng", "ç ±" => "Ling", "ç ²" => "Pao", "ç ³" => "Le", + "ç ´" => "Po", "ç µ" => "Bo", "ç ¶" => "Po", "ç ·" => "Shen", "ç ¸" => "Za", "ç ¹" => "Nuo", + "ç º" => "Li", "ç »" => "Long", "ç ¼" => "Tong", "ç ¾" => "Li", "ç ¿" => "Aragane", "ç¡€" => "Chu", + "ç¡" => "Keng", "ç¡‚" => "Quan", "硃" => "Zhu", "ç¡„" => "Kuang", "ç¡…" => "Huo", "硆" => "E", + "硇" => "Nao", "硈" => "Jia", "硉" => "Lu", "ç¡Š" => "Wei", "ç¡‹" => "Ai", "ç¡Œ" => "Luo", + "ç¡" => "Ken", "ç¡Ž" => "Xing", "ç¡" => "Yan", "ç¡" => "Tong", "ç¡‘" => "Peng", "ç¡’" => "Xi", + "ç¡”" => "Hong", "ç¡•" => "Shuo", "ç¡–" => "Xia", "ç¡—" => "Qiao", "ç¡™" => "Wei", "ç¡š" => "Qiao", + "ç¡œ" => "Keng", "ç¡" => "Xiao", "ç¡ž" => "Que", "ç¡Ÿ" => "Chan", "ç¡ " => "Lang", "ç¡¡" => "Hong", + "ç¡¢" => "Yu", "ç¡£" => "Xiao", "硤" => "Xia", "ç¡¥" => "Mang", "硦" => "Long", "硧" => "Iong", + "硨" => "Che", "ç¡©" => "Che", "硪" => "E", "ç¡«" => "Liu", "硬" => "Ying", "ç¡­" => "Mang", + "ç¡®" => "Que", "硯" => "Yan", "ç¡°" => "Sha", "硱" => "Kun", "硲" => "Yu", "ç¡´" => "Kaki", + "硵" => "Lu", "硶" => "Chen", "ç¡·" => "Jian", "硸" => "Nue", "硹" => "Song", "硺" => "Zhuo", + "ç¡»" => "Keng", "硼" => "Peng", "硽" => "Yan", "硾" => "Zhui", "ç¡¿" => "Kong", "碀" => "Ceng", + "ç¢" => "Qi", "碂" => "Zong", "碃" => "Qing", "碄" => "Lin", "碅" => "Jun", "碆" => "Bo", + "碇" => "Ding", "碈" => "Min", "碉" => "Diao", "碊" => "Jian", "碋" => "He", "碌" => "Lu", + "ç¢" => "Ai", "碎" => "Sui", "ç¢" => "Que", "ç¢" => "Ling", "碑" => "Bei", "碒" => "Yin", + "碓" => "Dui", "碔" => "Wu", "碕" => "Qi", "碖" => "Lun", "碗" => "Wan", "碘" => "Dian", + "碙" => "Gang", "碚" => "Pei", "碛" => "Qi", "碜" => "Chen", "ç¢" => "Ruan", "碞" => "Yan", + "碟" => "Die", "碠" => "Ding", "碡" => "Du", "碢" => "Tuo", "碣" => "Jie", "碤" => "Ying", + "碥" => "Bian", "碦" => "Ke", "碧" => "Bi", "碨" => "Wei", "碩" => "Shuo", "碪" => "Zhen", + "碫" => "Duan", "碬" => "Xia", "碭" => "Dang", "碮" => "Ti", "碯" => "Nao", "碰" => "Peng", + "碱" => "Jian", "碲" => "Di", "碳" => "Tan", "碴" => "Cha", "碵" => "Seki", "碶" => "Qi", + "碸" => "Feng", "碹" => "Xuan", "確" => "Que", "碻" => "Que", "碼" => "Ma", "碽" => "Gong", + "碾" => "Nian", "碿" => "Su", "磀" => "E", "ç£" => "Ci", "磂" => "Liu", "磃" => "Si", + "磄" => "Tang", "磅" => "Bang", "磆" => "Hua", "磇" => "Pi", "磈" => "Wei", "磉" => "Sang", + "磊" => "Lei", "磋" => "Cuo", "磌" => "Zhen", "ç£" => "Xia", "磎" => "Qi", "ç£" => "Lian", + "ç£" => "Pan", "磑" => "Wei", "磒" => "Yun", "磓" => "Dui", "磔" => "Zhe", "磕" => "Ke", + "磖" => "La", "磘" => "Qing", "磙" => "Gun", "磚" => "Zhuan", "磛" => "Chan", "磜" => "Qi", + "ç£" => "Ao", "磞" => "Peng", "磟" => "Lu", "磠" => "Lu", "磡" => "Kan", "磢" => "Qiang", + "磣" => "Chen", "磤" => "Yin", "磥" => "Lei", "磦" => "Biao", "磧" => "Qi", "磨" => "Mo", + "磩" => "Qi", "磪" => "Cui", "磫" => "Zong", "磬" => "Qing", "磭" => "Chuo", "磯" => "Ji", + "磰" => "Shan", "磱" => "Lao", "磲" => "Qu", "磳" => "Zeng", "磴" => "Deng", "磵" => "Jian", + "磶" => "Xi", "磷" => "Lin", "磸" => "Ding", "磹" => "Dian", "磺" => "Huang", "磻" => "Pan", + "磼" => "Za", "磽" => "Qiao", "磾" => "Di", "磿" => "Li", "ç¤" => "Jiao", "礃" => "Zhang", + "礄" => "Qiao", "礅" => "Dun", "礆" => "Xian", "礇" => "Yu", "礈" => "Zhui", "礉" => "He", + "礊" => "Huo", "礋" => "Zhai", "礌" => "Lei", "ç¤" => "Ke", "礎" => "Chu", "ç¤" => "Ji", + "ç¤" => "Que", "礑" => "Dang", "礒" => "Yi", "礓" => "Jiang", "礔" => "Pi", "礕" => "Pi", + "礖" => "Yu", "礗" => "Pin", "礘" => "Qi", "礙" => "Ai", "礚" => "Kai", "礛" => "Jian", + "礜" => "Yu", "ç¤" => "Ruan", "礞" => "Meng", "礟" => "Pao", "礠" => "Ci", "礣" => "Mie", + "礤" => "Ca", "礥" => "Xian", "礦" => "Kuang", "礧" => "Lei", "礨" => "Lei", "礩" => "Zhi", + "礪" => "Li", "礫" => "Li", "礬" => "Fan", "礭" => "Que", "礮" => "Pao", "礯" => "Ying", + "礰" => "Li", "礱" => "Long", "礲" => "Long", "礳" => "Mo", "礴" => "Bo", "礵" => "Shuang", + "礶" => "Guan", "礷" => "Lan", "礸" => "Zan", "礹" => "Yan", "示" => "Shi", "礻" => "Shi", + "礼" => "Li", "礽" => "Reng", "社" => "She", "礿" => "Yue", "祀" => "Si", "ç¥" => "Qi", + "祂" => "Ta", "祃" => "Ma", "祄" => "Xie", "祅" => "Xian", "祆" => "Xian", "祇" => "Zhi", + "祈" => "Qi", "祉" => "Zhi", "祊" => "Beng", "祋" => "Dui", "祌" => "Zhong", "祎" => "Yi", + "ç¥" => "Shi", "ç¥" => "You", "祑" => "Zhi", "祒" => "Tiao", "祓" => "Fu", "祔" => "Fu", + "祕" => "Mi", "祖" => "Zu", "祗" => "Zhi", "祘" => "Suan", "祙" => "Mei", "祚" => "Zuo", + "祛" => "Qu", "祜" => "Hu", "ç¥" => "Zhu", "神" => "Shen", "祟" => "Sui", "祠" => "Ci", + "祡" => "Chai", "祢" => "Mi", "祣" => "Lu", "祤" => "Yu", "祥" => "Xiang", "祦" => "Wu", + "祧" => "Tiao", "票" => "Piao", "祩" => "Zhu", "祪" => "Gui", "祫" => "Xia", "祬" => "Zhi", + "祭" => "Ji", "祮" => "Gao", "祯" => "Zhen", "祰" => "Gao", "祱" => "Shui", "祲" => "Jin", + "祳" => "Chen", "祴" => "Gai", "祵" => "Kun", "祶" => "Di", "祷" => "Dao", "祸" => "Huo", + "祹" => "Tao", "祺" => "Qi", "祻" => "Gu", "祼" => "Guan", "祽" => "Zui", "祾" => "Ling", + "祿" => "Lu", "禀" => "Bing", "ç¦" => "Jin", "禂" => "Dao", "禃" => "Zhi", "禄" => "Lu", + "禅" => "Shan", "禆" => "Bei", "禇" => "Zhe", "禈" => "Hui", "禉" => "You", "禊" => "Xi", + "禋" => "Yin", "禌" => "Zi", "ç¦" => "Huo", "禎" => "Zhen", "ç¦" => "Fu", "ç¦" => "Yuan", + "禑" => "Wu", "禒" => "Xian", "禓" => "Yang", "禔" => "Ti", "禕" => "Yi", "禖" => "Mei", + "禗" => "Si", "禘" => "Di", "禚" => "Zhuo", "禛" => "Zhen", "禜" => "Yong", "ç¦" => "Ji", + "禞" => "Gao", "禟" => "Tang", "禠" => "Si", "禡" => "Ma", "禢" => "Ta", "禤" => "Xuan", + "禥" => "Qi", "禦" => "Yu", "禧" => "Xi", "禨" => "Ji", "禩" => "Si", "禪" => "Chan", + "禫" => "Tan", "禬" => "Kuai", "禭" => "Sui", "禮" => "Li", "禯" => "Nong", "禰" => "Ni", + "禱" => "Dao", "禲" => "Li", "禳" => "Rang", "禴" => "Yue", "禵" => "Ti", "禶" => "Zan", + "禷" => "Lei", "禸" => "Rou", "禹" => "Yu", "禺" => "Yu", "离" => "Chi", "禼" => "Xie", + "禽" => "Qin", "禾" => "He", "禿" => "Tu", "秀" => "Xiu", "ç§" => "Si", "秂" => "Ren", + "秃" => "Tu", "秄" => "Zi", "秅" => "Cha", "秆" => "Gan", "秇" => "Yi", "秈" => "Xian", + "秉" => "Bing", "秊" => "Nian", "秋" => "Qiu", "秌" => "Qiu", "ç§" => "Chong", "秎" => "Fen", + "ç§" => "Hao", "ç§" => "Yun", "科" => "Ke", "秒" => "Miao", "秓" => "Zhi", "秔" => "Geng", + "秕" => "Bi", "秖" => "Zhi", "秗" => "Yu", "秘" => "Mi", "秙" => "Ku", "秚" => "Ban", + "秛" => "Pi", "秜" => "Ni", "ç§" => "Li", "秞" => "You", "租" => "Zu", "秠" => "Pi", + "秡" => "Ba", "秢" => "Ling", "秣" => "Mo", "秤" => "Cheng", "秥" => "Nian", "秦" => "Qin", + "秧" => "Yang", "秨" => "Zuo", "秩" => "Zhi", "秪" => "Zhi", "秫" => "Shu", "秬" => "Ju", + "秭" => "Zi", "秮" => "Huo", "积" => "Ji", "称" => "Cheng", "秱" => "Tong", "秲" => "Zhi", + "秳" => "Huo", "秴" => "He", "秵" => "Yin", "秶" => "Zi", "秷" => "Zhi", "秸" => "Jie", + "秹" => "Ren", "秺" => "Du", "移" => "Yi", "秼" => "Zhu", "秽" => "Hui", "秾" => "Nong", + "秿" => "Fu", "ç¨" => "Kao", "稂" => "Lang", "稃" => "Fu", "稄" => "Ze", "稅" => "Shui", + "稆" => "Lu", "稇" => "Kun", "稈" => "Gan", "稉" => "Geng", "稊" => "Ti", "程" => "Cheng", + "稌" => "Tu", "ç¨" => "Shao", "税" => "Shui", "ç¨" => "Ya", "ç¨" => "Lun", "稑" => "Lu", + "稒" => "Gu", "稓" => "Zuo", "稔" => "Ren", "稕" => "Zhun", "稖" => "Bang", "稗" => "Bai", + "稘" => "Ji", "稙" => "Zhi", "稚" => "Zhi", "稛" => "Kun", "稜" => "Leng", "ç¨" => "Peng", + "稞" => "Ke", "稟" => "Bing", "稠" => "Chou", "稡" => "Zu", "稢" => "Yu", "稣" => "Su", + "稤" => "Lue", "稦" => "Yi", "稧" => "Xi", "稨" => "Bian", "稩" => "Ji", "稪" => "Fu", + "稫" => "Bi", "稬" => "Nuo", "稭" => "Jie", "種" => "Zhong", "稯" => "Zong", "稰" => "Xu", + "稱" => "Cheng", "稲" => "Dao", "稳" => "Wen", "稴" => "Lian", "稵" => "Zi", "稶" => "Yu", + "稷" => "Ji", "稸" => "Xu", "稹" => "Zhen", "稺" => "Zhi", "稻" => "Dao", "稼" => "Jia", + "稽" => "Ji", "稾" => "Gao", "稿" => "Gao", "ç©€" => "Gu", "ç©" => "Rong", "ç©‚" => "Sui", + "穃" => "You", "ç©„" => "Ji", "ç©…" => "Kang", "穆" => "Mu", "穇" => "Shan", "穈" => "Men", + "穉" => "Zhi", "ç©Š" => "Ji", "ç©‹" => "Lu", "ç©Œ" => "Su", "ç©" => "Ji", "ç©Ž" => "Ying", + "ç©" => "Wen", "ç©" => "Qiu", "ç©‘" => "Se", "ç©“" => "Yi", "ç©”" => "Huang", "ç©•" => "Qie", + "ç©–" => "Ji", "ç©—" => "Sui", "穘" => "Xiao", "ç©™" => "Pu", "ç©š" => "Jiao", "ç©›" => "Zhuo", + "ç©œ" => "Tong", "ç©" => "Sai", "ç©ž" => "Lu", "ç©Ÿ" => "Sui", "ç© " => "Nong", "ç©¡" => "Se", + "ç©¢" => "Hui", "ç©£" => "Rang", "穤" => "Nuo", "ç©¥" => "Yu", "穦" => "Bin", "穧" => "Ji", + "穨" => "Tui", "ç©©" => "Wen", "穪" => "Cheng", "ç©«" => "Huo", "穬" => "Gong", "ç©­" => "Lu", + "ç©®" => "Biao", "ç©°" => "Rang", "穱" => "Zhuo", "穲" => "Li", "穳" => "Zan", "ç©´" => "Xue", + "穵" => "Wa", "究" => "Jiu", "ç©·" => "Qiong", "穸" => "Xi", "穹" => "Qiong", "空" => "Kong", + "ç©»" => "Yu", "穼" => "Sen", "穽" => "Jing", "穾" => "Yao", "ç©¿" => "Chuan", "窀" => "Zhun", + "çª" => "Tu", "窂" => "Lao", "窃" => "Qie", "窄" => "Zhai", "窅" => "Yao", "窆" => "Bian", + "窇" => "Bao", "窈" => "Yao", "窉" => "Bing", "窊" => "Wa", "窋" => "Zhu", "窌" => "Jiao", + "çª" => "Qiao", "窎" => "Diao", "çª" => "Wu", "çª" => "Gui", "窑" => "Yao", "窒" => "Zhi", + "窓" => "Chuang", "窔" => "Yao", "窕" => "Tiao", "窖" => "Jiao", "窗" => "Chuang", "窘" => "Jiong", + "窙" => "Xiao", "窚" => "Cheng", "窛" => "Kou", "窜" => "Cuan", "çª" => "Wo", "窞" => "Dan", + "窟" => "Ku", "窠" => "Ke", "窡" => "Zhui", "窢" => "Xu", "窣" => "Su", "窤" => "Guan", + "窥" => "Kui", "窦" => "Dou", "窨" => "Yin", "窩" => "Wo", "窪" => "Wa", "窫" => "Ya", + "窬" => "Yu", "窭" => "Ju", "窮" => "Qiong", "窯" => "Yao", "窰" => "Yao", "窱" => "Tiao", + "窲" => "Chao", "窳" => "Yu", "窴" => "Tian", "窵" => "Diao", "窶" => "Ju", "窷" => "Liao", + "窸" => "Xi", "窹" => "Wu", "窺" => "Kui", "窻" => "Chuang", "窼" => "Zhao", "窾" => "Kuan", + "窿" => "Long", "ç«€" => "Cheng", "ç«" => "Cui", "ç«‚" => "Piao", "竃" => "Zao", "ç«„" => "Cuan", + "ç«…" => "Qiao", "竆" => "Qiong", "竇" => "Dou", "竈" => "Zao", "竉" => "Long", "ç«Š" => "Qie", + "ç«‹" => "Li", "ç«Œ" => "Chu", "ç«" => "Shi", "ç«Ž" => "Fou", "ç«" => "Qian", "ç«" => "Chu", + "ç«‘" => "Hong", "ç«’" => "Qi", "ç«“" => "Qian", "ç«”" => "Gong", "ç«•" => "Shi", "ç«–" => "Shu", + "ç«—" => "Miao", "竘" => "Ju", "ç«™" => "Zhan", "ç«š" => "Zhu", "ç«›" => "Ling", "ç«œ" => "Long", + "ç«" => "Bing", "ç«ž" => "Jing", "ç«Ÿ" => "Jing", "ç« " => "Zhang", "ç«¡" => "Yi", "ç«¢" => "Si", + "ç«£" => "Jun", "竤" => "Hong", "ç«¥" => "Tong", "竦" => "Song", "竧" => "Jing", "竨" => "Diao", + "ç«©" => "Yi", "竪" => "Shu", "ç««" => "Jing", "竬" => "Qu", "ç«­" => "Jie", "ç«®" => "Ping", + "端" => "Duan", "ç«°" => "Shao", "竱" => "Zhuan", "竲" => "Ceng", "竳" => "Deng", "ç«´" => "Cui", + "竵" => "Huai", "競" => "Jing", "ç«·" => "Kan", "竸" => "Jing", "竹" => "Zhu", "竺" => "Zhu", + "ç«»" => "Le", "竼" => "Peng", "竽" => "Yu", "竾" => "Chi", "ç«¿" => "Gan", "ç¬" => "Zhu", + "笂" => "Utsubo", "笃" => "Du", "笄" => "Ji", "笅" => "Xiao", "笆" => "Ba", "笇" => "Suan", + "笈" => "Ji", "笉" => "Zhen", "笊" => "Zhao", "笋" => "Sun", "笌" => "Ya", "ç¬" => "Zhui", + "笎" => "Yuan", "ç¬" => "Hu", "ç¬" => "Gang", "笑" => "Xiao", "笒" => "Cen", "笓" => "Pi", + "笔" => "Bi", "笕" => "Jian", "笖" => "Yi", "笗" => "Dong", "笘" => "Shan", "笙" => "Sheng", + "笚" => "Xia", "笛" => "Di", "笜" => "Zhu", "ç¬" => "Na", "笞" => "Chi", "笟" => "Gu", + "笠" => "Li", "笡" => "Qie", "笢" => "Min", "笣" => "Bao", "笤" => "Tiao", "笥" => "Si", + "符" => "Fu", "笧" => "Ce", "笨" => "Ben", "笩" => "Pei", "笪" => "Da", "笫" => "Zi", + "第" => "Di", "笭" => "Ling", "笮" => "Ze", "笯" => "Nu", "笰" => "Fu", "笱" => "Gou", + "笲" => "Fan", "笳" => "Jia", "笴" => "Ge", "笵" => "Fan", "笶" => "Shi", "笷" => "Mao", + "笸" => "Po", "笹" => "Sey", "笺" => "Jian", "笻" => "Qiong", "笼" => "Long", "笽" => "Souke", + "笾" => "Bian", "笿" => "Luo", "ç­€" => "Gui", "ç­" => "Qu", "ç­‚" => "Chi", "ç­ƒ" => "Yin", + "ç­„" => "Yao", "ç­…" => "Xian", "ç­†" => "Bi", "ç­‡" => "Qiong", "ç­ˆ" => "Gua", "ç­‰" => "Deng", + "ç­Š" => "Jiao", "ç­‹" => "Jin", "ç­Œ" => "Quan", "ç­" => "Sun", "ç­Ž" => "Ru", "ç­" => "Fa", + "ç­" => "Kuang", "ç­‘" => "Zhu", "ç­’" => "Tong", "ç­“" => "Ji", "ç­”" => "Da", "ç­•" => "Xing", + "ç­–" => "Ce", "ç­—" => "Zhong", "ç­˜" => "Kou", "ç­™" => "Lai", "ç­š" => "Bi", "ç­›" => "Shai", + "ç­œ" => "Dang", "ç­" => "Zheng", "ç­ž" => "Ce", "ç­Ÿ" => "Fu", "ç­ " => "Yun", "ç­¡" => "Tu", + "ç­¢" => "Pa", "ç­£" => "Li", "ç­¤" => "Lang", "ç­¥" => "Ju", "ç­¦" => "Guan", "ç­§" => "Jian", + "ç­¨" => "Han", "ç­©" => "Tong", "ç­ª" => "Xia", "ç­«" => "Zhi", "ç­¬" => "Cheng", "ç­­" => "Suan", + "ç­®" => "Shi", "ç­¯" => "Zhu", "ç­°" => "Zuo", "ç­±" => "Xiao", "ç­²" => "Shao", "ç­³" => "Ting", + "ç­´" => "Ce", "ç­µ" => "Yan", "ç­¶" => "Gao", "ç­·" => "Kuai", "ç­¸" => "Gan", "ç­¹" => "Chou", + "ç­º" => "Kago", "ç­»" => "Gang", "ç­¼" => "Yun", "ç­½" => "O", "ç­¾" => "Qian", "ç­¿" => "Xiao", + "简" => "Jian", "ç®" => "Pu", "箂" => "Lai", "箃" => "Zou", "箄" => "Bi", "ç®…" => "Bi", + "箆" => "Bi", "箇" => "Ge", "箈" => "Chi", "箉" => "Guai", "箊" => "Yu", "箋" => "Jian", + "箌" => "Zhao", "ç®" => "Gu", "箎" => "Chi", "ç®" => "Zheng", "ç®" => "Jing", "箑" => "Sha", + "ç®’" => "Zhou", "箓" => "Lu", "ç®”" => "Bo", "箕" => "Ji", "ç®–" => "Lin", "ç®—" => "Suan", + "箘" => "Jun", "ç®™" => "Fu", "箚" => "Zha", "ç®›" => "Gu", "箜" => "Kong", "ç®" => "Qian", + "箞" => "Quan", "箟" => "Jun", "ç® " => "Chui", "管" => "Guan", "箢" => "Yuan", "箣" => "Ce", + "箤" => "Ju", "箥" => "Bo", "箦" => "Ze", "箧" => "Qie", "箨" => "Tuo", "箩" => "Luo", + "箪" => "Dan", "箫" => "Xiao", "箬" => "Ruo", "ç®­" => "Jian", "ç®®" => "Xuan", "箯" => "Bian", + "ç®°" => "Sun", "ç®±" => "Xiang", "箲" => "Xian", "箳" => "Ping", "ç®´" => "Zhen", "箵" => "Sheng", + "箶" => "Hu", "ç®·" => "Shi", "箸" => "Zhu", "箹" => "Yue", "箺" => "Chun", "ç®»" => "Lu", + "箼" => "Wu", "箽" => "Dong", "箾" => "Xiao", "箿" => "Ji", "節" => "Jie", "ç¯" => "Huang", + "篂" => "Xing", "篃" => "Mei", "範" => "Fan", "篅" => "Chui", "篆" => "Zhuan", "篇" => "Pian", + "篈" => "Feng", "築" => "Zhu", "篊" => "Hong", "篋" => "Qie", "篌" => "Hou", "ç¯" => "Qiu", + "篎" => "Miao", "ç¯" => "Qian", "篑" => "Kui", "篒" => "Sik", "篓" => "Lou", "篔" => "Yun", + "篕" => "He", "篖" => "Tang", "篗" => "Yue", "篘" => "Chou", "篙" => "Gao", "篚" => "Fei", + "篛" => "Ruo", "篜" => "Zheng", "ç¯" => "Gou", "篞" => "Nie", "篟" => "Qian", "篠" => "Xiao", + "篡" => "Cuan", "篢" => "Gong", "篣" => "Pang", "篤" => "Du", "篥" => "Li", "篦" => "Bi", + "篧" => "Zhuo", "篨" => "Chu", "篩" => "Shai", "篪" => "Chi", "篫" => "Zhu", "篬" => "Qiang", + "篭" => "Long", "篮" => "Lan", "篯" => "Jian", "篰" => "Bu", "篱" => "Li", "篲" => "Hui", + "篳" => "Bi", "篴" => "Di", "篵" => "Cong", "篶" => "Yan", "篷" => "Peng", "篸" => "Sen", + "篹" => "Zhuan", "篺" => "Pai", "篻" => "Piao", "篼" => "Dou", "篽" => "Yu", "篾" => "Mie", + "篿" => "Zhuan", "ç°" => "Xi", "ç°‚" => "Guo", "ç°ƒ" => "Yi", "ç°„" => "Hu", "ç°…" => "Chan", + "ç°†" => "Kou", "ç°‡" => "Cu", "ç°ˆ" => "Ping", "ç°‰" => "Chou", "ç°Š" => "Ji", "ç°‹" => "Gui", + "ç°Œ" => "Su", "ç°" => "Lou", "ç°Ž" => "Zha", "ç°" => "Lu", "ç°" => "Nian", "ç°‘" => "Suo", + "ç°’" => "Cuan", "ç°“" => "Sasara", "ç°”" => "Suo", "ç°•" => "Le", "ç°–" => "Duan", "ç°—" => "Yana", + "ç°˜" => "Xiao", "ç°™" => "Bo", "ç°š" => "Mi", "ç°›" => "Si", "ç°œ" => "Dang", "ç°" => "Liao", + "ç°ž" => "Dan", "ç°Ÿ" => "Dian", "ç° " => "Fu", "ç°¡" => "Jian", "ç°¢" => "Min", "ç°£" => "Kui", + "ç°¤" => "Dai", "ç°¥" => "Qiao", "ç°¦" => "Deng", "ç°§" => "Huang", "ç°¨" => "Sun", "ç°©" => "Lao", + "ç°ª" => "Zan", "ç°«" => "Xiao", "ç°¬" => "Du", "ç°­" => "Shi", "ç°®" => "Zan", "ç°°" => "Pai", + "ç°±" => "Hata", "ç°²" => "Pai", "ç°³" => "Gan", "ç°´" => "Ju", "ç°µ" => "Du", "ç°¶" => "Lu", + "ç°·" => "Yan", "ç°¸" => "Bo", "ç°¹" => "Dang", "ç°º" => "Sai", "ç°»" => "Ke", "ç°¼" => "Long", + "ç°½" => "Qian", "ç°¾" => "Lian", "ç°¿" => "Bo", "ç±€" => "Zhou", "ç±" => "Lai", "籃" => "Lan", + "籄" => "Kui", "ç±…" => "Yu", "籆" => "Yue", "籇" => "Hao", "籈" => "Zhen", "籉" => "Tai", + "籊" => "Ti", "籋" => "Mi", "籌" => "Chou", "ç±" => "Ji", "ç±" => "Hata", "ç±" => "Teng", + "籑" => "Zhuan", "ç±’" => "Zhou", "籓" => "Fan", "ç±”" => "Sou", "籕" => "Zhou", "ç±–" => "Kuji", + "ç±—" => "Zhuo", "籘" => "Teng", "ç±™" => "Lu", "籚" => "Lu", "ç±›" => "Jian", "籜" => "Tuo", + "ç±" => "Ying", "籞" => "Yu", "籟" => "Lai", "ç± " => "Long", "籡" => "Shinshi", "ç±¢" => "Lian", + "ç±£" => "Lan", "籤" => "Qian", "ç±¥" => "Yue", "籦" => "Zhong", "籧" => "Qu", "籨" => "Lian", + "籩" => "Bian", "籪" => "Duan", "籫" => "Zuan", "籬" => "Li", "ç±­" => "Si", "ç±®" => "Luo", + "籯" => "Ying", "ç±°" => "Yue", "ç±±" => "Zhuo", "ç±²" => "Xu", "ç±³" => "Mi", "ç±´" => "Di", + "ç±µ" => "Fan", "籶" => "Shen", "ç±·" => "Zhe", "籸" => "Shen", "ç±¹" => "Nu", "籺" => "Xie", + "ç±»" => "Lei", "ç±¼" => "Xian", "ç±½" => "Zi", "ç±¾" => "Ni", "籿" => "Cun", "ç²" => "Qian", + "粂" => "Kume", "粃" => "Bi", "粄" => "Ban", "ç²…" => "Wu", "粆" => "Sha", "粇" => "Kang", + "粈" => "Rou", "粉" => "Fen", "粊" => "Bi", "粋" => "Cui", "ç²" => "Li", "粎" => "Chi", + "ç²" => "Nukamiso", "ç²" => "Ro", "粑" => "Ba", "ç²’" => "Li", "粓" => "Gan", "ç²”" => "Ju", + "粕" => "Po", "ç²–" => "Mo", "ç²—" => "Cu", "粘" => "Nian", "ç²™" => "Zhou", "粚" => "Li", + "ç²›" => "Su", "粜" => "Tiao", "ç²" => "Li", "粞" => "Qi", "粟" => "Su", "ç² " => "Hong", + "粡" => "Tong", "ç²¢" => "Zi", "ç²£" => "Ce", "粤" => "Yue", "ç²¥" => "Zhou", "粦" => "Lin", + "粧" => "Zhuang", "粨" => "Bai", "粪" => "Fen", "粫" => "Ji", "ç²­" => "Sukumo", "ç²®" => "Liang", + "粯" => "Xian", "ç²°" => "Fu", "ç²±" => "Liang", "ç²²" => "Can", "ç²³" => "Geng", "ç²´" => "Li", + "ç²µ" => "Yue", "粶" => "Lu", "ç²·" => "Ju", "粸" => "Qi", "ç²¹" => "Cui", "粺" => "Bai", + "ç²»" => "Zhang", "ç²¼" => "Lin", "ç²½" => "Zong", "ç²¾" => "Jing", "粿" => "Guo", "ç³€" => "Kouji", + "ç³" => "San", "糂" => "San", "糃" => "Tang", "糄" => "Bian", "ç³…" => "Rou", "糆" => "Mian", + "糇" => "Hou", "糈" => "Xu", "糉" => "Zong", "糊" => "Hu", "糋" => "Jian", "糌" => "Zan", + "ç³" => "Ci", "糎" => "Li", "ç³" => "Xie", "ç³" => "Fu", "糑" => "Ni", "ç³’" => "Bei", + "糓" => "Gu", "ç³”" => "Xiu", "糕" => "Gao", "ç³–" => "Tang", "ç³—" => "Qiu", "糘" => "Sukumo", + "ç³™" => "Cao", "糚" => "Zhuang", "ç³›" => "Tang", "糜" => "Mi", "ç³" => "San", "糞" => "Fen", + "糟" => "Zao", "ç³ " => "Kang", "糡" => "Jiang", "ç³¢" => "Mo", "ç³£" => "San", "糤" => "San", + "ç³¥" => "Nuo", "糦" => "Xi", "糧" => "Liang", "糨" => "Jiang", "糩" => "Kuai", "糪" => "Bo", + "糫" => "Huan", "ç³­" => "Zong", "ç³®" => "Xian", "糯" => "Nuo", "ç³°" => "Tuan", "ç³±" => "Nie", + "ç³²" => "Li", "ç³³" => "Zuo", "ç³´" => "Di", "ç³µ" => "Nie", "糶" => "Tiao", "ç³·" => "Lan", + "糸" => "Mi", "ç³¹" => "Jiao", "糺" => "Jiu", "ç³»" => "Xi", "ç³¼" => "Gong", "ç³½" => "Zheng", + "ç³¾" => "Jiu", "糿" => "You", "ç´" => "Cha", "ç´‚" => "Zhou", "ç´ƒ" => "Xun", "ç´„" => "Yue", + "ç´…" => "Hong", "ç´†" => "Yu", "ç´‡" => "He", "ç´ˆ" => "Wan", "ç´‰" => "Ren", "ç´Š" => "Wen", + "ç´‹" => "Wen", "ç´Œ" => "Qiu", "ç´" => "Na", "ç´Ž" => "Zi", "ç´" => "Tou", "ç´" => "Niu", + "ç´‘" => "Fou", "ç´’" => "Jie", "ç´“" => "Shu", "ç´”" => "Chun", "ç´•" => "Pi", "ç´–" => "Yin", + "ç´—" => "Sha", "ç´˜" => "Hong", "ç´™" => "Zhi", "ç´š" => "Ji", "ç´›" => "Fen", "ç´œ" => "Yun", + "ç´" => "Ren", "ç´ž" => "Dan", "ç´Ÿ" => "Jin", "ç´ " => "Su", "ç´¡" => "Fang", "ç´¢" => "Suo", + "ç´£" => "Cui", "ç´¤" => "Jiu", "ç´¥" => "Zha", "ç´¦" => "Kinu", "ç´§" => "Jin", "ç´¨" => "Fu", + "ç´©" => "Zhi", "ç´ª" => "Ci", "ç´«" => "Zi", "ç´¬" => "Chou", "ç´­" => "Hong", "ç´®" => "Zha", + "ç´¯" => "Lei", "ç´°" => "Xi", "ç´±" => "Fu", "ç´²" => "Xie", "ç´³" => "Shen", "ç´´" => "Bei", + "ç´µ" => "Zhu", "ç´¶" => "Qu", "ç´·" => "Ling", "ç´¸" => "Zhu", "ç´¹" => "Shao", "ç´º" => "Gan", + "ç´»" => "Yang", "ç´¼" => "Fu", "ç´½" => "Tuo", "ç´¾" => "Zhen", "ç´¿" => "Dai", "çµ€" => "Zhuo", + "çµ" => "Shi", "終" => "Zhong", "絃" => "Xian", "組" => "Zu", "çµ…" => "Jiong", "絆" => "Ban", + "絇" => "Ju", "絈" => "Mo", "絉" => "Shu", "絊" => "Zui", "絋" => "Wata", "経" => "Jing", + "çµ" => "Ren", "絎" => "Heng", "çµ" => "Xie", "çµ" => "Jie", "絑" => "Zhu", "çµ’" => "Chou", + "絓" => "Gua", "çµ”" => "Bai", "絕" => "Jue", "çµ–" => "Kuang", "çµ—" => "Hu", "絘" => "Ci", + "çµ™" => "Geng", "絚" => "Geng", "çµ›" => "Tao", "絜" => "Xie", "çµ" => "Ku", "絞" => "Jiao", + "絟" => "Quan", "çµ " => "Gai", "絡" => "Luo", "çµ¢" => "Xuan", "çµ£" => "Bing", "絤" => "Xian", + "çµ¥" => "Fu", "給" => "Gei", "絧" => "Tong", "絨" => "Rong", "絩" => "Tiao", "絪" => "Yin", + "絫" => "Lei", "絬" => "Xie", "çµ­" => "Quan", "çµ®" => "Xu", "絯" => "Lun", "çµ°" => "Die", + "çµ±" => "Tong", "çµ²" => "Si", "çµ³" => "Jiang", "çµ´" => "Xiang", "çµµ" => "Hui", "絶" => "Jue", + "çµ·" => "Zhi", "絸" => "Jian", "çµ¹" => "Juan", "絺" => "Chi", "çµ»" => "Mian", "çµ¼" => "Zhen", + "çµ½" => "Lu", "çµ¾" => "Cheng", "絿" => "Qiu", "綀" => "Shu", "ç¶" => "Bang", "綂" => "Tong", + "綃" => "Xiao", "綄" => "Wan", "綅" => "Qin", "綆" => "Geng", "綇" => "Xiu", "綈" => "Ti", + "綉" => "Xiu", "綊" => "Xie", "綋" => "Hong", "綌" => "Xi", "ç¶" => "Fu", "綎" => "Ting", + "ç¶" => "Sui", "ç¶" => "Dui", "綑" => "Kun", "綒" => "Fu", "經" => "Jing", "綔" => "Hu", + "綕" => "Zhi", "綖" => "Yan", "綗" => "Jiong", "綘" => "Feng", "継" => "Ji", "続" => "Sok", + "綛" => "Kase", "綜" => "Zong", "ç¶" => "Lin", "綞" => "Duo", "綟" => "Li", "綠" => "Lu", + "綡" => "Liang", "綢" => "Chou", "綣" => "Quan", "綤" => "Shao", "綥" => "Qi", "綦" => "Qi", + "綧" => "Zhun", "綨" => "Qi", "綩" => "Wan", "綪" => "Qian", "綫" => "Xian", "綬" => "Shou", + "維" => "Wei", "綮" => "Qi", "綯" => "Tao", "綰" => "Wan", "綱" => "Gang", "網" => "Wang", + "綳" => "Beng", "綴" => "Zhui", "綵" => "Cai", "綶" => "Guo", "綷" => "Cui", "綸" => "Lun", + "綹" => "Liu", "綺" => "Qi", "綻" => "Zhan", "綼" => "Bei", "綽" => "Chuo", "綾" => "Ling", + "綿" => "Mian", "ç·€" => "Qi", "ç·" => "Qie", "ç·‚" => "Tan", "ç·ƒ" => "Zong", "ç·„" => "Gun", + "ç·…" => "Zou", "ç·†" => "Yi", "ç·‡" => "Zi", "ç·ˆ" => "Xing", "ç·‰" => "Liang", "ç·Š" => "Jin", + "ç·‹" => "Fei", "ç·Œ" => "Rui", "ç·" => "Min", "ç·Ž" => "Yu", "ç·" => "Zong", "ç·" => "Fan", + "ç·‘" => "Lu", "ç·’" => "Xu", "ç·“" => "Yingl", "ç·”" => "Zhang", "ç·•" => "Kasuri", "ç·–" => "Xu", + "ç·—" => "Xiang", "ç·˜" => "Jian", "ç·™" => "Ke", "ç·š" => "Xian", "ç·›" => "Ruan", "ç·œ" => "Mian", + "ç·" => "Qi", "ç·ž" => "Duan", "ç·Ÿ" => "Zhong", "ç· " => "Di", "ç·¡" => "Min", "ç·¢" => "Miao", + "ç·£" => "Yuan", "ç·¤" => "Xie", "ç·¥" => "Bao", "ç·¦" => "Si", "ç·§" => "Qiu", "ç·¨" => "Bian", + "ç·©" => "Huan", "ç·ª" => "Geng", "ç·«" => "Cong", "ç·¬" => "Mian", "ç·­" => "Wei", "ç·®" => "Fu", + "ç·¯" => "Wei", "ç·°" => "Yu", "ç·±" => "Gou", "ç·²" => "Miao", "ç·³" => "Xie", "ç·´" => "Lian", + "ç·µ" => "Zong", "ç·¶" => "Bian", "ç··" => "Yun", "ç·¸" => "Yin", "ç·¹" => "Ti", "ç·º" => "Gua", + "ç·»" => "Zhi", "ç·¼" => "Yun", "ç·½" => "Cheng", "ç·¾" => "Chan", "ç·¿" => "Dai", "ç¸" => "Yuan", + "縂" => "Zong", "縃" => "Xu", "縄" => "Nawa", "縅" => "Odoshi", "縆" => "Geng", "縇" => "Sen", + "縈" => "Ying", "縉" => "Jin", "縊" => "Yi", "縋" => "Zhui", "縌" => "Ni", "ç¸" => "Bang", + "縎" => "Gu", "ç¸" => "Pan", "ç¸" => "Zhou", "縑" => "Jian", "縒" => "Cuo", "縓" => "Quan", + "縔" => "Shuang", "縕" => "Yun", "縖" => "Xia", "縗" => "Shuai", "縘" => "Xi", "縙" => "Rong", + "縚" => "Tao", "縛" => "Fu", "縜" => "Yun", "ç¸" => "Zhen", "縞" => "Gao", "縟" => "Ru", + "縠" => "Hu", "縡" => "Zai", "縢" => "Teng", "縣" => "Xian", "縤" => "Su", "縥" => "Zhen", + "縦" => "Zong", "縧" => "Tao", "縨" => "Horo", "縩" => "Cai", "縪" => "Bi", "縫" => "Feng", + "縬" => "Cu", "縭" => "Li", "縮" => "Suo", "縯" => "Yin", "縰" => "Xi", "縱" => "Zong", + "縲" => "Lei", "縳" => "Zhuan", "縴" => "Qian", "縵" => "Man", "縶" => "Zhi", "縷" => "Lu", + "縸" => "Mo", "縹" => "Piao", "縺" => "Lian", "縻" => "Mi", "縼" => "Xuan", "總" => "Zong", + "績" => "Ji", "縿" => "Shan", "ç¹€" => "Sui", "ç¹" => "Fan", "繂" => "Shuai", "繃" => "Beng", + "繄" => "Yi", "ç¹…" => "Sao", "繆" => "Mou", "繇" => "Zhou", "繈" => "Qiang", "繉" => "Hun", + "繊" => "Sem", "繋" => "Xi", "繌" => "Jung", "ç¹" => "Xiu", "繎" => "Ran", "ç¹" => "Xuan", + "ç¹" => "Hui", "繑" => "Qiao", "ç¹’" => "Zeng", "繓" => "Zuo", "ç¹”" => "Zhi", "繕" => "Shan", + "ç¹–" => "San", "ç¹—" => "Lin", "繘" => "Yu", "ç¹™" => "Fan", "繚" => "Liao", "ç¹›" => "Chuo", + "繜" => "Zun", "ç¹" => "Jian", "繞" => "Rao", "繟" => "Chan", "ç¹ " => "Rui", "繡" => "Xiu", + "ç¹¢" => "Hui", "ç¹£" => "Hua", "繤" => "Zuan", "ç¹¥" => "Xi", "繦" => "Qiang", "繧" => "Un", + "繨" => "Da", "繩" => "Sheng", "繪" => "Hui", "繫" => "Xi", "繬" => "Se", "ç¹­" => "Jian", + "ç¹®" => "Jiang", "繯" => "Huan", "ç¹°" => "Zao", "ç¹±" => "Cong", "ç¹²" => "Jie", "ç¹³" => "Jiao", + "ç¹´" => "Bo", "ç¹µ" => "Chan", "繶" => "Yi", "ç¹·" => "Nao", "繸" => "Sui", "ç¹¹" => "Yi", + "繺" => "Shai", "ç¹»" => "Xu", "ç¹¼" => "Ji", "ç¹½" => "Bin", "ç¹¾" => "Qian", "繿" => "Lan", + "纀" => "Pu", "çº" => "Xun", "纂" => "Zuan", "纃" => "Qi", "纄" => "Peng", "纅" => "Li", + "纆" => "Mo", "纇" => "Lei", "纈" => "Xie", "纉" => "Zuan", "纊" => "Kuang", "纋" => "You", + "續" => "Xu", "çº" => "Lei", "纎" => "Xian", "çº" => "Chan", "çº" => "Kou", "纑" => "Lu", + "纒" => "Chan", "纓" => "Ying", "纔" => "Cai", "纕" => "Xiang", "纖" => "Xian", "纗" => "Zui", + "纘" => "Zuan", "纙" => "Luo", "纚" => "Xi", "纛" => "Dao", "纜" => "Lan", "çº" => "Lei", + "纞" => "Lian", "纟" => "Si", "纠" => "Jiu", "纡" => "Yu", "红" => "Hong", "纣" => "Zhou", + "纤" => "Xian", "纥" => "He", "约" => "Yue", "级" => "Ji", "纨" => "Wan", "纩" => "Kuang", + "纪" => "Ji", "纫" => "Ren", "纬" => "Wei", "纭" => "Yun", "纮" => "Hong", "纯" => "Chun", + "纰" => "Pi", "纱" => "Sha", "纲" => "Gang", "纳" => "Na", "纴" => "Ren", "纵" => "Zong", + "纶" => "Lun", "纷" => "Fen", "纸" => "Zhi", "纹" => "Wen", "纺" => "Fang", "纻" => "Zhu", + "纼" => "Yin", "纽" => "Niu", "纾" => "Shu", "线" => "Xian", "绀" => "Gan", "ç»" => "Xie", + "绂" => "Fu", "练" => "Lian", "组" => "Zu", "ç»…" => "Shen", "细" => "Xi", "织" => "Zhi", + "终" => "Zhong", "绉" => "Zhou", "绊" => "Ban", "绋" => "Fu", "绌" => "Zhuo", "ç»" => "Shao", + "绎" => "Yi", "ç»" => "Jing", "ç»" => "Dai", "绑" => "Bang", "ç»’" => "Rong", "结" => "Jie", + "ç»”" => "Ku", "绕" => "Rao", "ç»–" => "Die", "ç»—" => "Heng", "绘" => "Hui", "ç»™" => "Gei", + "绚" => "Xuan", "ç»›" => "Jiang", "络" => "Luo", "ç»" => "Jue", "绞" => "Jiao", "统" => "Tong", + "ç» " => "Geng", "绡" => "Xiao", "绢" => "Juan", "绣" => "Xiu", "绤" => "Xi", "绥" => "Sui", + "绦" => "Tao", "继" => "Ji", "绨" => "Ti", "绩" => "Ji", "绪" => "Xu", "绫" => "Ling", + "ç»­" => "Xu", "ç»®" => "Qi", "绯" => "Fei", "ç»°" => "Chuo", "ç»±" => "Zhang", "绲" => "Gun", + "绳" => "Sheng", "ç»´" => "Wei", "绵" => "Mian", "绶" => "Shou", "ç»·" => "Beng", "绸" => "Chou", + "绹" => "Tao", "绺" => "Liu", "ç»»" => "Quan", "综" => "Zong", "绽" => "Zhan", "绾" => "Wan", + "绿" => "Lu", "ç¼" => "Zi", "缂" => "Ke", "缃" => "Xiang", "缄" => "Jian", "ç¼…" => "Mian", + "缆" => "Lan", "缇" => "Ti", "缈" => "Miao", "缉" => "Qi", "缊" => "Yun", "缋" => "Hui", + "缌" => "Si", "ç¼" => "Duo", "缎" => "Duan", "ç¼" => "Bian", "ç¼" => "Xian", "缑" => "Gou", + "ç¼’" => "Zhui", "缓" => "Huan", "ç¼”" => "Di", "缕" => "Lu", "ç¼–" => "Bian", "ç¼—" => "Min", + "缘" => "Yuan", "ç¼™" => "Jin", "缚" => "Fu", "ç¼›" => "Ru", "缜" => "Zhen", "ç¼" => "Feng", + "缞" => "Shuai", "缟" => "Gao", "ç¼ " => "Chan", "缡" => "Li", "ç¼¢" => "Yi", "ç¼£" => "Jian", + "缤" => "Bin", "ç¼¥" => "Piao", "缦" => "Man", "缧" => "Lei", "缨" => "Ying", "缩" => "Suo", + "缪" => "Mou", "缫" => "Sao", "缬" => "Xie", "ç¼­" => "Liao", "ç¼®" => "Shan", "缯" => "Zeng", + "ç¼°" => "Jiang", "ç¼±" => "Qian", "ç¼²" => "Zao", "ç¼³" => "Huan", "ç¼´" => "Jiao", "ç¼µ" => "Zuan", + "缶" => "Fou", "ç¼·" => "Xie", "缸" => "Gang", "ç¼¹" => "Fou", "缺" => "Que", "ç¼»" => "Fou", + "ç¼¼" => "Kaakeru", "ç¼½" => "Bo", "ç¼¾" => "Ping", "缿" => "Hou", "ç½" => "Gang", "罂" => "Ying", + "罃" => "Ying", "罄" => "Qing", "ç½…" => "Xia", "罆" => "Guan", "罇" => "Zun", "罈" => "Tan", + "罉" => "Chang", "罊" => "Qi", "罋" => "Weng", "罌" => "Ying", "ç½" => "Lei", "罎" => "Tan", + "ç½" => "Lu", "ç½" => "Guan", "网" => "Wang", "ç½’" => "Wang", "罓" => "Gang", "ç½”" => "Wang", + "罕" => "Han", "ç½—" => "Luo", "罘" => "Fu", "ç½™" => "Mi", "罚" => "Fa", "ç½›" => "Gu", + "罜" => "Zhu", "ç½" => "Ju", "罞" => "Mao", "罟" => "Gu", "ç½ " => "Min", "罡" => "Gang", + "ç½¢" => "Ba", "ç½£" => "Gua", "罤" => "Ti", "ç½¥" => "Juan", "罦" => "Fu", "罧" => "Lin", + "罨" => "Yan", "罩" => "Zhao", "罪" => "Zui", "罫" => "Gua", "罬" => "Zhuo", "ç½­" => "Yu", + "ç½®" => "Zhi", "罯" => "An", "ç½°" => "Fa", "ç½±" => "Nan", "ç½²" => "Shu", "ç½³" => "Si", + "ç½´" => "Pi", "ç½µ" => "Ma", "罶" => "Liu", "ç½·" => "Ba", "罸" => "Fa", "ç½¹" => "Li", + "罺" => "Chao", "ç½»" => "Wei", "ç½¼" => "Bi", "ç½½" => "Ji", "ç½¾" => "Zeng", "罿" => "Tong", + "ç¾€" => "Liu", "ç¾" => "Ji", "羂" => "Juan", "羃" => "Mi", "羄" => "Zhao", "ç¾…" => "Luo", + "羆" => "Pi", "羇" => "Ji", "羈" => "Ji", "羉" => "Luan", "羊" => "Yang", "羋" => "Mie", + "羌" => "Qiang", "ç¾" => "Ta", "美" => "Mei", "ç¾" => "Yang", "ç¾" => "You", "羑" => "You", + "ç¾’" => "Fen", "羓" => "Ba", "ç¾”" => "Gao", "羕" => "Yang", "ç¾–" => "Gu", "ç¾—" => "Qiang", + "羘" => "Zang", "ç¾™" => "Gao", "羚" => "Ling", "ç¾›" => "Yi", "羜" => "Zhu", "ç¾" => "Di", + "羞" => "Xiu", "羟" => "Qian", "ç¾ " => "Yi", "羡" => "Xian", "ç¾¢" => "Rong", "ç¾£" => "Qun", + "群" => "Qun", "ç¾¥" => "Qian", "羦" => "Huan", "羧" => "Zui", "羨" => "Xian", "義" => "Yi", + "羪" => "Yashinau", "羫" => "Qiang", "羬" => "Xian", "ç¾­" => "Yu", "ç¾®" => "Geng", "羯" => "Jie", + "ç¾°" => "Tang", "ç¾±" => "Yuan", "ç¾²" => "Xi", "ç¾³" => "Fan", "ç¾´" => "Shan", "ç¾µ" => "Fen", + "羶" => "Shan", "ç¾·" => "Lian", "羸" => "Lei", "ç¾¹" => "Geng", "羺" => "Nou", "ç¾»" => "Qiang", + "ç¾¼" => "Chan", "ç¾½" => "Yu", "ç¾¾" => "Gong", "羿" => "Yi", "ç¿€" => "Chong", "ç¿" => "Weng", + "ç¿‚" => "Fen", "翃" => "Hong", "ç¿„" => "Chi", "ç¿…" => "Chi", "翆" => "Cui", "翇" => "Fu", + "翈" => "Xia", "翉" => "Pen", "ç¿Š" => "Yi", "ç¿‹" => "La", "ç¿Œ" => "Yi", "ç¿" => "Pi", + "ç¿Ž" => "Ling", "ç¿" => "Liu", "ç¿" => "Zhi", "ç¿‘" => "Qu", "ç¿’" => "Xi", "ç¿“" => "Xie", + "ç¿”" => "Xiang", "ç¿•" => "Xi", "ç¿–" => "Xi", "ç¿—" => "Qi", "翘" => "Qiao", "ç¿™" => "Hui", + "ç¿š" => "Hui", "ç¿›" => "Xiao", "ç¿œ" => "Se", "ç¿" => "Hong", "ç¿ž" => "Jiang", "ç¿Ÿ" => "Di", + "ç¿ " => "Cui", "ç¿¡" => "Fei", "ç¿¢" => "Tao", "ç¿£" => "Sha", "翤" => "Chi", "ç¿¥" => "Zhu", + "翦" => "Jian", "翧" => "Xuan", "翨" => "Shi", "ç¿©" => "Pian", "翪" => "Zong", "ç¿«" => "Wan", + "翬" => "Hui", "ç¿­" => "Hou", "ç¿®" => "He", "翯" => "He", "ç¿°" => "Han", "翱" => "Ao", + "翲" => "Piao", "翳" => "Yi", "ç¿´" => "Lian", "翵" => "Qu", "ç¿·" => "Lin", "翸" => "Pen", + "翹" => "Qiao", "翺" => "Ao", "ç¿»" => "Fan", "翼" => "Yi", "翽" => "Hui", "翾" => "Xuan", + "ç¿¿" => "Dao", "è€" => "Lao", "考" => "Kao", "耄" => "Mao", "者" => "Zhe", "耆" => "Qi", + "耇" => "Gou", "耈" => "Gou", "耉" => "Gou", "耊" => "Die", "耋" => "Die", "而" => "Er", + "è€" => "Shua", "耎" => "Ruan", "è€" => "Er", "è€" => "Nai", "耑" => "Zhuan", "耒" => "Lei", + "耓" => "Ting", "耔" => "Zi", "耕" => "Geng", "耖" => "Chao", "耗" => "Hao", "耘" => "Yun", + "耙" => "Pa", "耚" => "Pi", "耛" => "Chi", "耜" => "Si", "è€" => "Chu", "耞" => "Jia", + "耟" => "Ju", "耠" => "He", "耡" => "Chu", "耢" => "Lao", "耣" => "Lun", "耤" => "Ji", + "耥" => "Tang", "耦" => "Ou", "耧" => "Lou", "耨" => "Nou", "耩" => "Gou", "耪" => "Pang", + "耫" => "Ze", "耬" => "Lou", "耭" => "Ji", "耮" => "Lao", "耯" => "Huo", "耰" => "You", + "耱" => "Mo", "耲" => "Huai", "耳" => "Er", "耴" => "Zhe", "耵" => "Ting", "耶" => "Ye", + "耷" => "Da", "耸" => "Song", "耹" => "Qin", "耺" => "Yun", "耻" => "Chi", "耼" => "Dan", + "耽" => "Dan", "耾" => "Hong", "耿" => "Geng", "è€" => "Zhi", "è‚" => "Nie", "èƒ" => "Dan", + "è„" => "Zhen", "è…" => "Che", "è†" => "Ling", "è‡" => "Zheng", "èˆ" => "You", "è‰" => "Wa", + "èŠ" => "Liao", "è‹" => "Long", "èŒ" => "Zhi", "è" => "Ning", "èŽ" => "Tiao", "è" => "Er", + "è" => "Ya", "è‘" => "Die", "è’" => "Gua", "è”" => "Lian", "è•" => "Hao", "è–" => "Sheng", + "è—" => "Lie", "è˜" => "Pin", "è™" => "Jing", "èš" => "Ju", "è›" => "Bi", "èœ" => "Di", + "è" => "Guo", "èž" => "Wen", "èŸ" => "Xu", "è " => "Ping", "è¡" => "Cong", "è¢" => "Shikato", + "è¤" => "Ting", "è¥" => "Yu", "è¦" => "Cong", "è§" => "Kui", "è¨" => "Tsuraneru", "è©" => "Kui", + "èª" => "Cong", "è«" => "Lian", "è¬" => "Weng", "è­" => "Kui", "è®" => "Lian", "è¯" => "Lian", + "è°" => "Cong", "è±" => "Ao", "è²" => "Sheng", "è³" => "Song", "è´" => "Ting", "èµ" => "Kui", + "è¶" => "Nie", "è·" => "Zhi", "è¸" => "Dan", "è¹" => "Ning", "èº" => "Qie", "è»" => "Ji", + "è¼" => "Ting", "è½" => "Ting", "è¾" => "Long", "è¿" => "Yu", "è‚€" => "Yu", "è‚" => "Zhao", + "è‚‚" => "Si", "肃" => "Su", "è‚„" => "Yi", "è‚…" => "Su", "肆" => "Si", "肇" => "Zhao", + "肈" => "Zhao", "肉" => "Rou", "è‚Š" => "Yi", "è‚‹" => "Le", "è‚Œ" => "Ji", "è‚" => "Qiu", + "è‚Ž" => "Ken", "è‚" => "Cao", "è‚" => "Ge", "è‚‘" => "Di", "è‚’" => "Huan", "è‚“" => "Huang", + "è‚”" => "Yi", "è‚•" => "Ren", "è‚–" => "Xiao", "è‚—" => "Ru", "肘" => "Zhou", "è‚™" => "Yuan", + "è‚š" => "Du", "è‚›" => "Gang", "è‚œ" => "Rong", "è‚" => "Gan", "è‚ž" => "Cha", "è‚Ÿ" => "Wo", + "è‚ " => "Chang", "è‚¡" => "Gu", "è‚¢" => "Zhi", "è‚£" => "Han", "肤" => "Fu", "è‚¥" => "Fei", + "肦" => "Fen", "肧" => "Pei", "肨" => "Pang", "è‚©" => "Jian", "肪" => "Fang", "è‚«" => "Zhun", + "肬" => "You", "è‚­" => "Na", "è‚®" => "Hang", "肯" => "Ken", "è‚°" => "Ran", "肱" => "Gong", + "育" => "Yu", "肳" => "Wen", "è‚´" => "Yao", "肵" => "Jin", "肶" => "Pi", "è‚·" => "Qian", + "肸" => "Xi", "肹" => "Xi", "肺" => "Fei", "è‚»" => "Ken", "肼" => "Jing", "肽" => "Tai", + "肾" => "Shen", "è‚¿" => "Zhong", "胀" => "Zhang", "èƒ" => "Xie", "胂" => "Shen", "胃" => "Wei", + "胄" => "Zhou", "胅" => "Die", "胆" => "Dan", "胇" => "Fei", "胈" => "Ba", "胉" => "Bo", + "胊" => "Qu", "胋" => "Tian", "背" => "Bei", "èƒ" => "Gua", "胎" => "Tai", "èƒ" => "Zi", + "èƒ" => "Ku", "胑" => "Zhi", "胒" => "Ni", "胓" => "Ping", "胔" => "Zi", "胕" => "Fu", + "胖" => "Pang", "胗" => "Zhen", "胘" => "Xian", "胙" => "Zuo", "胚" => "Pei", "胛" => "Jia", + "胜" => "Sheng", "èƒ" => "Zhi", "胞" => "Bao", "胟" => "Mu", "胠" => "Qu", "胡" => "Hu", + "胢" => "Ke", "胣" => "Yi", "胤" => "Yin", "胥" => "Xu", "胦" => "Yang", "胧" => "Long", + "胨" => "Dong", "胩" => "Ka", "胪" => "Lu", "胫" => "Jing", "胬" => "Nu", "胭" => "Yan", + "胮" => "Pang", "胯" => "Kua", "胰" => "Yi", "胱" => "Guang", "胲" => "Gai", "胳" => "Ge", + "胴" => "Dong", "胵" => "Zhi", "胶" => "Xiao", "胷" => "Xiong", "胸" => "Xiong", "胹" => "Er", + "胺" => "E", "胻" => "Xing", "胼" => "Pian", "能" => "Neng", "胾" => "Zi", "胿" => "Gui", + "è„" => "Tiao", "è„‚" => "Zhi", "脃" => "Cui", "è„„" => "Mei", "è„…" => "Xie", "脆" => "Cui", + "脇" => "Xie", "脈" => "Mo", "脉" => "Mai", "è„Š" => "Ji", "è„‹" => "Obiyaakasu", "è„" => "Kuai", + "è„Ž" => "Sa", "è„" => "Zang", "è„" => "Qi", "è„‘" => "Nao", "è„’" => "Mi", "è„“" => "Nong", + "è„”" => "Luan", "è„•" => "Wan", "è„–" => "Bo", "è„—" => "Wen", "脘" => "Guan", "è„™" => "Qiu", + "è„š" => "Jiao", "è„›" => "Jing", "è„œ" => "Rou", "è„" => "Heng", "è„ž" => "Cuo", "è„Ÿ" => "Lie", + "è„ " => "Shan", "è„¡" => "Ting", "è„¢" => "Mei", "è„£" => "Chun", "脤" => "Shen", "è„¥" => "Xie", + "脦" => "De", "脧" => "Zui", "脨" => "Cu", "è„©" => "Xiu", "脪" => "Xin", "è„«" => "Tuo", + "脬" => "Pao", "è„­" => "Cheng", "è„®" => "Nei", "脯" => "Fu", "è„°" => "Dou", "脱" => "Tuo", + "脲" => "Niao", "脳" => "Noy", "è„´" => "Pi", "脵" => "Gu", "脶" => "Gua", "è„·" => "Li", + "脸" => "Lian", "脹" => "Zhang", "脺" => "Cui", "è„»" => "Jie", "脼" => "Liang", "脽" => "Zhou", + "脾" => "Pi", "è„¿" => "Biao", "è…€" => "Lun", "è…" => "Pian", "è…‚" => "Guo", "è…ƒ" => "Kui", + "è…„" => "Chui", "è……" => "Dan", "è…†" => "Tian", "è…‡" => "Nei", "è…ˆ" => "Jing", "è…‰" => "Jie", + "è…Š" => "La", "è…‹" => "Yi", "è…Œ" => "An", "è…" => "Ren", "è…Ž" => "Shen", "è…" => "Chuo", + "è…" => "Fu", "è…‘" => "Fu", "è…’" => "Ju", "è…“" => "Fei", "è…”" => "Qiang", "è…•" => "Wan", + "è…–" => "Dong", "è…—" => "Pi", "è…˜" => "Guo", "è…™" => "Zong", "è…š" => "Ding", "è…›" => "Wu", + "è…œ" => "Mei", "è…" => "Ruan", "è…ž" => "Zhuan", "è…Ÿ" => "Zhi", "è… " => "Cou", "è…¡" => "Gua", + "è…¢" => "Ou", "è…£" => "Di", "è…¤" => "An", "è…¥" => "Xing", "è…¦" => "Nao", "è…§" => "Yu", + "è…¨" => "Chuan", "è…©" => "Nan", "è…ª" => "Yun", "è…«" => "Zhong", "è…¬" => "Rou", "è…­" => "E", + "è…®" => "Sai", "è…¯" => "Tu", "è…°" => "Yao", "è…±" => "Jian", "è…²" => "Wei", "è…³" => "Jiao", + "è…´" => "Yu", "è…µ" => "Jia", "è…¶" => "Duan", "è…·" => "Bi", "è…¸" => "Chang", "è…¹" => "Fu", + "è…º" => "Xian", "è…»" => "Ni", "è…¼" => "Mian", "è…½" => "Wa", "è…¾" => "Teng", "è…¿" => "Tui", + "膀" => "Bang", "è†" => "Qian", "膂" => "Lu", "膃" => "Wa", "膄" => "Sou", "膅" => "Tang", + "膆" => "Su", "膇" => "Zhui", "膈" => "Ge", "膉" => "Yi", "膊" => "Bo", "膋" => "Liao", + "膌" => "Ji", "è†" => "Pi", "膎" => "Xie", "è†" => "Gao", "è†" => "Lu", "膑" => "Bin", + "膒" => "Ou", "膓" => "Chang", "膔" => "Lu", "膕" => "Guo", "膖" => "Pang", "膗" => "Chuai", + "膘" => "Piao", "膙" => "Jiang", "膚" => "Fu", "膛" => "Tang", "膜" => "Mo", "è†" => "Xi", + "膞" => "Zhuan", "膟" => "Lu", "膠" => "Jiao", "膡" => "Ying", "膢" => "Lu", "膣" => "Zhi", + "膤" => "Tara", "膥" => "Chun", "膦" => "Lian", "膧" => "Tong", "膨" => "Peng", "膩" => "Ni", + "膪" => "Zha", "膫" => "Liao", "膬" => "Cui", "膭" => "Gui", "膮" => "Xiao", "膯" => "Teng", + "膰" => "Fan", "膱" => "Zhi", "膲" => "Jiao", "膳" => "Shan", "膴" => "Wu", "膵" => "Cui", + "膶" => "Run", "膷" => "Xiang", "膸" => "Sui", "膹" => "Fen", "膺" => "Ying", "膻" => "Tan", + "膼" => "Zhua", "膽" => "Dan", "膾" => "Kuai", "膿" => "Nong", "臀" => "Tun", "è‡" => "Lian", + "臂" => "Bi", "臃" => "Yong", "臄" => "Jue", "臅" => "Chu", "臆" => "Yi", "臇" => "Juan", + "臈" => "La", "臉" => "Lian", "臊" => "Sao", "臋" => "Tun", "臌" => "Gu", "è‡" => "Qi", + "臎" => "Cui", "è‡" => "Bin", "è‡" => "Xun", "臑" => "Ru", "臒" => "Huo", "臓" => "Zang", + "臔" => "Xian", "臕" => "Biao", "臖" => "Xing", "臗" => "Kuan", "臘" => "La", "臙" => "Yan", + "臚" => "Lu", "臛" => "Huo", "臜" => "Zang", "è‡" => "Luo", "臞" => "Qu", "臟" => "Zang", + "臠" => "Luan", "臡" => "Ni", "臢" => "Zang", "臣" => "Chen", "臤" => "Qian", "臥" => "Wo", + "臦" => "Guang", "臧" => "Zang", "臨" => "Lin", "臩" => "Guang", "自" => "Zi", "臫" => "Jiao", + "臬" => "Nie", "臭" => "Chou", "臮" => "Ji", "臯" => "Gao", "臰" => "Chou", "臱" => "Mian", + "臲" => "Nie", "至" => "Zhi", "致" => "Zhi", "臵" => "Ge", "臶" => "Jian", "臷" => "Die", + "臸" => "Zhi", "臹" => "Xiu", "臺" => "Tai", "臻" => "Zhen", "臼" => "Jiu", "臽" => "Xian", + "臾" => "Yu", "臿" => "Cha", "èˆ" => "Yu", "舂" => "Chong", "舃" => "Xi", "舄" => "Xi", + "舅" => "Jiu", "舆" => "Yu", "與" => "Yu", "興" => "Xing", "舉" => "Ju", "舊" => "Jiu", + "舋" => "Xin", "舌" => "She", "èˆ" => "She", "舎" => "Yadoru", "èˆ" => "Jiu", "èˆ" => "Shi", + "舑" => "Tan", "舒" => "Shu", "舓" => "Shi", "舔" => "Tian", "舕" => "Dan", "舖" => "Pu", + "舗" => "Pu", "舘" => "Guan", "舙" => "Hua", "舚" => "Tan", "舛" => "Chuan", "舜" => "Shun", + "èˆ" => "Xia", "舞" => "Wu", "舟" => "Zhou", "舠" => "Dao", "舡" => "Gang", "舢" => "Shan", + "舣" => "Yi", "舥" => "Pa", "舦" => "Tai", "舧" => "Fan", "舨" => "Ban", "舩" => "Chuan", + "航" => "Hang", "舫" => "Fang", "般" => "Ban", "舭" => "Que", "舮" => "Hesaki", "舯" => "Zhong", + "舰" => "Jian", "舱" => "Cang", "舲" => "Ling", "舳" => "Zhu", "舴" => "Ze", "舵" => "Duo", + "舶" => "Bo", "舷" => "Xian", "舸" => "Ge", "船" => "Chuan", "舺" => "Jia", "舻" => "Lu", + "舼" => "Hong", "舽" => "Pang", "舾" => "Xi", "艀" => "Fu", "è‰" => "Zao", "艂" => "Feng", + "艃" => "Li", "艄" => "Shao", "艅" => "Yu", "艆" => "Lang", "艇" => "Ting", "艉" => "Wei", + "艊" => "Bo", "艋" => "Meng", "艌" => "Nian", "è‰" => "Ju", "艎" => "Huang", "è‰" => "Shou", + "è‰" => "Zong", "艑" => "Bian", "艒" => "Mao", "艓" => "Die", "艕" => "Bang", "艖" => "Cha", + "艗" => "Yi", "艘" => "Sao", "艙" => "Cang", "艚" => "Cao", "艛" => "Lou", "艜" => "Dai", + "è‰" => "Sori", "艞" => "Yao", "艟" => "Tong", "艠" => "Yofune", "艡" => "Dang", "艢" => "Tan", + "艣" => "Lu", "艤" => "Yi", "艥" => "Jie", "艦" => "Jian", "艧" => "Huo", "艨" => "Meng", + "艩" => "Qi", "艪" => "Lu", "艫" => "Lu", "艬" => "Chan", "艭" => "Shuang", "艮" => "Gen", + "良" => "Liang", "艰" => "Jian", "艱" => "Jian", "色" => "Se", "艳" => "Yan", "艴" => "Fu", + "艵" => "Ping", "艶" => "Yan", "艷" => "Yan", "艸" => "Cao", "艹" => "Cao", "艺" => "Yi", + "艻" => "Le", "艼" => "Ting", "艽" => "Qiu", "艾" => "Ai", "艿" => "Nai", "芀" => "Tiao", + "èŠ" => "Jiao", "节" => "Jie", "芃" => "Peng", "芄" => "Wan", "芅" => "Yi", "芆" => "Chai", + "芇" => "Mian", "芈" => "Mie", "芉" => "Gan", "芊" => "Qian", "芋" => "Yu", "芌" => "Yu", + "èŠ" => "Shuo", "芎" => "Qiong", "èŠ" => "Tu", "èŠ" => "Xia", "芑" => "Qi", "芒" => "Mang", + "芓" => "Zi", "芔" => "Hui", "芕" => "Sui", "芖" => "Zhi", "芗" => "Xiang", "芘" => "Bi", + "芙" => "Fu", "芚" => "Tun", "芛" => "Wei", "芜" => "Wu", "èŠ" => "Zhi", "芞" => "Qi", + "芟" => "Shan", "芠" => "Wen", "芡" => "Qian", "芢" => "Ren", "芣" => "Fou", "芤" => "Kou", + "芥" => "Jie", "芦" => "Lu", "芧" => "Xu", "芨" => "Ji", "芩" => "Qin", "芪" => "Qi", + "芫" => "Yuan", "芬" => "Fen", "芭" => "Ba", "芮" => "Rui", "芯" => "Xin", "芰" => "Ji", + "花" => "Hua", "芲" => "Hua", "芳" => "Fang", "芴" => "Wu", "芵" => "Jue", "芶" => "Gou", + "芷" => "Zhi", "芸" => "Yun", "芹" => "Qin", "芺" => "Ao", "芻" => "Chu", "芼" => "Mao", + "芽" => "Ya", "芾" => "Fei", "芿" => "Reng", "è‹€" => "Hang", "è‹" => "Cong", "è‹‚" => "Yin", + "苃" => "You", "è‹„" => "Bian", "è‹…" => "Yi", "苆" => "Susa", "苇" => "Wei", "苈" => "Li", + "苉" => "Pi", "è‹Š" => "E", "è‹‹" => "Xian", "è‹Œ" => "Chang", "è‹" => "Cang", "è‹Ž" => "Meng", + "è‹" => "Su", "è‹" => "Yi", "è‹‘" => "Yuan", "è‹’" => "Ran", "è‹“" => "Ling", "è‹”" => "Tai", + "è‹•" => "Tiao", "è‹–" => "Di", "è‹—" => "Miao", "苘" => "Qiong", "è‹™" => "Li", "è‹š" => "Yong", + "è‹›" => "Ke", "è‹œ" => "Mu", "è‹" => "Pei", "è‹ž" => "Bao", "è‹Ÿ" => "Gou", "è‹ " => "Min", + "è‹¡" => "Yi", "è‹¢" => "Yi", "è‹£" => "Ju", "苤" => "Pi", "è‹¥" => "Ruo", "苦" => "Ku", + "苧" => "Zhu", "苨" => "Ni", "è‹©" => "Bo", "苪" => "Bing", "è‹«" => "Shan", "苬" => "Qiu", + "è‹­" => "Yao", "è‹®" => "Xian", "苯" => "Ben", "è‹°" => "Hong", "英" => "Ying", "苲" => "Zha", + "苳" => "Dong", "è‹´" => "Ju", "苵" => "Die", "苶" => "Nie", "è‹·" => "Gan", "苸" => "Hu", + "苹" => "Ping", "苺" => "Mei", "è‹»" => "Fu", "苼" => "Sheng", "苽" => "Gu", "苾" => "Bi", + "è‹¿" => "Wei", "èŒ" => "Zhuo", "茂" => "Mao", "范" => "Fan", "茄" => "Qie", "茅" => "Mao", + "茆" => "Mao", "茇" => "Ba", "茈" => "Zi", "茉" => "Mo", "茊" => "Zi", "茋" => "Di", + "茌" => "Chi", "èŒ" => "Ji", "茎" => "Jing", "èŒ" => "Long", "茑" => "Niao", "茓" => "Xue", + "茔" => "Ying", "茕" => "Qiong", "茖" => "Ge", "茗" => "Ming", "茘" => "Li", "茙" => "Rong", + "茚" => "Yin", "茛" => "Gen", "茜" => "Qian", "èŒ" => "Chai", "茞" => "Chen", "茟" => "Yu", + "茠" => "Xiu", "茡" => "Zi", "茢" => "Lie", "茣" => "Wu", "茤" => "Ji", "茥" => "Kui", + "茦" => "Ce", "茧" => "Chong", "茨" => "Ci", "茩" => "Gou", "茪" => "Guang", "茫" => "Mang", + "茬" => "Chi", "茭" => "Jiao", "茮" => "Jiao", "茯" => "Fu", "茰" => "Yu", "茱" => "Zhu", + "茲" => "Zi", "茳" => "Jiang", "茴" => "Hui", "茵" => "Yin", "茶" => "Cha", "茷" => "Fa", + "茸" => "Rong", "茹" => "Ru", "茺" => "Chong", "茻" => "Mang", "茼" => "Tong", "茽" => "Zhong", + "茿" => "Zhu", "è€" => "Xun", "è" => "Huan", "è‚" => "Kua", "èƒ" => "Quan", "è„" => "Gai", + "è…" => "Da", "è†" => "Jing", "è‡" => "Xing", "èˆ" => "Quan", "è‰" => "Cao", "èŠ" => "Jing", + "è‹" => "Er", "èŒ" => "An", "è" => "Shou", "èŽ" => "Chi", "è" => "Ren", "è" => "Jian", + "è‘" => "Ti", "è’" => "Huang", "è“" => "Ping", "è”" => "Li", "è•" => "Jin", "è–" => "Lao", + "è—" => "Shu", "è˜" => "Zhuang", "è™" => "Da", "èš" => "Jia", "è›" => "Rao", "èœ" => "Bi", + "è" => "Ze", "èž" => "Qiao", "èŸ" => "Hui", "è " => "Qi", "è¡" => "Dang", "è£" => "Rong", + "è¤" => "Hun", "è¥" => "Ying", "è¦" => "Luo", "è§" => "Ying", "è¨" => "Xun", "è©" => "Jin", + "èª" => "Sun", "è«" => "Yin", "è¬" => "Mai", "è­" => "Hong", "è®" => "Zhou", "è¯" => "Yao", + "è°" => "Du", "è±" => "Wei", "è²" => "Chu", "è³" => "Dou", "è´" => "Fu", "èµ" => "Ren", + "è¶" => "Yin", "è·" => "He", "è¸" => "Bi", "è¹" => "Bu", "èº" => "Yun", "è»" => "Di", + "è¼" => "Tu", "è½" => "Sui", "è¾" => "Sui", "è¿" => "Cheng", "莀" => "Chen", "èŽ" => "Wu", + "莂" => "Bie", "莃" => "Xi", "莄" => "Geng", "莅" => "Li", "莆" => "Fu", "莇" => "Zhu", + "莈" => "Mo", "莉" => "Li", "莊" => "Zhuang", "莋" => "Ji", "莌" => "Duo", "èŽ" => "Qiu", + "莎" => "Sha", "èŽ" => "Suo", "èŽ" => "Chen", "莑" => "Feng", "莒" => "Ju", "莓" => "Mei", + "莔" => "Meng", "莕" => "Xing", "莖" => "Jing", "莗" => "Che", "莘" => "Xin", "莙" => "Jun", + "莚" => "Yan", "莛" => "Ting", "莜" => "Diao", "èŽ" => "Cuo", "莞" => "Wan", "莟" => "Han", + "莠" => "You", "莡" => "Cuo", "莢" => "Jia", "莣" => "Wang", "莤" => "You", "莥" => "Niu", + "莦" => "Shao", "莧" => "Xian", "莨" => "Lang", "莩" => "Fu", "莪" => "E", "莫" => "Mo", + "莬" => "Wen", "莭" => "Jie", "莮" => "Nan", "莯" => "Mu", "莰" => "Kan", "莱" => "Lai", + "莲" => "Lian", "莳" => "Shi", "莴" => "Wo", "莵" => "Usagi", "莶" => "Lian", "获" => "Huo", + "莸" => "You", "莹" => "Ying", "莺" => "Ying", "莻" => "Nuc", "莼" => "Chun", "莽" => "Mang", + "莾" => "Mang", "莿" => "Ci", "è€" => "Wan", "è" => "Jing", "è‚" => "Di", "èƒ" => "Qu", + "è„" => "Dong", "è…" => "Jian", "è†" => "Zou", "è‡" => "Gu", "èˆ" => "La", "è‰" => "Lu", + "èŠ" => "Ju", "è‹" => "Wei", "èŒ" => "Jun", "è" => "Nie", "èŽ" => "Kun", "è" => "He", + "è" => "Pu", "è‘" => "Zi", "è’" => "Gao", "è“" => "Guo", "è”" => "Fu", "è•" => "Lun", + "è–" => "Chang", "è—" => "Chou", "è˜" => "Song", "è™" => "Chui", "èš" => "Zhan", "è›" => "Men", + "èœ" => "Cai", "è" => "Ba", "èž" => "Li", "èŸ" => "Tu", "è " => "Bo", "è¡" => "Han", + "è¢" => "Bao", "è£" => "Qin", "è¤" => "Juan", "è¥" => "Xi", "è¦" => "Qin", "è§" => "Di", + "è¨" => "Jie", "è©" => "Pu", "èª" => "Dang", "è«" => "Jin", "è¬" => "Zhao", "è­" => "Tai", + "è®" => "Geng", "è¯" => "Hua", "è°" => "Gu", "è±" => "Ling", "è²" => "Fei", "è³" => "Jin", + "è´" => "An", "èµ" => "Wang", "è¶" => "Beng", "è·" => "Zhou", "è¸" => "Yan", "è¹" => "Ju", + "èº" => "Jian", "è»" => "Lin", "è¼" => "Tan", "è½" => "Shu", "è¾" => "Tian", "è¿" => "Dao", + "è" => "Qi", "è‚" => "He", "èƒ" => "Cui", "è„" => "Tao", "è…" => "Chun", "è†" => "Bei", + "è‡" => "Chang", "èˆ" => "Huan", "è‰" => "Fei", "èŠ" => "Lai", "è‹" => "Qi", "èŒ" => "Meng", + "è" => "Ping", "èŽ" => "Wei", "è" => "Dan", "è" => "Sha", "è‘" => "Huan", "è’" => "Yan", + "è“" => "Yi", "è”" => "Tiao", "è•" => "Qi", "è–" => "Wan", "è—" => "Ce", "è˜" => "Nai", + "è™" => "Kutabireru", "èš" => "Tuo", "è›" => "Jiu", "èœ" => "Tie", "è" => "Luo", "è " => "Meng", + "è¢" => "Yaji", "è¤" => "Ying", "è¥" => "Ying", "è¦" => "Ying", "è§" => "Xiao", "è¨" => "Sa", + "è©" => "Qiu", "èª" => "Ke", "è«" => "Xiang", "è¬" => "Wan", "è­" => "Yu", "è®" => "Yu", + "è¯" => "Fu", "è°" => "Lian", "è±" => "Xuan", "è²" => "Yuan", "è³" => "Nan", "è´" => "Ze", + "èµ" => "Wo", "è¶" => "Chun", "è·" => "Xiao", "è¸" => "Yu", "è¹" => "Pian", "èº" => "Mao", + "è»" => "An", "è¼" => "E", "è½" => "Luo", "è¾" => "Ying", "è¿" => "Huo", "è‘€" => "Gua", + "è‘" => "Jiang", "è‘‚" => "Mian", "葃" => "Zuo", "è‘„" => "Zuo", "è‘…" => "Ju", "葆" => "Bao", + "葇" => "Rou", "葈" => "Xi", "葉" => "Xie", "è‘Š" => "An", "è‘‹" => "Qu", "è‘Œ" => "Jian", + "è‘" => "Fu", "è‘Ž" => "Lu", "è‘" => "Jing", "è‘" => "Pen", "è‘‘" => "Feng", "è‘’" => "Hong", + "è‘“" => "Hong", "è‘”" => "Hou", "è‘•" => "Yan", "è‘–" => "Tu", "è‘—" => "Zhu", "葘" => "Zi", + "è‘™" => "Xiang", "è‘š" => "Shen", "è‘›" => "Ge", "è‘œ" => "Jie", "è‘" => "Jing", "è‘ž" => "Mi", + "è‘Ÿ" => "Huang", "è‘ " => "Shen", "è‘¡" => "Pu", "è‘¢" => "Gai", "è‘£" => "Dong", "葤" => "Zhou", + "è‘¥" => "Qian", "葦" => "Wei", "葧" => "Bo", "葨" => "Wei", "è‘©" => "Pa", "葪" => "Ji", + "è‘«" => "Hu", "葬" => "Zang", "è‘­" => "Jia", "è‘®" => "Duan", "葯" => "Yao", "è‘°" => "Jun", + "葱" => "Cong", "葲" => "Quan", "葳" => "Wei", "è‘´" => "Xian", "葵" => "Kui", "葶" => "Ting", + "è‘·" => "Hun", "葸" => "Xi", "葹" => "Shi", "葺" => "Qi", "è‘»" => "Lan", "葼" => "Zong", + "葽" => "Yao", "葾" => "Yuan", "è‘¿" => "Mei", "è’€" => "Yun", "è’" => "Shu", "è’‚" => "Di", + "è’ƒ" => "Zhuan", "è’„" => "Guan", "è’…" => "Sukumo", "è’†" => "Xue", "è’‡" => "Chan", "è’ˆ" => "Kai", + "è’‰" => "Kui", "è’‹" => "Jiang", "è’Œ" => "Lou", "è’" => "Wei", "è’Ž" => "Pai", "è’" => "Sou", + "è’‘" => "Yin", "è’’" => "Shi", "è’“" => "Chun", "è’”" => "Shi", "è’•" => "Yun", "è’–" => "Zhen", + "è’—" => "Lang", "è’˜" => "Nu", "è’™" => "Meng", "è’š" => "He", "è’›" => "Que", "è’œ" => "Suan", + "è’" => "Yuan", "è’ž" => "Li", "è’Ÿ" => "Ju", "è’ " => "Xi", "è’¡" => "Pang", "è’¢" => "Chu", + "è’£" => "Xu", "è’¤" => "Tu", "è’¥" => "Liu", "è’¦" => "Wo", "è’§" => "Zhen", "è’¨" => "Qian", + "è’©" => "Zu", "è’ª" => "Po", "è’«" => "Cuo", "è’¬" => "Yuan", "è’­" => "Chu", "è’®" => "Yu", + "è’¯" => "Kuai", "è’°" => "Pan", "è’±" => "Pu", "è’²" => "Pu", "è’³" => "Na", "è’´" => "Shuo", + "è’µ" => "Xi", "è’¶" => "Fen", "è’·" => "Yun", "è’¸" => "Zheng", "è’¹" => "Jian", "è’º" => "Ji", + "è’»" => "Ruo", "è’¼" => "Cang", "è’½" => "En", "è’¾" => "Mi", "è’¿" => "Hao", "è“€" => "Sun", + "è“" => "Zhen", "è“‚" => "Ming", "蓃" => "Sou", "è“„" => "Xu", "è“…" => "Liu", "蓆" => "Xi", + "蓇" => "Gu", "蓈" => "Lang", "蓉" => "Rong", "è“Š" => "Weng", "è“‹" => "Gai", "è“Œ" => "Cuo", + "è“" => "Shi", "è“Ž" => "Tang", "è“" => "Luo", "è“" => "Ru", "è“‘" => "Suo", "è“’" => "Xian", + "è““" => "Bei", "è“”" => "Yao", "è“•" => "Gui", "è“–" => "Bi", "è“—" => "Zong", "蓘" => "Gun", + "è“™" => "Za", "è“š" => "Xiu", "è“›" => "Ce", "è“œ" => "Hai", "è“" => "Lan", "è“Ÿ" => "Ji", + "è“ " => "Li", "è“¡" => "Can", "è“¢" => "Lang", "è“£" => "Yu", "è“¥" => "Ying", "蓦" => "Mo", + "蓧" => "Diao", "蓨" => "Tiao", "è“©" => "Mao", "蓪" => "Tong", "è“«" => "Zhu", "蓬" => "Peng", + "è“­" => "An", "è“®" => "Lian", "蓯" => "Cong", "è“°" => "Xi", "蓱" => "Ping", "蓲" => "Qiu", + "蓳" => "Jin", "è“´" => "Chun", "蓵" => "Jie", "蓶" => "Wei", "è“·" => "Tui", "蓸" => "Cao", + "蓹" => "Yu", "蓺" => "Yi", "è“»" => "Ji", "蓼" => "Liao", "蓽" => "Bi", "蓾" => "Lu", + "è“¿" => "Su", "è”" => "Zhang", "蔂" => "Luo", "蔃" => "Jiang", "蔄" => "Man", "è”…" => "Yan", + "蔆" => "Ling", "蔇" => "Ji", "蔈" => "Piao", "蔉" => "Gun", "蔊" => "Han", "蔋" => "Di", + "蔌" => "Su", "è”" => "Lu", "蔎" => "She", "è”" => "Shang", "è”" => "Di", "蔑" => "Mie", + "è”’" => "Xun", "蔓" => "Man", "è””" => "Bo", "蔕" => "Di", "è”–" => "Cuo", "è”—" => "Zhe", + "蔘" => "Sen", "è”™" => "Xuan", "蔚" => "Wei", "è”›" => "Hu", "蔜" => "Ao", "è”" => "Mi", + "蔞" => "Lou", "蔟" => "Cu", "è” " => "Zhong", "蔡" => "Cai", "蔢" => "Po", "蔣" => "Jiang", + "蔤" => "Mi", "蔥" => "Cong", "蔦" => "Niao", "蔧" => "Hui", "蔨" => "Jun", "蔩" => "Yin", + "蔪" => "Jian", "蔫" => "Yan", "蔬" => "Shu", "è”­" => "Yin", "è”®" => "Kui", "蔯" => "Chen", + "è”°" => "Hu", "è”±" => "Sha", "蔲" => "Kou", "蔳" => "Qian", "è”´" => "Ma", "蔵" => "Zang", + "蔶" => "Sonoko", "è”·" => "Qiang", "蔸" => "Dou", "蔹" => "Lian", "蔺" => "Lin", "è”»" => "Kou", + "蔼" => "Ai", "蔽" => "Bi", "蔾" => "Li", "蔿" => "Wei", "è•€" => "Ji", "è•" => "Xun", + "è•‚" => "Sheng", "蕃" => "Fan", "è•„" => "Meng", "è•…" => "Ou", "蕆" => "Chan", "蕇" => "Dian", + "蕈" => "Xun", "蕉" => "Jiao", "è•Š" => "Rui", "è•‹" => "Rui", "è•Œ" => "Lei", "è•" => "Yu", + "è•Ž" => "Qiao", "è•" => "Chu", "è•" => "Hua", "è•‘" => "Jian", "è•’" => "Mai", "è•“" => "Yun", + "è•”" => "Bao", "è••" => "You", "è•–" => "Qu", "è•—" => "Lu", "蕘" => "Rao", "è•™" => "Hui", + "è•š" => "E", "è•›" => "Teng", "è•œ" => "Fei", "è•" => "Jue", "è•ž" => "Zui", "è•Ÿ" => "Fa", + "è• " => "Ru", "è•¡" => "Fen", "è•¢" => "Kui", "è•£" => "Shun", "蕤" => "Rui", "è•¥" => "Ya", + "蕦" => "Xu", "蕧" => "Fu", "蕨" => "Jue", "è•©" => "Dang", "蕪" => "Wu", "è•«" => "Tong", + "蕬" => "Si", "è•­" => "Xiao", "è•®" => "Xi", "蕯" => "Long", "è•°" => "Yun", "蕲" => "Qi", + "蕳" => "Jian", "è•´" => "Yun", "蕵" => "Sun", "蕶" => "Ling", "è•·" => "Yu", "蕸" => "Xia", + "蕹" => "Yong", "蕺" => "Ji", "è•»" => "Hong", "蕼" => "Si", "蕽" => "Nong", "蕾" => "Lei", + "è•¿" => "Xuan", "è–€" => "Yun", "è–" => "Yu", "è–‚" => "Xi", "è–ƒ" => "Hao", "è–„" => "Bo", + "è–…" => "Hao", "è–†" => "Ai", "è–‡" => "Wei", "è–ˆ" => "Hui", "è–‰" => "Wei", "è–Š" => "Ji", + "è–‹" => "Ci", "è–Œ" => "Xiang", "è–" => "Luan", "è–Ž" => "Mie", "è–" => "Yi", "è–" => "Leng", + "è–‘" => "Jiang", "è–’" => "Can", "è–“" => "Shen", "è–”" => "Qiang", "è–•" => "Lian", "è––" => "Ke", + "è–—" => "Yuan", "è–˜" => "Da", "è–™" => "Ti", "è–š" => "Tang", "è–›" => "Xie", "è–œ" => "Bi", + "è–" => "Zhan", "è–ž" => "Sun", "è–Ÿ" => "Lian", "è– " => "Fan", "è–¡" => "Ding", "è–¢" => "Jie", + "è–£" => "Gu", "è–¤" => "Xie", "è–¥" => "Shu", "è–¦" => "Jian", "è–§" => "Kao", "è–¨" => "Hong", + "è–©" => "Sa", "è–ª" => "Xin", "è–«" => "Xun", "è–¬" => "Yao", "è–­" => "Hie", "è–®" => "Sou", + "è–¯" => "Shu", "è–°" => "Xun", "è–±" => "Dui", "è–²" => "Pin", "è–³" => "Wei", "è–´" => "Neng", + "è–µ" => "Chou", "è–¶" => "Mai", "è–·" => "Ru", "è–¸" => "Piao", "è–¹" => "Tai", "è–º" => "Qi", + "è–»" => "Zao", "è–¼" => "Chen", "è–½" => "Zhen", "è–¾" => "Er", "è–¿" => "Ni", "è—€" => "Ying", + "è—" => "Gao", "è—‚" => "Cong", "è—ƒ" => "Xiao", "è—„" => "Qi", "è—…" => "Fa", "è—†" => "Jian", + "è—‡" => "Xu", "è—ˆ" => "Kui", "è—‰" => "Jie", "è—Š" => "Bian", "è—‹" => "Diao", "è—Œ" => "Mi", + "è—" => "Lan", "è—Ž" => "Jin", "è—" => "Cang", "è—" => "Miao", "è—‘" => "Qiong", "è—’" => "Qie", + "è—“" => "Xian", "è—•" => "Ou", "è—–" => "Xian", "è——" => "Su", "è—˜" => "Lu", "è—™" => "Yi", + "è—š" => "Xu", "è—›" => "Xie", "è—œ" => "Li", "è—" => "Yi", "è—ž" => "La", "è—Ÿ" => "Lei", + "è— " => "Xiao", "è—¡" => "Di", "è—¢" => "Zhi", "è—£" => "Bei", "è—¤" => "Teng", "è—¥" => "Yao", + "è—¦" => "Mo", "è—§" => "Huan", "è—¨" => "Piao", "è—©" => "Fan", "è—ª" => "Sou", "è—«" => "Tan", + "è—¬" => "Tui", "è—­" => "Qiong", "è—®" => "Qiao", "è—¯" => "Wei", "è—°" => "Liu", "è—±" => "Hui", + "è—³" => "Gao", "è—´" => "Yun", "è—¶" => "Li", "è—·" => "Shu", "è—¸" => "Chu", "è—¹" => "Ai", + "è—º" => "Lin", "è—»" => "Zao", "è—¼" => "Xuan", "è—½" => "Chen", "è—¾" => "Lai", "è—¿" => "Huo", + "è˜" => "Wu", "蘂" => "Rui", "蘃" => "Rui", "蘄" => "Qi", "蘅" => "Heng", "蘆" => "Lu", + "蘇" => "Su", "蘈" => "Tui", "蘉" => "Mang", "蘊" => "Yun", "蘋" => "Pin", "蘌" => "Yu", + "è˜" => "Xun", "蘎" => "Ji", "è˜" => "Jiong", "è˜" => "Xian", "蘑" => "Mo", "蘒" => "Hagi", + "蘓" => "Su", "蘔" => "Jiong", "蘖" => "Nie", "蘗" => "Bo", "蘘" => "Rang", "蘙" => "Yi", + "蘚" => "Xian", "蘛" => "Yu", "蘜" => "Ju", "è˜" => "Lian", "蘞" => "Lian", "蘟" => "Yin", + "蘠" => "Qiang", "蘡" => "Ying", "蘢" => "Long", "蘣" => "Tong", "蘤" => "Wei", "蘥" => "Yue", + "蘦" => "Ling", "蘧" => "Qu", "蘨" => "Yao", "蘩" => "Fan", "蘪" => "Mi", "蘫" => "Lan", + "蘬" => "Kui", "蘭" => "Lan", "蘮" => "Ji", "蘯" => "Dang", "蘰" => "Katsura", "蘱" => "Lei", + "蘲" => "Lei", "蘳" => "Hua", "蘴" => "Feng", "蘵" => "Zhi", "蘶" => "Wei", "蘷" => "Kui", + "蘸" => "Zhan", "蘹" => "Huai", "蘺" => "Li", "蘻" => "Ji", "蘼" => "Mi", "蘽" => "Lei", + "蘾" => "Huai", "蘿" => "Luo", "虀" => "Ji", "è™" => "Kui", "虂" => "Lu", "虃" => "Jian", + "虄" => "San", "虆" => "Lei", "虇" => "Quan", "虈" => "Xiao", "虉" => "Yi", "虊" => "Luan", + "虋" => "Men", "虌" => "Bie", "è™" => "Hu", "虎" => "Hu", "è™" => "Lu", "è™" => "Nue", + "虑" => "Lu", "è™’" => "Si", "虓" => "Xiao", "è™”" => "Qian", "處" => "Chu", "è™–" => "Hu", + "è™—" => "Xu", "虘" => "Cuo", "è™™" => "Fu", "虚" => "Xu", "è™›" => "Xu", "虜" => "Lu", + "è™" => "Hu", "虞" => "Yu", "號" => "Hao", "è™ " => "Jiao", "虡" => "Ju", "虢" => "Guo", + "虣" => "Bao", "虤" => "Yan", "虥" => "Zhan", "虦" => "Zhan", "虧" => "Kui", "虨" => "Ban", + "虩" => "Xi", "虪" => "Shu", "虫" => "Chong", "虬" => "Qiu", "è™­" => "Diao", "è™®" => "Ji", + "虯" => "Qiu", "è™°" => "Cheng", "è™±" => "Shi", "虳" => "Di", "è™´" => "Zhe", "虵" => "She", + "虶" => "Yu", "è™·" => "Gan", "虸" => "Zi", "虹" => "Hong", "虺" => "Hui", "è™»" => "Meng", + "虼" => "Ge", "虽" => "Sui", "虾" => "Xia", "虿" => "Chai", "蚀" => "Shi", "èš" => "Yi", + "èš‚" => "Ma", "蚃" => "Xiang", "èš„" => "Fang", "èš…" => "E", "蚆" => "Pa", "蚇" => "Chi", + "蚈" => "Qian", "蚉" => "Wen", "蚊" => "Wen", "èš‹" => "Rui", "蚌" => "Bang", "èš" => "Bi", + "蚎" => "Yue", "èš" => "Yue", "èš" => "Jun", "èš‘" => "Qi", "èš’" => "Ran", "èš“" => "Yin", + "èš”" => "Qi", "èš•" => "Tian", "èš–" => "Yuan", "èš—" => "Jue", "蚘" => "Hui", "èš™" => "Qin", + "èšš" => "Qi", "èš›" => "Zhong", "èšœ" => "Ya", "èš" => "Ci", "èšž" => "Mu", "蚟" => "Wang", + "èš " => "Fen", "èš¡" => "Fen", "蚢" => "Hang", "蚣" => "Gong", "蚤" => "Zao", "蚥" => "Fu", + "蚦" => "Ran", "蚧" => "Jie", "蚨" => "Fu", "èš©" => "Chi", "蚪" => "Dou", "èš«" => "Piao", + "蚬" => "Xian", "èš­" => "Ni", "èš®" => "Te", "蚯" => "Qiu", "èš°" => "You", "èš±" => "Zha", + "èš²" => "Ping", "èš³" => "Chi", "èš´" => "You", "èšµ" => "He", "蚶" => "Han", "èš·" => "Ju", + "蚸" => "Li", "èš¹" => "Fu", "蚺" => "Ran", "èš»" => "Zha", "èš¼" => "Gou", "èš½" => "Pi", + "èš¾" => "Bo", "èš¿" => "Xian", "蛀" => "Zhu", "è›" => "Diao", "蛂" => "Bie", "蛃" => "Bing", + "蛄" => "Gu", "è›…" => "Ran", "蛆" => "Qu", "蛇" => "She", "蛈" => "Tie", "蛉" => "Ling", + "蛊" => "Gu", "蛋" => "Dan", "蛌" => "Gu", "è›" => "Ying", "蛎" => "Li", "è›" => "Cheng", + "è›" => "Qu", "蛑" => "Mou", "è›’" => "Ge", "蛓" => "Ci", "è›”" => "Hui", "蛕" => "Hui", + "è›–" => "Mang", "è›—" => "Fu", "蛘" => "Yang", "è›™" => "Wa", "蛚" => "Lie", "è››" => "Zhu", + "蛜" => "Yi", "è›" => "Xian", "蛞" => "Kuo", "蛟" => "Jiao", "è› " => "Li", "蛡" => "Yi", + "蛢" => "Ping", "蛣" => "Ji", "蛤" => "Ha", "蛥" => "She", "蛦" => "Yi", "蛧" => "Wang", + "蛨" => "Mo", "蛩" => "Qiong", "蛪" => "Qie", "蛫" => "Gui", "蛬" => "Gong", "è›­" => "Zhi", + "è›®" => "Man", "蛯" => "Ebi", "è›°" => "Zhi", "è›±" => "Jia", "蛲" => "Rao", "蛳" => "Si", + "è›´" => "Qi", "蛵" => "Xing", "蛶" => "Lie", "è›·" => "Qiu", "蛸" => "Shao", "蛹" => "Yong", + "蛺" => "Jia", "è›»" => "Shui", "蛼" => "Che", "蛽" => "Bai", "蛾" => "E", "蛿" => "Han", + "èœ" => "Xuan", "蜂" => "Feng", "蜃" => "Shen", "蜄" => "Zhen", "蜅" => "Fu", "蜆" => "Xian", + "蜇" => "Zhe", "蜈" => "Wu", "蜉" => "Fu", "蜊" => "Li", "蜋" => "Lang", "蜌" => "Bi", + "èœ" => "Chu", "蜎" => "Yuan", "èœ" => "You", "èœ" => "Jie", "蜑" => "Dan", "蜒" => "Yan", + "蜓" => "Ting", "蜔" => "Dian", "蜕" => "Shui", "蜖" => "Hui", "蜗" => "Gua", "蜘" => "Zhi", + "蜙" => "Song", "蜚" => "Fei", "蜛" => "Ju", "蜜" => "Mi", "èœ" => "Qi", "蜞" => "Qi", + "蜟" => "Yu", "蜠" => "Jun", "蜡" => "Zha", "蜢" => "Meng", "蜣" => "Qiang", "蜤" => "Si", + "蜥" => "Xi", "蜦" => "Lun", "蜧" => "Li", "蜨" => "Die", "蜩" => "Tiao", "蜪" => "Tao", + "蜫" => "Kun", "蜬" => "Gan", "蜭" => "Han", "蜮" => "Yu", "蜯" => "Bang", "蜰" => "Fei", + "蜱" => "Pi", "蜲" => "Wei", "蜳" => "Dun", "蜴" => "Yi", "蜵" => "Yuan", "蜶" => "Su", + "蜷" => "Quan", "蜸" => "Qian", "蜹" => "Rui", "蜺" => "Ni", "蜻" => "Qing", "蜼" => "Wei", + "蜽" => "Liang", "蜾" => "Guo", "蜿" => "Wan", "è€" => "Dong", "è" => "E", "è‚" => "Ban", + "èƒ" => "Di", "è„" => "Wang", "è…" => "Can", "è†" => "Yang", "è‡" => "Ying", "èˆ" => "Guo", + "è‰" => "Chan", "è‹" => "La", "èŒ" => "Ke", "è" => "Ji", "èŽ" => "He", "è" => "Ting", + "è" => "Mai", "è‘" => "Xu", "è’" => "Mian", "è“" => "Yu", "è”" => "Jie", "è•" => "Shi", + "è–" => "Xuan", "è—" => "Huang", "è˜" => "Yan", "è™" => "Bian", "èš" => "Rou", "è›" => "Wei", + "èœ" => "Fu", "è" => "Yuan", "èž" => "Mei", "èŸ" => "Wei", "è " => "Fu", "è¡" => "Ruan", + "è¢" => "Xie", "è£" => "You", "è¤" => "Qiu", "è¥" => "Mao", "è¦" => "Xia", "è§" => "Ying", + "è¨" => "Shi", "è©" => "Chong", "èª" => "Tang", "è«" => "Zhu", "è¬" => "Zong", "è­" => "Ti", + "è®" => "Fu", "è¯" => "Yuan", "è°" => "Hui", "è±" => "Meng", "è²" => "La", "è³" => "Du", + "è´" => "Hu", "èµ" => "Qiu", "è¶" => "Die", "è·" => "Li", "è¸" => "Gua", "è¹" => "Yun", + "èº" => "Ju", "è»" => "Nan", "è¼" => "Lou", "è½" => "Qun", "è¾" => "Rong", "è¿" => "Ying", + "螀" => "Jiang", "èž‚" => "Lang", "螃" => "Pang", "èž„" => "Si", "èž…" => "Xi", "螆" => "Ci", + "螇" => "Xi", "螈" => "Yuan", "螉" => "Weng", "螊" => "Lian", "èž‹" => "Sou", "螌" => "Ban", + "èž" => "Rong", "螎" => "Rong", "èž" => "Ji", "èž" => "Wu", "èž‘" => "Qiu", "èž’" => "Han", + "èž“" => "Qin", "èž”" => "Yi", "èž•" => "Bi", "èž–" => "Hua", "èž—" => "Tang", "螘" => "Yi", + "èž™" => "Du", "èžš" => "Nai", "èž›" => "He", "èžœ" => "Hu", "èž" => "Hui", "èžž" => "Ma", + "螟" => "Ming", "èž " => "Yi", "èž¡" => "Wen", "螢" => "Ying", "螣" => "Teng", "螤" => "Yu", + "螥" => "Cang", "螦" => "So", "螧" => "Ebi", "螨" => "Man", "螪" => "Shang", "èž«" => "Zhe", + "螬" => "Cao", "èž­" => "Chi", "èž®" => "Di", "螯" => "Ao", "èž°" => "Lu", "èž±" => "Wei", + "èž²" => "Zhi", "èž³" => "Tang", "èž´" => "Chen", "èžµ" => "Piao", "螶" => "Qu", "èž·" => "Pi", + "螸" => "Yu", "èž¹" => "Jian", "螺" => "Luo", "èž»" => "Lou", "èž¼" => "Qin", "èž½" => "Zhong", + "èž¾" => "Yin", "èž¿" => "Jiang", "蟀" => "Shuai", "èŸ" => "Wen", "蟂" => "Jiao", "蟃" => "Wan", + "蟄" => "Zhi", "蟅" => "Zhe", "蟆" => "Ma", "蟇" => "Ma", "蟈" => "Guo", "蟉" => "Liu", + "蟊" => "Mao", "蟋" => "Xi", "蟌" => "Cong", "èŸ" => "Li", "蟎" => "Man", "èŸ" => "Xiao", + "èŸ" => "Kamakiri", "蟑" => "Zhang", "蟒" => "Mang", "蟓" => "Xiang", "蟔" => "Mo", "蟕" => "Zui", + "蟖" => "Si", "蟗" => "Qiu", "蟘" => "Te", "蟙" => "Zhi", "蟚" => "Peng", "蟛" => "Peng", + "蟜" => "Jiao", "èŸ" => "Qu", "蟞" => "Bie", "蟟" => "Liao", "蟠" => "Pan", "蟡" => "Gui", + "蟢" => "Xi", "蟣" => "Ji", "蟤" => "Zhuan", "蟥" => "Huang", "蟦" => "Fei", "蟧" => "Lao", + "蟨" => "Jue", "蟩" => "Jue", "蟪" => "Hui", "蟫" => "Yin", "蟬" => "Chan", "蟭" => "Jiao", + "蟮" => "Shan", "蟯" => "Rao", "蟰" => "Xiao", "蟱" => "Mou", "蟲" => "Chong", "蟳" => "Xun", + "蟴" => "Si", "蟶" => "Cheng", "蟷" => "Dang", "蟸" => "Li", "蟹" => "Xie", "蟺" => "Shan", + "蟻" => "Yi", "蟼" => "Jing", "蟽" => "Da", "蟾" => "Chan", "蟿" => "Qi", "è " => "Xiang", + "è ‚" => "She", "è ƒ" => "Luo", "è „" => "Qin", "è …" => "Ying", "è †" => "Chai", "è ‡" => "Li", + "è ˆ" => "Ze", "è ‰" => "Xuan", "è Š" => "Lian", "è ‹" => "Zhu", "è Œ" => "Ze", "è " => "Xie", + "è Ž" => "Mang", "è " => "Xie", "è " => "Qi", "è ‘" => "Rong", "è ’" => "Jian", "è “" => "Meng", + "è ”" => "Hao", "è •" => "Ruan", "è –" => "Huo", "è —" => "Zhuo", "è ˜" => "Jie", "è ™" => "Bin", + "è š" => "He", "è ›" => "Mie", "è œ" => "Fan", "è " => "Lei", "è ž" => "Jie", "è Ÿ" => "La", + "è  " => "Mi", "è ¡" => "Li", "è ¢" => "Chun", "è £" => "Li", "è ¤" => "Qiu", "è ¥" => "Nie", + "è ¦" => "Lu", "è §" => "Du", "è ¨" => "Xiao", "è ©" => "Zhu", "è ª" => "Long", "è «" => "Li", + "è ¬" => "Long", "è ­" => "Feng", "è ®" => "Ye", "è ¯" => "Beng", "è °" => "Shang", "è ±" => "Gu", + "è ²" => "Juan", "è ³" => "Ying", "è µ" => "Xi", "è ¶" => "Can", "è ·" => "Qu", "è ¸" => "Quan", + "è ¹" => "Du", "è º" => "Can", "è »" => "Man", "è ¼" => "Jue", "è ½" => "Jie", "è ¾" => "Zhu", + "è ¿" => "Zha", "è¡€" => "Xie", "è¡" => "Huang", "è¡‚" => "Niu", "衃" => "Pei", "è¡„" => "Nu", + "è¡…" => "Xin", "衆" => "Zhong", "衇" => "Mo", "衈" => "Er", "衉" => "Ke", "è¡Š" => "Mie", + "è¡‹" => "Xi", "è¡Œ" => "Xing", "è¡" => "Yan", "è¡Ž" => "Kan", "è¡" => "Yuan", "è¡‘" => "Ling", + "è¡’" => "Xuan", "è¡“" => "Shu", "è¡”" => "Xian", "è¡•" => "Tong", "è¡–" => "Long", "è¡—" => "Jie", + "衘" => "Xian", "è¡™" => "Ya", "è¡š" => "Hu", "è¡›" => "Wei", "è¡œ" => "Dao", "è¡" => "Chong", + "è¡ž" => "Wei", "è¡Ÿ" => "Dao", "è¡ " => "Zhun", "è¡¡" => "Heng", "è¡¢" => "Qu", "è¡£" => "Yi", + "衤" => "Yi", "è¡¥" => "Bu", "衦" => "Gan", "衧" => "Yu", "表" => "Biao", "è¡©" => "Cha", + "衪" => "Yi", "è¡«" => "Shan", "衬" => "Chen", "è¡­" => "Fu", "è¡®" => "Gun", "衯" => "Fen", + "è¡°" => "Shuai", "衱" => "Jie", "衲" => "Na", "衳" => "Zhong", "è¡´" => "Dan", "衵" => "Ri", + "衶" => "Zhong", "è¡·" => "Zhong", "衸" => "Xie", "衹" => "Qi", "衺" => "Xie", "è¡»" => "Ran", + "衼" => "Zhi", "衽" => "Ren", "衾" => "Qin", "è¡¿" => "Jin", "袀" => "Jun", "è¢" => "Yuan", + "袂" => "Mei", "袃" => "Chai", "袄" => "Ao", "袅" => "Niao", "袆" => "Hui", "袇" => "Ran", + "袈" => "Jia", "袉" => "Tuo", "袊" => "Ling", "袋" => "Dai", "袌" => "Bao", "è¢" => "Pao", + "袎" => "Yao", "è¢" => "Zuo", "è¢" => "Bi", "袑" => "Shao", "袒" => "Tan", "袓" => "Ju", + "袔" => "He", "袕" => "Shu", "袖" => "Xiu", "袗" => "Zhen", "袘" => "Yi", "袙" => "Pa", + "袚" => "Bo", "袛" => "Di", "袜" => "Wa", "è¢" => "Fu", "袞" => "Gun", "袟" => "Zhi", + "袠" => "Zhi", "袡" => "Ran", "袢" => "Pan", "袣" => "Yi", "袤" => "Mao", "袥" => "Tuo", + "袦" => "Na", "袧" => "Kou", "袨" => "Xian", "袩" => "Chan", "袪" => "Qu", "被" => "Bei", + "袬" => "Gun", "袭" => "Xi", "袮" => "Ne", "袯" => "Bo", "袰" => "Horo", "袱" => "Fu", + "袲" => "Yi", "袳" => "Chi", "袴" => "Ku", "袵" => "Ren", "袶" => "Jiang", "袷" => "Jia", + "袸" => "Cun", "袹" => "Mo", "袺" => "Jie", "袻" => "Er", "袼" => "Luo", "袽" => "Ru", + "袾" => "Zhu", "袿" => "Gui", "裀" => "Yin", "è£" => "Cai", "裂" => "Lie", "裃" => "Kamishimo", + "裄" => "Yuki", "装" => "Zhuang", "裆" => "Dang", "裈" => "Kun", "裉" => "Ken", "裊" => "Niao", + "裋" => "Shu", "裌" => "Jia", "è£" => "Kun", "裎" => "Cheng", "è£" => "Li", "è£" => "Juan", + "裑" => "Shen", "裒" => "Pou", "裓" => "Ge", "裔" => "Yi", "裕" => "Yu", "裖" => "Zhen", + "裗" => "Liu", "裘" => "Qiu", "裙" => "Qun", "裚" => "Ji", "裛" => "Yi", "補" => "Bu", + "è£" => "Zhuang", "裞" => "Shui", "裟" => "Sha", "裠" => "Qun", "裡" => "Li", "裢" => "Lian", + "裣" => "Lian", "裤" => "Ku", "裥" => "Jian", "裦" => "Fou", "裧" => "Chan", "裨" => "Bi", + "裩" => "Gun", "裪" => "Tao", "裫" => "Yuan", "裬" => "Ling", "裭" => "Chi", "裮" => "Chang", + "裯" => "Chou", "裰" => "Duo", "裱" => "Biao", "裲" => "Liang", "裳" => "Chang", "裴" => "Pei", + "裵" => "Pei", "裶" => "Fei", "裷" => "Yuan", "裸" => "Luo", "裹" => "Guo", "裺" => "Yan", + "裻" => "Du", "裼" => "Xi", "製" => "Zhi", "裾" => "Ju", "裿" => "Qi", "è¤" => "Zhi", + "褂" => "Gua", "褃" => "Ken", "褄" => "Che", "褅" => "Ti", "褆" => "Ti", "複" => "Fu", + "褈" => "Chong", "褉" => "Xie", "褊" => "Bian", "褋" => "Die", "褌" => "Kun", "è¤" => "Duan", + "褎" => "Xiu", "è¤" => "Xiu", "è¤" => "He", "褑" => "Yuan", "褒" => "Bao", "褓" => "Bao", + "褔" => "Fu", "褕" => "Yu", "褖" => "Tuan", "褗" => "Yan", "褘" => "Hui", "褙" => "Bei", + "褚" => "Chu", "褛" => "Lu", "褜" => "Ena", "è¤" => "Hitoe", "褞" => "Yun", "褟" => "Da", + "褠" => "Gou", "褡" => "Da", "褢" => "Huai", "褣" => "Rong", "褤" => "Yuan", "褥" => "Ru", + "褦" => "Nai", "褧" => "Jiong", "褨" => "Suo", "褩" => "Ban", "褪" => "Tun", "褫" => "Chi", + "褬" => "Sang", "褭" => "Niao", "褮" => "Ying", "褯" => "Jie", "褰" => "Qian", "褱" => "Huai", + "褲" => "Ku", "褳" => "Lian", "褴" => "Bao", "褵" => "Li", "褶" => "Zhe", "褷" => "Shi", + "褸" => "Lu", "褹" => "Yi", "褺" => "Die", "褻" => "Xie", "褼" => "Xian", "褽" => "Wei", + "褾" => "Biao", "褿" => "Cao", "襀" => "Ji", "è¥" => "Jiang", "襂" => "Sen", "襃" => "Bao", + "襄" => "Xiang", "襅" => "Chihaya", "襆" => "Pu", "襇" => "Jian", "襈" => "Zhuan", "襉" => "Jian", + "襊" => "Zui", "襋" => "Ji", "襌" => "Dan", "è¥" => "Za", "襎" => "Fan", "è¥" => "Bo", + "è¥" => "Xiang", "襑" => "Xin", "襒" => "Bie", "襓" => "Rao", "襔" => "Man", "襕" => "Lan", + "襖" => "Ao", "襗" => "Duo", "襘" => "Gui", "襙" => "Cao", "襚" => "Sui", "襛" => "Nong", + "襜" => "Chan", "è¥" => "Lian", "襞" => "Bi", "襟" => "Jin", "襠" => "Dang", "襡" => "Shu", + "襢" => "Tan", "襣" => "Bi", "襤" => "Lan", "襥" => "Pu", "襦" => "Ru", "襧" => "Zhi", + "襩" => "Shu", "襪" => "Wa", "襫" => "Shi", "襬" => "Bai", "襭" => "Xie", "襮" => "Bo", + "襯" => "Chen", "襰" => "Lai", "襱" => "Long", "襲" => "Xi", "襳" => "Xian", "襴" => "Lan", + "襵" => "Zhe", "襶" => "Dai", "襷" => "Tasuki", "襸" => "Zan", "襹" => "Shi", "襺" => "Jian", + "襻" => "Pan", "襼" => "Yi", "襽" => "Ran", "襾" => "Ya", "西" => "Xi", "覀" => "Xi", + "è¦" => "Yao", "覂" => "Feng", "覃" => "Tan", "覅" => "Biao", "覆" => "Fu", "覇" => "Ba", + "覈" => "He", "覉" => "Ji", "覊" => "Ji", "見" => "Jian", "覌" => "Guan", "è¦" => "Bian", + "覎" => "Yan", "è¦" => "Gui", "è¦" => "Jue", "覑" => "Pian", "覒" => "Mao", "覓" => "Mi", + "覔" => "Mi", "覕" => "Mie", "視" => "Shi", "覗" => "Si", "覘" => "Zhan", "覙" => "Luo", + "覚" => "Jue", "覛" => "Mi", "覜" => "Tiao", "è¦" => "Lian", "覞" => "Yao", "覟" => "Zhi", + "覠" => "Jun", "覡" => "Xi", "覢" => "Shan", "覣" => "Wei", "覤" => "Xi", "覥" => "Tian", + "覦" => "Yu", "覧" => "Lan", "覨" => "E", "覩" => "Du", "親" => "Qin", "覫" => "Pang", + "覬" => "Ji", "覭" => "Ming", "覮" => "Ying", "覯" => "Gou", "覰" => "Qu", "覱" => "Zhan", + "覲" => "Jin", "観" => "Guan", "覴" => "Deng", "覵" => "Jian", "覶" => "Luo", "覷" => "Qu", + "覸" => "Jian", "覹" => "Wei", "覺" => "Jue", "覻" => "Qu", "覼" => "Luo", "覽" => "Lan", + "覾" => "Shen", "覿" => "Di", "觀" => "Guan", "è§" => "Jian", "观" => "Guan", "觃" => "Yan", + "规" => "Gui", "觅" => "Mi", "视" => "Shi", "觇" => "Zhan", "览" => "Lan", "觉" => "Jue", + "觊" => "Ji", "觋" => "Xi", "觌" => "Di", "è§" => "Tian", "觎" => "Yu", "è§" => "Gou", + "è§" => "Jin", "觑" => "Qu", "角" => "Jiao", "觓" => "Jiu", "觔" => "Jin", "觕" => "Cu", + "觖" => "Jue", "觗" => "Zhi", "觘" => "Chao", "觙" => "Ji", "觚" => "Gu", "觛" => "Dan", + "觜" => "Zui", "è§" => "Di", "觞" => "Shang", "觟" => "Hua", "觠" => "Quan", "觡" => "Ge", + "觢" => "Chi", "解" => "Jie", "觤" => "Gui", "觥" => "Gong", "触" => "Hong", "觧" => "Jie", + "觨" => "Hun", "觩" => "Qiu", "觪" => "Xing", "觫" => "Su", "觬" => "Ni", "觭" => "Ji", + "觮" => "Lu", "觯" => "Zhi", "觰" => "Zha", "觱" => "Bi", "觲" => "Xing", "觳" => "Hu", + "觴" => "Shang", "觵" => "Gong", "觶" => "Zhi", "觷" => "Xue", "觸" => "Chu", "觹" => "Xi", + "觺" => "Yi", "觻" => "Lu", "觼" => "Jue", "觽" => "Xi", "觾" => "Yan", "觿" => "Xi", + "è¨" => "Yan", "訂" => "Ding", "訃" => "Fu", "訄" => "Qiu", "訅" => "Qiu", "訆" => "Jiao", + "訇" => "Hong", "計" => "Ji", "訉" => "Fan", "訊" => "Xun", "訋" => "Diao", "訌" => "Hong", + "è¨" => "Cha", "討" => "Tao", "è¨" => "Xu", "è¨" => "Jie", "訑" => "Yi", "訒" => "Ren", + "訓" => "Xun", "訔" => "Yin", "訕" => "Shan", "訖" => "Qi", "託" => "Tuo", "記" => "Ji", + "訙" => "Xun", "訚" => "Yin", "訛" => "E", "訜" => "Fen", "è¨" => "Ya", "訞" => "Yao", + "訟" => "Song", "訠" => "Shen", "訡" => "Yin", "訢" => "Xin", "訣" => "Jue", "訤" => "Xiao", + "訥" => "Ne", "訦" => "Chen", "訧" => "You", "訨" => "Zhi", "訩" => "Xiong", "訪" => "Fang", + "訫" => "Xin", "訬" => "Chao", "設" => "She", "訮" => "Xian", "訯" => "Sha", "訰" => "Tun", + "許" => "Xu", "訲" => "Yi", "訳" => "Yi", "訴" => "Su", "訵" => "Chi", "訶" => "He", + "訷" => "Shen", "訸" => "He", "訹" => "Xu", "診" => "Zhen", "註" => "Zhu", "証" => "Zheng", + "訽" => "Gou", "訾" => "Zi", "訿" => "Zi", "è©€" => "Zhan", "è©" => "Gu", "è©‚" => "Fu", + "詃" => "Quan", "è©„" => "Die", "è©…" => "Ling", "詆" => "Di", "詇" => "Yang", "詈" => "Li", + "詉" => "Nao", "è©Š" => "Pan", "è©‹" => "Zhou", "è©Œ" => "Gan", "è©" => "Yi", "è©Ž" => "Ju", + "è©" => "Ao", "è©" => "Zha", "è©‘" => "Tuo", "è©’" => "Yi", "è©“" => "Qu", "è©”" => "Zhao", + "è©•" => "Ping", "è©–" => "Bi", "è©—" => "Xiong", "詘" => "Qu", "è©™" => "Ba", "è©š" => "Da", + "è©›" => "Zu", "è©œ" => "Tao", "è©" => "Zhu", "è©ž" => "Ci", "è©Ÿ" => "Zhe", "è© " => "Yong", + "è©¡" => "Xu", "è©¢" => "Xun", "è©£" => "Yi", "詤" => "Huang", "è©¥" => "He", "試" => "Shi", + "詧" => "Cha", "詨" => "Jiao", "è©©" => "Shi", "詪" => "Hen", "è©«" => "Cha", "詬" => "Gou", + "è©­" => "Gui", "è©®" => "Quan", "詯" => "Hui", "è©°" => "Jie", "話" => "Hua", "該" => "Gai", + "詳" => "Xiang", "è©´" => "Wei", "詵" => "Shen", "詶" => "Chou", "è©·" => "Tong", "詸" => "Mi", + "詹" => "Zhan", "詺" => "Ming", "è©»" => "E", "詼" => "Hui", "詽" => "Yan", "詾" => "Xiong", + "è©¿" => "Gua", "誀" => "Er", "èª" => "Beng", "誂" => "Tiao", "誃" => "Chi", "誄" => "Lei", + "誅" => "Zhu", "誆" => "Kuang", "誇" => "Kua", "誈" => "Wu", "誉" => "Yu", "誊" => "Teng", + "誋" => "Ji", "誌" => "Zhi", "èª" => "Ren", "誎" => "Su", "èª" => "Lang", "èª" => "E", + "誑" => "Kuang", "誒" => "E", "誓" => "Shi", "誔" => "Ting", "誕" => "Dan", "誖" => "Bo", + "誗" => "Chan", "誘" => "You", "誙" => "Heng", "誚" => "Qiao", "誛" => "Qin", "誜" => "Shua", + "èª" => "An", "語" => "Yu", "誟" => "Xiao", "誠" => "Cheng", "誡" => "Jie", "誢" => "Xian", + "誣" => "Wu", "誤" => "Wu", "誥" => "Gao", "誦" => "Song", "誧" => "Pu", "誨" => "Hui", + "誩" => "Jing", "說" => "Shuo", "誫" => "Zhen", "説" => "Shuo", "読" => "Du", "誮" => "Yasashi", + "誯" => "Chang", "誰" => "Shui", "誱" => "Jie", "課" => "Ke", "誳" => "Qu", "誴" => "Cong", + "誵" => "Xiao", "誶" => "Sui", "誷" => "Wang", "誸" => "Xuan", "誹" => "Fei", "誺" => "Chi", + "誻" => "Ta", "誼" => "Yi", "誽" => "Na", "誾" => "Yin", "調" => "Diao", "è«€" => "Pi", + "è«" => "Chuo", "è«‚" => "Chan", "諃" => "Chen", "è«„" => "Zhun", "è«…" => "Ji", "諆" => "Qi", + "談" => "Tan", "諈" => "Zhui", "諉" => "Wei", "è«Š" => "Ju", "è«‹" => "Qing", "è«Œ" => "Jian", + "è«" => "Zheng", "è«Ž" => "Ze", "è«" => "Zou", "è«" => "Qian", "è«‘" => "Zhuo", "è«’" => "Liang", + "è«“" => "Jian", "è«”" => "Zhu", "è«•" => "Hao", "è«–" => "Lun", "è«—" => "Shen", "諘" => "Biao", + "è«™" => "Huai", "è«š" => "Pian", "è«›" => "Yu", "è«œ" => "Die", "è«" => "Xu", "è«ž" => "Pian", + "è«Ÿ" => "Shi", "è« " => "Xuan", "è«¡" => "Shi", "è«¢" => "Hun", "è«£" => "Hua", "諤" => "E", + "è«¥" => "Zhong", "諦" => "Di", "諧" => "Xie", "諨" => "Fu", "è«©" => "Pu", "諪" => "Ting", + "è««" => "Jian", "諬" => "Qi", "è«­" => "Yu", "è«®" => "Zi", "諯" => "Chuan", "è«°" => "Xi", + "諱" => "Hui", "諲" => "Yin", "諳" => "An", "è«´" => "Xian", "諵" => "Nan", "諶" => "Chen", + "è«·" => "Feng", "諸" => "Zhu", "諹" => "Yang", "諺" => "Yan", "è«»" => "Heng", "諼" => "Xuan", + "諽" => "Ge", "諾" => "Nuo", "è«¿" => "Qi", "è¬" => "Ye", "謂" => "Wei", "謄" => "Teng", + "謅" => "Zou", "謆" => "Shan", "謇" => "Jian", "謈" => "Bo", "謉" => "Ku", "謊" => "Huang", + "謋" => "Huo", "謌" => "Ge", "è¬" => "Ying", "謎" => "Mi", "è¬" => "Xiao", "è¬" => "Mi", + "謑" => "Xi", "謒" => "Qiang", "謓" => "Chen", "謔" => "Nue", "謕" => "Ti", "謖" => "Su", + "謗" => "Bang", "謘" => "Chi", "謙" => "Qian", "謚" => "Shi", "講" => "Jiang", "謜" => "Yuan", + "è¬" => "Xie", "謞" => "Xue", "謟" => "Tao", "謠" => "Yao", "謡" => "Yao", "謣" => "Yu", + "謤" => "Biao", "謥" => "Cong", "謦" => "Qing", "謧" => "Li", "謨" => "Mo", "謩" => "Mo", + "謪" => "Shang", "謫" => "Zhe", "謬" => "Miu", "謭" => "Jian", "謮" => "Ze", "謯" => "Jie", + "謰" => "Lian", "謱" => "Lou", "謲" => "Can", "謳" => "Ou", "謴" => "Guan", "謵" => "Xi", + "謶" => "Zhuo", "謷" => "Ao", "謸" => "Ao", "謹" => "Jin", "謺" => "Zhe", "謻" => "Yi", + "謼" => "Hu", "謽" => "Jiang", "謾" => "Man", "謿" => "Chao", "è­€" => "Han", "è­" => "Hua", + "è­‚" => "Chan", "è­ƒ" => "Xu", "è­„" => "Zeng", "è­…" => "Se", "è­†" => "Xi", "è­‡" => "She", + "è­ˆ" => "Dui", "è­‰" => "Zheng", "è­Š" => "Nao", "è­‹" => "Lan", "è­Œ" => "E", "è­" => "Ying", + "è­Ž" => "Jue", "è­" => "Ji", "è­" => "Zun", "è­‘" => "Jiao", "è­’" => "Bo", "è­“" => "Hui", + "è­”" => "Zhuan", "è­•" => "Mu", "è­–" => "Zen", "è­—" => "Zha", "è­˜" => "Shi", "è­™" => "Qiao", + "è­š" => "Tan", "è­›" => "Zen", "è­œ" => "Pu", "è­" => "Sheng", "è­ž" => "Xuan", "è­Ÿ" => "Zao", + "è­ " => "Tan", "è­¡" => "Dang", "è­¢" => "Sui", "è­£" => "Qian", "è­¤" => "Ji", "è­¥" => "Jiao", + "è­¦" => "Jing", "è­§" => "Lian", "è­¨" => "Nou", "è­©" => "Yi", "è­ª" => "Ai", "è­«" => "Zhan", + "è­¬" => "Pi", "è­­" => "Hui", "è­®" => "Hua", "è­¯" => "Yi", "è­°" => "Yi", "è­±" => "Shan", + "è­²" => "Rang", "è­³" => "Nou", "è­´" => "Qian", "è­µ" => "Zhui", "è­¶" => "Ta", "è­·" => "Hu", + "è­¸" => "Zhou", "è­¹" => "Hao", "è­º" => "Ye", "è­»" => "Ying", "è­¼" => "Jian", "è­½" => "Yu", + "è­¾" => "Jian", "è­¿" => "Hui", "讀" => "Du", "è®" => "Zhe", "讂" => "Xuan", "讃" => "Zan", + "讄" => "Lei", "è®…" => "Shen", "讆" => "Wei", "讇" => "Chan", "讈" => "Li", "讉" => "Yi", + "變" => "Bian", "讋" => "Zhe", "讌" => "Yan", "è®" => "E", "讎" => "Chou", "è®" => "Wei", + "è®" => "Chou", "讑" => "Yao", "è®’" => "Chan", "讓" => "Rang", "è®”" => "Yin", "讕" => "Lan", + "è®–" => "Chen", "è®—" => "Huo", "讘" => "Zhe", "è®™" => "Huan", "讚" => "Zan", "è®›" => "Yi", + "讜" => "Dang", "è®" => "Zhan", "讞" => "Yan", "讟" => "Du", "è® " => "Yan", "计" => "Ji", + "订" => "Ding", "讣" => "Fu", "认" => "Ren", "讥" => "Ji", "讦" => "Jie", "讧" => "Hong", + "讨" => "Tao", "让" => "Rang", "讪" => "Shan", "讫" => "Qi", "讬" => "Tuo", "è®­" => "Xun", + "è®®" => "Yi", "讯" => "Xun", "è®°" => "Ji", "è®±" => "Ren", "讲" => "Jiang", "讳" => "Hui", + "è®´" => "Ou", "讵" => "Ju", "讶" => "Ya", "è®·" => "Ne", "许" => "Xu", "讹" => "E", + "论" => "Lun", "è®»" => "Xiong", "讼" => "Song", "讽" => "Feng", "设" => "She", "访" => "Fang", + "诀" => "Jue", "è¯" => "Zheng", "诂" => "Gu", "诃" => "He", "评" => "Ping", "诅" => "Zu", + "识" => "Shi", "诇" => "Xiong", "诈" => "Zha", "诉" => "Su", "诊" => "Zhen", "诋" => "Di", + "诌" => "Zou", "è¯" => "Ci", "诎" => "Qu", "è¯" => "Zhao", "è¯" => "Bi", "译" => "Yi", + "诒" => "Yi", "诓" => "Kuang", "诔" => "Lei", "试" => "Shi", "诖" => "Gua", "诗" => "Shi", + "诘" => "Jie", "诙" => "Hui", "诚" => "Cheng", "诛" => "Zhu", "诜" => "Shen", "è¯" => "Hua", + "诞" => "Dan", "诟" => "Gou", "诠" => "Quan", "诡" => "Gui", "询" => "Xun", "诣" => "Yi", + "诤" => "Zheng", "该" => "Gai", "详" => "Xiang", "诧" => "Cha", "诨" => "Hun", "诩" => "Xu", + "诪" => "Zhou", "诫" => "Jie", "诬" => "Wu", "语" => "Yu", "诮" => "Qiao", "误" => "Wu", + "诰" => "Gao", "诱" => "You", "诲" => "Hui", "诳" => "Kuang", "说" => "Shuo", "诵" => "Song", + "诶" => "Ai", "请" => "Qing", "诸" => "Zhu", "诹" => "Zou", "诺" => "Nuo", "读" => "Du", + "诼" => "Zhuo", "诽" => "Fei", "课" => "Ke", "诿" => "Wei", "è°" => "Shui", "è°‚" => "Shen", + "è°ƒ" => "Diao", "è°„" => "Chan", "è°…" => "Liang", "è°†" => "Zhun", "è°‡" => "Sui", "è°ˆ" => "Tan", + "è°‰" => "Shen", "è°Š" => "Yi", "è°‹" => "Mou", "è°Œ" => "Chen", "è°" => "Die", "è°Ž" => "Huang", + "è°" => "Jian", "è°" => "Xie", "è°‘" => "Nue", "è°’" => "Ye", "è°“" => "Wei", "è°”" => "E", + "è°•" => "Yu", "è°–" => "Xuan", "è°—" => "Chan", "è°˜" => "Zi", "è°™" => "An", "è°š" => "Yan", + "è°›" => "Di", "è°œ" => "Mi", "è°" => "Pian", "è°ž" => "Xu", "è°Ÿ" => "Mo", "è° " => "Dang", + "è°¡" => "Su", "è°¢" => "Xie", "è°£" => "Yao", "è°¤" => "Bang", "è°¥" => "Shi", "è°¦" => "Qian", + "è°§" => "Mi", "è°¨" => "Jin", "è°©" => "Man", "è°ª" => "Zhe", "è°«" => "Jian", "è°¬" => "Miu", + "è°­" => "Tan", "è°®" => "Zen", "è°¯" => "Qiao", "è°°" => "Lan", "è°±" => "Pu", "è°²" => "Jue", + "è°³" => "Yan", "è°´" => "Qian", "è°µ" => "Zhan", "è°¶" => "Chen", "è°·" => "Gu", "è°¸" => "Qian", + "è°¹" => "Hong", "è°º" => "Xia", "è°»" => "Jue", "è°¼" => "Hong", "è°½" => "Han", "è°¾" => "Hong", + "è°¿" => "Xi", "è±€" => "Xi", "è±" => "Huo", "豂" => "Liao", "豃" => "Han", "豄" => "Du", + "è±…" => "Long", "豆" => "Dou", "豇" => "Jiang", "豈" => "Qi", "豉" => "Shi", "豊" => "Li", + "豋" => "Deng", "豌" => "Wan", "è±" => "Bi", "豎" => "Shu", "è±" => "Xian", "è±" => "Feng", + "豑" => "Zhi", "è±’" => "Zhi", "豓" => "Yan", "è±”" => "Yan", "豕" => "Shi", "è±–" => "Chu", + "è±—" => "Hui", "豘" => "Tun", "è±™" => "Yi", "豚" => "Tun", "è±›" => "Yi", "豜" => "Jian", + "è±" => "Ba", "豞" => "Hou", "豟" => "E", "è± " => "Cu", "象" => "Xiang", "è±¢" => "Huan", + "è±£" => "Jian", "豤" => "Ken", "è±¥" => "Gai", "豦" => "Qu", "豧" => "Fu", "豨" => "Xi", + "豩" => "Bin", "豪" => "Hao", "豫" => "Yu", "豬" => "Zhu", "è±­" => "Jia", "豯" => "Xi", + "è±°" => "Bo", "è±±" => "Wen", "è±²" => "Huan", "è±³" => "Bin", "è±´" => "Di", "è±µ" => "Zong", + "豶" => "Fen", "è±·" => "Yi", "豸" => "Zhi", "è±¹" => "Bao", "豺" => "Chai", "è±»" => "Han", + "è±¼" => "Pi", "è±½" => "Na", "è±¾" => "Pi", "豿" => "Gou", "è²€" => "Na", "è²" => "You", + "貂" => "Diao", "貃" => "Mo", "貄" => "Si", "è²…" => "Xiu", "貆" => "Huan", "貇" => "Kun", + "貈" => "He", "貉" => "He", "貊" => "Mo", "貋" => "Han", "貌" => "Mao", "è²" => "Li", + "貎" => "Ni", "è²" => "Bi", "è²" => "Yu", "貑" => "Jia", "è²’" => "Tuan", "貓" => "Mao", + "è²”" => "Pi", "貕" => "Xi", "è²–" => "E", "è²—" => "Ju", "貘" => "Mo", "è²™" => "Chu", + "貚" => "Tan", "è²›" => "Huan", "貜" => "Jue", "è²" => "Bei", "貞" => "Zhen", "貟" => "Yuan", + "è² " => "Fu", "財" => "Cai", "è²¢" => "Gong", "è²£" => "Te", "貤" => "Yi", "è²¥" => "Hang", + "貦" => "Wan", "貧" => "Pin", "貨" => "Huo", "販" => "Fan", "貪" => "Tan", "貫" => "Guan", + "責" => "Ze", "è²­" => "Zhi", "è²®" => "Er", "貯" => "Zhu", "è²°" => "Shi", "è²±" => "Bi", + "è²²" => "Zi", "è²³" => "Er", "è²´" => "Gui", "è²µ" => "Pian", "貶" => "Bian", "è²·" => "Mai", + "貸" => "Dai", "è²¹" => "Sheng", "貺" => "Kuang", "è²»" => "Fei", "è²¼" => "Tie", "è²½" => "Yi", + "è²¾" => "Chi", "貿" => "Mao", "è³€" => "He", "è³" => "Bi", "賂" => "Lu", "賃" => "Ren", + "賄" => "Hui", "è³…" => "Gai", "賆" => "Pian", "資" => "Zi", "賈" => "Jia", "賉" => "Xu", + "賊" => "Zei", "賋" => "Jiao", "賌" => "Gai", "è³" => "Zang", "賎" => "Jian", "è³" => "Ying", + "è³" => "Xun", "賑" => "Zhen", "è³’" => "She", "賓" => "Bin", "è³”" => "Bin", "賕" => "Qiu", + "è³–" => "She", "è³—" => "Chuan", "賘" => "Zang", "è³™" => "Zhou", "賚" => "Lai", "è³›" => "Zan", + "賜" => "Si", "è³" => "Chen", "賞" => "Shang", "賟" => "Tian", "è³ " => "Pei", "賡" => "Geng", + "è³¢" => "Xian", "è³£" => "Mai", "賤" => "Jian", "è³¥" => "Sui", "賦" => "Fu", "賧" => "Tan", + "賨" => "Cong", "賩" => "Cong", "質" => "Zhi", "賫" => "Ji", "賬" => "Zhang", "è³­" => "Du", + "è³®" => "Jin", "賯" => "Xiong", "è³°" => "Shun", "è³±" => "Yun", "è³²" => "Bao", "è³³" => "Zai", + "è³´" => "Lai", "è³µ" => "Feng", "賶" => "Cang", "è³·" => "Ji", "賸" => "Sheng", "è³¹" => "Ai", + "賺" => "Zhuan", "è³»" => "Fu", "è³¼" => "Gou", "è³½" => "Sai", "è³¾" => "Ze", "賿" => "Liao", + "è´" => "Bai", "è´‚" => "Chen", "è´ƒ" => "Zhuan", "è´„" => "Zhi", "è´…" => "Zhui", "è´†" => "Biao", + "è´‡" => "Yun", "è´ˆ" => "Zeng", "è´‰" => "Tan", "è´Š" => "Zan", "è´‹" => "Yan", "è´" => "Shan", + "è´Ž" => "Wan", "è´" => "Ying", "è´" => "Jin", "è´‘" => "Gan", "è´’" => "Xian", "è´“" => "Zang", + "è´”" => "Bi", "è´•" => "Du", "è´–" => "Shu", "è´—" => "Yan", "è´™" => "Xuan", "è´š" => "Long", + "è´›" => "Gan", "è´œ" => "Zang", "è´" => "Bei", "è´ž" => "Zhen", "è´Ÿ" => "Fu", "è´ " => "Yuan", + "è´¡" => "Gong", "è´¢" => "Cai", "è´£" => "Ze", "è´¤" => "Xian", "è´¥" => "Bai", "è´¦" => "Zhang", + "è´§" => "Huo", "è´¨" => "Zhi", "è´©" => "Fan", "è´ª" => "Tan", "è´«" => "Pin", "è´¬" => "Bian", + "è´­" => "Gou", "è´®" => "Zhu", "è´¯" => "Guan", "è´°" => "Er", "è´±" => "Jian", "è´²" => "Bi", + "è´³" => "Shi", "è´´" => "Tie", "è´µ" => "Gui", "è´¶" => "Kuang", "è´·" => "Dai", "è´¸" => "Mao", + "è´¹" => "Fei", "è´º" => "He", "è´»" => "Yi", "è´¼" => "Zei", "è´½" => "Zhi", "è´¾" => "Jia", + "è´¿" => "Hui", "èµ€" => "Zi", "èµ" => "Ren", "赂" => "Lu", "赃" => "Zang", "资" => "Zi", + "èµ…" => "Gai", "赆" => "Jin", "赇" => "Qiu", "赈" => "Zhen", "赉" => "Lai", "赊" => "She", + "赋" => "Fu", "赌" => "Du", "èµ" => "Ji", "赎" => "Shu", "èµ" => "Shang", "èµ" => "Si", + "赑" => "Bi", "èµ’" => "Zhou", "赓" => "Geng", "èµ”" => "Pei", "赕" => "Tan", "èµ–" => "Lai", + "èµ—" => "Feng", "赘" => "Zhui", "èµ™" => "Fu", "赚" => "Zhuan", "èµ›" => "Sai", "赜" => "Ze", + "èµ" => "Yan", "赞" => "Zan", "赟" => "Yun", "èµ " => "Zeng", "赡" => "Shan", "èµ¢" => "Ying", + "èµ£" => "Gan", "赤" => "Chi", "èµ¥" => "Xi", "赦" => "She", "赧" => "Nan", "赨" => "Xiong", + "赩" => "Xi", "赪" => "Cheng", "赫" => "He", "赬" => "Cheng", "èµ­" => "Zhe", "èµ®" => "Xia", + "赯" => "Tang", "èµ°" => "Zou", "èµ±" => "Zou", "èµ²" => "Li", "èµ³" => "Jiu", "èµ´" => "Fu", + "èµµ" => "Zhao", "赶" => "Gan", "èµ·" => "Qi", "赸" => "Shan", "èµ¹" => "Qiong", "赺" => "Qin", + "èµ»" => "Xian", "èµ¼" => "Ci", "èµ½" => "Jue", "èµ¾" => "Qin", "赿" => "Chi", "趀" => "Ci", + "è¶" => "Chen", "趂" => "Chen", "趃" => "Die", "趄" => "Ju", "超" => "Chao", "趆" => "Di", + "趇" => "Se", "趈" => "Zhan", "趉" => "Zhu", "越" => "Yue", "趋" => "Qu", "趌" => "Jie", + "è¶" => "Chi", "趎" => "Chu", "è¶" => "Gua", "è¶" => "Xue", "趑" => "Ci", "趒" => "Tiao", + "趓" => "Duo", "趔" => "Lie", "趕" => "Gan", "趖" => "Suo", "趗" => "Cu", "趘" => "Xi", + "趙" => "Zhao", "趚" => "Su", "趛" => "Yin", "趜" => "Ju", "è¶" => "Jian", "趞" => "Que", + "趟" => "Tang", "趠" => "Chuo", "趡" => "Cui", "趢" => "Lu", "趣" => "Qu", "趤" => "Dang", + "趥" => "Qiu", "趦" => "Zi", "趧" => "Ti", "趨" => "Qu", "趩" => "Chi", "趪" => "Huang", + "趫" => "Qiao", "趬" => "Qiao", "趭" => "Yao", "趮" => "Zao", "趯" => "Ti", "趱" => "Zan", + "趲" => "Zan", "足" => "Zu", "趴" => "Pa", "趵" => "Bao", "趶" => "Ku", "趷" => "Ke", + "趸" => "Dun", "趹" => "Jue", "趺" => "Fu", "趻" => "Chen", "趼" => "Jian", "趽" => "Fang", + "趾" => "Zhi", "趿" => "Sa", "è·€" => "Yue", "è·" => "Pa", "è·‚" => "Qi", "è·ƒ" => "Yue", + "è·„" => "Qiang", "è·…" => "Tuo", "è·†" => "Tai", "è·‡" => "Yi", "è·ˆ" => "Nian", "è·‰" => "Ling", + "è·Š" => "Mei", "è·‹" => "Ba", "è·Œ" => "Die", "è·" => "Ku", "è·Ž" => "Tuo", "è·" => "Jia", + "è·" => "Ci", "è·‘" => "Pao", "è·’" => "Qia", "è·“" => "Zhu", "è·”" => "Ju", "è·•" => "Die", + "è·–" => "Zhi", "è·—" => "Fu", "è·˜" => "Pan", "è·™" => "Ju", "è·š" => "Shan", "è·›" => "Bo", + "è·œ" => "Ni", "è·" => "Ju", "è·ž" => "Li", "è·Ÿ" => "Gen", "è· " => "Yi", "è·¡" => "Ji", + "è·¢" => "Dai", "è·£" => "Xian", "è·¤" => "Jiao", "è·¥" => "Duo", "è·¦" => "Zhu", "è·§" => "Zhuan", + "è·¨" => "Kua", "è·©" => "Zhuai", "è·ª" => "Gui", "è·«" => "Qiong", "è·¬" => "Kui", "è·­" => "Xiang", + "è·®" => "Chi", "è·¯" => "Lu", "è·°" => "Beng", "è·±" => "Zhi", "è·²" => "Jia", "è·³" => "Tiao", + "è·´" => "Cai", "è·µ" => "Jian", "è·¶" => "Ta", "è··" => "Qiao", "è·¸" => "Bi", "è·¹" => "Xian", + "è·º" => "Duo", "è·»" => "Ji", "è·¼" => "Ju", "è·½" => "Ji", "è·¾" => "Shu", "è·¿" => "Tu", + "è¸" => "Jing", "踂" => "Nie", "踃" => "Xiao", "踄" => "Bo", "踅" => "Chi", "踆" => "Qun", + "踇" => "Mou", "踈" => "Shu", "踉" => "Lang", "踊" => "Yong", "踋" => "Jiao", "踌" => "Chou", + "è¸" => "Qiao", "è¸" => "Ta", "è¸" => "Jian", "踑" => "Qi", "踒" => "Wo", "踓" => "Wei", + "踔" => "Zhuo", "踕" => "Jie", "踖" => "Ji", "踗" => "Nie", "踘" => "Ju", "踙" => "Ju", + "踚" => "Lun", "踛" => "Lu", "踜" => "Leng", "è¸" => "Huai", "踞" => "Ju", "踟" => "Chi", + "踠" => "Wan", "踡" => "Quan", "踢" => "Ti", "踣" => "Bo", "踤" => "Zu", "踥" => "Qie", + "踦" => "Ji", "踧" => "Cu", "踨" => "Zong", "踩" => "Cai", "踪" => "Zong", "踫" => "Peng", + "踬" => "Zhi", "踭" => "Zheng", "踮" => "Dian", "踯" => "Zhi", "踰" => "Yu", "踱" => "Duo", + "踲" => "Dun", "踳" => "Chun", "踴" => "Yong", "踵" => "Zhong", "踶" => "Di", "踷" => "Zhe", + "踸" => "Chen", "踹" => "Chuai", "踺" => "Jian", "踻" => "Gua", "踼" => "Tang", "踽" => "Ju", + "踾" => "Fu", "踿" => "Zu", "è¹€" => "Die", "è¹" => "Pian", "蹂" => "Rou", "蹃" => "Nuo", + "蹄" => "Ti", "è¹…" => "Cha", "蹆" => "Tui", "蹇" => "Jian", "蹈" => "Dao", "蹉" => "Cuo", + "蹊" => "Xi", "蹋" => "Ta", "蹌" => "Qiang", "è¹" => "Zhan", "蹎" => "Dian", "è¹" => "Ti", + "è¹" => "Ji", "蹑" => "Nie", "è¹’" => "Man", "蹓" => "Liu", "è¹”" => "Zhan", "蹕" => "Bi", + "è¹–" => "Chong", "è¹—" => "Lu", "蹘" => "Liao", "è¹™" => "Cu", "蹚" => "Tang", "è¹›" => "Dai", + "蹜" => "Suo", "è¹" => "Xi", "蹞" => "Kui", "蹟" => "Ji", "è¹ " => "Zhi", "蹡" => "Qiang", + "è¹¢" => "Di", "è¹£" => "Man", "蹤" => "Zong", "è¹¥" => "Lian", "蹦" => "Beng", "蹧" => "Zao", + "蹨" => "Nian", "蹩" => "Bie", "蹪" => "Tui", "蹫" => "Ju", "蹬" => "Deng", "è¹­" => "Ceng", + "è¹®" => "Xian", "蹯" => "Fan", "è¹°" => "Chu", "è¹±" => "Zhong", "è¹²" => "Dun", "è¹³" => "Bo", + "è¹´" => "Cu", "è¹µ" => "Zu", "蹶" => "Jue", "è¹·" => "Jue", "蹸" => "Lin", "è¹¹" => "Ta", + "蹺" => "Qiao", "è¹»" => "Qiao", "è¹¼" => "Pu", "è¹½" => "Liao", "è¹¾" => "Dun", "蹿" => "Cuan", + "躀" => "Kuang", "èº" => "Zao", "躂" => "Ta", "躃" => "Bi", "躄" => "Bi", "躅" => "Zhu", + "躆" => "Ju", "躇" => "Chu", "躈" => "Qiao", "躉" => "Dun", "躊" => "Chou", "躋" => "Ji", + "躌" => "Wu", "èº" => "Yue", "躎" => "Nian", "èº" => "Lin", "èº" => "Lie", "躑" => "Zhi", + "躒" => "Li", "躓" => "Zhi", "躔" => "Chan", "躕" => "Chu", "躖" => "Duan", "躗" => "Wei", + "躘" => "Long", "躙" => "Lin", "躚" => "Xian", "躛" => "Wei", "躜" => "Zuan", "èº" => "Lan", + "躞" => "Xie", "躟" => "Rang", "躠" => "Xie", "躡" => "Nie", "躢" => "Ta", "躣" => "Qu", + "躤" => "Jie", "躥" => "Cuan", "躦" => "Zuan", "躧" => "Xi", "躨" => "Kui", "躩" => "Jue", + "躪" => "Lin", "身" => "Shen", "躬" => "Gong", "躭" => "Dan", "躮" => "Segare", "躯" => "Qu", + "躰" => "Ti", "躱" => "Duo", "躲" => "Duo", "躳" => "Gong", "躴" => "Lang", "躵" => "Nerau", + "躶" => "Luo", "躷" => "Ai", "躸" => "Ji", "躹" => "Ju", "躺" => "Tang", "躻" => "Utsuke", + "躽" => "Yan", "躾" => "Shitsuke", "躿" => "Kang", "軀" => "Qu", "è»" => "Lou", "軂" => "Lao", + "軃" => "Tuo", "軄" => "Zhi", "è»…" => "Yagate", "軆" => "Ti", "軇" => "Dao", "軈" => "Yagate", + "軉" => "Yu", "車" => "Che", "軋" => "Ya", "軌" => "Gui", "è»" => "Jun", "軎" => "Wei", + "è»" => "Yue", "è»" => "Xin", "軑" => "Di", "è»’" => "Xuan", "軓" => "Fan", "è»”" => "Ren", + "軕" => "Shan", "è»–" => "Qiang", "è»—" => "Shu", "軘" => "Tun", "è»™" => "Chen", "軚" => "Dai", + "è»›" => "E", "軜" => "Na", "è»" => "Qi", "軞" => "Mao", "軟" => "Ruan", "è» " => "Ren", + "軡" => "Fan", "転" => "Zhuan", "軣" => "Hong", "軤" => "Hu", "軥" => "Qu", "軦" => "Huang", + "軧" => "Di", "軨" => "Ling", "軩" => "Dai", "軪" => "Ao", "軫" => "Zhen", "軬" => "Fan", + "è»­" => "Kuang", "è»®" => "Ang", "軯" => "Peng", "è»°" => "Bei", "è»±" => "Gu", "軲" => "Ku", + "軳" => "Pao", "è»´" => "Zhu", "軵" => "Rong", "軶" => "E", "è»·" => "Ba", "軸" => "Zhou", + "軹" => "Zhi", "軺" => "Yao", "è»»" => "Ke", "軼" => "Yi", "軽" => "Qing", "軾" => "Shi", + "軿" => "Ping", "è¼" => "Qiong", "輂" => "Ju", "較" => "Jiao", "輄" => "Guang", "è¼…" => "Lu", + "輆" => "Kai", "輇" => "Quan", "輈" => "Zhou", "載" => "Zai", "輊" => "Zhi", "輋" => "She", + "輌" => "Liang", "è¼" => "Yu", "輎" => "Shao", "è¼" => "You", "è¼" => "Huan", "輑" => "Yun", + "è¼’" => "Zhe", "輓" => "Wan", "è¼”" => "Fu", "輕" => "Qing", "è¼–" => "Zhou", "è¼—" => "Ni", + "輘" => "Ling", "è¼™" => "Zhe", "輚" => "Zhan", "è¼›" => "Liang", "輜" => "Zi", "è¼" => "Hui", + "輞" => "Wang", "輟" => "Chuo", "è¼ " => "Guo", "輡" => "Kan", "è¼¢" => "Yi", "è¼£" => "Peng", + "輤" => "Qian", "è¼¥" => "Gun", "輦" => "Nian", "輧" => "Pian", "輨" => "Guan", "輩" => "Bei", + "輪" => "Lun", "輫" => "Pai", "輬" => "Liang", "è¼­" => "Ruan", "è¼®" => "Rou", "輯" => "Ji", + "è¼°" => "Yang", "è¼±" => "Xian", "è¼²" => "Chuan", "è¼³" => "Cou", "è¼´" => "Qun", "è¼µ" => "Ge", + "輶" => "You", "è¼·" => "Hong", "輸" => "Shu", "è¼¹" => "Fu", "輺" => "Zi", "è¼»" => "Fu", + "è¼¼" => "Wen", "è¼½" => "Ben", "è¼¾" => "Zhan", "輿" => "Yu", "è½€" => "Wen", "è½" => "Tao", + "轂" => "Gu", "轃" => "Zhen", "轄" => "Xia", "è½…" => "Yuan", "轆" => "Lu", "轇" => "Jiu", + "轈" => "Chao", "轉" => "Zhuan", "轊" => "Wei", "轋" => "Hun", "轌" => "Sori", "è½" => "Che", + "轎" => "Jiao", "è½" => "Zhan", "è½" => "Pu", "轑" => "Lao", "è½’" => "Fen", "轓" => "Fan", + "è½”" => "Lin", "轕" => "Ge", "è½–" => "Se", "è½—" => "Kan", "轘" => "Huan", "è½™" => "Yi", + "轚" => "Ji", "è½›" => "Dui", "轜" => "Er", "è½" => "Yu", "轞" => "Xian", "轟" => "Hong", + "è½ " => "Lei", "轡" => "Pei", "è½¢" => "Li", "è½£" => "Li", "轤" => "Lu", "è½¥" => "Lin", + "车" => "Che", "轧" => "Ya", "轨" => "Gui", "轩" => "Xuan", "轪" => "Di", "轫" => "Ren", + "转" => "Zhuan", "è½­" => "E", "è½®" => "Lun", "软" => "Ruan", "è½°" => "Hong", "è½±" => "Ku", + "è½²" => "Ke", "è½³" => "Lu", "è½´" => "Zhou", "è½µ" => "Zhi", "轶" => "Yi", "è½·" => "Hu", + "轸" => "Zhen", "è½¹" => "Li", "轺" => "Yao", "è½»" => "Qing", "è½¼" => "Shi", "è½½" => "Zai", + "è½¾" => "Zhi", "轿" => "Jiao", "è¾€" => "Zhou", "è¾" => "Quan", "辂" => "Lu", "较" => "Jiao", + "辄" => "Zhe", "è¾…" => "Fu", "辆" => "Liang", "辇" => "Nian", "辈" => "Bei", "辉" => "Hui", + "辊" => "Gun", "辋" => "Wang", "辌" => "Liang", "è¾" => "Chuo", "辎" => "Zi", "è¾" => "Cou", + "è¾" => "Fu", "辑" => "Ji", "è¾’" => "Wen", "输" => "Shu", "è¾”" => "Pei", "辕" => "Yuan", + "è¾–" => "Xia", "è¾—" => "Zhan", "辘" => "Lu", "è¾™" => "Che", "辚" => "Lin", "è¾›" => "Xin", + "辜" => "Gu", "è¾" => "Ci", "辞" => "Ci", "辟" => "Pi", "è¾ " => "Zui", "辡" => "Bian", + "è¾¢" => "La", "è¾£" => "La", "辤" => "Ci", "è¾¥" => "Xue", "辦" => "Ban", "辧" => "Bian", + "辨" => "Bian", "辩" => "Bian", "辫" => "Bian", "辬" => "Ban", "è¾­" => "Ci", "è¾®" => "Bian", + "辯" => "Bian", "è¾°" => "Chen", "è¾±" => "Ru", "è¾²" => "Nong", "è¾³" => "Nong", "è¾´" => "Zhen", + "è¾µ" => "Chuo", "辶" => "Chuo", "è¾·" => "Suberu", "辸" => "Reng", "è¾¹" => "Bian", "辺" => "Bian", + "è¾»" => "Sip", "è¾¼" => "Ip", "è¾½" => "Liao", "è¾¾" => "Da", "辿" => "Chan", "è¿€" => "Gan", + "è¿" => "Qian", "è¿‚" => "Yu", "迃" => "Yu", "è¿„" => "Qi", "è¿…" => "Xun", "迆" => "Yi", + "过" => "Guo", "迈" => "Mai", "迉" => "Qi", "è¿Š" => "Za", "è¿‹" => "Wang", "è¿Œ" => "Jia", + "è¿" => "Zhun", "è¿Ž" => "Ying", "è¿" => "Ti", "è¿" => "Yun", "è¿‘" => "Jin", "è¿’" => "Hang", + "è¿“" => "Ya", "è¿”" => "Fan", "è¿•" => "Wu", "è¿–" => "Da", "è¿—" => "E", "还" => "Huan", + "è¿™" => "Zhe", "è¿š" => "Totemo", "è¿›" => "Jin", "è¿œ" => "Yuan", "è¿" => "Wei", "è¿ž" => "Lian", + "è¿Ÿ" => "Chi", "è¿ " => "Che", "è¿¡" => "Ni", "è¿¢" => "Tiao", "è¿£" => "Zhi", "迤" => "Yi", + "è¿¥" => "Jiong", "迦" => "Jia", "迧" => "Chen", "迨" => "Dai", "è¿©" => "Er", "迪" => "Di", + "è¿«" => "Po", "迬" => "Wang", "è¿­" => "Die", "è¿®" => "Ze", "迯" => "Tao", "è¿°" => "Shu", + "迱" => "Tuo", "迲" => "Kep", "迳" => "Jing", "è¿´" => "Hui", "迵" => "Tong", "迶" => "You", + "è¿·" => "Mi", "迸" => "Beng", "迹" => "Ji", "迺" => "Nai", "è¿»" => "Yi", "迼" => "Jie", + "追" => "Zhui", "迾" => "Lie", "è¿¿" => "Xun", "é€" => "Song", "适" => "Gua", "逃" => "Tao", + "逄" => "Pang", "逅" => "Hou", "逆" => "Ni", "逇" => "Dun", "逈" => "Jiong", "选" => "Xuan", + "逊" => "Xun", "逋" => "Bu", "逌" => "You", "é€" => "Xiao", "逎" => "Qiu", "é€" => "Tou", + "é€" => "Zhu", "逑" => "Qiu", "递" => "Di", "逓" => "Di", "途" => "Tu", "逕" => "Jing", + "逖" => "Ti", "逗" => "Dou", "逘" => "Yi", "這" => "Zhe", "通" => "Tong", "逛" => "Guang", + "逜" => "Wu", "é€" => "Shi", "逞" => "Cheng", "速" => "Su", "造" => "Zao", "逡" => "Qun", + "逢" => "Feng", "連" => "Lian", "逤" => "Suo", "逥" => "Hui", "逦" => "Li", "逧" => "Sako", + "逨" => "Lai", "逩" => "Ben", "逪" => "Cuo", "逫" => "Jue", "逬" => "Beng", "逭" => "Huan", + "逮" => "Dai", "逯" => "Lu", "逰" => "You", "週" => "Zhou", "進" => "Jin", "逳" => "Yu", + "逴" => "Chuo", "逵" => "Kui", "逶" => "Wei", "逷" => "Ti", "逸" => "Yi", "逹" => "Da", + "逺" => "Yuan", "逻" => "Luo", "逼" => "Bi", "逽" => "Nuo", "逾" => "Yu", "逿" => "Dang", + "é€" => "Sui", "é" => "Dun", "é‚" => "Sui", "éƒ" => "Yan", "é„" => "Chuan", "é…" => "Chi", + "é†" => "Ti", "é‡" => "Yu", "éˆ" => "Shi", "é‰" => "Zhen", "éŠ" => "You", "é‹" => "Yun", + "éŒ" => "E", "é" => "Bian", "éŽ" => "Guo", "é" => "E", "é" => "Xia", "é‘" => "Huang", + "é’" => "Qiu", "é“" => "Dao", "é”" => "Da", "é•" => "Wei", "é–" => "Appare", "é—" => "Yi", + "é˜" => "Gou", "é™" => "Yao", "éš" => "Chu", "é›" => "Liu", "éœ" => "Xun", "é" => "Ta", + "éž" => "Di", "éŸ" => "Chi", "é " => "Yuan", "é¡" => "Su", "é¢" => "Ta", "é£" => "Qian", + "é¥" => "Yao", "é¦" => "Guan", "é§" => "Zhang", "é¨" => "Ao", "é©" => "Shi", "éª" => "Ce", + "é«" => "Chi", "é¬" => "Su", "é­" => "Zao", "é®" => "Zhe", "é¯" => "Dun", "é°" => "Di", + "é±" => "Lou", "é²" => "Chi", "é³" => "Cuo", "é´" => "Lin", "éµ" => "Zun", "é¶" => "Rao", + "é·" => "Qian", "é¸" => "Xuan", "é¹" => "Yu", "éº" => "Yi", "é»" => "Wu", "é¼" => "Liao", + "é½" => "Ju", "é¾" => "Shi", "é¿" => "Bi", "é‚€" => "Yao", "é‚" => "Mai", "é‚‚" => "Xie", + "邃" => "Sui", "é‚„" => "Huan", "é‚…" => "Zhan", "邆" => "Teng", "邇" => "Er", "邈" => "Miao", + "邉" => "Bian", "é‚Š" => "Bian", "é‚‹" => "La", "é‚Œ" => "Li", "é‚" => "Yuan", "é‚Ž" => "Yao", + "é‚" => "Luo", "é‚" => "Li", "é‚‘" => "Yi", "é‚’" => "Ting", "é‚“" => "Deng", "é‚”" => "Qi", + "é‚•" => "Yong", "é‚–" => "Shan", "é‚—" => "Han", "邘" => "Yu", "é‚™" => "Mang", "é‚š" => "Ru", + "é‚›" => "Qiong", "é‚" => "Kuang", "é‚ž" => "Fu", "é‚Ÿ" => "Kang", "é‚ " => "Bin", "é‚¡" => "Fang", + "é‚¢" => "Xing", "é‚£" => "Na", "邤" => "Xin", "é‚¥" => "Shen", "邦" => "Bang", "邧" => "Yuan", + "邨" => "Cun", "é‚©" => "Huo", "邪" => "Xie", "é‚«" => "Bang", "邬" => "Wu", "é‚­" => "Ju", + "é‚®" => "You", "邯" => "Han", "é‚°" => "Tai", "邱" => "Qiu", "邲" => "Bi", "邳" => "Pei", + "é‚´" => "Bing", "邵" => "Shao", "邶" => "Bei", "é‚·" => "Wa", "邸" => "Di", "邹" => "Zou", + "邺" => "Ye", "é‚»" => "Lin", "邼" => "Kuang", "邽" => "Gui", "邾" => "Zhu", "é‚¿" => "Shi", + "郀" => "Ku", "éƒ" => "Yu", "郂" => "Gai", "郃" => "Ge", "郄" => "Xi", "郅" => "Zhi", + "郆" => "Ji", "郇" => "Xun", "郈" => "Hou", "郉" => "Xing", "郊" => "Jiao", "郋" => "Xi", + "郌" => "Gui", "éƒ" => "Nuo", "郎" => "Lang", "éƒ" => "Jia", "éƒ" => "Kuai", "郑" => "Zheng", + "郒" => "Otoko", "郓" => "Yun", "郔" => "Yan", "郕" => "Cheng", "郖" => "Dou", "郗" => "Chi", + "郘" => "Lu", "郙" => "Fu", "郚" => "Wu", "郛" => "Fu", "郜" => "Gao", "éƒ" => "Hao", + "郞" => "Lang", "郟" => "Jia", "郠" => "Geng", "郡" => "Jun", "郢" => "Ying", "郣" => "Bo", + "郤" => "Xi", "郥" => "Bei", "郦" => "Li", "郧" => "Yun", "部" => "Bu", "郩" => "Xiao", + "郪" => "Qi", "郫" => "Pi", "郬" => "Qing", "郭" => "Guo", "郮" => "Zhou", "郯" => "Tan", + "郰" => "Zou", "郱" => "Ping", "郲" => "Lai", "郳" => "Ni", "郴" => "Chen", "郵" => "You", + "郶" => "Bu", "郷" => "Xiang", "郸" => "Dan", "郹" => "Ju", "郺" => "Yong", "郻" => "Qiao", + "郼" => "Yi", "都" => "Du", "郾" => "Yan", "郿" => "Mei", "é„" => "Bei", "é„‚" => "E", + "鄃" => "Yu", "é„„" => "Juan", "é„…" => "Yu", "鄆" => "Yun", "鄇" => "Hou", "鄈" => "Kui", + "鄉" => "Xiang", "é„Š" => "Xiang", "é„‹" => "Sou", "é„Œ" => "Tang", "é„" => "Ming", "é„Ž" => "Xi", + "é„" => "Ru", "é„" => "Chu", "é„‘" => "Zi", "é„’" => "Zou", "é„“" => "Ju", "é„”" => "Wu", + "é„•" => "Xiang", "é„–" => "Yun", "é„—" => "Hao", "鄘" => "Yong", "é„™" => "Bi", "é„š" => "Mo", + "é„›" => "Chao", "é„œ" => "Fu", "é„" => "Liao", "é„ž" => "Yin", "é„Ÿ" => "Zhuan", "é„ " => "Hu", + "é„¡" => "Qiao", "é„¢" => "Yan", "é„£" => "Zhang", "鄤" => "Fan", "é„¥" => "Qiao", "鄦" => "Xu", + "鄧" => "Deng", "鄨" => "Bi", "é„©" => "Xin", "鄪" => "Bi", "é„«" => "Ceng", "鄬" => "Wei", + "é„­" => "Zheng", "é„®" => "Mao", "鄯" => "Shan", "é„°" => "Lin", "鄱" => "Po", "鄲" => "Dan", + "鄳" => "Meng", "é„´" => "Ye", "鄵" => "Cao", "鄶" => "Kuai", "é„·" => "Feng", "鄸" => "Meng", + "鄹" => "Zou", "鄺" => "Kuang", "é„»" => "Lian", "鄼" => "Zan", "鄽" => "Chan", "鄾" => "You", + "é„¿" => "Qi", "é…€" => "Yan", "é…" => "Chan", "é…‚" => "Zan", "é…ƒ" => "Ling", "é…„" => "Huan", + "é……" => "Xi", "é…†" => "Feng", "é…‡" => "Zan", "é…ˆ" => "Li", "é…‰" => "You", "é…Š" => "Ding", + "é…‹" => "Qiu", "é…Œ" => "Zhuo", "é…" => "Pei", "é…Ž" => "Zhou", "é…" => "Yi", "é…" => "Hang", + "é…‘" => "Yu", "é…’" => "Jiu", "é…“" => "Yan", "é…”" => "Zui", "é…•" => "Mao", "é…–" => "Dan", + "é…—" => "Xu", "é…˜" => "Tou", "é…™" => "Zhen", "é…š" => "Fen", "é…›" => "Sakenomoto", "é…" => "Yun", + "é…ž" => "Tai", "é…Ÿ" => "Tian", "é… " => "Qia", "é…¡" => "Tuo", "é…¢" => "Zuo", "é…£" => "Han", + "é…¤" => "Gu", "é…¥" => "Su", "é…¦" => "Po", "é…§" => "Chou", "é…¨" => "Zai", "é…©" => "Ming", + "é…ª" => "Luo", "é…«" => "Chuo", "é…¬" => "Chou", "é…­" => "You", "é…®" => "Tong", "é…¯" => "Zhi", + "é…°" => "Xian", "é…±" => "Jiang", "é…²" => "Cheng", "é…³" => "Yin", "é…´" => "Tu", "é…µ" => "Xiao", + "é…¶" => "Mei", "é…·" => "Ku", "é…¸" => "Suan", "é…¹" => "Lei", "é…º" => "Pu", "é…»" => "Zui", + "é…¼" => "Hai", "é…½" => "Yan", "é…¾" => "Xi", "é…¿" => "Niang", "醀" => "Wei", "é†" => "Lu", + "醂" => "Lan", "醃" => "Yan", "醄" => "Tao", "醅" => "Pei", "醆" => "Zhan", "醇" => "Chun", + "醈" => "Tan", "醉" => "Zui", "醊" => "Chuo", "醋" => "Cu", "醌" => "Kun", "é†" => "Ti", + "醎" => "Mian", "é†" => "Du", "é†" => "Hu", "醑" => "Xu", "醒" => "Xing", "醓" => "Tan", + "醔" => "Jiu", "醕" => "Chun", "醖" => "Yun", "醗" => "Po", "醘" => "Ke", "醙" => "Sou", + "醚" => "Mi", "醛" => "Quan", "醜" => "Chou", "é†" => "Cuo", "醞" => "Yun", "醟" => "Yong", + "醠" => "Ang", "醡" => "Zha", "醢" => "Hai", "醣" => "Tang", "醤" => "Jiang", "醥" => "Piao", + "醦" => "Shan", "醧" => "Yu", "醨" => "Li", "醩" => "Zao", "醪" => "Lao", "醫" => "Yi", + "醬" => "Jiang", "醭" => "Pu", "醮" => "Jiao", "醯" => "Xi", "醰" => "Tan", "醱" => "Po", + "醲" => "Nong", "醳" => "Yi", "醴" => "Li", "醵" => "Ju", "醶" => "Jiao", "醷" => "Yi", + "醸" => "Niang", "醹" => "Ru", "醺" => "Xun", "醻" => "Chou", "醼" => "Yan", "醽" => "Ling", + "醾" => "Mi", "醿" => "Mi", "釀" => "Niang", "é‡" => "Xin", "釂" => "Jiao", "釃" => "Xi", + "釄" => "Mi", "釅" => "Yan", "釆" => "Bian", "采" => "Cai", "釈" => "Shi", "釉" => "You", + "释" => "Shi", "釋" => "Shi", "里" => "Li", "é‡" => "Zhong", "野" => "Ye", "é‡" => "Liang", + "é‡" => "Li", "金" => "Jin", "釒" => "Jin", "釓" => "Qiu", "釔" => "Yi", "釕" => "Diao", + "釖" => "Dao", "釗" => "Zhao", "釘" => "Ding", "釙" => "Po", "釚" => "Qiu", "釛" => "He", + "釜" => "Fu", "é‡" => "Zhen", "釞" => "Zhi", "釟" => "Ba", "釠" => "Luan", "釡" => "Fu", + "釢" => "Nai", "釣" => "Diao", "釤" => "Shan", "釥" => "Qiao", "釦" => "Kou", "釧" => "Chuan", + "釨" => "Zi", "釩" => "Fan", "釪" => "Yu", "釫" => "Hua", "釬" => "Han", "釭" => "Gong", + "釮" => "Qi", "釯" => "Mang", "釰" => "Ri", "釱" => "Di", "釲" => "Si", "釳" => "Xi", + "釴" => "Yi", "釵" => "Chai", "釶" => "Shi", "釷" => "Tu", "釸" => "Xi", "釹" => "Nu", + "釺" => "Qian", "釻" => "Ishiyumi", "釼" => "Jian", "釽" => "Pi", "釾" => "Ye", "釿" => "Yin", + "éˆ" => "Fang", "鈂" => "Chen", "鈃" => "Xing", "鈄" => "Tou", "鈅" => "Yue", "鈆" => "Yan", + "鈇" => "Fu", "鈈" => "Pi", "鈉" => "Na", "鈊" => "Xin", "鈋" => "E", "鈌" => "Jue", + "éˆ" => "Dun", "鈎" => "Gou", "éˆ" => "Yin", "éˆ" => "Qian", "鈑" => "Ban", "鈒" => "Ji", + "鈓" => "Ren", "鈔" => "Chao", "鈕" => "Niu", "鈖" => "Fen", "鈗" => "Yun", "鈘" => "Ji", + "鈙" => "Qin", "鈚" => "Pi", "鈛" => "Guo", "鈜" => "Hong", "éˆ" => "Yin", "鈞" => "Jun", + "鈟" => "Shi", "鈠" => "Yi", "鈡" => "Zhong", "鈢" => "Nie", "鈣" => "Gai", "鈤" => "Ri", + "鈥" => "Huo", "鈦" => "Tai", "鈧" => "Kang", "鈨" => "Habaki", "鈩" => "Irori", "鈪" => "Ngaak", + "鈬" => "Duo", "鈭" => "Zi", "鈮" => "Ni", "鈯" => "Tu", "鈰" => "Shi", "鈱" => "Min", + "鈲" => "Gu", "鈳" => "E", "鈴" => "Ling", "鈵" => "Bing", "鈶" => "Yi", "鈷" => "Gu", + "鈸" => "Ba", "鈹" => "Pi", "鈺" => "Yu", "鈻" => "Si", "鈼" => "Zuo", "鈽" => "Bu", + "鈾" => "You", "鈿" => "Dian", "鉀" => "Jia", "é‰" => "Zhen", "鉂" => "Shi", "鉃" => "Shi", + "鉄" => "Tie", "鉅" => "Ju", "鉆" => "Zhan", "鉇" => "Shi", "鉈" => "She", "鉉" => "Xuan", + "鉊" => "Zhao", "鉋" => "Bao", "鉌" => "He", "é‰" => "Bi", "鉎" => "Sheng", "é‰" => "Chu", + "é‰" => "Shi", "鉑" => "Bo", "鉒" => "Zhu", "鉓" => "Chi", "鉔" => "Za", "鉕" => "Po", + "鉖" => "Tong", "鉗" => "Qian", "鉘" => "Fu", "鉙" => "Zhai", "鉚" => "Liu", "鉛" => "Qian", + "鉜" => "Fu", "é‰" => "Li", "鉞" => "Yue", "鉟" => "Pi", "鉠" => "Yang", "鉡" => "Ban", + "鉢" => "Bo", "鉣" => "Jie", "鉤" => "Gou", "鉥" => "Shu", "鉦" => "Zheng", "鉧" => "Mu", + "鉨" => "Ni", "鉩" => "Nie", "鉪" => "Di", "鉫" => "Jia", "鉬" => "Mu", "鉭" => "Dan", + "鉮" => "Shen", "鉯" => "Yi", "鉰" => "Si", "鉱" => "Kuang", "鉲" => "Ka", "鉳" => "Bei", + "鉴" => "Jian", "鉵" => "Tong", "鉶" => "Xing", "鉷" => "Hong", "鉸" => "Jiao", "鉹" => "Chi", + "鉺" => "Er", "鉻" => "Ge", "鉼" => "Bing", "鉽" => "Shi", "鉾" => "Mou", "鉿" => "Jia", + "銀" => "Yin", "éŠ" => "Jun", "銂" => "Zhou", "銃" => "Chong", "銄" => "Shang", "銅" => "Tong", + "銆" => "Mo", "銇" => "Lei", "銈" => "Ji", "銉" => "Yu", "銊" => "Xu", "銋" => "Ren", + "銌" => "Zun", "éŠ" => "Zhi", "銎" => "Qiong", "éŠ" => "Shan", "éŠ" => "Chi", "銑" => "Xian", + "銒" => "Xing", "銓" => "Quan", "銔" => "Pi", "銕" => "Tie", "銖" => "Zhu", "銗" => "Hou", + "銘" => "Ming", "銙" => "Kua", "銚" => "Yao", "銛" => "Xian", "銜" => "Xian", "éŠ" => "Xiu", + "銞" => "Jun", "銟" => "Cha", "銠" => "Lao", "銡" => "Ji", "銢" => "Pi", "銣" => "Ru", + "銤" => "Mi", "銥" => "Yi", "銦" => "Yin", "銧" => "Guang", "銨" => "An", "銩" => "Diou", + "銪" => "You", "銫" => "Se", "銬" => "Kao", "銭" => "Qian", "銮" => "Luan", "銯" => "Kasugai", + "銰" => "Ai", "銱" => "Diao", "銲" => "Han", "銳" => "Rui", "銴" => "Shi", "銵" => "Keng", + "銶" => "Qiu", "銷" => "Xiao", "銸" => "Zhe", "銹" => "Xiu", "銺" => "Zang", "銻" => "Ti", + "銼" => "Cuo", "銽" => "Gua", "銾" => "Gong", "銿" => "Zhong", "é‹€" => "Dou", "é‹" => "Lu", + "é‹‚" => "Mei", "鋃" => "Lang", "é‹„" => "Wan", "é‹…" => "Xin", "鋆" => "Yun", "鋇" => "Bei", + "鋈" => "Wu", "鋉" => "Su", "é‹Š" => "Yu", "é‹‹" => "Chan", "é‹Œ" => "Ting", "é‹" => "Bo", + "é‹Ž" => "Han", "é‹" => "Jia", "é‹" => "Hong", "é‹‘" => "Cuan", "é‹’" => "Feng", "é‹“" => "Chan", + "é‹”" => "Wan", "é‹•" => "Zhi", "é‹–" => "Si", "é‹—" => "Xuan", "鋘" => "Wu", "é‹™" => "Wu", + "é‹š" => "Tiao", "é‹›" => "Gong", "é‹œ" => "Zhuo", "é‹" => "Lue", "é‹ž" => "Xing", "é‹Ÿ" => "Qian", + "é‹ " => "Shen", "é‹¡" => "Han", "é‹¢" => "Lue", "é‹£" => "Xie", "鋤" => "Chu", "é‹¥" => "Zheng", + "鋦" => "Ju", "鋧" => "Xian", "鋨" => "Tie", "é‹©" => "Mang", "鋪" => "Pu", "é‹«" => "Li", + "鋬" => "Pan", "é‹­" => "Rui", "é‹®" => "Cheng", "鋯" => "Gao", "é‹°" => "Li", "鋱" => "Te", + "鋲" => "Pyeng", "鋳" => "Zhu", "鋵" => "Tu", "鋶" => "Liu", "é‹·" => "Zui", "鋸" => "Ju", + "鋹" => "Chang", "鋺" => "Yuan", "é‹»" => "Jian", "鋼" => "Gang", "鋽" => "Diao", "鋾" => "Tao", + "é‹¿" => "Chang", "éŒ" => "Kua", "錂" => "Ling", "錃" => "Bei", "錄" => "Lu", "錅" => "Li", + "錆" => "Qiang", "錇" => "Pou", "錈" => "Juan", "錉" => "Min", "錊" => "Zui", "錋" => "Peng", + "錌" => "An", "éŒ" => "Pi", "錎" => "Xian", "éŒ" => "Ya", "éŒ" => "Zhui", "錑" => "Lei", + "錒" => "A", "錓" => "Kong", "錔" => "Ta", "錕" => "Kun", "錖" => "Du", "錗" => "Wei", + "錘" => "Chui", "錙" => "Zi", "錚" => "Zheng", "錛" => "Ben", "錜" => "Nie", "éŒ" => "Cong", + "錞" => "Qun", "錟" => "Tan", "錠" => "Ding", "錡" => "Qi", "錢" => "Qian", "錣" => "Zhuo", + "錤" => "Qi", "錥" => "Yu", "錦" => "Jin", "錧" => "Guan", "錨" => "Mao", "錩" => "Chang", + "錪" => "Tian", "錫" => "Xi", "錬" => "Lian", "錭" => "Tao", "錮" => "Gu", "錯" => "Cuo", + "錰" => "Shu", "錱" => "Zhen", "録" => "Lu", "錳" => "Meng", "錴" => "Lu", "錵" => "Hua", + "錶" => "Biao", "錷" => "Ga", "錸" => "Lai", "錹" => "Ken", "錺" => "Kazari", "錻" => "Bu", + "錼" => "Nai", "錽" => "Wan", "錾" => "Zan", "é€" => "De", "é" => "Xian", "éƒ" => "Huo", + "é„" => "Liang", "é†" => "Men", "é‡" => "Kai", "éˆ" => "Ying", "é‰" => "Di", "éŠ" => "Lian", + "é‹" => "Guo", "éŒ" => "Xian", "é" => "Du", "éŽ" => "Tu", "é" => "Wei", "é" => "Cong", + "é‘" => "Fu", "é’" => "Rou", "é“" => "Ji", "é”" => "E", "é•" => "Rou", "é–" => "Chen", + "é—" => "Ti", "é˜" => "Zha", "é™" => "Hong", "éš" => "Yang", "é›" => "Duan", "éœ" => "Xia", + "é" => "Yu", "éž" => "Keng", "éŸ" => "Xing", "é " => "Huang", "é¡" => "Wei", "é¢" => "Fu", + "é£" => "Zhao", "é¤" => "Cha", "é¥" => "Qie", "é¦" => "She", "é§" => "Hong", "é¨" => "Kui", + "é©" => "Tian", "éª" => "Mou", "é«" => "Qiao", "é¬" => "Qiao", "é­" => "Hou", "é®" => "Tou", + "é¯" => "Cong", "é°" => "Huan", "é±" => "Ye", "é²" => "Min", "é³" => "Jian", "é´" => "Duan", + "éµ" => "Jian", "é¶" => "Song", "é·" => "Kui", "é¸" => "Hu", "é¹" => "Xuan", "éº" => "Duo", + "é»" => "Jie", "é¼" => "Zhen", "é½" => "Bian", "é¾" => "Zhong", "é¿" => "Zi", "鎀" => "Xiu", + "éŽ" => "Ye", "鎂" => "Mei", "鎃" => "Pai", "鎄" => "Ai", "鎅" => "Jie", "鎇" => "Mei", + "鎈" => "Chuo", "鎉" => "Ta", "鎊" => "Bang", "鎋" => "Xia", "鎌" => "Lian", "éŽ" => "Suo", + "鎎" => "Xi", "éŽ" => "Liu", "éŽ" => "Zu", "鎑" => "Ye", "鎒" => "Nou", "鎓" => "Weng", + "鎔" => "Rong", "鎕" => "Tang", "鎖" => "Suo", "鎗" => "Qiang", "鎘" => "Ge", "鎙" => "Shuo", + "鎚" => "Chui", "鎛" => "Bo", "鎜" => "Pan", "éŽ" => "Sa", "鎞" => "Bi", "鎟" => "Sang", + "鎠" => "Gang", "鎡" => "Zi", "鎢" => "Wu", "鎣" => "Ying", "鎤" => "Huang", "鎥" => "Tiao", + "鎦" => "Liu", "鎧" => "Kai", "鎨" => "Sun", "鎩" => "Sha", "鎪" => "Sou", "鎫" => "Wan", + "鎬" => "Hao", "鎭" => "Zhen", "鎮" => "Zhen", "鎯" => "Luo", "鎰" => "Yi", "鎱" => "Yuan", + "鎲" => "Tang", "鎳" => "Nie", "鎴" => "Xi", "鎵" => "Jia", "鎶" => "Ge", "鎷" => "Ma", + "鎸" => "Juan", "鎹" => "Kasugai", "鎺" => "Habaki", "鎻" => "Suo", "鎿" => "Na", "é€" => "Lu", + "é" => "Suo", "é‚" => "Ou", "éƒ" => "Zu", "é„" => "Tuan", "é…" => "Xiu", "é†" => "Guan", + "é‡" => "Xuan", "éˆ" => "Lian", "é‰" => "Shou", "éŠ" => "Ao", "é‹" => "Man", "éŒ" => "Mo", + "é" => "Luo", "éŽ" => "Bi", "é" => "Wei", "é" => "Liu", "é‘" => "Di", "é’" => "Qiao", + "é“" => "Cong", "é”" => "Yi", "é•" => "Lu", "é–" => "Ao", "é—" => "Keng", "é˜" => "Qiang", + "é™" => "Cui", "éš" => "Qi", "é›" => "Chang", "éœ" => "Tang", "é" => "Man", "éž" => "Yong", + "éŸ" => "Chan", "é " => "Feng", "é¡" => "Jing", "é¢" => "Biao", "é£" => "Shu", "é¤" => "Lou", + "é¥" => "Xiu", "é¦" => "Cong", "é§" => "Long", "é¨" => "Zan", "é©" => "Jian", "éª" => "Cao", + "é«" => "Li", "é¬" => "Xia", "é­" => "Xi", "é®" => "Kang", "é°" => "Beng", "é³" => "Zheng", + "é´" => "Lu", "éµ" => "Hua", "é¶" => "Ji", "é·" => "Pu", "é¸" => "Hui", "é¹" => "Qiang", + "éº" => "Po", "é»" => "Lin", "é¼" => "Suo", "é½" => "Xiu", "é¾" => "San", "é¿" => "Cheng", + "é" => "Si", "é‚" => "Liu", "éƒ" => "Nao", "é„" => "Heng", "é…" => "Pie", "é†" => "Sui", + "é‡" => "Fan", "éˆ" => "Qiao", "é‰" => "Quan", "éŠ" => "Yang", "é‹" => "Tang", "éŒ" => "Xiang", + "é" => "Jue", "éŽ" => "Jiao", "é" => "Zun", "é" => "Liao", "é‘" => "Jie", "é’" => "Lao", + "é“" => "Dui", "é”" => "Tan", "é•" => "Zan", "é–" => "Ji", "é—" => "Jian", "é˜" => "Zhong", + "é™" => "Deng", "éš" => "Ya", "é›" => "Ying", "éœ" => "Dui", "é" => "Jue", "éž" => "Nou", + "éŸ" => "Ti", "é " => "Pu", "é¡" => "Tie", "é¤" => "Ding", "é¥" => "Shan", "é¦" => "Kai", + "é§" => "Jian", "é¨" => "Fei", "é©" => "Sui", "éª" => "Lu", "é«" => "Juan", "é¬" => "Hui", + "é­" => "Yu", "é®" => "Lian", "é¯" => "Zhuo", "é°" => "Qiao", "é±" => "Qian", "é²" => "Zhuo", + "é³" => "Lei", "é´" => "Bi", "éµ" => "Tie", "é¶" => "Huan", "é·" => "Ye", "é¸" => "Duo", + "é¹" => "Guo", "éº" => "Dang", "é»" => "Ju", "é¼" => "Fen", "é½" => "Da", "é¾" => "Bei", + "é¿" => "Yi", "é‘€" => "Ai", "é‘" => "Zong", "é‘‚" => "Xun", "鑃" => "Diao", "é‘„" => "Zhu", + "é‘…" => "Heng", "鑆" => "Zhui", "鑇" => "Ji", "鑈" => "Nie", "鑉" => "Ta", "é‘Š" => "Huo", + "é‘‹" => "Qing", "é‘Œ" => "Bin", "é‘" => "Ying", "é‘Ž" => "Kui", "é‘" => "Ning", "é‘" => "Xu", + "é‘‘" => "Jian", "é‘’" => "Jian", "é‘“" => "Yari", "é‘”" => "Cha", "é‘•" => "Zhi", "é‘–" => "Mie", + "é‘—" => "Li", "鑘" => "Lei", "é‘™" => "Ji", "é‘š" => "Zuan", "é‘›" => "Kuang", "é‘œ" => "Shang", + "é‘" => "Peng", "é‘ž" => "La", "é‘Ÿ" => "Du", "é‘ " => "Shuo", "é‘¡" => "Chuo", "é‘¢" => "Lu", + "é‘£" => "Biao", "鑤" => "Bao", "é‘¥" => "Lu", "鑨" => "Long", "é‘©" => "E", "鑪" => "Lu", + "é‘«" => "Xin", "鑬" => "Jian", "é‘­" => "Lan", "é‘®" => "Bo", "鑯" => "Jian", "é‘°" => "Yao", + "鑱" => "Chan", "鑲" => "Xiang", "鑳" => "Jian", "é‘´" => "Xi", "鑵" => "Guan", "鑶" => "Cang", + "é‘·" => "Nie", "鑸" => "Lei", "鑹" => "Cuan", "鑺" => "Qu", "é‘»" => "Pan", "鑼" => "Luo", + "鑽" => "Zuan", "鑾" => "Luan", "é‘¿" => "Zao", "é’€" => "Nie", "é’" => "Jue", "é’‚" => "Tang", + "é’ƒ" => "Shu", "é’„" => "Lan", "é’…" => "Jin", "é’†" => "Qiu", "é’‡" => "Yi", "é’ˆ" => "Zhen", + "é’‰" => "Ding", "é’Š" => "Zhao", "é’‹" => "Po", "é’Œ" => "Diao", "é’" => "Tu", "é’Ž" => "Qian", + "é’" => "Chuan", "é’" => "Shan", "é’‘" => "Ji", "é’’" => "Fan", "é’“" => "Diao", "é’”" => "Men", + "é’•" => "Nu", "é’–" => "Xi", "é’—" => "Chai", "é’˜" => "Xing", "é’™" => "Gai", "é’š" => "Bu", + "é’›" => "Tai", "é’œ" => "Ju", "é’" => "Dun", "é’ž" => "Chao", "é’Ÿ" => "Zhong", "é’ " => "Na", + "é’¡" => "Bei", "é’¢" => "Gang", "é’£" => "Ban", "é’¤" => "Qian", "é’¥" => "Yao", "é’¦" => "Qin", + "é’§" => "Jun", "é’¨" => "Wu", "é’©" => "Gou", "é’ª" => "Kang", "é’«" => "Fang", "é’¬" => "Huo", + "é’­" => "Tou", "é’®" => "Niu", "é’¯" => "Ba", "é’°" => "Yu", "é’±" => "Qian", "é’²" => "Zheng", + "é’³" => "Qian", "é’´" => "Gu", "é’µ" => "Bo", "é’¶" => "E", "é’·" => "Po", "é’¸" => "Bu", + "é’¹" => "Ba", "é’º" => "Yue", "é’»" => "Zuan", "é’¼" => "Mu", "é’½" => "Dan", "é’¾" => "Jia", + "é’¿" => "Dian", "é“€" => "You", "é“" => "Tie", "é“‚" => "Bo", "铃" => "Ling", "é“„" => "Shuo", + "é“…" => "Qian", "铆" => "Liu", "铇" => "Bao", "铈" => "Shi", "铉" => "Xuan", "é“Š" => "She", + "é“‹" => "Bi", "é“Œ" => "Ni", "é“" => "Pi", "é“Ž" => "Duo", "é“" => "Xing", "é“" => "Kao", + "é“‘" => "Lao", "é“’" => "Er", "é““" => "Mang", "é“”" => "Ya", "é“•" => "You", "é“–" => "Cheng", + "é“—" => "Jia", "铘" => "Ye", "é“™" => "Nao", "é“š" => "Zhi", "é“›" => "Dang", "é“œ" => "Tong", + "é“" => "Lu", "é“ž" => "Diao", "é“Ÿ" => "Yin", "é“ " => "Kai", "é“¡" => "Zha", "é“¢" => "Zhu", + "é“£" => "Xian", "铤" => "Ting", "é“¥" => "Diu", "铦" => "Xian", "铧" => "Hua", "铨" => "Quan", + "é“©" => "Sha", "铪" => "Jia", "é“«" => "Yao", "铬" => "Ge", "é“­" => "Ming", "é“®" => "Zheng", + "铯" => "Se", "é“°" => "Jiao", "铱" => "Yi", "铲" => "Chan", "铳" => "Chong", "é“´" => "Tang", + "铵" => "An", "银" => "Yin", "é“·" => "Ru", "铸" => "Zhu", "铹" => "Lao", "铺" => "Pu", + "é“»" => "Wu", "铼" => "Lai", "铽" => "Te", "链" => "Lian", "é“¿" => "Keng", "é”" => "Suo", + "锂" => "Li", "锃" => "Zheng", "锄" => "Chu", "é”…" => "Guo", "锆" => "Gao", "锇" => "Tie", + "锈" => "Xiu", "锉" => "Cuo", "锊" => "Lue", "锋" => "Feng", "锌" => "Xin", "é”" => "Liu", + "锎" => "Kai", "é”" => "Jian", "é”" => "Rui", "锑" => "Ti", "é”’" => "Lang", "锓" => "Qian", + "é””" => "Ju", "锕" => "A", "é”–" => "Qiang", "é”—" => "Duo", "锘" => "Tian", "é”™" => "Cuo", + "锚" => "Mao", "é”›" => "Ben", "锜" => "Qi", "é”" => "De", "锞" => "Kua", "锟" => "Kun", + "é” " => "Chang", "锡" => "Xi", "锢" => "Gu", "锣" => "Luo", "锤" => "Chui", "锥" => "Zhui", + "锦" => "Jin", "锧" => "Zhi", "锨" => "Xian", "锩" => "Juan", "锪" => "Huo", "锫" => "Pou", + "锬" => "Tan", "é”­" => "Ding", "é”®" => "Jian", "锯" => "Ju", "é”°" => "Meng", "é”±" => "Zi", + "锲" => "Qie", "锳" => "Ying", "é”´" => "Kai", "锵" => "Qiang", "锶" => "Song", "é”·" => "E", + "锸" => "Cha", "锹" => "Qiao", "锺" => "Zhong", "é”»" => "Duan", "锼" => "Sou", "锽" => "Huang", + "锾" => "Huan", "锿" => "Ai", "é•€" => "Du", "é•" => "Mei", "é•‚" => "Lou", "镃" => "Zi", + "é•„" => "Fei", "é•…" => "Mei", "镆" => "Mo", "镇" => "Zhen", "镈" => "Bo", "镉" => "Ge", + "é•Š" => "Nie", "é•‹" => "Tang", "é•Œ" => "Juan", "é•" => "Nie", "é•Ž" => "Na", "é•" => "Liu", + "é•" => "Hao", "é•‘" => "Bang", "é•’" => "Yi", "é•“" => "Jia", "é•”" => "Bin", "é••" => "Rong", + "é•–" => "Biao", "é•—" => "Tang", "镘" => "Man", "é•™" => "Luo", "é•š" => "Beng", "é•›" => "Yong", + "é•œ" => "Jing", "é•" => "Di", "é•ž" => "Zu", "é•Ÿ" => "Xuan", "é• " => "Liu", "é•¡" => "Tan", + "é•¢" => "Jue", "é•£" => "Liao", "镤" => "Pu", "é•¥" => "Lu", "镦" => "Dui", "镧" => "Lan", + "镨" => "Pu", "é•©" => "Cuan", "镪" => "Qiang", "é•«" => "Deng", "镬" => "Huo", "é•­" => "Lei", + "é•®" => "Huan", "镯" => "Zhuo", "é•°" => "Lian", "镱" => "Yi", "镲" => "Cha", "镳" => "Biao", + "é•´" => "La", "镵" => "Chan", "镶" => "Xiang", "é•·" => "Chang", "镸" => "Chang", "镹" => "Jiu", + "镺" => "Ao", "é•»" => "Die", "镼" => "Qu", "镽" => "Liao", "镾" => "Mi", "é•¿" => "Chang", + "é–€" => "Men", "é–" => "Ma", "é–‚" => "Shuan", "é–ƒ" => "Shan", "é–„" => "Huo", "é–…" => "Men", + "é–†" => "Yan", "é–‡" => "Bi", "é–ˆ" => "Han", "é–‰" => "Bi", "é–Š" => "San", "é–‹" => "Kai", + "é–Œ" => "Kang", "é–" => "Beng", "é–Ž" => "Hong", "é–" => "Run", "é–" => "San", "é–‘" => "Xian", + "é–’" => "Xian", "é–“" => "Jian", "é–”" => "Min", "é–•" => "Xia", "é––" => "Yuru", "é–—" => "Dou", + "é–˜" => "Zha", "é–™" => "Nao", "é–š" => "Jian", "é–›" => "Peng", "é–œ" => "Xia", "é–" => "Ling", + "é–ž" => "Bian", "é–Ÿ" => "Bi", "é– " => "Run", "é–¡" => "He", "é–¢" => "Guan", "é–£" => "Ge", + "é–¤" => "Ge", "é–¥" => "Fa", "é–¦" => "Chu", "é–§" => "Hong", "é–¨" => "Gui", "é–©" => "Min", + "é–ª" => "Se", "é–«" => "Kun", "é–¬" => "Lang", "é–­" => "Lu", "é–®" => "Ting", "é–¯" => "Sha", + "é–°" => "Ju", "é–±" => "Yue", "é–²" => "Yue", "é–³" => "Chan", "é–´" => "Qu", "é–µ" => "Lin", + "é–¶" => "Chang", "é–·" => "Shai", "é–¸" => "Kun", "é–¹" => "Yan", "é–º" => "Min", "é–»" => "Yan", + "é–¼" => "E", "é–½" => "Hun", "é–¾" => "Yu", "é–¿" => "Wen", "é—€" => "Xiang", "é—" => "Bao", + "é—‚" => "Xiang", "é—ƒ" => "Qu", "é—„" => "Yao", "é—…" => "Wen", "é—†" => "Ban", "é—‡" => "An", + "é—ˆ" => "Wei", "é—‰" => "Yin", "é—Š" => "Kuo", "é—‹" => "Que", "é—Œ" => "Lan", "é—" => "Du", + "é—" => "Phwung", "é—" => "Tian", "é—‘" => "Nie", "é—’" => "Ta", "é—“" => "Kai", "é—”" => "He", + "é—•" => "Que", "é—–" => "Chuang", "é——" => "Guan", "é—˜" => "Dou", "é—™" => "Qi", "é—š" => "Kui", + "é—›" => "Tang", "é—œ" => "Guan", "é—" => "Piao", "é—ž" => "Kan", "é—Ÿ" => "Xi", "é— " => "Hui", + "é—¡" => "Chan", "é—¢" => "Pi", "é—£" => "Dang", "é—¤" => "Huan", "é—¥" => "Ta", "é—¦" => "Wen", + "é—¨" => "Men", "é—©" => "Shuan", "é—ª" => "Shan", "é—«" => "Yan", "é—¬" => "Han", "é—­" => "Bi", + "é—®" => "Wen", "é—¯" => "Chuang", "é—°" => "Run", "é—±" => "Wei", "é—²" => "Xian", "é—³" => "Hong", + "é—´" => "Jian", "é—µ" => "Min", "é—¶" => "Kang", "é—·" => "Men", "é—¸" => "Zha", "é—¹" => "Nao", + "é—º" => "Gui", "é—»" => "Wen", "é—¼" => "Ta", "é—½" => "Min", "é—¾" => "Lu", "é—¿" => "Kai", + "é˜" => "Ge", "阂" => "He", "阃" => "Kun", "阄" => "Jiu", "阅" => "Yue", "阆" => "Lang", + "阇" => "Du", "阈" => "Yu", "阉" => "Yan", "阊" => "Chang", "阋" => "Xi", "阌" => "Wen", + "é˜" => "Hun", "阎" => "Yan", "é˜" => "E", "é˜" => "Chan", "阑" => "Lan", "阒" => "Qu", + "阓" => "Hui", "阔" => "Kuo", "阕" => "Que", "阖" => "Ge", "阗" => "Tian", "阘" => "Ta", + "阙" => "Que", "阚" => "Kan", "阛" => "Huan", "阜" => "Fu", "é˜" => "Fu", "阞" => "Le", + "队" => "Dui", "阠" => "Xin", "阡" => "Qian", "阢" => "Wu", "阣" => "Yi", "阤" => "Tuo", + "阥" => "Yin", "阦" => "Yang", "阧" => "Dou", "阨" => "E", "阩" => "Sheng", "阪" => "Ban", + "阫" => "Pei", "阬" => "Keng", "阭" => "Yun", "阮" => "Ruan", "阯" => "Zhi", "阰" => "Pi", + "阱" => "Jing", "防" => "Fang", "阳" => "Yang", "阴" => "Yin", "阵" => "Zhen", "阶" => "Jie", + "阷" => "Cheng", "阸" => "E", "阹" => "Qu", "阺" => "Di", "阻" => "Zu", "阼" => "Zuo", + "阽" => "Dian", "阾" => "Ling", "阿" => "A", "陀" => "Tuo", "é™" => "Tuo", "陂" => "Po", + "陃" => "Bing", "附" => "Fu", "é™…" => "Ji", "陆" => "Lu", "陇" => "Long", "陈" => "Chen", + "陉" => "Xing", "陊" => "Duo", "陋" => "Lou", "陌" => "Mo", "é™" => "Jiang", "陎" => "Shu", + "é™" => "Duo", "é™" => "Xian", "陑" => "Er", "é™’" => "Gui", "陓" => "Yu", "é™”" => "Gai", + "陕" => "Shan", "é™–" => "Xun", "é™—" => "Qiao", "陘" => "Xing", "é™™" => "Chun", "陚" => "Fu", + "é™›" => "Bi", "陜" => "Xia", "é™" => "Shan", "陞" => "Sheng", "陟" => "Zhi", "é™ " => "Pu", + "陡" => "Dou", "院" => "Yuan", "陣" => "Zhen", "除" => "Chu", "陥" => "Xian", "陦" => "Tou", + "陧" => "Nie", "陨" => "Yun", "险" => "Xian", "陪" => "Pei", "陫" => "Pei", "陬" => "Zou", + "é™­" => "Yi", "é™®" => "Dui", "陯" => "Lun", "é™°" => "Yin", "é™±" => "Ju", "陲" => "Chui", + "陳" => "Chen", "é™´" => "Pi", "陵" => "Ling", "陶" => "Tao", "é™·" => "Xian", "陸" => "Lu", + "陹" => "Sheng", "険" => "Xian", "é™»" => "Yin", "陼" => "Zhu", "陽" => "Yang", "陾" => "Reng", + "陿" => "Shan", "隀" => "Chong", "éš" => "Yan", "éš‚" => "Yin", "隃" => "Yu", "éš„" => "Ti", + "éš…" => "Yu", "隆" => "Long", "隇" => "Wei", "隈" => "Wei", "隉" => "Nie", "隊" => "Dui", + "éš‹" => "Sui", "隌" => "An", "éš" => "Huang", "階" => "Jie", "éš" => "Sui", "éš" => "Yin", + "éš‘" => "Gai", "éš’" => "Yan", "éš“" => "Hui", "éš”" => "Ge", "éš•" => "Yun", "éš–" => "Wu", + "éš—" => "Wei", "隘" => "Ai", "éš™" => "Xi", "éšš" => "Tang", "éš›" => "Ji", "éšœ" => "Zhang", + "éš" => "Dao", "éšž" => "Ao", "隟" => "Xi", "éš " => "Yin", "隢" => "Rao", "隣" => "Lin", + "隤" => "Tui", "隥" => "Deng", "隦" => "Pi", "隧" => "Sui", "隨" => "Sui", "éš©" => "Yu", + "險" => "Xian", "éš«" => "Fen", "隬" => "Ni", "éš­" => "Er", "éš®" => "Ji", "隯" => "Dao", + "éš°" => "Xi", "éš±" => "Yin", "éš²" => "E", "éš³" => "Hui", "éš´" => "Long", "éšµ" => "Xi", + "隶" => "Li", "éš·" => "Li", "隸" => "Li", "éš¹" => "Zhui", "隺" => "He", "éš»" => "Zhi", + "éš¼" => "Zhun", "éš½" => "Jun", "éš¾" => "Nan", "éš¿" => "Yi", "雀" => "Que", "é›" => "Yan", + "雂" => "Qian", "雃" => "Ya", "雄" => "Xiong", "é›…" => "Ya", "集" => "Ji", "雇" => "Gu", + "雈" => "Huan", "雉" => "Zhi", "雊" => "Gou", "雋" => "Jun", "雌" => "Ci", "é›" => "Yong", + "雎" => "Ju", "é›" => "Chu", "é›" => "Hu", "雑" => "Za", "é›’" => "Luo", "雓" => "Yu", + "é›”" => "Chou", "雕" => "Diao", "é›–" => "Sui", "é›—" => "Han", "雘" => "Huo", "é›™" => "Shuang", + "雚" => "Guan", "é››" => "Chu", "雜" => "Za", "é›" => "Yong", "雞" => "Ji", "雟" => "Xi", + "é› " => "Chou", "雡" => "Liu", "離" => "Li", "難" => "Nan", "雤" => "Xue", "雥" => "Za", + "雦" => "Ji", "雧" => "Ji", "雨" => "Yu", "雩" => "Yu", "雪" => "Xue", "雫" => "Na", + "雬" => "Fou", "é›­" => "Se", "é›®" => "Mu", "雯" => "Wen", "é›°" => "Fen", "é›±" => "Pang", + "雲" => "Yun", "雳" => "Li", "é›´" => "Li", "雵" => "Ang", "零" => "Ling", "é›·" => "Lei", + "雸" => "An", "雹" => "Bao", "雺" => "Meng", "é›»" => "Dian", "雼" => "Dang", "雽" => "Xing", + "雾" => "Wu", "雿" => "Zhao", "éœ" => "Ji", "霂" => "Mu", "霃" => "Chen", "霄" => "Xiao", + "霅" => "Zha", "霆" => "Ting", "震" => "Zhen", "霈" => "Pei", "霉" => "Mei", "霊" => "Ling", + "霋" => "Qi", "霌" => "Chou", "éœ" => "Huo", "霎" => "Sha", "éœ" => "Fei", "éœ" => "Weng", + "霑" => "Zhan", "霒" => "Yin", "霓" => "Ni", "霔" => "Chou", "霕" => "Tun", "霖" => "Lin", + "霘" => "Dong", "霙" => "Ying", "霚" => "Wu", "霛" => "Ling", "霜" => "Shuang", "éœ" => "Ling", + "霞" => "Xia", "霟" => "Hong", "霠" => "Yin", "霡" => "Mo", "霢" => "Mai", "霣" => "Yun", + "霤" => "Liu", "霥" => "Meng", "霦" => "Bin", "霧" => "Wu", "霨" => "Wei", "霩" => "Huo", + "霪" => "Yin", "霫" => "Xi", "霬" => "Yi", "霭" => "Ai", "霮" => "Dan", "霯" => "Deng", + "霰" => "Xian", "霱" => "Yu", "露" => "Lu", "霳" => "Long", "霴" => "Dai", "霵" => "Ji", + "霶" => "Pang", "霷" => "Yang", "霸" => "Ba", "霹" => "Pi", "霺" => "Wei", "霼" => "Xi", + "霽" => "Ji", "霾" => "Mai", "霿" => "Meng", "é€" => "Meng", "é" => "Lei", "é‚" => "Li", + "éƒ" => "Huo", "é„" => "Ai", "é…" => "Fei", "é†" => "Dai", "é‡" => "Long", "éˆ" => "Ling", + "é‰" => "Ai", "éŠ" => "Feng", "é‹" => "Li", "éŒ" => "Bao", "éŽ" => "He", "é" => "He", + "é" => "Bing", "é‘" => "Qing", "é’" => "Qing", "é“" => "Jing", "é”" => "Tian", "é•" => "Zhen", + "é–" => "Jing", "é—" => "Cheng", "é˜" => "Qing", "é™" => "Jing", "éš" => "Jing", "é›" => "Dian", + "éœ" => "Jing", "é" => "Tian", "éž" => "Fei", "éŸ" => "Fei", "é " => "Kao", "é¡" => "Mi", + "é¢" => "Mian", "é£" => "Mian", "é¤" => "Pao", "é¥" => "Ye", "é¦" => "Tian", "é§" => "Hui", + "é¨" => "Ye", "é©" => "Ge", "éª" => "Ding", "é«" => "Cha", "é¬" => "Jian", "é­" => "Ren", + "é®" => "Di", "é¯" => "Du", "é°" => "Wu", "é±" => "Ren", "é²" => "Qin", "é³" => "Jin", + "é´" => "Xue", "éµ" => "Niu", "é¶" => "Ba", "é·" => "Yin", "é¸" => "Sa", "é¹" => "Na", + "éº" => "Mo", "é»" => "Zu", "é¼" => "Da", "é½" => "Ban", "é¾" => "Yi", "é¿" => "Yao", + "鞀" => "Tao", "éž" => "Tuo", "éž‚" => "Jia", "鞃" => "Hong", "éž„" => "Pao", "éž…" => "Yang", + "鞆" => "Tomo", "鞇" => "Yin", "鞈" => "Jia", "鞉" => "Tao", "鞊" => "Ji", "éž‹" => "Xie", + "鞌" => "An", "éž" => "An", "鞎" => "Hen", "éž" => "Gong", "éž" => "Kohaze", "éž‘" => "Da", + "éž’" => "Qiao", "éž“" => "Ting", "éž”" => "Wan", "éž•" => "Ying", "éž–" => "Sui", "éž—" => "Tiao", + "鞘" => "Qiao", "éž™" => "Xuan", "éžš" => "Kong", "éž›" => "Beng", "éžœ" => "Ta", "éž" => "Zhang", + "éžž" => "Bing", "鞟" => "Kuo", "éž " => "Ju", "éž¡" => "La", "鞢" => "Xie", "鞣" => "Rou", + "鞤" => "Bang", "鞥" => "Yi", "鞦" => "Qiu", "鞧" => "Qiu", "鞨" => "He", "éž©" => "Xiao", + "鞪" => "Mu", "éž«" => "Ju", "鞬" => "Jian", "éž­" => "Bian", "éž®" => "Di", "鞯" => "Jian", + "éž°" => "On", "éž±" => "Tao", "éž²" => "Gou", "éž³" => "Ta", "éž´" => "Bei", "éžµ" => "Xie", + "鞶" => "Pan", "éž·" => "Ge", "鞸" => "Bi", "éž¹" => "Kuo", "鞺" => "Tang", "éž»" => "Lou", + "éž¼" => "Gui", "éž½" => "Qiao", "éž¾" => "Xue", "éž¿" => "Ji", "韀" => "Jian", "éŸ" => "Jiang", + "韂" => "Chan", "韃" => "Da", "韄" => "Huo", "韅" => "Xian", "韆" => "Qian", "韇" => "Du", + "韈" => "Wa", "韉" => "Jian", "韊" => "Lan", "韋" => "Wei", "韌" => "Ren", "éŸ" => "Fu", + "韎" => "Mei", "éŸ" => "Juan", "éŸ" => "Ge", "韑" => "Wei", "韒" => "Qiao", "韓" => "Han", + "韔" => "Chang", "韖" => "Rou", "韗" => "Xun", "韘" => "She", "韙" => "Wei", "韚" => "Ge", + "韛" => "Bei", "韜" => "Tao", "éŸ" => "Gou", "韞" => "Yun", "韠" => "Bi", "韡" => "Wei", + "韢" => "Hui", "韣" => "Du", "韤" => "Wa", "韥" => "Du", "韦" => "Wei", "韧" => "Ren", + "韨" => "Fu", "韩" => "Han", "韪" => "Wei", "韫" => "Yun", "韬" => "Tao", "韭" => "Jiu", + "韮" => "Jiu", "韯" => "Xian", "韰" => "Xie", "韱" => "Xian", "韲" => "Ji", "音" => "Yin", + "韴" => "Za", "韵" => "Yun", "韶" => "Shao", "韷" => "Le", "韸" => "Peng", "韹" => "Heng", + "韺" => "Ying", "韻" => "Yun", "韼" => "Peng", "韽" => "Yin", "韾" => "Yin", "響" => "Xiang", + "é " => "Ye", "é ‚" => "Ding", "é ƒ" => "Qing", "é „" => "Pan", "é …" => "Xiang", "é †" => "Shun", + "é ‡" => "Han", "é ˆ" => "Xu", "é ‰" => "Yi", "é Š" => "Xu", "é ‹" => "Gu", "é Œ" => "Song", + "é " => "Kui", "é Ž" => "Qi", "é " => "Hang", "é " => "Yu", "é ‘" => "Wan", "é ’" => "Ban", + "é “" => "Dun", "é ”" => "Di", "é •" => "Dan", "é –" => "Pan", "é —" => "Po", "é ˜" => "Ling", + "é ™" => "Ce", "é š" => "Jing", "é ›" => "Lei", "é œ" => "He", "é " => "Qiao", "é ž" => "E", + "é Ÿ" => "E", "é  " => "Wei", "é ¡" => "Jie", "é ¢" => "Gua", "é £" => "Shen", "é ¤" => "Yi", + "é ¥" => "Shen", "é ¦" => "Hai", "é §" => "Dui", "é ¨" => "Pian", "é ©" => "Ping", "é ª" => "Lei", + "é «" => "Fu", "é ¬" => "Jia", "é ­" => "Tou", "é ®" => "Hui", "é ¯" => "Kui", "é °" => "Jia", + "é ±" => "Le", "é ²" => "Tian", "é ³" => "Cheng", "é ´" => "Ying", "é µ" => "Jun", "é ¶" => "Hu", + "é ·" => "Han", "é ¸" => "Jing", "é ¹" => "Tui", "é º" => "Tui", "é »" => "Pin", "é ¼" => "Lai", + "é ½" => "Tui", "é ¾" => "Zi", "é ¿" => "Zi", "é¡€" => "Chui", "é¡" => "Ding", "é¡‚" => "Lai", + "顃" => "Yan", "é¡„" => "Han", "é¡…" => "Jian", "顆" => "Ke", "顇" => "Cui", "顈" => "Jiong", + "顉" => "Qin", "é¡Š" => "Yi", "é¡‹" => "Sai", "é¡Œ" => "Ti", "é¡" => "E", "é¡Ž" => "E", + "é¡" => "Yan", "é¡" => "Hun", "é¡‘" => "Kan", "é¡’" => "Yong", "é¡“" => "Zhuan", "é¡”" => "Yan", + "é¡•" => "Xian", "é¡–" => "Xin", "é¡—" => "Yi", "願" => "Yuan", "é¡™" => "Sang", "é¡š" => "Dian", + "é¡›" => "Dian", "é¡œ" => "Jiang", "é¡" => "Ku", "é¡ž" => "Lei", "é¡Ÿ" => "Liao", "é¡ " => "Piao", + "é¡¡" => "Yi", "é¡¢" => "Man", "é¡£" => "Qi", "顤" => "Rao", "é¡¥" => "Hao", "顦" => "Qiao", + "顧" => "Gu", "顨" => "Xun", "é¡©" => "Qian", "顪" => "Hui", "é¡«" => "Zhan", "顬" => "Ru", + "é¡­" => "Hong", "é¡®" => "Bin", "顯" => "Xian", "é¡°" => "Pin", "顱" => "Lu", "顲" => "Lan", + "顳" => "Nie", "é¡´" => "Quan", "页" => "Ye", "顶" => "Ding", "é¡·" => "Qing", "顸" => "Han", + "项" => "Xiang", "顺" => "Shun", "é¡»" => "Xu", "顼" => "Xu", "顽" => "Wan", "顾" => "Gu", + "é¡¿" => "Dun", "颀" => "Qi", "é¢" => "Ban", "颂" => "Song", "颃" => "Hang", "预" => "Yu", + "颅" => "Lu", "领" => "Ling", "颇" => "Po", "颈" => "Jing", "颉" => "Jie", "颊" => "Jia", + "颋" => "Tian", "颌" => "Han", "é¢" => "Ying", "颎" => "Jiong", "é¢" => "Hai", "é¢" => "Yi", + "频" => "Pin", "颒" => "Hui", "颓" => "Tui", "颔" => "Han", "颕" => "Ying", "颖" => "Ying", + "颗" => "Ke", "题" => "Ti", "颙" => "Yong", "颚" => "E", "颛" => "Zhuan", "颜" => "Yan", + "é¢" => "E", "颞" => "Nie", "颟" => "Man", "颠" => "Dian", "颡" => "Sang", "颢" => "Hao", + "颣" => "Lei", "颤" => "Zhan", "颥" => "Ru", "颦" => "Pin", "颧" => "Quan", "風" => "Feng", + "颩" => "Biao", "颪" => "Oroshi", "颫" => "Fu", "颬" => "Xia", "颭" => "Zhan", "颮" => "Biao", + "颯" => "Sa", "颰" => "Ba", "颱" => "Tai", "颲" => "Lie", "颳" => "Gua", "颴" => "Xuan", + "颵" => "Shao", "颶" => "Ju", "颷" => "Bi", "颸" => "Si", "颹" => "Wei", "颺" => "Yang", + "颻" => "Yao", "颼" => "Sou", "颽" => "Kai", "颾" => "Sao", "颿" => "Fan", "飀" => "Liu", + "é£" => "Xi", "飂" => "Liao", "飃" => "Piao", "飄" => "Piao", "飅" => "Liu", "飆" => "Biao", + "飇" => "Biao", "飈" => "Biao", "飉" => "Liao", "飋" => "Se", "飌" => "Feng", "é£" => "Biao", + "风" => "Feng", "é£" => "Yang", "é£" => "Zhan", "飑" => "Biao", "飒" => "Sa", "飓" => "Ju", + "飔" => "Si", "飕" => "Sou", "飖" => "Yao", "飗" => "Liu", "飘" => "Piao", "飙" => "Biao", + "飚" => "Biao", "飛" => "Fei", "飜" => "Fan", "é£" => "Fei", "飞" => "Fei", "食" => "Shi", + "飠" => "Shi", "飡" => "Can", "飢" => "Ji", "飣" => "Ding", "飤" => "Si", "飥" => "Tuo", + "飦" => "Zhan", "飧" => "Sun", "飨" => "Xiang", "飩" => "Tun", "飪" => "Ren", "飫" => "Yu", + "飬" => "Juan", "飭" => "Chi", "飮" => "Yin", "飯" => "Fan", "飰" => "Fan", "飱" => "Sun", + "飲" => "Yin", "飳" => "Zhu", "飴" => "Yi", "飵" => "Zhai", "飶" => "Bi", "飷" => "Jie", + "飸" => "Tao", "飹" => "Liu", "飺" => "Ci", "飻" => "Tie", "飼" => "Si", "飽" => "Bao", + "飾" => "Shi", "飿" => "Duo", "é¤" => "Ren", "餂" => "Tian", "餃" => "Jiao", "餄" => "Jia", + "餅" => "Bing", "餆" => "Yao", "餇" => "Tong", "餈" => "Ci", "餉" => "Xiang", "養" => "Yang", + "餋" => "Yang", "餌" => "Er", "é¤" => "Yan", "餎" => "Le", "é¤" => "Yi", "é¤" => "Can", + "餑" => "Bo", "餒" => "Nei", "餓" => "E", "餔" => "Bu", "餕" => "Jun", "餖" => "Dou", + "餗" => "Su", "餘" => "Yu", "餙" => "Shi", "餚" => "Yao", "餛" => "Hun", "餜" => "Guo", + "é¤" => "Shi", "餞" => "Jian", "餟" => "Zhui", "餠" => "Bing", "餡" => "Xian", "餢" => "Bu", + "餣" => "Ye", "餤" => "Tan", "餥" => "Fei", "餦" => "Zhang", "餧" => "Wei", "館" => "Guan", + "餩" => "E", "餪" => "Nuan", "餫" => "Hun", "餬" => "Hu", "餭" => "Huang", "餮" => "Tie", + "餯" => "Hui", "餰" => "Jian", "餱" => "Hou", "餲" => "He", "餳" => "Xing", "餴" => "Fen", + "餵" => "Wei", "餶" => "Gu", "餷" => "Cha", "餸" => "Song", "餹" => "Tang", "餺" => "Bo", + "餻" => "Gao", "餼" => "Xi", "餽" => "Kui", "餾" => "Liu", "餿" => "Sou", "饀" => "Tao", + "é¥" => "Ye", "饂" => "Yun", "饃" => "Mo", "饄" => "Tang", "饅" => "Man", "饆" => "Bi", + "饇" => "Yu", "饈" => "Xiu", "饉" => "Jin", "饊" => "San", "饋" => "Kui", "饌" => "Zhuan", + "é¥" => "Shan", "饎" => "Chi", "é¥" => "Dan", "é¥" => "Yi", "饑" => "Ji", "饒" => "Rao", + "饓" => "Cheng", "饔" => "Yong", "饕" => "Tao", "饖" => "Hui", "饗" => "Xiang", "饘" => "Zhan", + "饙" => "Fen", "饚" => "Hai", "饛" => "Meng", "饜" => "Yan", "é¥" => "Mo", "饞" => "Chan", + "饟" => "Xiang", "饠" => "Luo", "饡" => "Zuan", "饢" => "Nang", "饣" => "Shi", "饤" => "Ding", + "饥" => "Ji", "饦" => "Tuo", "饧" => "Xing", "饨" => "Tun", "饩" => "Xi", "饪" => "Ren", + "饫" => "Yu", "饬" => "Chi", "饭" => "Fan", "饮" => "Yin", "饯" => "Jian", "饰" => "Shi", + "饱" => "Bao", "饲" => "Si", "饳" => "Duo", "饴" => "Yi", "饵" => "Er", "饶" => "Rao", + "饷" => "Xiang", "饸" => "Jia", "饹" => "Le", "饺" => "Jiao", "饻" => "Yi", "饼" => "Bing", + "饽" => "Bo", "饾" => "Dou", "饿" => "E", "馀" => "Yu", "é¦" => "Nei", "馂" => "Jun", + "馃" => "Guo", "馄" => "Hun", "馅" => "Xian", "馆" => "Guan", "馇" => "Cha", "馈" => "Kui", + "馉" => "Gu", "馊" => "Sou", "馋" => "Chan", "馌" => "Ye", "é¦" => "Mo", "馎" => "Bo", + "é¦" => "Liu", "é¦" => "Xiu", "馑" => "Jin", "馒" => "Man", "馓" => "San", "馔" => "Zhuan", + "馕" => "Nang", "首" => "Shou", "馗" => "Kui", "馘" => "Guo", "香" => "Xiang", "馚" => "Fen", + "馛" => "Ba", "馜" => "Ni", "é¦" => "Bi", "馞" => "Bo", "馟" => "Tu", "馠" => "Han", + "馡" => "Fei", "馢" => "Jian", "馣" => "An", "馤" => "Ai", "馥" => "Fu", "馦" => "Xian", + "馧" => "Wen", "馨" => "Xin", "馩" => "Fen", "馪" => "Bin", "馫" => "Xing", "馬" => "Ma", + "馭" => "Yu", "馮" => "Feng", "馯" => "Han", "馰" => "Di", "馱" => "Tuo", "馲" => "Tuo", + "馳" => "Chi", "馴" => "Xun", "馵" => "Zhu", "馶" => "Zhi", "馷" => "Pei", "馸" => "Xin", + "馹" => "Ri", "馺" => "Sa", "馻" => "Yin", "馼" => "Wen", "馽" => "Zhi", "馾" => "Dan", + "馿" => "Lu", "駀" => "You", "é§" => "Bo", "駂" => "Bao", "駃" => "Kuai", "駄" => "Tuo", + "駅" => "Yi", "駆" => "Qu", "駈" => "Qu", "駉" => "Jiong", "駊" => "Bo", "駋" => "Zhao", + "駌" => "Yuan", "é§" => "Peng", "駎" => "Zhou", "é§" => "Ju", "é§" => "Zhu", "駑" => "Nu", + "駒" => "Ju", "駓" => "Pi", "駔" => "Zang", "駕" => "Jia", "駖" => "Ling", "駗" => "Zhen", + "駘" => "Tai", "駙" => "Fu", "駚" => "Yang", "駛" => "Shi", "駜" => "Bi", "é§" => "Tuo", + "駞" => "Tuo", "駟" => "Si", "駠" => "Liu", "駡" => "Ma", "駢" => "Pian", "駣" => "Tao", + "駤" => "Zhi", "駥" => "Rong", "駦" => "Teng", "駧" => "Dong", "駨" => "Xun", "駩" => "Quan", + "駪" => "Shen", "駫" => "Jiong", "駬" => "Er", "駭" => "Hai", "駮" => "Bo", "駯" => "Zhu", + "駰" => "Yin", "駱" => "Luo", "駲" => "Shuu", "駳" => "Dan", "駴" => "Xie", "駵" => "Liu", + "駶" => "Ju", "駷" => "Song", "駸" => "Qin", "駹" => "Mang", "駺" => "Liang", "駻" => "Han", + "駼" => "Tu", "駽" => "Xuan", "駾" => "Tui", "駿" => "Jun", "é¨" => "Cheng", "騂" => "Xin", + "騃" => "Ai", "騄" => "Lu", "騅" => "Zhui", "騆" => "Zhou", "騇" => "She", "騈" => "Pian", + "騉" => "Kun", "騊" => "Tao", "騋" => "Lai", "騌" => "Zong", "é¨" => "Ke", "騎" => "Qi", + "é¨" => "Qi", "é¨" => "Yan", "騑" => "Fei", "騒" => "Sao", "験" => "Yan", "騔" => "Jie", + "騕" => "Yao", "騖" => "Wu", "騗" => "Pian", "騘" => "Cong", "騙" => "Pian", "騚" => "Qian", + "騛" => "Fei", "騜" => "Huang", "é¨" => "Jian", "騞" => "Huo", "騟" => "Yu", "騠" => "Ti", + "騡" => "Quan", "騢" => "Xia", "騣" => "Zong", "騤" => "Kui", "騥" => "Rou", "騦" => "Si", + "騧" => "Gua", "騨" => "Tuo", "騩" => "Kui", "騪" => "Sou", "騫" => "Qian", "騬" => "Cheng", + "騭" => "Zhi", "騮" => "Liu", "騯" => "Pang", "騰" => "Teng", "騱" => "Xi", "騲" => "Cao", + "騳" => "Du", "騴" => "Yan", "騵" => "Yuan", "騶" => "Zou", "騷" => "Sao", "騸" => "Shan", + "騹" => "Li", "騺" => "Zhi", "騻" => "Shuang", "騼" => "Lu", "騽" => "Xi", "騾" => "Luo", + "騿" => "Zhang", "é©€" => "Mo", "é©" => "Ao", "é©‚" => "Can", "驃" => "Piao", "é©„" => "Cong", + "é©…" => "Qu", "驆" => "Bi", "驇" => "Zhi", "驈" => "Yu", "驉" => "Xu", "é©Š" => "Hua", + "é©‹" => "Bo", "é©Œ" => "Su", "é©" => "Xiao", "é©Ž" => "Lin", "é©" => "Chan", "é©" => "Dun", + "é©‘" => "Liu", "é©’" => "Tuo", "é©“" => "Zeng", "é©”" => "Tan", "é©•" => "Jiao", "é©–" => "Tie", + "é©—" => "Yan", "驘" => "Luo", "é©™" => "Zhan", "é©š" => "Jing", "é©›" => "Yi", "é©œ" => "Ye", + "é©" => "Tuo", "é©ž" => "Bin", "é©Ÿ" => "Zou", "é© " => "Yan", "é©¡" => "Peng", "é©¢" => "Lu", + "é©£" => "Teng", "驤" => "Xiang", "é©¥" => "Ji", "驦" => "Shuang", "驧" => "Ju", "驨" => "Xi", + "é©©" => "Huan", "驪" => "Li", "é©«" => "Biao", "马" => "Ma", "é©­" => "Yu", "é©®" => "Tuo", + "驯" => "Xun", "é©°" => "Chi", "驱" => "Qu", "驲" => "Ri", "驳" => "Bo", "é©´" => "Lu", + "驵" => "Zang", "驶" => "Shi", "é©·" => "Si", "驸" => "Fu", "驹" => "Ju", "驺" => "Zou", + "é©»" => "Zhu", "驼" => "Tuo", "驽" => "Nu", "驾" => "Jia", "é©¿" => "Yi", "骀" => "Tai", + "éª" => "Xiao", "骂" => "Ma", "骃" => "Yin", "骄" => "Jiao", "骅" => "Hua", "骆" => "Luo", + "骇" => "Hai", "骈" => "Pian", "骉" => "Biao", "骊" => "Li", "骋" => "Cheng", "验" => "Yan", + "éª" => "Xin", "骎" => "Qin", "éª" => "Jun", "éª" => "Qi", "骑" => "Qi", "骒" => "Ke", + "骓" => "Zhui", "骔" => "Zong", "骕" => "Su", "骖" => "Can", "骗" => "Pian", "骘" => "Zhi", + "骙" => "Kui", "骚" => "Sao", "骛" => "Wu", "骜" => "Ao", "éª" => "Liu", "骞" => "Qian", + "骟" => "Shan", "骠" => "Piao", "骡" => "Luo", "骢" => "Cong", "骣" => "Chan", "骤" => "Zou", + "骥" => "Ji", "骦" => "Shuang", "骧" => "Xiang", "骨" => "Gu", "骩" => "Wei", "骪" => "Wei", + "骫" => "Wei", "骬" => "Yu", "骭" => "Gan", "骮" => "Yi", "骯" => "Ang", "骰" => "Tou", + "骱" => "Xie", "骲" => "Bao", "骳" => "Bi", "骴" => "Chi", "骵" => "Ti", "骶" => "Di", + "骷" => "Ku", "骸" => "Hai", "骹" => "Qiao", "骺" => "Gou", "骻" => "Kua", "骼" => "Ge", + "骽" => "Tui", "骾" => "Geng", "骿" => "Pian", "é«€" => "Bi", "é«" => "Ke", "é«‚" => "Ka", + "髃" => "Yu", "é«„" => "Sui", "é«…" => "Lou", "髆" => "Bo", "髇" => "Xiao", "髈" => "Pang", + "髉" => "Bo", "é«Š" => "Ci", "é«‹" => "Kuan", "é«Œ" => "Bin", "é«" => "Mo", "é«Ž" => "Liao", + "é«" => "Lou", "é«" => "Nao", "é«‘" => "Du", "é«’" => "Zang", "é«“" => "Sui", "é«”" => "Ti", + "é«•" => "Bin", "é«–" => "Kuan", "é«—" => "Lu", "高" => "Gao", "é«™" => "Gao", "é«š" => "Qiao", + "é«›" => "Kao", "é«œ" => "Qiao", "é«" => "Lao", "é«ž" => "Zao", "é«Ÿ" => "Biao", "é« " => "Kun", + "é«¡" => "Kun", "é«¢" => "Ti", "é«£" => "Fang", "髤" => "Xiu", "é«¥" => "Ran", "髦" => "Mao", + "髧" => "Dan", "髨" => "Kun", "é«©" => "Bin", "髪" => "Fa", "é««" => "Tiao", "髬" => "Peng", + "é«­" => "Zi", "é«®" => "Fa", "髯" => "Ran", "é«°" => "Ti", "髱" => "Pao", "髲" => "Pi", + "髳" => "Mao", "é«´" => "Fu", "髵" => "Er", "髶" => "Rong", "é«·" => "Qu", "髸" => "Gong", + "髹" => "Xiu", "髺" => "Gua", "é«»" => "Ji", "髼" => "Peng", "髽" => "Zhua", "髾" => "Shao", + "é«¿" => "Sha", "é¬" => "Li", "鬂" => "Bin", "鬃" => "Zong", "鬄" => "Ti", "鬅" => "Peng", + "鬆" => "Song", "鬇" => "Zheng", "鬈" => "Quan", "鬉" => "Zong", "鬊" => "Shun", "鬋" => "Jian", + "鬌" => "Duo", "é¬" => "Hu", "鬎" => "La", "é¬" => "Jiu", "é¬" => "Qi", "鬑" => "Lian", + "鬒" => "Zhen", "鬓" => "Bin", "鬔" => "Peng", "鬕" => "Mo", "鬖" => "San", "鬗" => "Man", + "鬘" => "Man", "鬙" => "Seng", "鬚" => "Xu", "鬛" => "Lie", "鬜" => "Qian", "é¬" => "Qian", + "鬞" => "Nong", "鬟" => "Huan", "鬠" => "Kuai", "鬡" => "Ning", "鬢" => "Bin", "鬣" => "Lie", + "鬤" => "Rang", "鬥" => "Dou", "鬦" => "Dou", "鬧" => "Nao", "鬨" => "Hong", "鬩" => "Xi", + "鬪" => "Dou", "鬫" => "Han", "鬬" => "Dou", "鬭" => "Dou", "鬮" => "Jiu", "鬯" => "Chang", + "鬰" => "Yu", "鬱" => "Yu", "鬲" => "Li", "鬳" => "Juan", "鬴" => "Fu", "鬵" => "Qian", + "鬶" => "Gui", "鬷" => "Zong", "鬸" => "Liu", "鬹" => "Gui", "鬺" => "Shang", "鬻" => "Yu", + "鬼" => "Gui", "鬽" => "Mei", "鬾" => "Ji", "鬿" => "Qi", "é­€" => "Jie", "é­" => "Kui", + "é­‚" => "Hun", "é­ƒ" => "Ba", "é­„" => "Po", "é­…" => "Mei", "é­†" => "Xu", "é­‡" => "Yan", + "é­ˆ" => "Xiao", "é­‰" => "Liang", "é­Š" => "Yu", "é­‹" => "Tui", "é­Œ" => "Qi", "é­" => "Wang", + "é­Ž" => "Liang", "é­" => "Wei", "é­" => "Jian", "é­‘" => "Chi", "é­’" => "Piao", "é­“" => "Bi", + "é­”" => "Mo", "é­•" => "Ji", "é­–" => "Xu", "é­—" => "Chou", "é­˜" => "Yan", "é­™" => "Zhan", + "é­š" => "Yu", "é­›" => "Dao", "é­œ" => "Ren", "é­" => "Ji", "é­ž" => "Eri", "é­Ÿ" => "Gong", + "é­ " => "Tuo", "é­¡" => "Diao", "é­¢" => "Ji", "é­£" => "Xu", "é­¤" => "E", "é­¥" => "E", + "é­¦" => "Sha", "é­§" => "Hang", "é­¨" => "Tun", "é­©" => "Mo", "é­ª" => "Jie", "é­«" => "Shen", + "é­¬" => "Fan", "é­­" => "Yuan", "é­®" => "Bi", "é­¯" => "Lu", "é­°" => "Wen", "é­±" => "Hu", + "é­²" => "Lu", "é­³" => "Za", "é­´" => "Fang", "é­µ" => "Fen", "é­¶" => "Na", "é­·" => "You", + "é­¸" => "Namazu", "é­¹" => "Todo", "é­º" => "He", "é­»" => "Xia", "é­¼" => "Qu", "é­½" => "Han", + "é­¾" => "Pi", "é­¿" => "Ling", "鮀" => "Tuo", "é®" => "Bo", "鮂" => "Qiu", "鮃" => "Ping", + "鮄" => "Fu", "é®…" => "Bi", "鮆" => "Ji", "鮇" => "Wei", "鮈" => "Ju", "鮉" => "Diao", + "鮊" => "Bo", "鮋" => "You", "鮌" => "Gun", "é®" => "Pi", "鮎" => "Nian", "é®" => "Xing", + "é®" => "Tai", "鮑" => "Bao", "é®’" => "Fu", "鮓" => "Zha", "é®”" => "Ju", "鮕" => "Gu", + "é®–" => "Kajika", "é®—" => "Tong", "é®™" => "Ta", "鮚" => "Jie", "é®›" => "Shu", "鮜" => "Hou", + "é®" => "Xiang", "鮞" => "Er", "鮟" => "An", "é® " => "Wei", "鮡" => "Tiao", "鮢" => "Zhu", + "鮣" => "Yin", "鮤" => "Lie", "鮥" => "Luo", "鮦" => "Tong", "鮧" => "Yi", "鮨" => "Qi", + "鮩" => "Bing", "鮪" => "Wei", "鮫" => "Jiao", "鮬" => "Bu", "é®­" => "Gui", "é®®" => "Xian", + "鮯" => "Ge", "é®°" => "Hui", "é®±" => "Bora", "鮲" => "Mate", "鮳" => "Kao", "é®´" => "Gori", + "鮵" => "Duo", "鮶" => "Jun", "é®·" => "Ti", "鮸" => "Man", "鮹" => "Xiao", "鮺" => "Za", + "é®»" => "Sha", "鮼" => "Qin", "鮽" => "Yu", "鮾" => "Nei", "鮿" => "Zhe", "鯀" => "Gun", + "é¯" => "Geng", "鯂" => "Su", "鯃" => "Wu", "鯄" => "Qiu", "鯅" => "Ting", "鯆" => "Fu", + "鯇" => "Wan", "鯈" => "You", "鯉" => "Li", "鯊" => "Sha", "鯋" => "Sha", "鯌" => "Gao", + "é¯" => "Meng", "鯎" => "Ugui", "é¯" => "Asari", "é¯" => "Subashiri", "鯑" => "Kazunoko", "鯒" => "Yong", + "鯓" => "Ni", "鯔" => "Zi", "鯕" => "Qi", "鯖" => "Qing", "鯗" => "Xiang", "鯘" => "Nei", + "鯙" => "Chun", "鯚" => "Ji", "鯛" => "Diao", "鯜" => "Qie", "é¯" => "Gu", "鯞" => "Zhou", + "鯟" => "Dong", "鯠" => "Lai", "鯡" => "Fei", "鯢" => "Ni", "鯣" => "Yi", "鯤" => "Kun", + "鯥" => "Lu", "鯦" => "Jiu", "鯧" => "Chang", "鯨" => "Jing", "鯩" => "Lun", "鯪" => "Ling", + "鯫" => "Zou", "鯬" => "Li", "鯭" => "Meng", "鯮" => "Zong", "鯯" => "Zhi", "鯰" => "Nian", + "鯱" => "Shachi", "鯲" => "Dojou", "鯳" => "Sukesou", "鯴" => "Shi", "鯵" => "Shen", "鯶" => "Hun", + "鯷" => "Shi", "鯸" => "Hou", "鯹" => "Xing", "鯺" => "Zhu", "鯻" => "La", "鯼" => "Zong", + "鯽" => "Ji", "鯾" => "Bian", "鯿" => "Bian", "é°" => "Quan", "é°‚" => "Ze", "é°ƒ" => "Wei", + "é°„" => "Wei", "é°…" => "Yu", "é°†" => "Qun", "é°‡" => "Rou", "é°ˆ" => "Die", "é°‰" => "Huang", + "é°Š" => "Lian", "é°‹" => "Yan", "é°Œ" => "Qiu", "é°" => "Qiu", "é°Ž" => "Jian", "é°" => "Bi", + "é°" => "E", "é°‘" => "Yang", "é°’" => "Fu", "é°“" => "Sai", "é°”" => "Jian", "é°•" => "Xia", + "é°–" => "Tuo", "é°—" => "Hu", "é°˜" => "Muroaji", "é°™" => "Ruo", "é°š" => "Haraka", "é°›" => "Wen", + "é°œ" => "Jian", "é°" => "Hao", "é°ž" => "Wu", "é°Ÿ" => "Fang", "é° " => "Sao", "é°¡" => "Liu", + "é°¢" => "Ma", "é°£" => "Shi", "é°¤" => "Shi", "é°¥" => "Yin", "é°¦" => "Z", "é°§" => "Teng", + "é°¨" => "Ta", "é°©" => "Yao", "é°ª" => "Ge", "é°«" => "Rong", "é°¬" => "Qian", "é°­" => "Qi", + "é°®" => "Wen", "é°¯" => "Ruo", "é°°" => "Hatahata", "é°±" => "Lian", "é°²" => "Ao", "é°³" => "Le", + "é°´" => "Hui", "é°µ" => "Min", "é°¶" => "Ji", "é°·" => "Tiao", "é°¸" => "Qu", "é°¹" => "Jian", + "é°º" => "Sao", "é°»" => "Man", "é°¼" => "Xi", "é°½" => "Qiu", "é°¾" => "Biao", "é°¿" => "Ji", + "é±€" => "Ji", "é±" => "Zhu", "鱂" => "Jiang", "鱃" => "Qiu", "鱄" => "Zhuan", "é±…" => "Yong", + "鱆" => "Zhang", "鱇" => "Kang", "鱈" => "Xue", "鱉" => "Bie", "鱊" => "Jue", "鱋" => "Qu", + "鱌" => "Xiang", "é±" => "Bo", "鱎" => "Jiao", "é±" => "Xun", "é±" => "Su", "鱑" => "Huang", + "é±’" => "Zun", "鱓" => "Shan", "é±”" => "Shan", "鱕" => "Fan", "é±–" => "Jue", "é±—" => "Lin", + "鱘" => "Xun", "é±™" => "Miao", "鱚" => "Xi", "é±›" => "Eso", "鱜" => "Kyou", "é±" => "Fen", + "鱞" => "Guan", "鱟" => "Hou", "é± " => "Kuai", "鱡" => "Zei", "é±¢" => "Sao", "é±£" => "Zhan", + "鱤" => "Gan", "é±¥" => "Gui", "鱦" => "Sheng", "鱧" => "Li", "鱨" => "Chang", "鱩" => "Hatahata", + "鱪" => "Shiira", "鱫" => "Mutsu", "鱬" => "Ru", "é±­" => "Ji", "é±®" => "Xu", "鱯" => "Huo", + "é±°" => "Shiira", "é±±" => "Li", "é±²" => "Lie", "é±³" => "Li", "é±´" => "Mie", "é±µ" => "Zhen", + "鱶" => "Xiang", "é±·" => "E", "鱸" => "Lu", "é±¹" => "Guan", "鱺" => "Li", "é±»" => "Xian", + "é±¼" => "Yu", "é±½" => "Dao", "é±¾" => "Ji", "鱿" => "You", "é²€" => "Tun", "é²" => "Lu", + "鲂" => "Fang", "鲃" => "Ba", "鲄" => "He", "é²…" => "Bo", "鲆" => "Ping", "鲇" => "Nian", + "鲈" => "Lu", "鲉" => "You", "鲊" => "Zha", "鲋" => "Fu", "鲌" => "Bo", "é²" => "Bao", + "鲎" => "Hou", "é²" => "Pi", "é²" => "Tai", "鲑" => "Gui", "é²’" => "Jie", "鲓" => "Kao", + "é²”" => "Wei", "鲕" => "Er", "é²–" => "Tong", "é²—" => "Ze", "鲘" => "Hou", "é²™" => "Kuai", + "鲚" => "Ji", "é²›" => "Jiao", "鲜" => "Xian", "é²" => "Za", "鲞" => "Xiang", "鲟" => "Xun", + "é² " => "Geng", "鲡" => "Li", "é²¢" => "Lian", "é²£" => "Jian", "鲤" => "Li", "é²¥" => "Shi", + "鲦" => "Tiao", "鲧" => "Gun", "鲨" => "Sha", "鲩" => "Wan", "鲪" => "Jun", "鲫" => "Ji", + "鲬" => "Yong", "é²­" => "Qing", "é²®" => "Ling", "鲯" => "Qi", "é²°" => "Zou", "é²±" => "Fei", + "é²²" => "Kun", "é²³" => "Chang", "é²´" => "Gu", "é²µ" => "Ni", "鲶" => "Nian", "é²·" => "Diao", + "鲸" => "Jing", "é²¹" => "Shen", "鲺" => "Shi", "é²»" => "Zi", "é²¼" => "Fen", "é²½" => "Die", + "é²¾" => "Bi", "鲿" => "Chang", "é³€" => "Shi", "é³" => "Wen", "鳂" => "Wei", "鳃" => "Sai", + "鳄" => "E", "é³…" => "Qiu", "鳆" => "Fu", "鳇" => "Huang", "鳈" => "Quan", "鳉" => "Jiang", + "鳊" => "Bian", "鳋" => "Sao", "鳌" => "Ao", "é³" => "Qi", "鳎" => "Ta", "é³" => "Yin", + "é³" => "Yao", "鳑" => "Fang", "é³’" => "Jian", "鳓" => "Le", "é³”" => "Biao", "鳕" => "Xue", + "é³–" => "Bie", "é³—" => "Man", "鳘" => "Min", "é³™" => "Yong", "鳚" => "Wei", "é³›" => "Xi", + "鳜" => "Jue", "é³" => "Shan", "鳞" => "Lin", "鳟" => "Zun", "é³ " => "Huo", "鳡" => "Gan", + "é³¢" => "Li", "é³£" => "Zhan", "鳤" => "Guan", "é³¥" => "Niao", "鳦" => "Yi", "鳧" => "Fu", + "鳨" => "Li", "鳩" => "Jiu", "鳪" => "Bu", "鳫" => "Yan", "鳬" => "Fu", "é³­" => "Diao", + "é³®" => "Ji", "鳯" => "Feng", "é³°" => "Nio", "é³±" => "Gan", "é³²" => "Shi", "é³³" => "Feng", + "é³´" => "Ming", "é³µ" => "Bao", "鳶" => "Yuan", "é³·" => "Zhi", "鳸" => "Hu", "é³¹" => "Qin", + "鳺" => "Fu", "é³»" => "Fen", "é³¼" => "Wen", "é³½" => "Jian", "é³¾" => "Shi", "鳿" => "Yu", + "é´" => "Yiao", "é´‚" => "Jue", "é´ƒ" => "Jue", "é´„" => "Pi", "é´…" => "Huan", "é´†" => "Zhen", + "é´‡" => "Bao", "é´ˆ" => "Yan", "é´‰" => "Ya", "é´Š" => "Zheng", "é´‹" => "Fang", "é´Œ" => "Feng", + "é´" => "Wen", "é´Ž" => "Ou", "é´" => "Te", "é´" => "Jia", "é´‘" => "Nu", "é´’" => "Ling", + "é´“" => "Mie", "é´”" => "Fu", "é´•" => "Tuo", "é´–" => "Wen", "é´—" => "Li", "é´˜" => "Bian", + "é´™" => "Zhi", "é´š" => "Ge", "é´›" => "Yuan", "é´œ" => "Zi", "é´" => "Qu", "é´ž" => "Xiao", + "é´Ÿ" => "Zhi", "é´ " => "Dan", "é´¡" => "Ju", "é´¢" => "You", "é´£" => "Gu", "é´¤" => "Zhong", + "é´¥" => "Yu", "é´¦" => "Yang", "é´§" => "Rong", "é´¨" => "Ya", "é´©" => "Tie", "é´ª" => "Yu", + "é´«" => "Shigi", "é´¬" => "Ying", "é´­" => "Zhui", "é´®" => "Wu", "é´¯" => "Er", "é´°" => "Gua", + "é´±" => "Ai", "é´²" => "Zhi", "é´³" => "Yan", "é´´" => "Heng", "é´µ" => "Jiao", "é´¶" => "Ji", + "é´·" => "Lie", "é´¸" => "Zhu", "é´¹" => "Ren", "é´º" => "Yi", "é´»" => "Hong", "é´¼" => "Luo", + "é´½" => "Ru", "é´¾" => "Mou", "é´¿" => "Ge", "éµ€" => "Ren", "éµ" => "Jiao", "鵂" => "Xiu", + "鵃" => "Zhou", "鵄" => "Zhi", "éµ…" => "Luo", "鵆" => "Chidori", "鵇" => "Toki", "鵈" => "Ten", + "鵉" => "Luan", "鵊" => "Jia", "鵋" => "Ji", "鵌" => "Yu", "éµ" => "Huan", "鵎" => "Tuo", + "éµ" => "Bu", "éµ" => "Wu", "鵑" => "Juan", "éµ’" => "Yu", "鵓" => "Bo", "éµ”" => "Xun", + "鵕" => "Xun", "éµ–" => "Bi", "éµ—" => "Xi", "鵘" => "Jun", "éµ™" => "Ju", "鵚" => "Tu", + "éµ›" => "Jing", "鵜" => "Ti", "éµ" => "E", "鵞" => "E", "鵟" => "Kuang", "éµ " => "Hu", + "鵡" => "Wu", "éµ¢" => "Shen", "éµ£" => "Lai", "鵤" => "Ikaruga", "éµ¥" => "Kakesu", "鵦" => "Lu", + "鵧" => "Ping", "鵨" => "Shu", "鵩" => "Fu", "鵪" => "An", "鵫" => "Zhao", "鵬" => "Peng", + "éµ­" => "Qin", "éµ®" => "Qian", "鵯" => "Bei", "éµ°" => "Diao", "éµ±" => "Lu", "éµ²" => "Que", + "éµ³" => "Jian", "éµ´" => "Ju", "éµµ" => "Tu", "鵶" => "Ya", "éµ·" => "Yuan", "鵸" => "Qi", + "éµ¹" => "Li", "鵺" => "Ye", "éµ»" => "Zhui", "éµ¼" => "Kong", "éµ½" => "Zhui", "éµ¾" => "Kun", + "鵿" => "Sheng", "鶀" => "Qi", "é¶" => "Jing", "鶂" => "Yi", "鶃" => "Yi", "鶄" => "Jing", + "鶅" => "Zi", "鶆" => "Lai", "鶇" => "Dong", "鶈" => "Qi", "鶉" => "Chun", "鶊" => "Geng", + "鶋" => "Ju", "鶌" => "Qu", "é¶" => "Isuka", "鶎" => "Kikuitadaki", "é¶" => "Ji", "é¶" => "Shu", + "鶒" => "Chi", "鶓" => "Miao", "鶔" => "Rou", "鶕" => "An", "鶖" => "Qiu", "鶗" => "Ti", + "鶘" => "Hu", "鶙" => "Ti", "鶚" => "E", "鶛" => "Jie", "鶜" => "Mao", "é¶" => "Fu", + "鶞" => "Chun", "鶟" => "Tu", "鶠" => "Yan", "鶡" => "He", "鶢" => "Yuan", "鶣" => "Pian", + "鶤" => "Yun", "鶥" => "Mei", "鶦" => "Hu", "鶧" => "Ying", "鶨" => "Dun", "鶩" => "Mu", + "鶪" => "Ju", "鶫" => "Tsugumi", "鶬" => "Cang", "鶭" => "Fang", "鶮" => "Gu", "鶯" => "Ying", + "鶰" => "Yuan", "鶱" => "Xuan", "鶲" => "Weng", "鶳" => "Shi", "鶴" => "He", "鶵" => "Chu", + "鶶" => "Tang", "鶷" => "Xia", "鶸" => "Ruo", "鶹" => "Liu", "鶺" => "Ji", "鶻" => "Gu", + "鶼" => "Jian", "鶽" => "Zhun", "鶾" => "Han", "鶿" => "Zi", "é·€" => "Zi", "é·" => "Ni", + "é·‚" => "Yao", "é·ƒ" => "Yan", "é·„" => "Ji", "é·…" => "Li", "é·†" => "Tian", "é·‡" => "Kou", + "é·ˆ" => "Ti", "é·‰" => "Ti", "é·Š" => "Ni", "é·‹" => "Tu", "é·Œ" => "Ma", "é·" => "Jiao", + "é·Ž" => "Gao", "é·" => "Tian", "é·" => "Chen", "é·‘" => "Li", "é·’" => "Zhuan", "é·“" => "Zhe", + "é·”" => "Ao", "é·•" => "Yao", "é·–" => "Yi", "é·—" => "Ou", "é·˜" => "Chi", "é·™" => "Zhi", + "é·š" => "Liao", "é·›" => "Rong", "é·œ" => "Lou", "é·" => "Bi", "é·ž" => "Shuang", "é·Ÿ" => "Zhuo", + "é· " => "Yu", "é·¡" => "Wu", "é·¢" => "Jue", "é·£" => "Yin", "é·¤" => "Quan", "é·¥" => "Si", + "é·¦" => "Jiao", "é·§" => "Yi", "é·¨" => "Hua", "é·©" => "Bi", "é·ª" => "Ying", "é·«" => "Su", + "é·¬" => "Huang", "é·­" => "Fan", "é·®" => "Jiao", "é·¯" => "Liao", "é·°" => "Yan", "é·±" => "Kao", + "é·²" => "Jiu", "é·³" => "Xian", "é·´" => "Xian", "é·µ" => "Tu", "é·¶" => "Mai", "é··" => "Zun", + "é·¸" => "Yu", "é·¹" => "Ying", "é·º" => "Lu", "é·»" => "Tuan", "é·¼" => "Xian", "é·½" => "Xue", + "é·¾" => "Yi", "é·¿" => "Pi", "é¸" => "Luo", "鸂" => "Qi", "鸃" => "Yi", "鸄" => "Ji", + "鸅" => "Zhe", "鸆" => "Yu", "鸇" => "Zhan", "鸈" => "Ye", "鸉" => "Yang", "鸊" => "Pi", + "鸋" => "Ning", "鸌" => "Huo", "é¸" => "Mi", "鸎" => "Ying", "é¸" => "Meng", "é¸" => "Di", + "鸑" => "Yue", "鸒" => "Yu", "鸓" => "Lei", "鸔" => "Bao", "鸕" => "Lu", "鸖" => "He", + "鸗" => "Long", "鸘" => "Shuang", "鸙" => "Yue", "鸚" => "Ying", "鸛" => "Guan", "鸜" => "Qu", + "é¸" => "Li", "鸞" => "Luan", "鸟" => "Niao", "鸠" => "Jiu", "鸡" => "Ji", "鸢" => "Yuan", + "鸣" => "Ming", "鸤" => "Shi", "鸥" => "Ou", "鸦" => "Ya", "鸧" => "Cang", "鸨" => "Bao", + "鸩" => "Zhen", "鸪" => "Gu", "鸫" => "Dong", "鸬" => "Lu", "鸭" => "Ya", "鸮" => "Xiao", + "鸯" => "Yang", "鸰" => "Ling", "鸱" => "Zhi", "鸲" => "Qu", "鸳" => "Yuan", "鸴" => "Xue", + "鸵" => "Tuo", "鸶" => "Si", "鸷" => "Zhi", "鸸" => "Er", "鸹" => "Gua", "鸺" => "Xiu", + "鸻" => "Heng", "鸼" => "Zhou", "鸽" => "Ge", "鸾" => "Luan", "鸿" => "Hong", "é¹€" => "Wu", + "é¹" => "Bo", "鹂" => "Li", "鹃" => "Juan", "鹄" => "Hu", "é¹…" => "E", "鹆" => "Yu", + "鹇" => "Xian", "鹈" => "Ti", "鹉" => "Wu", "鹊" => "Que", "鹋" => "Miao", "鹌" => "An", + "é¹" => "Kun", "鹎" => "Bei", "é¹" => "Peng", "é¹" => "Qian", "鹑" => "Chun", "é¹’" => "Geng", + "鹓" => "Yuan", "é¹”" => "Su", "鹕" => "Hu", "é¹–" => "He", "é¹—" => "E", "鹘" => "Gu", + "é¹™" => "Qiu", "鹚" => "Zi", "é¹›" => "Mei", "鹜" => "Mu", "é¹" => "Ni", "鹞" => "Yao", + "鹟" => "Weng", "é¹ " => "Liu", "鹡" => "Ji", "é¹¢" => "Ni", "é¹£" => "Jian", "鹤" => "He", + "é¹¥" => "Yi", "鹦" => "Ying", "鹧" => "Zhe", "鹨" => "Liao", "鹩" => "Liao", "鹪" => "Jiao", + "鹫" => "Jiu", "鹬" => "Yu", "é¹­" => "Lu", "é¹®" => "Xuan", "鹯" => "Zhan", "é¹°" => "Ying", + "é¹±" => "Huo", "é¹²" => "Meng", "é¹³" => "Guan", "é¹´" => "Shuang", "é¹µ" => "Lu", "鹶" => "Jin", + "é¹·" => "Ling", "鹸" => "Jian", "é¹¹" => "Xian", "鹺" => "Cuo", "é¹»" => "Jian", "é¹¼" => "Jian", + "é¹½" => "Yan", "é¹¾" => "Cuo", "鹿" => "Lu", "麀" => "You", "éº" => "Cu", "麂" => "Ji", + "麃" => "Biao", "麄" => "Cu", "麅" => "Biao", "麆" => "Zhu", "麇" => "Jun", "麈" => "Zhu", + "麉" => "Jian", "麊" => "Mi", "麋" => "Mi", "麌" => "Wu", "éº" => "Liu", "麎" => "Chen", + "éº" => "Jun", "éº" => "Lin", "麑" => "Ni", "麒" => "Qi", "麓" => "Lu", "麔" => "Jiu", + "麕" => "Jun", "麖" => "Jing", "麗" => "Li", "麘" => "Xiang", "麙" => "Yan", "麚" => "Jia", + "麛" => "Mi", "麜" => "Li", "éº" => "She", "麞" => "Zhang", "麟" => "Lin", "麠" => "Jing", + "麡" => "Ji", "麢" => "Ling", "麣" => "Yan", "麤" => "Cu", "麥" => "Mai", "麦" => "Mai", + "麧" => "Ge", "麨" => "Chao", "麩" => "Fu", "麪" => "Mian", "麫" => "Mian", "麬" => "Fu", + "麭" => "Pao", "麮" => "Qu", "麯" => "Qu", "麰" => "Mou", "麱" => "Fu", "麲" => "Xian", + "麳" => "Lai", "麴" => "Qu", "麵" => "Mian", "麷" => "Feng", "麸" => "Fu", "麹" => "Qu", + "麺" => "Mian", "麻" => "Ma", "麼" => "Mo", "麽" => "Mo", "麾" => "Hui", "麿" => "Ma", + "黀" => "Zou", "é»" => "Nen", "黂" => "Fen", "黃" => "Huang", "黄" => "Huang", "é»…" => "Jin", + "黆" => "Guang", "黇" => "Tian", "黈" => "Tou", "黉" => "Heng", "黊" => "Xi", "黋" => "Kuang", + "黌" => "Heng", "é»" => "Shu", "黎" => "Li", "é»" => "Nian", "é»" => "Chi", "黑" => "Hei", + "é»’" => "Hei", "黓" => "Yi", "é»”" => "Qian", "黕" => "Dan", "é»–" => "Xi", "é»—" => "Tuan", + "默" => "Mo", "é»™" => "Mo", "黚" => "Qian", "é»›" => "Dai", "黜" => "Chu", "é»" => "You", + "點" => "Dian", "黟" => "Yi", "é» " => "Xia", "黡" => "Yan", "黢" => "Qu", "黣" => "Mei", + "黤" => "Yan", "黥" => "Jing", "黦" => "Yu", "黧" => "Li", "黨" => "Dang", "黩" => "Du", + "黪" => "Can", "黫" => "Yin", "黬" => "An", "é»­" => "Yan", "é»®" => "Tan", "黯" => "An", + "é»°" => "Zhen", "é»±" => "Dai", "黲" => "Can", "黳" => "Yi", "é»´" => "Mei", "黵" => "Dan", + "黶" => "Yan", "é»·" => "Du", "黸" => "Lu", "黹" => "Zhi", "黺" => "Fen", "é»»" => "Fu", + "黼" => "Fu", "黽" => "Min", "黾" => "Min", "黿" => "Yuan", "é¼" => "Qu", "鼂" => "Chao", + "鼃" => "Wa", "鼄" => "Zhu", "é¼…" => "Zhi", "鼆" => "Mang", "鼇" => "Ao", "鼈" => "Bie", + "鼉" => "Tuo", "鼊" => "Bi", "鼋" => "Yuan", "鼌" => "Chao", "é¼" => "Tuo", "鼎" => "Ding", + "é¼" => "Mi", "é¼" => "Nai", "鼑" => "Ding", "é¼’" => "Zi", "鼓" => "Gu", "é¼”" => "Gu", + "鼕" => "Dong", "é¼–" => "Fen", "é¼—" => "Tao", "鼘" => "Yuan", "é¼™" => "Pi", "鼚" => "Chang", + "é¼›" => "Gao", "鼜" => "Qi", "é¼" => "Yuan", "鼞" => "Tang", "鼟" => "Teng", "é¼ " => "Shu", + "鼡" => "Shu", "é¼¢" => "Fen", "é¼£" => "Fei", "鼤" => "Wen", "é¼¥" => "Ba", "鼦" => "Diao", + "鼧" => "Tuo", "鼨" => "Tong", "鼩" => "Qu", "鼪" => "Sheng", "鼫" => "Shi", "鼬" => "You", + "é¼­" => "Shi", "é¼®" => "Ting", "鼯" => "Wu", "é¼°" => "Nian", "é¼±" => "Jing", "é¼²" => "Hun", + "é¼³" => "Ju", "é¼´" => "Yan", "é¼µ" => "Tu", "鼶" => "Ti", "é¼·" => "Xi", "鼸" => "Xian", + "é¼¹" => "Yan", "鼺" => "Lei", "é¼»" => "Bi", "é¼¼" => "Yao", "é¼½" => "Qiu", "é¼¾" => "Han", + "鼿" => "Wu", "é½€" => "Wu", "é½" => "Hou", "齂" => "Xi", "齃" => "Ge", "齄" => "Zha", + "é½…" => "Xiu", "齆" => "Weng", "齇" => "Zha", "齈" => "Nong", "齉" => "Nang", "齊" => "Qi", + "齋" => "Zhai", "齌" => "Ji", "é½" => "Zi", "齎" => "Ji", "é½" => "Ji", "é½" => "Qi", + "齑" => "Ji", "é½’" => "Chi", "齓" => "Chen", "é½”" => "Chen", "齕" => "He", "é½–" => "Ya", + "é½—" => "Ken", "齘" => "Xie", "é½™" => "Pao", "齚" => "Cuo", "é½›" => "Shi", "齜" => "Zi", + "é½" => "Chi", "齞" => "Nian", "齟" => "Ju", "é½ " => "Tiao", "齡" => "Ling", "é½¢" => "Ling", + "é½£" => "Chu", "齤" => "Quan", "é½¥" => "Xie", "齦" => "Ken", "齧" => "Nie", "齨" => "Jiu", + "齩" => "Yao", "齪" => "Chuo", "齫" => "Kun", "齬" => "Yu", "é½­" => "Chu", "é½®" => "Yi", + "齯" => "Ni", "é½°" => "Cuo", "é½±" => "Zou", "é½²" => "Qu", "é½³" => "Nen", "é½´" => "Xian", + "é½µ" => "Ou", "齶" => "E", "é½·" => "Wo", "齸" => "Yi", "é½¹" => "Chuo", "齺" => "Zou", + "é½»" => "Dian", "é½¼" => "Chu", "é½½" => "Jin", "é½¾" => "Ya", "齿" => "Chi", "é¾€" => "Chen", + "é¾" => "He", "龂" => "Ken", "龃" => "Ju", "龄" => "Ling", "é¾…" => "Pao", "龆" => "Tiao", + "龇" => "Zi", "龈" => "Ken", "龉" => "Yu", "龊" => "Chuo", "龋" => "Qu", "龌" => "Wo", + "é¾" => "Long", "龎" => "Pang", "é¾" => "Gong", "é¾" => "Pang", "龑" => "Yan", "é¾’" => "Long", + "龓" => "Long", "é¾”" => "Gong", "龕" => "Kan", "é¾–" => "Ta", "é¾—" => "Ling", "龘" => "Ta", + "é¾™" => "Long", "龚" => "Gong", "é¾›" => "Kan", "龜" => "Gui", "é¾" => "Qiu", "龞" => "Bie", + "龟" => "Gui", "é¾ " => "Yue", "龡" => "Chui", "é¾¢" => "He", "é¾£" => "Jue", "龤" => "Xie", + "é¾¥" => "Yu", "ê€" => "ix", "ꀂ" => "i", "ꀃ" => "ip", "ꀄ" => "iet", "ꀅ" => "iex", + "ꀆ" => "ie", "ꀇ" => "iep", "ꀈ" => "at", "ꀉ" => "ax", "ꀊ" => "a", "ꀋ" => "ap", + "ꀌ" => "uox", "ê€" => "uo", "ꀎ" => "uop", "ê€" => "ot", "ê€" => "ox", "ꀑ" => "o", + "ꀒ" => "op", "ꀓ" => "ex", "ꀔ" => "e", "ꀕ" => "wu", "ꀖ" => "bit", "ꀗ" => "bix", + "ꀘ" => "bi", "ꀙ" => "bip", "ꀚ" => "biet", "ꀛ" => "biex", "ꀜ" => "bie", "ê€" => "biep", + "ꀞ" => "bat", "ꀟ" => "bax", "ꀠ" => "ba", "ꀡ" => "bap", "ꀢ" => "buox", "ꀣ" => "buo", + "ꀤ" => "buop", "ꀥ" => "bot", "ꀦ" => "box", "ꀧ" => "bo", "ꀨ" => "bop", "ꀩ" => "bex", + "ꀪ" => "be", "ꀫ" => "bep", "ꀬ" => "but", "ꀭ" => "bux", "ꀮ" => "bu", "ꀯ" => "bup", + "ꀰ" => "burx", "ꀱ" => "bur", "ꀲ" => "byt", "ꀳ" => "byx", "ꀴ" => "by", "ꀵ" => "byp", + "ꀶ" => "byrx", "ꀷ" => "byr", "ꀸ" => "pit", "ꀹ" => "pix", "ꀺ" => "pi", "ꀻ" => "pip", + "ꀼ" => "piex", "ꀽ" => "pie", "ꀾ" => "piep", "ꀿ" => "pat", "ê€" => "pax", "ê" => "pa", + "ê‚" => "pap", "êƒ" => "puox", "ê„" => "puo", "ê…" => "puop", "ê†" => "pot", "ê‡" => "pox", + "êˆ" => "po", "ê‰" => "pop", "êŠ" => "put", "ê‹" => "pux", "êŒ" => "pu", "ê" => "pup", + "êŽ" => "purx", "ê" => "pur", "ê" => "pyt", "ê‘" => "pyx", "ê’" => "py", "ê“" => "pyp", + "ê”" => "pyrx", "ê•" => "pyr", "ê–" => "bbit", "ê—" => "bbix", "ê˜" => "bbi", "ê™" => "bbip", + "êš" => "bbiet", "ê›" => "bbiex", "êœ" => "bbie", "ê" => "bbiep", "êž" => "bbat", "êŸ" => "bbax", + "ê " => "bba", "ê¡" => "bbap", "ê¢" => "bbuox", "ê£" => "bbuo", "ê¤" => "bbuop", "ê¥" => "bbot", + "ê¦" => "bbox", "ê§" => "bbo", "ê¨" => "bbop", "ê©" => "bbex", "êª" => "bbe", "ê«" => "bbep", + "ê¬" => "bbut", "ê­" => "bbux", "ê®" => "bbu", "ê¯" => "bbup", "ê°" => "bburx", "ê±" => "bbur", + "ê²" => "bbyt", "ê³" => "bbyx", "ê´" => "bby", "êµ" => "bbyp", "ê¶" => "nbit", "ê·" => "nbix", + "ê¸" => "nbi", "ê¹" => "nbip", "êº" => "nbiex", "ê»" => "nbie", "ê¼" => "nbiep", "ê½" => "nbat", + "ê¾" => "nbax", "ê¿" => "nba", "ê‚€" => "nbap", "ê‚" => "nbot", "ê‚‚" => "nbox", "ꂃ" => "nbo", + "ê‚„" => "nbop", "ê‚…" => "nbut", "ꂆ" => "nbux", "ꂇ" => "nbu", "ꂈ" => "nbup", "ꂉ" => "nburx", + "ê‚Š" => "nbur", "ê‚‹" => "nbyt", "ê‚Œ" => "nbyx", "ê‚" => "nby", "ê‚Ž" => "nbyp", "ê‚" => "nbyrx", + "ê‚" => "nbyr", "ê‚‘" => "hmit", "ê‚’" => "hmix", "ê‚“" => "hmi", "ê‚”" => "hmip", "ê‚•" => "hmiex", + "ê‚–" => "hmie", "ê‚—" => "hmiep", "ꂘ" => "hmat", "ê‚™" => "hmax", "ê‚š" => "hma", "ê‚›" => "hmap", + "ê‚œ" => "hmuox", "ê‚" => "hmuo", "ê‚ž" => "hmuop", "ê‚Ÿ" => "hmot", "ê‚ " => "hmox", "ê‚¡" => "hmo", + "ê‚¢" => "hmop", "ê‚£" => "hmut", "ꂤ" => "hmux", "ê‚¥" => "hmu", "ꂦ" => "hmup", "ꂧ" => "hmurx", + "ꂨ" => "hmur", "ê‚©" => "hmyx", "ꂪ" => "hmy", "ê‚«" => "hmyp", "ꂬ" => "hmyrx", "ê‚­" => "hmyr", + "ê‚®" => "mit", "ꂯ" => "mix", "ê‚°" => "mi", "ꂱ" => "mip", "ꂲ" => "miex", "ꂳ" => "mie", + "ê‚´" => "miep", "ꂵ" => "mat", "ꂶ" => "max", "ê‚·" => "ma", "ꂸ" => "map", "ꂹ" => "muot", + "ꂺ" => "muox", "ê‚»" => "muo", "ꂼ" => "muop", "ꂽ" => "mot", "ꂾ" => "mox", "ê‚¿" => "mo", + "ꃀ" => "mop", "êƒ" => "mex", "ꃂ" => "me", "ꃃ" => "mut", "ꃄ" => "mux", "ꃅ" => "mu", + "ꃆ" => "mup", "ꃇ" => "murx", "ꃈ" => "mur", "ꃉ" => "myt", "ꃊ" => "myx", "ꃋ" => "my", + "ꃌ" => "myp", "êƒ" => "fit", "ꃎ" => "fix", "êƒ" => "fi", "êƒ" => "fip", "ꃑ" => "fat", + "ꃒ" => "fax", "ꃓ" => "fa", "ꃔ" => "fap", "ꃕ" => "fox", "ꃖ" => "fo", "ꃗ" => "fop", + "ꃘ" => "fut", "ꃙ" => "fux", "ꃚ" => "fu", "ꃛ" => "fup", "ꃜ" => "furx", "êƒ" => "fur", + "ꃞ" => "fyt", "ꃟ" => "fyx", "ꃠ" => "fy", "ꃡ" => "fyp", "ꃢ" => "vit", "ꃣ" => "vix", + "ꃤ" => "vi", "ꃥ" => "vip", "ꃦ" => "viet", "ꃧ" => "viex", "ꃨ" => "vie", "ꃩ" => "viep", + "ꃪ" => "vat", "ꃫ" => "vax", "ꃬ" => "va", "ꃭ" => "vap", "ꃮ" => "vot", "ꃯ" => "vox", + "ꃰ" => "vo", "ꃱ" => "vop", "ꃲ" => "vex", "ꃳ" => "vep", "ꃴ" => "vut", "ꃵ" => "vux", + "ꃶ" => "vu", "ꃷ" => "vup", "ꃸ" => "vurx", "ꃹ" => "vur", "ꃺ" => "vyt", "ꃻ" => "vyx", + "ꃼ" => "vy", "ꃽ" => "vyp", "ꃾ" => "vyrx", "ꃿ" => "vyr", "ê„" => "dix", "ê„‚" => "di", + "ꄃ" => "dip", "ê„„" => "diex", "ê„…" => "die", "ꄆ" => "diep", "ꄇ" => "dat", "ꄈ" => "dax", + "ꄉ" => "da", "ê„Š" => "dap", "ê„‹" => "duox", "ê„Œ" => "duo", "ê„" => "dot", "ê„Ž" => "dox", + "ê„" => "do", "ê„" => "dop", "ê„‘" => "dex", "ê„’" => "de", "ê„“" => "dep", "ê„”" => "dut", + "ê„•" => "dux", "ê„–" => "du", "ê„—" => "dup", "ꄘ" => "durx", "ê„™" => "dur", "ê„š" => "tit", + "ê„›" => "tix", "ê„œ" => "ti", "ê„" => "tip", "ê„ž" => "tiex", "ê„Ÿ" => "tie", "ê„ " => "tiep", + "ê„¡" => "tat", "ê„¢" => "tax", "ê„£" => "ta", "ꄤ" => "tap", "ê„¥" => "tuot", "ꄦ" => "tuox", + "ꄧ" => "tuo", "ꄨ" => "tuop", "ê„©" => "tot", "ꄪ" => "tox", "ê„«" => "to", "ꄬ" => "top", + "ê„­" => "tex", "ê„®" => "te", "ꄯ" => "tep", "ê„°" => "tut", "ꄱ" => "tux", "ꄲ" => "tu", + "ꄳ" => "tup", "ê„´" => "turx", "ꄵ" => "tur", "ꄶ" => "ddit", "ê„·" => "ddix", "ꄸ" => "ddi", + "ꄹ" => "ddip", "ꄺ" => "ddiex", "ê„»" => "ddie", "ꄼ" => "ddiep", "ꄽ" => "ddat", "ꄾ" => "ddax", + "ê„¿" => "dda", "ê…€" => "ddap", "ê…" => "dduox", "ê…‚" => "dduo", "ê…ƒ" => "dduop", "ê…„" => "ddot", + "ê……" => "ddox", "ê…†" => "ddo", "ê…‡" => "ddop", "ê…ˆ" => "ddex", "ê…‰" => "dde", "ê…Š" => "ddep", + "ê…‹" => "ddut", "ê…Œ" => "ddux", "ê…" => "ddu", "ê…Ž" => "ddup", "ê…" => "ddurx", "ê…" => "ddur", + "ê…‘" => "ndit", "ê…’" => "ndix", "ê…“" => "ndi", "ê…”" => "ndip", "ê…•" => "ndiex", "ê…–" => "ndie", + "ê…—" => "ndat", "ê…˜" => "ndax", "ê…™" => "nda", "ê…š" => "ndap", "ê…›" => "ndot", "ê…œ" => "ndox", + "ê…" => "ndo", "ê…ž" => "ndop", "ê…Ÿ" => "ndex", "ê… " => "nde", "ê…¡" => "ndep", "ê…¢" => "ndut", + "ê…£" => "ndux", "ê…¤" => "ndu", "ê…¥" => "ndup", "ê…¦" => "ndurx", "ê…§" => "ndur", "ê…¨" => "hnit", + "ê…©" => "hnix", "ê…ª" => "hni", "ê…«" => "hnip", "ê…¬" => "hniet", "ê…­" => "hniex", "ê…®" => "hnie", + "ê…¯" => "hniep", "ê…°" => "hnat", "ê…±" => "hnax", "ê…²" => "hna", "ê…³" => "hnap", "ê…´" => "hnuox", + "ê…µ" => "hnuo", "ê…¶" => "hnot", "ê…·" => "hnox", "ê…¸" => "hnop", "ê…¹" => "hnex", "ê…º" => "hne", + "ê…»" => "hnep", "ê…¼" => "hnut", "ê…½" => "nit", "ê…¾" => "nix", "ê…¿" => "ni", "ꆀ" => "nip", + "ê†" => "niex", "ꆂ" => "nie", "ꆃ" => "niep", "ꆄ" => "nax", "ꆅ" => "na", "ꆆ" => "nap", + "ꆇ" => "nuox", "ꆈ" => "nuo", "ꆉ" => "nuop", "ꆊ" => "not", "ꆋ" => "nox", "ꆌ" => "no", + "ê†" => "nop", "ꆎ" => "nex", "ê†" => "ne", "ê†" => "nep", "ꆑ" => "nut", "ꆒ" => "nux", + "ꆓ" => "nu", "ꆔ" => "nup", "ꆕ" => "nurx", "ꆖ" => "nur", "ꆗ" => "hlit", "ꆘ" => "hlix", + "ꆙ" => "hli", "ꆚ" => "hlip", "ꆛ" => "hliex", "ꆜ" => "hlie", "ê†" => "hliep", "ꆞ" => "hlat", + "ꆟ" => "hlax", "ꆠ" => "hla", "ꆡ" => "hlap", "ꆢ" => "hluox", "ꆣ" => "hluo", "ꆤ" => "hluop", + "ꆥ" => "hlox", "ꆦ" => "hlo", "ꆧ" => "hlop", "ꆨ" => "hlex", "ꆩ" => "hle", "ꆪ" => "hlep", + "ꆫ" => "hlut", "ꆬ" => "hlux", "ꆭ" => "hlu", "ꆮ" => "hlup", "ꆯ" => "hlurx", "ꆰ" => "hlur", + "ꆱ" => "hlyt", "ꆲ" => "hlyx", "ꆳ" => "hly", "ꆴ" => "hlyp", "ꆵ" => "hlyrx", "ꆶ" => "hlyr", + "ꆷ" => "lit", "ꆸ" => "lix", "ꆹ" => "li", "ꆺ" => "lip", "ꆻ" => "liet", "ꆼ" => "liex", + "ꆽ" => "lie", "ꆾ" => "liep", "ꆿ" => "lat", "ꇀ" => "lax", "ê‡" => "la", "ꇂ" => "lap", + "ꇃ" => "luot", "ꇄ" => "luox", "ꇅ" => "luo", "ꇆ" => "luop", "ꇇ" => "lot", "ꇈ" => "lox", + "ꇉ" => "lo", "ꇊ" => "lop", "ꇋ" => "lex", "ꇌ" => "le", "ê‡" => "lep", "ꇎ" => "lut", + "ê‡" => "lux", "ê‡" => "lu", "ꇑ" => "lup", "ꇒ" => "lurx", "ꇓ" => "lur", "ꇔ" => "lyt", + "ꇕ" => "lyx", "ꇖ" => "ly", "ꇗ" => "lyp", "ꇘ" => "lyrx", "ꇙ" => "lyr", "ꇚ" => "git", + "ꇛ" => "gix", "ꇜ" => "gi", "ê‡" => "gip", "ꇞ" => "giet", "ꇟ" => "giex", "ꇠ" => "gie", + "ꇡ" => "giep", "ꇢ" => "gat", "ꇣ" => "gax", "ꇤ" => "ga", "ꇥ" => "gap", "ꇦ" => "guot", + "ꇧ" => "guox", "ꇨ" => "guo", "ꇩ" => "guop", "ꇪ" => "got", "ꇫ" => "gox", "ꇬ" => "go", + "ꇭ" => "gop", "ꇮ" => "get", "ꇯ" => "gex", "ꇰ" => "ge", "ꇱ" => "gep", "ꇲ" => "gut", + "ꇳ" => "gux", "ꇴ" => "gu", "ꇵ" => "gup", "ꇶ" => "gurx", "ꇷ" => "gur", "ꇸ" => "kit", + "ꇹ" => "kix", "ꇺ" => "ki", "ꇻ" => "kip", "ꇼ" => "kiex", "ꇽ" => "kie", "ꇾ" => "kiep", + "ꇿ" => "kat", "êˆ" => "ka", "ꈂ" => "kap", "ꈃ" => "kuox", "ꈄ" => "kuo", "ꈅ" => "kuop", + "ꈆ" => "kot", "ꈇ" => "kox", "ꈈ" => "ko", "ꈉ" => "kop", "ꈊ" => "ket", "ꈋ" => "kex", + "ꈌ" => "ke", "êˆ" => "kep", "ꈎ" => "kut", "êˆ" => "kux", "êˆ" => "ku", "ꈑ" => "kup", + "ꈒ" => "kurx", "ꈓ" => "kur", "ꈔ" => "ggit", "ꈕ" => "ggix", "ꈖ" => "ggi", "ꈗ" => "ggiex", + "ꈘ" => "ggie", "ꈙ" => "ggiep", "ꈚ" => "ggat", "ꈛ" => "ggax", "ꈜ" => "gga", "êˆ" => "ggap", + "ꈞ" => "gguot", "ꈟ" => "gguox", "ꈠ" => "gguo", "ꈡ" => "gguop", "ꈢ" => "ggot", "ꈣ" => "ggox", + "ꈤ" => "ggo", "ꈥ" => "ggop", "ꈦ" => "gget", "ꈧ" => "ggex", "ꈨ" => "gge", "ꈩ" => "ggep", + "ꈪ" => "ggut", "ꈫ" => "ggux", "ꈬ" => "ggu", "ꈭ" => "ggup", "ꈮ" => "ggurx", "ꈯ" => "ggur", + "ꈰ" => "mgiex", "ꈱ" => "mgie", "ꈲ" => "mgat", "ꈳ" => "mgax", "ꈴ" => "mga", "ꈵ" => "mgap", + "ꈶ" => "mguox", "ꈷ" => "mguo", "ꈸ" => "mguop", "ꈹ" => "mgot", "ꈺ" => "mgox", "ꈻ" => "mgo", + "ꈼ" => "mgop", "ꈽ" => "mgex", "ꈾ" => "mge", "ꈿ" => "mgep", "ꉀ" => "mgut", "ê‰" => "mgux", + "ꉂ" => "mgu", "ꉃ" => "mgup", "ꉄ" => "mgurx", "ꉅ" => "mgur", "ꉆ" => "hxit", "ꉇ" => "hxix", + "ꉈ" => "hxi", "ꉉ" => "hxip", "ꉊ" => "hxiet", "ꉋ" => "hxiex", "ꉌ" => "hxie", "ê‰" => "hxiep", + "ꉎ" => "hxat", "ê‰" => "hxax", "ê‰" => "hxa", "ꉑ" => "hxap", "ꉒ" => "hxuot", "ꉓ" => "hxuox", + "ꉔ" => "hxuo", "ꉕ" => "hxuop", "ꉖ" => "hxot", "ꉗ" => "hxox", "ꉘ" => "hxo", "ꉙ" => "hxop", + "ꉚ" => "hxex", "ꉛ" => "hxe", "ꉜ" => "hxep", "ê‰" => "ngiex", "ꉞ" => "ngie", "ꉟ" => "ngiep", + "ꉠ" => "ngat", "ꉡ" => "ngax", "ꉢ" => "nga", "ꉣ" => "ngap", "ꉤ" => "nguot", "ꉥ" => "nguox", + "ꉦ" => "nguo", "ꉧ" => "ngot", "ꉨ" => "ngox", "ꉩ" => "ngo", "ꉪ" => "ngop", "ꉫ" => "ngex", + "ꉬ" => "nge", "ꉭ" => "ngep", "ꉮ" => "hit", "ꉯ" => "hiex", "ꉰ" => "hie", "ꉱ" => "hat", + "ꉲ" => "hax", "ꉳ" => "ha", "ꉴ" => "hap", "ꉵ" => "huot", "ꉶ" => "huox", "ꉷ" => "huo", + "ꉸ" => "huop", "ꉹ" => "hot", "ꉺ" => "hox", "ꉻ" => "ho", "ꉼ" => "hop", "ꉽ" => "hex", + "ꉾ" => "he", "ꉿ" => "hep", "ꊀ" => "wat", "êŠ" => "wax", "ꊂ" => "wa", "ꊃ" => "wap", + "ꊄ" => "wuox", "ꊅ" => "wuo", "ꊆ" => "wuop", "ꊇ" => "wox", "ꊈ" => "wo", "ꊉ" => "wop", + "ꊊ" => "wex", "ꊋ" => "we", "ꊌ" => "wep", "êŠ" => "zit", "ꊎ" => "zix", "êŠ" => "zi", + "êŠ" => "zip", "ꊑ" => "ziex", "ꊒ" => "zie", "ꊓ" => "ziep", "ꊔ" => "zat", "ꊕ" => "zax", + "ꊖ" => "za", "ꊗ" => "zap", "ꊘ" => "zuox", "ꊙ" => "zuo", "ꊚ" => "zuop", "ꊛ" => "zot", + "ꊜ" => "zox", "êŠ" => "zo", "ꊞ" => "zop", "ꊟ" => "zex", "ꊠ" => "ze", "ꊡ" => "zep", + "ꊢ" => "zut", "ꊣ" => "zux", "ꊤ" => "zu", "ꊥ" => "zup", "ꊦ" => "zurx", "ꊧ" => "zur", + "ꊨ" => "zyt", "ꊩ" => "zyx", "ꊪ" => "zy", "ꊫ" => "zyp", "ꊬ" => "zyrx", "ꊭ" => "zyr", + "ꊮ" => "cit", "ꊯ" => "cix", "ꊰ" => "ci", "ꊱ" => "cip", "ꊲ" => "ciet", "ꊳ" => "ciex", + "ꊴ" => "cie", "ꊵ" => "ciep", "ꊶ" => "cat", "ꊷ" => "cax", "ꊸ" => "ca", "ꊹ" => "cap", + "ꊺ" => "cuox", "ꊻ" => "cuo", "ꊼ" => "cuop", "ꊽ" => "cot", "ꊾ" => "cox", "ꊿ" => "co", + "ê‹€" => "cop", "ê‹" => "cex", "ê‹‚" => "ce", "ꋃ" => "cep", "ê‹„" => "cut", "ê‹…" => "cux", + "ꋆ" => "cu", "ꋇ" => "cup", "ꋈ" => "curx", "ꋉ" => "cur", "ê‹Š" => "cyt", "ê‹‹" => "cyx", + "ê‹Œ" => "cy", "ê‹" => "cyp", "ê‹Ž" => "cyrx", "ê‹" => "cyr", "ê‹" => "zzit", "ê‹‘" => "zzix", + "ê‹’" => "zzi", "ê‹“" => "zzip", "ê‹”" => "zziet", "ê‹•" => "zziex", "ê‹–" => "zzie", "ê‹—" => "zziep", + "ꋘ" => "zzat", "ê‹™" => "zzax", "ê‹š" => "zza", "ê‹›" => "zzap", "ê‹œ" => "zzox", "ê‹" => "zzo", + "ê‹ž" => "zzop", "ê‹Ÿ" => "zzex", "ê‹ " => "zze", "ê‹¡" => "zzep", "ê‹¢" => "zzux", "ê‹£" => "zzu", + "ꋤ" => "zzup", "ê‹¥" => "zzurx", "ꋦ" => "zzur", "ꋧ" => "zzyt", "ꋨ" => "zzyx", "ê‹©" => "zzy", + "ꋪ" => "zzyp", "ê‹«" => "zzyrx", "ꋬ" => "zzyr", "ê‹­" => "nzit", "ê‹®" => "nzix", "ꋯ" => "nzi", + "ê‹°" => "nzip", "ꋱ" => "nziex", "ꋲ" => "nzie", "ꋳ" => "nziep", "ê‹´" => "nzat", "ꋵ" => "nzax", + "ꋶ" => "nza", "ê‹·" => "nzap", "ꋸ" => "nzuox", "ꋹ" => "nzuo", "ꋺ" => "nzox", "ê‹»" => "nzop", + "ꋼ" => "nzex", "ꋽ" => "nze", "ꋾ" => "nzux", "ê‹¿" => "nzu", "êŒ" => "nzurx", "ꌂ" => "nzur", + "ꌃ" => "nzyt", "ꌄ" => "nzyx", "ꌅ" => "nzy", "ꌆ" => "nzyp", "ꌇ" => "nzyrx", "ꌈ" => "nzyr", + "ꌉ" => "sit", "ꌊ" => "six", "ꌋ" => "si", "ꌌ" => "sip", "êŒ" => "siex", "ꌎ" => "sie", + "êŒ" => "siep", "êŒ" => "sat", "ꌑ" => "sax", "ꌒ" => "sa", "ꌓ" => "sap", "ꌔ" => "suox", + "ꌕ" => "suo", "ꌖ" => "suop", "ꌗ" => "sot", "ꌘ" => "sox", "ꌙ" => "so", "ꌚ" => "sop", + "ꌛ" => "sex", "ꌜ" => "se", "êŒ" => "sep", "ꌞ" => "sut", "ꌟ" => "sux", "ꌠ" => "su", + "ꌡ" => "sup", "ꌢ" => "surx", "ꌣ" => "sur", "ꌤ" => "syt", "ꌥ" => "syx", "ꌦ" => "sy", + "ꌧ" => "syp", "ꌨ" => "syrx", "ꌩ" => "syr", "ꌪ" => "ssit", "ꌫ" => "ssix", "ꌬ" => "ssi", + "ꌭ" => "ssip", "ꌮ" => "ssiex", "ꌯ" => "ssie", "ꌰ" => "ssiep", "ꌱ" => "ssat", "ꌲ" => "ssax", + "ꌳ" => "ssa", "ꌴ" => "ssap", "ꌵ" => "ssot", "ꌶ" => "ssox", "ꌷ" => "sso", "ꌸ" => "ssop", + "ꌹ" => "ssex", "ꌺ" => "sse", "ꌻ" => "ssep", "ꌼ" => "ssut", "ꌽ" => "ssux", "ꌾ" => "ssu", + "ꌿ" => "ssup", "ê€" => "ssyt", "ê" => "ssyx", "ê‚" => "ssy", "êƒ" => "ssyp", "ê„" => "ssyrx", + "ê…" => "ssyr", "ê†" => "zhat", "ê‡" => "zhax", "êˆ" => "zha", "ê‰" => "zhap", "êŠ" => "zhuox", + "ê‹" => "zhuo", "êŒ" => "zhuop", "ê" => "zhot", "êŽ" => "zhox", "ê" => "zho", "ê" => "zhop", + "ê‘" => "zhet", "ê’" => "zhex", "ê“" => "zhe", "ê”" => "zhep", "ê•" => "zhut", "ê–" => "zhux", + "ê—" => "zhu", "ê˜" => "zhup", "ê™" => "zhurx", "êš" => "zhur", "ê›" => "zhyt", "êœ" => "zhyx", + "ê" => "zhy", "êž" => "zhyp", "êŸ" => "zhyrx", "ê " => "zhyr", "ê¡" => "chat", "ê¢" => "chax", + "ê£" => "cha", "ê¤" => "chap", "ê¥" => "chuot", "ê¦" => "chuox", "ê§" => "chuo", "ê¨" => "chuop", + "ê©" => "chot", "êª" => "chox", "ê«" => "cho", "ê¬" => "chop", "ê­" => "chet", "ê®" => "chex", + "ê¯" => "che", "ê°" => "chep", "ê±" => "chux", "ê²" => "chu", "ê³" => "chup", "ê´" => "churx", + "êµ" => "chur", "ê¶" => "chyt", "ê·" => "chyx", "ê¸" => "chy", "ê¹" => "chyp", "êº" => "chyrx", + "ê»" => "chyr", "ê¼" => "rrax", "ê½" => "rra", "ê¾" => "rruox", "ê¿" => "rruo", "ꎀ" => "rrot", + "êŽ" => "rrox", "ꎂ" => "rro", "ꎃ" => "rrop", "ꎄ" => "rret", "ꎅ" => "rrex", "ꎆ" => "rre", + "ꎇ" => "rrep", "ꎈ" => "rrut", "ꎉ" => "rrux", "ꎊ" => "rru", "ꎋ" => "rrup", "ꎌ" => "rrurx", + "êŽ" => "rrur", "ꎎ" => "rryt", "êŽ" => "rryx", "êŽ" => "rry", "ꎑ" => "rryp", "ꎒ" => "rryrx", + "ꎓ" => "rryr", "ꎔ" => "nrat", "ꎕ" => "nrax", "ꎖ" => "nra", "ꎗ" => "nrap", "ꎘ" => "nrox", + "ꎙ" => "nro", "ꎚ" => "nrop", "ꎛ" => "nret", "ꎜ" => "nrex", "êŽ" => "nre", "ꎞ" => "nrep", + "ꎟ" => "nrut", "ꎠ" => "nrux", "ꎡ" => "nru", "ꎢ" => "nrup", "ꎣ" => "nrurx", "ꎤ" => "nrur", + "ꎥ" => "nryt", "ꎦ" => "nryx", "ꎧ" => "nry", "ꎨ" => "nryp", "ꎩ" => "nryrx", "ꎪ" => "nryr", + "ꎫ" => "shat", "ꎬ" => "shax", "ꎭ" => "sha", "ꎮ" => "shap", "ꎯ" => "shuox", "ꎰ" => "shuo", + "ꎱ" => "shuop", "ꎲ" => "shot", "ꎳ" => "shox", "ꎴ" => "sho", "ꎵ" => "shop", "ꎶ" => "shet", + "ꎷ" => "shex", "ꎸ" => "she", "ꎹ" => "shep", "ꎺ" => "shut", "ꎻ" => "shux", "ꎼ" => "shu", + "ꎽ" => "shup", "ꎾ" => "shurx", "ꎿ" => "shur", "ê€" => "shyt", "ê" => "shyx", "ê‚" => "shy", + "êƒ" => "shyp", "ê„" => "shyrx", "ê…" => "shyr", "ê†" => "rat", "ê‡" => "rax", "êˆ" => "ra", + "ê‰" => "rap", "êŠ" => "ruox", "ê‹" => "ruo", "êŒ" => "ruop", "ê" => "rot", "êŽ" => "rox", + "ê" => "ro", "ê" => "rop", "ê‘" => "rex", "ê’" => "re", "ê“" => "rep", "ê”" => "rut", + "ê•" => "rux", "ê–" => "ru", "ê—" => "rup", "ê˜" => "rurx", "ê™" => "rur", "êš" => "ryt", + "ê›" => "ryx", "êœ" => "ry", "ê" => "ryp", "êž" => "ryrx", "êŸ" => "ryr", "ê " => "jit", + "ê¡" => "jix", "ê¢" => "ji", "ê£" => "jip", "ê¤" => "jiet", "ê¥" => "jiex", "ê¦" => "jie", + "ê§" => "jiep", "ê¨" => "juot", "ê©" => "juox", "êª" => "juo", "ê«" => "juop", "ê¬" => "jot", + "ê­" => "jox", "ê®" => "jo", "ê¯" => "jop", "ê°" => "jut", "ê±" => "jux", "ê²" => "ju", + "ê³" => "jup", "ê´" => "jurx", "êµ" => "jur", "ê¶" => "jyt", "ê·" => "jyx", "ê¸" => "jy", + "ê¹" => "jyp", "êº" => "jyrx", "ê»" => "jyr", "ê¼" => "qit", "ê½" => "qix", "ê¾" => "qi", + "ê¿" => "qip", "ê" => "qiex", "ê‚" => "qie", "êƒ" => "qiep", "ê„" => "quot", "ê…" => "quox", + "ê†" => "quo", "ê‡" => "quop", "êˆ" => "qot", "ê‰" => "qox", "êŠ" => "qo", "ê‹" => "qop", + "êŒ" => "qut", "ê" => "qux", "êŽ" => "qu", "ê" => "qup", "ê" => "qurx", "ê‘" => "qur", + "ê’" => "qyt", "ê“" => "qyx", "ê”" => "qy", "ê•" => "qyp", "ê–" => "qyrx", "ê—" => "qyr", + "ê˜" => "jjit", "ê™" => "jjix", "êš" => "jji", "ê›" => "jjip", "êœ" => "jjiet", "ê" => "jjiex", + "êž" => "jjie", "êŸ" => "jjiep", "ê " => "jjuox", "ê¡" => "jjuo", "ê¢" => "jjuop", "ê£" => "jjot", + "ê¤" => "jjox", "ê¥" => "jjo", "ê¦" => "jjop", "ê§" => "jjut", "ê¨" => "jjux", "ê©" => "jju", + "êª" => "jjup", "ê«" => "jjurx", "ê¬" => "jjur", "ê­" => "jjyt", "ê®" => "jjyx", "ê¯" => "jjy", + "ê°" => "jjyp", "ê±" => "njit", "ê²" => "njix", "ê³" => "nji", "ê´" => "njip", "êµ" => "njiet", + "ê¶" => "njiex", "ê·" => "njie", "ê¸" => "njiep", "ê¹" => "njuox", "êº" => "njuo", "ê»" => "njot", + "ê¼" => "njox", "ê½" => "njo", "ê¾" => "njop", "ê¿" => "njux", "ê‘€" => "nju", "ê‘" => "njup", + "ê‘‚" => "njurx", "ꑃ" => "njur", "ê‘„" => "njyt", "ê‘…" => "njyx", "ꑆ" => "njy", "ꑇ" => "njyp", + "ꑈ" => "njyrx", "ꑉ" => "njyr", "ê‘Š" => "nyit", "ê‘‹" => "nyix", "ê‘Œ" => "nyi", "ê‘" => "nyip", + "ê‘Ž" => "nyiet", "ê‘" => "nyiex", "ê‘" => "nyie", "ê‘‘" => "nyiep", "ê‘’" => "nyuox", "ê‘“" => "nyuo", + "ê‘”" => "nyuop", "ê‘•" => "nyot", "ê‘–" => "nyox", "ê‘—" => "nyo", "ꑘ" => "nyop", "ê‘™" => "nyut", + "ê‘š" => "nyux", "ê‘›" => "nyu", "ê‘œ" => "nyup", "ê‘" => "xit", "ê‘ž" => "xix", "ê‘Ÿ" => "xi", + "ê‘ " => "xip", "ê‘¡" => "xiet", "ê‘¢" => "xiex", "ê‘£" => "xie", "ꑤ" => "xiep", "ê‘¥" => "xuox", + "ꑦ" => "xuo", "ꑧ" => "xot", "ꑨ" => "xox", "ê‘©" => "xo", "ꑪ" => "xop", "ê‘«" => "xyt", + "ꑬ" => "xyx", "ê‘­" => "xy", "ê‘®" => "xyp", "ꑯ" => "xyrx", "ê‘°" => "xyr", "ꑱ" => "yit", + "ꑲ" => "yix", "ꑳ" => "yi", "ê‘´" => "yip", "ꑵ" => "yiet", "ꑶ" => "yiex", "ê‘·" => "yie", + "ꑸ" => "yiep", "ꑹ" => "yuot", "ꑺ" => "yuox", "ê‘»" => "yuo", "ꑼ" => "yuop", "ꑽ" => "yot", + "ꑾ" => "yox", "ê‘¿" => "yo", "ê’€" => "yop", "ê’" => "yut", "ê’‚" => "yux", "ê’ƒ" => "yu", + "ê’„" => "yup", "ê’…" => "yurx", "ê’†" => "yur", "ê’‡" => "yyt", "ê’ˆ" => "yyx", "ê’‰" => "yy", + "ê’Š" => "yyp", "ê’‹" => "yyrx", "ê’Œ" => "yyr", "ê’" => "Qot", "ê’‘" => "Li", "ê’’" => "Kit", + "ê’“" => "Nyip", "ê’”" => "Cyp", "ê’•" => "Ssi", "ê’–" => "Ggop", "ê’—" => "Gep", "ê’˜" => "Mi", + "ê’™" => "Hxit", "ê’š" => "Lyr", "ê’›" => "Bbut", "ê’œ" => "Mop", "ê’" => "Yo", "ê’ž" => "Put", + "ê’Ÿ" => "Hxuo", "ê’ " => "Tat", "ê’¡" => "Ga", "ê’¤" => "Ddur", "ê’¥" => "Bur", "ê’¦" => "Gguo", + "ê’§" => "Nyop", "ê’¨" => "Tu", "ê’©" => "Op", "ê’ª" => "Jjut", "ê’«" => "Zot", "ê’¬" => "Pyt", + "ê’­" => "Hmo", "ê’®" => "Yit", "ê’¯" => "Vur", "ê’°" => "Shy", "ê’±" => "Vep", "ê’²" => "Za", + "ê’³" => "Jo", "ê’µ" => "Jjy", "ê’¶" => "Got", "ê’·" => "Jjie", "ê’¸" => "Wo", "ê’¹" => "Du", + "ê’º" => "Shur", "ê’»" => "Lie", "ê’¼" => "Cy", "ê’½" => "Cuop", "ê’¾" => "Cip", "ê’¿" => "Hxop", + "ê“€" => "Shat", "ê“‚" => "Shop", "꓃" => "Che", "ê“„" => "Zziet", "꓆" => "Ke", "ê°" => "gag", + "ê°‚" => "gagg", "ê°ƒ" => "gags", "ê°„" => "gan", "ê°…" => "ganj", "ê°†" => "ganh", "ê°‡" => "gad", + "ê°ˆ" => "gal", "ê°‰" => "galg", "ê°Š" => "galm", "ê°‹" => "galb", "ê°Œ" => "gals", "ê°" => "galt", + "ê°Ž" => "galp", "ê°" => "galh", "ê°" => "gam", "ê°‘" => "gab", "ê°’" => "gabs", "ê°“" => "gas", + "ê°”" => "gass", "ê°•" => "gang", "ê°–" => "gaj", "ê°—" => "gac", "ê°˜" => "gak", "ê°™" => "gat", + "ê°š" => "gap", "ê°›" => "gah", "ê°œ" => "gae", "ê°" => "gaeg", "ê°ž" => "gaegg", "ê°Ÿ" => "gaegs", + "ê° " => "gaen", "ê°¡" => "gaenj", "ê°¢" => "gaenh", "ê°£" => "gaed", "ê°¤" => "gael", "ê°¥" => "gaelg", + "ê°¦" => "gaelm", "ê°§" => "gaelb", "ê°¨" => "gaels", "ê°©" => "gaelt", "ê°ª" => "gaelp", "ê°«" => "gaelh", + "ê°¬" => "gaem", "ê°­" => "gaeb", "ê°®" => "gaebs", "ê°¯" => "gaes", "ê°°" => "gaess", "ê°±" => "gaeng", + "ê°²" => "gaej", "ê°³" => "gaec", "ê°´" => "gaek", "ê°µ" => "gaet", "ê°¶" => "gaep", "ê°·" => "gaeh", + "ê°¸" => "gya", "ê°¹" => "gyag", "ê°º" => "gyagg", "ê°»" => "gyags", "ê°¼" => "gyan", "ê°½" => "gyanj", + "ê°¾" => "gyanh", "ê°¿" => "gyad", "ê±€" => "gyal", "ê±" => "gyalg", "걂" => "gyalm", "걃" => "gyalb", + "걄" => "gyals", "ê±…" => "gyalt", "걆" => "gyalp", "걇" => "gyalh", "걈" => "gyam", "걉" => "gyab", + "걊" => "gyabs", "걋" => "gyas", "걌" => "gyass", "ê±" => "gyang", "걎" => "gyaj", "ê±" => "gyac", + "ê±" => "gyak", "걑" => "gyat", "ê±’" => "gyap", "걓" => "gyah", "ê±”" => "gyae", "걕" => "gyaeg", + "ê±–" => "gyaegg", "ê±—" => "gyaegs", "걘" => "gyaen", "ê±™" => "gyaenj", "걚" => "gyaenh", "ê±›" => "gyaed", + "걜" => "gyael", "ê±" => "gyaelg", "걞" => "gyaelm", "걟" => "gyaelb", "ê± " => "gyaels", "걡" => "gyaelt", + "ê±¢" => "gyaelp", "ê±£" => "gyaelh", "걤" => "gyaem", "ê±¥" => "gyaeb", "걦" => "gyaebs", "걧" => "gyaes", + "걨" => "gyaess", "걩" => "gyaeng", "걪" => "gyaej", "걫" => "gyaec", "걬" => "gyaek", "ê±­" => "gyaet", + "ê±®" => "gyaep", "걯" => "gyaeh", "ê±°" => "geo", "ê±±" => "geog", "ê±²" => "geogg", "ê±³" => "geogs", + "ê±´" => "geon", "ê±µ" => "geonj", "걶" => "geonh", "ê±·" => "geod", "걸" => "geol", "ê±¹" => "geolg", + "걺" => "geolm", "ê±»" => "geolb", "ê±¼" => "geols", "ê±½" => "geolt", "ê±¾" => "geolp", "걿" => "geolh", + "ê²€" => "geom", "ê²" => "geob", "겂" => "geobs", "것" => "geos", "겄" => "geoss", "ê²…" => "geong", + "겆" => "geoj", "겇" => "geoc", "겈" => "geok", "겉" => "geot", "겊" => "geop", "겋" => "geoh", + "게" => "ge", "ê²" => "geg", "겎" => "gegg", "ê²" => "gegs", "ê²" => "gen", "겑" => "genj", + "ê²’" => "genh", "겓" => "ged", "ê²”" => "gel", "겕" => "gelg", "ê²–" => "gelm", "ê²—" => "gelb", + "겘" => "gels", "ê²™" => "gelt", "겚" => "gelp", "ê²›" => "gelh", "겜" => "gem", "ê²" => "geb", + "겞" => "gebs", "겟" => "ges", "ê² " => "gess", "겡" => "geng", "ê²¢" => "gej", "ê²£" => "gec", + "겤" => "gek", "ê²¥" => "get", "겦" => "gep", "겧" => "geh", "겨" => "gyeo", "격" => "gyeog", + "겪" => "gyeogg", "겫" => "gyeogs", "견" => "gyeon", "ê²­" => "gyeonj", "ê²®" => "gyeonh", "겯" => "gyeod", + "ê²°" => "gyeol", "ê²±" => "gyeolg", "ê²²" => "gyeolm", "ê²³" => "gyeolb", "ê²´" => "gyeols", "ê²µ" => "gyeolt", + "겶" => "gyeolp", "ê²·" => "gyeolh", "겸" => "gyeom", "ê²¹" => "gyeob", "겺" => "gyeobs", "ê²»" => "gyeos", + "ê²¼" => "gyeoss", "ê²½" => "gyeong", "ê²¾" => "gyeoj", "겿" => "gyeoc", "ê³€" => "gyeok", "ê³" => "gyeot", + "곂" => "gyeop", "곃" => "gyeoh", "계" => "gye", "ê³…" => "gyeg", "곆" => "gyegg", "곇" => "gyegs", + "곈" => "gyen", "곉" => "gyenj", "곊" => "gyenh", "곋" => "gyed", "곌" => "gyel", "ê³" => "gyelg", + "곎" => "gyelm", "ê³" => "gyelb", "ê³" => "gyels", "곑" => "gyelt", "ê³’" => "gyelp", "곓" => "gyelh", + "ê³”" => "gyem", "곕" => "gyeb", "ê³–" => "gyebs", "ê³—" => "gyes", "곘" => "gyess", "ê³™" => "gyeng", + "곚" => "gyej", "ê³›" => "gyec", "곜" => "gyek", "ê³" => "gyet", "곞" => "gyep", "곟" => "gyeh", + "ê³ " => "go", "곡" => "gog", "ê³¢" => "gogg", "ê³£" => "gogs", "곤" => "gon", "ê³¥" => "gonj", + "곦" => "gonh", "곧" => "god", "골" => "gol", "곩" => "golg", "곪" => "golm", "곫" => "golb", + "곬" => "gols", "ê³­" => "golt", "ê³®" => "golp", "곯" => "golh", "ê³°" => "gom", "ê³±" => "gob", + "ê³²" => "gobs", "ê³³" => "gos", "ê³´" => "goss", "ê³µ" => "gong", "곶" => "goj", "ê³·" => "goc", + "곸" => "gok", "ê³¹" => "got", "곺" => "gop", "ê³»" => "goh", "ê³¼" => "gwa", "ê³½" => "gwag", + "ê³¾" => "gwagg", "곿" => "gwags", "ê´" => "gwanj", "ê´‚" => "gwanh", "ê´ƒ" => "gwad", "ê´„" => "gwal", + "ê´…" => "gwalg", "ê´†" => "gwalm", "ê´‡" => "gwalb", "ê´ˆ" => "gwals", "ê´‰" => "gwalt", "ê´Š" => "gwalp", + "ê´‹" => "gwalh", "ê´Œ" => "gwam", "ê´" => "gwab", "ê´Ž" => "gwabs", "ê´" => "gwas", "ê´" => "gwass", + "ê´‘" => "gwang", "ê´’" => "gwaj", "ê´“" => "gwac", "ê´”" => "gwak", "ê´•" => "gwat", "ê´–" => "gwap", + "ê´—" => "gwah", "ê´˜" => "gwae", "ê´™" => "gwaeg", "ê´š" => "gwaegg", "ê´›" => "gwaegs", "ê´œ" => "gwaen", + "ê´" => "gwaenj", "ê´ž" => "gwaenh", "ê´Ÿ" => "gwaed", "ê´ " => "gwael", "ê´¡" => "gwaelg", "ê´¢" => "gwaelm", + "ê´£" => "gwaelb", "ê´¤" => "gwaels", "ê´¥" => "gwaelt", "ê´¦" => "gwaelp", "ê´§" => "gwaelh", "ê´¨" => "gwaem", + "ê´©" => "gwaeb", "ê´ª" => "gwaebs", "ê´«" => "gwaes", "ê´¬" => "gwaess", "ê´­" => "gwaeng", "ê´®" => "gwaej", + "ê´¯" => "gwaec", "ê´°" => "gwaek", "ê´±" => "gwaet", "ê´²" => "gwaep", "ê´³" => "gwaeh", "ê´´" => "goe", + "ê´µ" => "goeg", "ê´¶" => "goegg", "ê´·" => "goegs", "ê´¸" => "goen", "ê´¹" => "goenj", "ê´º" => "goenh", + "ê´»" => "goed", "ê´¼" => "goel", "ê´½" => "goelg", "ê´¾" => "goelm", "ê´¿" => "goelb", "êµ€" => "goels", + "êµ" => "goelt", "굂" => "goelp", "굃" => "goelh", "굄" => "goem", "êµ…" => "goeb", "굆" => "goebs", + "굇" => "goes", "굈" => "goess", "굉" => "goeng", "굊" => "goej", "굋" => "goec", "굌" => "goek", + "êµ" => "goet", "굎" => "goep", "êµ" => "goeh", "êµ" => "gyo", "굑" => "gyog", "êµ’" => "gyogg", + "굓" => "gyogs", "êµ”" => "gyon", "굕" => "gyonj", "êµ–" => "gyonh", "êµ—" => "gyod", "굘" => "gyol", + "êµ™" => "gyolg", "굚" => "gyolm", "êµ›" => "gyolb", "굜" => "gyols", "êµ" => "gyolt", "굞" => "gyolp", + "굟" => "gyolh", "êµ " => "gyom", "굡" => "gyob", "êµ¢" => "gyobs", "êµ£" => "gyos", "굤" => "gyoss", + "êµ¥" => "gyong", "굦" => "gyoj", "굧" => "gyoc", "굨" => "gyok", "굩" => "gyot", "굪" => "gyop", + "굫" => "gyoh", "구" => "gu", "êµ­" => "gug", "êµ®" => "gugg", "굯" => "gugs", "êµ°" => "gun", + "êµ±" => "gunj", "êµ²" => "gunh", "êµ³" => "gud", "êµ´" => "gul", "êµµ" => "gulg", "굶" => "gulm", + "êµ·" => "gulb", "굸" => "guls", "êµ¹" => "gult", "굺" => "gulp", "êµ»" => "gulh", "êµ¼" => "gum", + "êµ½" => "gub", "êµ¾" => "gubs", "굿" => "gus", "궀" => "guss", "ê¶" => "gung", "궂" => "guj", + "궃" => "guc", "궄" => "guk", "궅" => "gut", "궆" => "gup", "궇" => "guh", "궈" => "gweo", + "궉" => "gweog", "궊" => "gweogg", "궋" => "gweogs", "권" => "gweon", "ê¶" => "gweonj", "궎" => "gweonh", + "ê¶" => "gweod", "ê¶" => "gweol", "궑" => "gweolg", "궒" => "gweolm", "궓" => "gweolb", "궔" => "gweols", + "궕" => "gweolt", "궖" => "gweolp", "궗" => "gweolh", "궘" => "gweom", "궙" => "gweob", "궚" => "gweobs", + "궛" => "gweos", "궜" => "gweoss", "ê¶" => "gweong", "궞" => "gweoj", "궟" => "gweoc", "궠" => "gweok", + "궡" => "gweot", "궢" => "gweop", "궣" => "gweoh", "궤" => "gwe", "궥" => "gweg", "궦" => "gwegg", + "궧" => "gwegs", "궨" => "gwen", "궩" => "gwenj", "궪" => "gwenh", "궫" => "gwed", "궬" => "gwel", + "궭" => "gwelg", "궮" => "gwelm", "궯" => "gwelb", "궰" => "gwels", "궱" => "gwelt", "궲" => "gwelp", + "궳" => "gwelh", "궴" => "gwem", "궵" => "gweb", "궶" => "gwebs", "궷" => "gwes", "궸" => "gwess", + "궹" => "gweng", "궺" => "gwej", "궻" => "gwec", "궼" => "gwek", "궽" => "gwet", "궾" => "gwep", + "궿" => "gweh", "ê·€" => "gwi", "ê·" => "gwig", "ê·‚" => "gwigg", "ê·ƒ" => "gwigs", "ê·„" => "gwin", + "ê·…" => "gwinj", "ê·†" => "gwinh", "ê·‡" => "gwid", "ê·ˆ" => "gwil", "ê·‰" => "gwilg", "ê·Š" => "gwilm", + "ê·‹" => "gwilb", "ê·Œ" => "gwils", "ê·" => "gwilt", "ê·Ž" => "gwilp", "ê·" => "gwilh", "ê·" => "gwim", + "ê·‘" => "gwib", "ê·’" => "gwibs", "ê·“" => "gwis", "ê·”" => "gwiss", "ê·•" => "gwing", "ê·–" => "gwij", + "ê·—" => "gwic", "ê·˜" => "gwik", "ê·™" => "gwit", "ê·š" => "gwip", "ê·›" => "gwih", "ê·œ" => "gyu", + "ê·" => "gyug", "ê·ž" => "gyugg", "ê·Ÿ" => "gyugs", "ê· " => "gyun", "ê·¡" => "gyunj", "ê·¢" => "gyunh", + "ê·£" => "gyud", "ê·¤" => "gyul", "ê·¥" => "gyulg", "ê·¦" => "gyulm", "ê·§" => "gyulb", "ê·¨" => "gyuls", + "ê·©" => "gyult", "ê·ª" => "gyulp", "ê·«" => "gyulh", "ê·¬" => "gyum", "ê·­" => "gyub", "ê·®" => "gyubs", + "ê·¯" => "gyus", "ê·°" => "gyuss", "ê·±" => "gyung", "ê·²" => "gyuj", "ê·³" => "gyuc", "ê·´" => "gyuk", + "ê·µ" => "gyut", "ê·¶" => "gyup", "ê··" => "gyuh", "ê·¸" => "geu", "ê·¹" => "geug", "ê·º" => "geugg", + "ê·»" => "geugs", "ê·¼" => "geun", "ê·½" => "geunj", "ê·¾" => "geunh", "ê·¿" => "geud", "ê¸" => "geulg", + "긂" => "geulm", "긃" => "geulb", "긄" => "geuls", "긅" => "geult", "긆" => "geulp", "긇" => "geulh", + "금" => "geum", "급" => "geub", "긊" => "geubs", "긋" => "geus", "긌" => "geuss", "ê¸" => "geung", + "긎" => "geuj", "ê¸" => "geuc", "ê¸" => "geuk", "긑" => "geut", "긒" => "geup", "긓" => "geuh", + "긔" => "gyi", "긕" => "gyig", "긖" => "gyigg", "긗" => "gyigs", "긘" => "gyin", "긙" => "gyinj", + "긚" => "gyinh", "긛" => "gyid", "긜" => "gyil", "ê¸" => "gyilg", "긞" => "gyilm", "긟" => "gyilb", + "긠" => "gyils", "긡" => "gyilt", "긢" => "gyilp", "긣" => "gyilh", "긤" => "gyim", "긥" => "gyib", + "긦" => "gyibs", "긧" => "gyis", "긨" => "gyiss", "긩" => "gying", "긪" => "gyij", "긫" => "gyic", + "긬" => "gyik", "긭" => "gyit", "긮" => "gyip", "긯" => "gyih", "기" => "gi", "긱" => "gig", + "긲" => "gigg", "긳" => "gigs", "긴" => "gin", "긵" => "ginj", "긶" => "ginh", "긷" => "gid", + "길" => "gil", "긹" => "gilg", "긺" => "gilm", "긻" => "gilb", "긼" => "gils", "긽" => "gilt", + "긾" => "gilp", "긿" => "gilh", "ê¹€" => "gim", "ê¹" => "gib", "깂" => "gibs", "깃" => "gis", + "깄" => "giss", "ê¹…" => "ging", "깆" => "gij", "깇" => "gic", "깈" => "gik", "깉" => "git", + "깊" => "gip", "깋" => "gih", "까" => "gga", "ê¹" => "ggag", "깎" => "ggagg", "ê¹" => "ggags", + "ê¹" => "ggan", "깑" => "gganj", "ê¹’" => "gganh", "깓" => "ggad", "ê¹”" => "ggal", "깕" => "ggalg", + "ê¹–" => "ggalm", "ê¹—" => "ggalb", "깘" => "ggals", "ê¹™" => "ggalt", "깚" => "ggalp", "ê¹›" => "ggalh", + "깜" => "ggam", "ê¹" => "ggab", "깞" => "ggabs", "깟" => "ggas", "ê¹ " => "ggass", "깡" => "ggang", + "ê¹¢" => "ggaj", "ê¹£" => "ggac", "깤" => "ggak", "ê¹¥" => "ggat", "깦" => "ggap", "깧" => "ggah", + "깨" => "ggae", "깩" => "ggaeg", "깪" => "ggaegg", "깫" => "ggaegs", "깬" => "ggaen", "ê¹­" => "ggaenj", + "ê¹®" => "ggaenh", "깯" => "ggaed", "ê¹°" => "ggael", "ê¹±" => "ggaelg", "ê¹²" => "ggaelm", "ê¹³" => "ggaelb", + "ê¹´" => "ggaels", "ê¹µ" => "ggaelt", "깶" => "ggaelp", "ê¹·" => "ggaelh", "깸" => "ggaem", "ê¹¹" => "ggaeb", + "깺" => "ggaebs", "ê¹»" => "ggaes", "ê¹¼" => "ggaess", "ê¹½" => "ggaeng", "ê¹¾" => "ggaej", "깿" => "ggaec", + "꺀" => "ggaek", "êº" => "ggaet", "꺂" => "ggaep", "꺃" => "ggaeh", "꺄" => "ggya", "꺅" => "ggyag", + "꺆" => "ggyagg", "꺇" => "ggyags", "꺈" => "ggyan", "꺉" => "ggyanj", "꺊" => "ggyanh", "꺋" => "ggyad", + "꺌" => "ggyal", "êº" => "ggyalg", "꺎" => "ggyalm", "êº" => "ggyalb", "êº" => "ggyals", "꺑" => "ggyalt", + "꺒" => "ggyalp", "꺓" => "ggyalh", "꺔" => "ggyam", "꺕" => "ggyab", "꺖" => "ggyabs", "꺗" => "ggyas", + "꺘" => "ggyass", "꺙" => "ggyang", "꺚" => "ggyaj", "꺛" => "ggyac", "꺜" => "ggyak", "êº" => "ggyat", + "꺞" => "ggyap", "꺟" => "ggyah", "꺠" => "ggyae", "꺡" => "ggyaeg", "꺢" => "ggyaegg", "꺣" => "ggyaegs", + "꺤" => "ggyaen", "꺥" => "ggyaenj", "꺦" => "ggyaenh", "꺧" => "ggyaed", "꺨" => "ggyael", "꺩" => "ggyaelg", + "꺪" => "ggyaelm", "꺫" => "ggyaelb", "꺬" => "ggyaels", "꺭" => "ggyaelt", "꺮" => "ggyaelp", "꺯" => "ggyaelh", + "꺰" => "ggyaem", "꺱" => "ggyaeb", "꺲" => "ggyaebs", "꺳" => "ggyaes", "꺴" => "ggyaess", "꺵" => "ggyaeng", + "꺶" => "ggyaej", "꺷" => "ggyaec", "꺸" => "ggyaek", "꺹" => "ggyaet", "꺺" => "ggyaep", "꺻" => "ggyaeh", + "꺼" => "ggeo", "꺽" => "ggeog", "꺾" => "ggeogg", "꺿" => "ggeogs", "껀" => "ggeon", "ê»" => "ggeonj", + "껂" => "ggeonh", "껃" => "ggeod", "껄" => "ggeol", "ê»…" => "ggeolg", "껆" => "ggeolm", "껇" => "ggeolb", + "껈" => "ggeols", "껉" => "ggeolt", "껊" => "ggeolp", "껋" => "ggeolh", "껌" => "ggeom", "ê»" => "ggeob", + "껎" => "ggeobs", "ê»" => "ggeos", "ê»" => "ggeoss", "껑" => "ggeong", "ê»’" => "ggeoj", "껓" => "ggeoc", + "ê»”" => "ggeok", "껕" => "ggeot", "ê»–" => "ggeop", "ê»—" => "ggeoh", "께" => "gge", "ê»™" => "ggeg", + "껚" => "ggegg", "ê»›" => "ggegs", "껜" => "ggen", "ê»" => "ggenj", "껞" => "ggenh", "껟" => "gged", + "ê» " => "ggel", "껡" => "ggelg", "껢" => "ggelm", "껣" => "ggelb", "껤" => "ggels", "껥" => "ggelt", + "껦" => "ggelp", "껧" => "ggelh", "껨" => "ggem", "껩" => "ggeb", "껪" => "ggebs", "껫" => "gges", + "껬" => "ggess", "ê»­" => "ggeng", "ê»®" => "ggej", "껯" => "ggec", "ê»°" => "ggek", "ê»±" => "gget", + "껲" => "ggep", "껳" => "ggeh", "ê»´" => "ggyeo", "껵" => "ggyeog", "껶" => "ggyeogg", "ê»·" => "ggyeogs", + "껸" => "ggyeon", "껹" => "ggyeonj", "껺" => "ggyeonh", "ê»»" => "ggyeod", "껼" => "ggyeol", "껽" => "ggyeolg", + "껾" => "ggyeolm", "껿" => "ggyeolb", "ê¼" => "ggyeolt", "꼂" => "ggyeolp", "꼃" => "ggyeolh", "꼄" => "ggyeom", + "ê¼…" => "ggyeob", "꼆" => "ggyeobs", "꼇" => "ggyeos", "꼈" => "ggyeoss", "꼉" => "ggyeong", "꼊" => "ggyeoj", + "꼋" => "ggyeoc", "꼌" => "ggyeok", "ê¼" => "ggyeot", "꼎" => "ggyeop", "ê¼" => "ggyeoh", "ê¼" => "ggye", + "꼑" => "ggyeg", "ê¼’" => "ggyegg", "꼓" => "ggyegs", "ê¼”" => "ggyen", "꼕" => "ggyenj", "ê¼–" => "ggyenh", + "ê¼—" => "ggyed", "꼘" => "ggyel", "ê¼™" => "ggyelg", "꼚" => "ggyelm", "ê¼›" => "ggyelb", "꼜" => "ggyels", + "ê¼" => "ggyelt", "꼞" => "ggyelp", "꼟" => "ggyelh", "ê¼ " => "ggyem", "꼡" => "ggyeb", "ê¼¢" => "ggyebs", + "ê¼£" => "ggyes", "꼤" => "ggyess", "ê¼¥" => "ggyeng", "꼦" => "ggyej", "꼧" => "ggyec", "꼨" => "ggyek", + "꼩" => "ggyet", "꼪" => "ggyep", "꼫" => "ggyeh", "꼬" => "ggo", "ê¼­" => "ggog", "ê¼®" => "ggogg", + "꼯" => "ggogs", "ê¼°" => "ggon", "ê¼±" => "ggonj", "ê¼²" => "ggonh", "ê¼³" => "ggod", "ê¼´" => "ggol", + "ê¼µ" => "ggolg", "꼶" => "ggolm", "ê¼·" => "ggolb", "꼸" => "ggols", "ê¼¹" => "ggolt", "꼺" => "ggolp", + "ê¼»" => "ggolh", "ê¼¼" => "ggom", "ê¼½" => "ggob", "ê¼¾" => "ggobs", "꼿" => "ggos", "ê½€" => "ggoss", + "ê½" => "ggong", "꽂" => "ggoj", "꽃" => "ggoc", "꽄" => "ggok", "ê½…" => "ggot", "꽆" => "ggop", + "꽇" => "ggoh", "꽈" => "ggwa", "꽉" => "ggwag", "꽊" => "ggwagg", "꽋" => "ggwags", "꽌" => "ggwan", + "ê½" => "ggwanj", "꽎" => "ggwanh", "ê½" => "ggwad", "ê½" => "ggwal", "꽑" => "ggwalg", "ê½’" => "ggwalm", + "꽓" => "ggwalb", "ê½”" => "ggwals", "꽕" => "ggwalt", "ê½–" => "ggwalp", "ê½—" => "ggwalh", "꽘" => "ggwam", + "ê½™" => "ggwab", "꽚" => "ggwabs", "ê½›" => "ggwas", "꽜" => "ggwass", "ê½" => "ggwang", "꽞" => "ggwaj", + "꽟" => "ggwac", "ê½ " => "ggwak", "꽡" => "ggwat", "ê½¢" => "ggwap", "ê½£" => "ggwah", "꽤" => "ggwae", + "ê½¥" => "ggwaeg", "꽦" => "ggwaegg", "꽧" => "ggwaegs", "꽨" => "ggwaen", "꽩" => "ggwaenj", "꽪" => "ggwaenh", + "꽫" => "ggwaed", "꽬" => "ggwael", "ê½­" => "ggwaelg", "ê½®" => "ggwaelm", "꽯" => "ggwaelb", "ê½°" => "ggwaels", + "ê½±" => "ggwaelt", "ê½²" => "ggwaelp", "ê½³" => "ggwaelh", "ê½´" => "ggwaem", "ê½µ" => "ggwaeb", "꽶" => "ggwaebs", + "ê½·" => "ggwaes", "꽸" => "ggwaess", "ê½¹" => "ggwaeng", "꽺" => "ggwaej", "ê½»" => "ggwaec", "ê½¼" => "ggwaek", + "ê½½" => "ggwaet", "ê½¾" => "ggwaep", "꽿" => "ggwaeh", "ê¾€" => "ggoe", "ê¾" => "ggoeg", "꾂" => "ggoegg", + "꾃" => "ggoegs", "꾄" => "ggoen", "ê¾…" => "ggoenj", "꾆" => "ggoenh", "꾇" => "ggoed", "꾈" => "ggoel", + "꾉" => "ggoelg", "꾊" => "ggoelm", "꾋" => "ggoelb", "꾌" => "ggoels", "ê¾" => "ggoelt", "꾎" => "ggoelp", + "ê¾" => "ggoelh", "ê¾" => "ggoem", "꾑" => "ggoeb", "ê¾’" => "ggoebs", "꾓" => "ggoes", "ê¾”" => "ggoess", + "꾕" => "ggoeng", "ê¾–" => "ggoej", "ê¾—" => "ggoec", "꾘" => "ggoek", "ê¾™" => "ggoet", "꾚" => "ggoep", + "ê¾›" => "ggoeh", "꾜" => "ggyo", "ê¾" => "ggyog", "꾞" => "ggyogg", "꾟" => "ggyogs", "ê¾ " => "ggyon", + "꾡" => "ggyonj", "ê¾¢" => "ggyonh", "ê¾£" => "ggyod", "꾤" => "ggyol", "ê¾¥" => "ggyolg", "꾦" => "ggyolm", + "꾧" => "ggyolb", "꾨" => "ggyols", "꾩" => "ggyolt", "꾪" => "ggyolp", "꾫" => "ggyolh", "꾬" => "ggyom", + "ê¾­" => "ggyob", "ê¾®" => "ggyobs", "꾯" => "ggyos", "ê¾°" => "ggyoss", "ê¾±" => "ggyong", "ê¾²" => "ggyoj", + "ê¾³" => "ggyoc", "ê¾´" => "ggyok", "ê¾µ" => "ggyot", "꾶" => "ggyop", "ê¾·" => "ggyoh", "꾸" => "ggu", + "ê¾¹" => "ggug", "꾺" => "ggugg", "ê¾»" => "ggugs", "ê¾¼" => "ggun", "ê¾½" => "ggunj", "ê¾¾" => "ggunh", + "꾿" => "ggud", "ê¿€" => "ggul", "ê¿" => "ggulg", "ê¿‚" => "ggulm", "꿃" => "ggulb", "ê¿„" => "gguls", + "ê¿…" => "ggult", "꿆" => "ggulp", "꿇" => "ggulh", "꿈" => "ggum", "꿉" => "ggub", "ê¿Š" => "ggubs", + "ê¿‹" => "ggus", "ê¿Œ" => "gguss", "ê¿" => "ggung", "ê¿Ž" => "gguj", "ê¿" => "gguc", "ê¿" => "gguk", + "ê¿‘" => "ggut", "ê¿’" => "ggup", "ê¿“" => "gguh", "ê¿”" => "ggweo", "ê¿•" => "ggweog", "ê¿–" => "ggweogg", + "ê¿—" => "ggweogs", "꿘" => "ggweon", "ê¿™" => "ggweonj", "ê¿š" => "ggweonh", "ê¿›" => "ggweod", "ê¿œ" => "ggweol", + "ê¿" => "ggweolg", "ê¿ž" => "ggweolm", "ê¿Ÿ" => "ggweolb", "ê¿ " => "ggweols", "ê¿¡" => "ggweolt", "ê¿¢" => "ggweolp", + "ê¿£" => "ggweolh", "꿤" => "ggweom", "ê¿¥" => "ggweob", "꿦" => "ggweobs", "꿧" => "ggweos", "꿨" => "ggweoss", + "ê¿©" => "ggweong", "꿪" => "ggweoj", "ê¿«" => "ggweoc", "꿬" => "ggweok", "ê¿­" => "ggweot", "ê¿®" => "ggweop", + "꿯" => "ggweoh", "ê¿°" => "ggwe", "꿱" => "ggweg", "꿲" => "ggwegg", "꿳" => "ggwegs", "ê¿´" => "ggwen", + "꿵" => "ggwenj", "꿶" => "ggwenh", "ê¿·" => "ggwed", "꿸" => "ggwel", "꿹" => "ggwelg", "꿺" => "ggwelm", + "ê¿»" => "ggwelb", "꿼" => "ggwels", "꿽" => "ggwelt", "꿾" => "ggwelp", "ê¿¿" => "ggwelh", "ë€" => "ggweb", + "뀂" => "ggwebs", "뀃" => "ggwes", "뀄" => "ggwess", "뀅" => "ggweng", "뀆" => "ggwej", "뀇" => "ggwec", + "뀈" => "ggwek", "뀉" => "ggwet", "뀊" => "ggwep", "뀋" => "ggweh", "뀌" => "ggwi", "ë€" => "ggwig", + "뀎" => "ggwigg", "ë€" => "ggwigs", "ë€" => "ggwin", "뀑" => "ggwinj", "뀒" => "ggwinh", "뀓" => "ggwid", + "뀔" => "ggwil", "뀕" => "ggwilg", "뀖" => "ggwilm", "뀗" => "ggwilb", "뀘" => "ggwils", "뀙" => "ggwilt", + "뀚" => "ggwilp", "뀛" => "ggwilh", "뀜" => "ggwim", "ë€" => "ggwib", "뀞" => "ggwibs", "뀟" => "ggwis", + "뀠" => "ggwiss", "뀡" => "ggwing", "뀢" => "ggwij", "뀣" => "ggwic", "뀤" => "ggwik", "뀥" => "ggwit", + "뀦" => "ggwip", "뀧" => "ggwih", "뀨" => "ggyu", "뀩" => "ggyug", "뀪" => "ggyugg", "뀫" => "ggyugs", + "뀬" => "ggyun", "뀭" => "ggyunj", "뀮" => "ggyunh", "뀯" => "ggyud", "뀰" => "ggyul", "뀱" => "ggyulg", + "뀲" => "ggyulm", "뀳" => "ggyulb", "뀴" => "ggyuls", "뀵" => "ggyult", "뀶" => "ggyulp", "뀷" => "ggyulh", + "뀸" => "ggyum", "뀹" => "ggyub", "뀺" => "ggyubs", "뀻" => "ggyus", "뀼" => "ggyuss", "뀽" => "ggyung", + "뀾" => "ggyuj", "뀿" => "ggyuc", "ë€" => "ggyuk", "ë" => "ggyut", "ë‚" => "ggyup", "ëƒ" => "ggyuh", + "ë„" => "ggeu", "ë…" => "ggeug", "ë†" => "ggeugg", "ë‡" => "ggeugs", "ëˆ" => "ggeun", "ë‰" => "ggeunj", + "ëŠ" => "ggeunh", "ë‹" => "ggeud", "ëŒ" => "ggeul", "ë" => "ggeulg", "ëŽ" => "ggeulm", "ë" => "ggeulb", + "ë" => "ggeuls", "ë‘" => "ggeult", "ë’" => "ggeulp", "ë“" => "ggeulh", "ë”" => "ggeum", "ë•" => "ggeub", + "ë–" => "ggeubs", "ë—" => "ggeus", "ë˜" => "ggeuss", "ë™" => "ggeung", "ëš" => "ggeuj", "ë›" => "ggeuc", + "ëœ" => "ggeuk", "ë" => "ggeut", "ëž" => "ggeup", "ëŸ" => "ggeuh", "ë " => "ggyi", "ë¡" => "ggyig", + "ë¢" => "ggyigg", "ë£" => "ggyigs", "ë¤" => "ggyin", "ë¥" => "ggyinj", "ë¦" => "ggyinh", "ë§" => "ggyid", + "ë¨" => "ggyil", "ë©" => "ggyilg", "ëª" => "ggyilm", "ë«" => "ggyilb", "ë¬" => "ggyils", "ë­" => "ggyilt", + "ë®" => "ggyilp", "ë¯" => "ggyilh", "ë°" => "ggyim", "ë±" => "ggyib", "ë²" => "ggyibs", "ë³" => "ggyis", + "ë´" => "ggyiss", "ëµ" => "ggying", "ë¶" => "ggyij", "ë·" => "ggyic", "ë¸" => "ggyik", "ë¹" => "ggyit", + "ëº" => "ggyip", "ë»" => "ggyih", "ë¼" => "ggi", "ë½" => "ggig", "ë¾" => "ggigg", "ë¿" => "ggigs", + "ë‚€" => "ggin", "ë‚" => "gginj", "ë‚‚" => "gginh", "낃" => "ggid", "ë‚„" => "ggil", "ë‚…" => "ggilg", + "낆" => "ggilm", "낇" => "ggilb", "낈" => "ggils", "낉" => "ggilt", "ë‚Š" => "ggilp", "ë‚‹" => "ggilh", + "ë‚Œ" => "ggim", "ë‚" => "ggib", "ë‚Ž" => "ggibs", "ë‚" => "ggis", "ë‚" => "ggiss", "ë‚‘" => "gging", + "ë‚’" => "ggij", "ë‚“" => "ggic", "ë‚”" => "ggik", "ë‚•" => "ggit", "ë‚–" => "ggip", "ë‚—" => "ggih", + "나" => "na", "ë‚™" => "nag", "ë‚š" => "nagg", "ë‚›" => "nags", "ë‚œ" => "nan", "ë‚" => "nanj", + "ë‚ž" => "nanh", "ë‚Ÿ" => "nad", "ë‚ " => "nal", "ë‚¡" => "nalg", "ë‚¢" => "nalm", "ë‚£" => "nalb", + "낤" => "nals", "ë‚¥" => "nalt", "낦" => "nalp", "낧" => "nalh", "남" => "nam", "ë‚©" => "nab", + "낪" => "nabs", "ë‚«" => "nas", "났" => "nass", "ë‚­" => "nang", "ë‚®" => "naj", "낯" => "nac", + "ë‚°" => "nak", "낱" => "nat", "낲" => "nap", "낳" => "nah", "ë‚´" => "nae", "낵" => "naeg", + "낶" => "naegg", "ë‚·" => "naegs", "낸" => "naen", "낹" => "naenj", "낺" => "naenh", "ë‚»" => "naed", + "낼" => "nael", "낽" => "naelg", "낾" => "naelm", "ë‚¿" => "naelb", "냀" => "naels", "ëƒ" => "naelt", + "냂" => "naelp", "냃" => "naelh", "냄" => "naem", "냅" => "naeb", "냆" => "naebs", "냇" => "naes", + "냈" => "naess", "냉" => "naeng", "냊" => "naej", "냋" => "naec", "냌" => "naek", "ëƒ" => "naet", + "냎" => "naep", "ëƒ" => "naeh", "ëƒ" => "nya", "냑" => "nyag", "냒" => "nyagg", "냓" => "nyags", + "냔" => "nyan", "냕" => "nyanj", "냖" => "nyanh", "냗" => "nyad", "냘" => "nyal", "냙" => "nyalg", + "냚" => "nyalm", "냛" => "nyalb", "냜" => "nyals", "ëƒ" => "nyalt", "냞" => "nyalp", "냟" => "nyalh", + "냠" => "nyam", "냡" => "nyab", "냢" => "nyabs", "냣" => "nyas", "냤" => "nyass", "냥" => "nyang", + "냦" => "nyaj", "냧" => "nyac", "냨" => "nyak", "냩" => "nyat", "냪" => "nyap", "냫" => "nyah", + "냬" => "nyae", "냭" => "nyaeg", "냮" => "nyaegg", "냯" => "nyaegs", "냰" => "nyaen", "냱" => "nyaenj", + "냲" => "nyaenh", "냳" => "nyaed", "냴" => "nyael", "냵" => "nyaelg", "냶" => "nyaelm", "냷" => "nyaelb", + "냸" => "nyaels", "냹" => "nyaelt", "냺" => "nyaelp", "냻" => "nyaelh", "냼" => "nyaem", "냽" => "nyaeb", + "냾" => "nyaebs", "냿" => "nyaes", "ë„" => "nyaeng", "ë„‚" => "nyaej", "넃" => "nyaec", "ë„„" => "nyaek", + "ë„…" => "nyaet", "넆" => "nyaep", "넇" => "nyaeh", "너" => "neo", "넉" => "neog", "ë„Š" => "neogg", + "ë„‹" => "neogs", "ë„Œ" => "neon", "ë„" => "neonj", "ë„Ž" => "neonh", "ë„" => "neod", "ë„" => "neol", + "ë„‘" => "neolg", "ë„’" => "neolm", "ë„“" => "neolb", "ë„”" => "neols", "ë„•" => "neolt", "ë„–" => "neolp", + "ë„—" => "neolh", "넘" => "neom", "ë„™" => "neob", "ë„š" => "neobs", "ë„›" => "neos", "ë„œ" => "neoss", + "ë„" => "neong", "ë„ž" => "neoj", "ë„Ÿ" => "neoc", "ë„ " => "neok", "ë„¡" => "neot", "ë„¢" => "neop", + "ë„£" => "neoh", "네" => "ne", "ë„¥" => "neg", "넦" => "negg", "넧" => "negs", "넨" => "nen", + "ë„©" => "nenj", "넪" => "nenh", "ë„«" => "ned", "넬" => "nel", "ë„­" => "nelg", "ë„®" => "nelm", + "넯" => "nelb", "ë„°" => "nels", "넱" => "nelt", "넲" => "nelp", "넳" => "nelh", "ë„´" => "nem", + "넵" => "neb", "넶" => "nebs", "ë„·" => "nes", "넸" => "ness", "넹" => "neng", "넺" => "nej", + "ë„»" => "nec", "넼" => "nek", "넽" => "net", "넾" => "nep", "ë„¿" => "neh", "ë…€" => "nyeo", + "ë…" => "nyeog", "ë…‚" => "nyeogg", "ë…ƒ" => "nyeogs", "ë…„" => "nyeon", "ë……" => "nyeonj", "ë…†" => "nyeonh", + "ë…‡" => "nyeod", "ë…ˆ" => "nyeol", "ë…‰" => "nyeolg", "ë…Š" => "nyeolm", "ë…‹" => "nyeolb", "ë…Œ" => "nyeols", + "ë…" => "nyeolt", "ë…Ž" => "nyeolp", "ë…" => "nyeolh", "ë…" => "nyeom", "ë…‘" => "nyeob", "ë…’" => "nyeobs", + "ë…“" => "nyeos", "ë…”" => "nyeoss", "ë…•" => "nyeong", "ë…–" => "nyeoj", "ë…—" => "nyeoc", "ë…˜" => "nyeok", + "ë…™" => "nyeot", "ë…š" => "nyeop", "ë…›" => "nyeoh", "ë…œ" => "nye", "ë…" => "nyeg", "ë…ž" => "nyegg", + "ë…Ÿ" => "nyegs", "ë… " => "nyen", "ë…¡" => "nyenj", "ë…¢" => "nyenh", "ë…£" => "nyed", "ë…¤" => "nyel", + "ë…¥" => "nyelg", "ë…¦" => "nyelm", "ë…§" => "nyelb", "ë…¨" => "nyels", "ë…©" => "nyelt", "ë…ª" => "nyelp", + "ë…«" => "nyelh", "ë…¬" => "nyem", "ë…­" => "nyeb", "ë…®" => "nyebs", "ë…¯" => "nyes", "ë…°" => "nyess", + "ë…±" => "nyeng", "ë…²" => "nyej", "ë…³" => "nyec", "ë…´" => "nyek", "ë…µ" => "nyet", "ë…¶" => "nyep", + "ë…·" => "nyeh", "ë…¸" => "no", "ë…¹" => "nog", "ë…º" => "nogg", "ë…»" => "nogs", "ë…¼" => "non", + "ë…½" => "nonj", "ë…¾" => "nonh", "ë…¿" => "nod", "놀" => "nol", "ë†" => "nolg", "놂" => "nolm", + "놃" => "nolb", "놄" => "nols", "놅" => "nolt", "놆" => "nolp", "놇" => "nolh", "놈" => "nom", + "놉" => "nob", "놊" => "nobs", "놋" => "nos", "놌" => "noss", "ë†" => "nong", "놎" => "noj", + "ë†" => "noc", "ë†" => "nok", "놑" => "not", "높" => "nop", "놓" => "noh", "놔" => "nwa", + "놕" => "nwag", "놖" => "nwagg", "놗" => "nwags", "놘" => "nwan", "놙" => "nwanj", "놚" => "nwanh", + "놛" => "nwad", "놜" => "nwal", "ë†" => "nwalg", "놞" => "nwalm", "놟" => "nwalb", "놠" => "nwals", + "놡" => "nwalt", "놢" => "nwalp", "놣" => "nwalh", "놤" => "nwam", "놥" => "nwab", "놦" => "nwabs", + "놧" => "nwas", "놨" => "nwass", "놩" => "nwang", "놪" => "nwaj", "놫" => "nwac", "놬" => "nwak", + "놭" => "nwat", "놮" => "nwap", "놯" => "nwah", "놰" => "nwae", "놱" => "nwaeg", "놲" => "nwaegg", + "놳" => "nwaegs", "놴" => "nwaen", "놵" => "nwaenj", "놶" => "nwaenh", "놷" => "nwaed", "놸" => "nwael", + "놹" => "nwaelg", "놺" => "nwaelm", "놻" => "nwaelb", "놼" => "nwaels", "놽" => "nwaelt", "놾" => "nwaelp", + "놿" => "nwaelh", "뇀" => "nwaem", "ë‡" => "nwaeb", "뇂" => "nwaebs", "뇃" => "nwaes", "뇄" => "nwaess", + "뇅" => "nwaeng", "뇆" => "nwaej", "뇇" => "nwaec", "뇈" => "nwaek", "뇉" => "nwaet", "뇊" => "nwaep", + "뇋" => "nwaeh", "뇌" => "noe", "ë‡" => "noeg", "뇎" => "noegg", "ë‡" => "noegs", "ë‡" => "noen", + "뇑" => "noenj", "뇒" => "noenh", "뇓" => "noed", "뇔" => "noel", "뇕" => "noelg", "뇖" => "noelm", + "뇗" => "noelb", "뇘" => "noels", "뇙" => "noelt", "뇚" => "noelp", "뇛" => "noelh", "뇜" => "noem", + "ë‡" => "noeb", "뇞" => "noebs", "뇟" => "noes", "뇠" => "noess", "뇡" => "noeng", "뇢" => "noej", + "뇣" => "noec", "뇤" => "noek", "뇥" => "noet", "뇦" => "noep", "뇧" => "noeh", "뇨" => "nyo", + "뇩" => "nyog", "뇪" => "nyogg", "뇫" => "nyogs", "뇬" => "nyon", "뇭" => "nyonj", "뇮" => "nyonh", + "뇯" => "nyod", "뇰" => "nyol", "뇱" => "nyolg", "뇲" => "nyolm", "뇳" => "nyolb", "뇴" => "nyols", + "뇵" => "nyolt", "뇶" => "nyolp", "뇷" => "nyolh", "뇸" => "nyom", "뇹" => "nyob", "뇺" => "nyobs", + "뇻" => "nyos", "뇼" => "nyoss", "뇽" => "nyong", "뇾" => "nyoj", "뇿" => "nyoc", "ëˆ" => "nyot", + "눂" => "nyop", "눃" => "nyoh", "누" => "nu", "눅" => "nug", "눆" => "nugg", "눇" => "nugs", + "눈" => "nun", "눉" => "nunj", "눊" => "nunh", "눋" => "nud", "눌" => "nul", "ëˆ" => "nulg", + "눎" => "nulm", "ëˆ" => "nulb", "ëˆ" => "nuls", "눑" => "nult", "눒" => "nulp", "눓" => "nulh", + "눔" => "num", "눕" => "nub", "눖" => "nubs", "눗" => "nus", "눘" => "nuss", "눙" => "nung", + "눚" => "nuj", "눛" => "nuc", "눜" => "nuk", "ëˆ" => "nut", "눞" => "nup", "눟" => "nuh", + "눠" => "nweo", "눡" => "nweog", "눢" => "nweogg", "눣" => "nweogs", "눤" => "nweon", "눥" => "nweonj", + "눦" => "nweonh", "눧" => "nweod", "눨" => "nweol", "눩" => "nweolg", "눪" => "nweolm", "눫" => "nweolb", + "눬" => "nweols", "눭" => "nweolt", "눮" => "nweolp", "눯" => "nweolh", "눰" => "nweom", "눱" => "nweob", + "눲" => "nweobs", "눳" => "nweos", "눴" => "nweoss", "눵" => "nweong", "눶" => "nweoj", "눷" => "nweoc", + "눸" => "nweok", "눹" => "nweot", "눺" => "nweop", "눻" => "nweoh", "눼" => "nwe", "눽" => "nweg", + "눾" => "nwegg", "눿" => "nwegs", "뉀" => "nwen", "ë‰" => "nwenj", "뉂" => "nwenh", "뉃" => "nwed", + "뉄" => "nwel", "뉅" => "nwelg", "뉆" => "nwelm", "뉇" => "nwelb", "뉈" => "nwels", "뉉" => "nwelt", + "뉊" => "nwelp", "뉋" => "nwelh", "뉌" => "nwem", "ë‰" => "nweb", "뉎" => "nwebs", "ë‰" => "nwes", + "ë‰" => "nwess", "뉑" => "nweng", "뉒" => "nwej", "뉓" => "nwec", "뉔" => "nwek", "뉕" => "nwet", + "뉖" => "nwep", "뉗" => "nweh", "뉘" => "nwi", "뉙" => "nwig", "뉚" => "nwigg", "뉛" => "nwigs", + "뉜" => "nwin", "ë‰" => "nwinj", "뉞" => "nwinh", "뉟" => "nwid", "뉠" => "nwil", "뉡" => "nwilg", + "뉢" => "nwilm", "뉣" => "nwilb", "뉤" => "nwils", "뉥" => "nwilt", "뉦" => "nwilp", "뉧" => "nwilh", + "뉨" => "nwim", "뉩" => "nwib", "뉪" => "nwibs", "뉫" => "nwis", "뉬" => "nwiss", "뉭" => "nwing", + "뉮" => "nwij", "뉯" => "nwic", "뉰" => "nwik", "뉱" => "nwit", "뉲" => "nwip", "뉳" => "nwih", + "뉴" => "nyu", "뉵" => "nyug", "뉶" => "nyugg", "뉷" => "nyugs", "뉸" => "nyun", "뉹" => "nyunj", + "뉺" => "nyunh", "뉻" => "nyud", "뉼" => "nyul", "뉽" => "nyulg", "뉾" => "nyulm", "뉿" => "nyulb", + "늀" => "nyuls", "ëŠ" => "nyult", "늂" => "nyulp", "늃" => "nyulh", "늄" => "nyum", "늅" => "nyub", + "늆" => "nyubs", "늇" => "nyus", "늈" => "nyuss", "늉" => "nyung", "늊" => "nyuj", "늋" => "nyuc", + "늌" => "nyuk", "ëŠ" => "nyut", "늎" => "nyup", "ëŠ" => "nyuh", "ëŠ" => "neu", "늑" => "neug", + "늒" => "neugg", "늓" => "neugs", "는" => "neun", "늕" => "neunj", "늖" => "neunh", "늗" => "neud", + "늘" => "neul", "늙" => "neulg", "늚" => "neulm", "늛" => "neulb", "늜" => "neuls", "ëŠ" => "neult", + "늞" => "neulp", "늟" => "neulh", "늠" => "neum", "늡" => "neub", "늢" => "neubs", "늣" => "neus", + "늤" => "neuss", "능" => "neung", "늦" => "neuj", "늧" => "neuc", "늨" => "neuk", "늩" => "neut", + "늪" => "neup", "늫" => "neuh", "늬" => "nyi", "늭" => "nyig", "늮" => "nyigg", "늯" => "nyigs", + "늰" => "nyin", "늱" => "nyinj", "늲" => "nyinh", "늳" => "nyid", "늴" => "nyil", "늵" => "nyilg", + "늶" => "nyilm", "늷" => "nyilb", "늸" => "nyils", "늹" => "nyilt", "늺" => "nyilp", "늻" => "nyilh", + "늼" => "nyim", "늽" => "nyib", "늾" => "nyibs", "늿" => "nyis", "ë‹€" => "nyiss", "ë‹" => "nying", + "ë‹‚" => "nyij", "닃" => "nyic", "ë‹„" => "nyik", "ë‹…" => "nyit", "닆" => "nyip", "닇" => "nyih", + "니" => "ni", "닉" => "nig", "ë‹Š" => "nigg", "ë‹‹" => "nigs", "ë‹Œ" => "nin", "ë‹" => "ninj", + "ë‹Ž" => "ninh", "ë‹" => "nid", "ë‹" => "nil", "ë‹‘" => "nilg", "ë‹’" => "nilm", "ë‹“" => "nilb", + "ë‹”" => "nils", "ë‹•" => "nilt", "ë‹–" => "nilp", "ë‹—" => "nilh", "님" => "nim", "ë‹™" => "nib", + "ë‹š" => "nibs", "ë‹›" => "nis", "ë‹œ" => "niss", "ë‹" => "ning", "ë‹ž" => "nij", "ë‹Ÿ" => "nic", + "ë‹ " => "nik", "ë‹¡" => "nit", "ë‹¢" => "nip", "ë‹£" => "nih", "다" => "da", "ë‹¥" => "dag", + "닦" => "dagg", "닧" => "dags", "단" => "dan", "ë‹©" => "danj", "닪" => "danh", "ë‹«" => "dad", + "달" => "dal", "ë‹­" => "dalg", "ë‹®" => "dalm", "닯" => "dalb", "ë‹°" => "dals", "닱" => "dalt", + "닲" => "dalp", "닳" => "dalh", "ë‹´" => "dam", "답" => "dab", "닶" => "dabs", "ë‹·" => "das", + "닸" => "dass", "당" => "dang", "닺" => "daj", "ë‹»" => "dac", "닼" => "dak", "닽" => "dat", + "닾" => "dap", "ë‹¿" => "dah", "ëŒ" => "daeg", "댂" => "daegg", "댃" => "daegs", "댄" => "daen", + "댅" => "daenj", "댆" => "daenh", "댇" => "daed", "댈" => "dael", "댉" => "daelg", "댊" => "daelm", + "댋" => "daelb", "댌" => "daels", "ëŒ" => "daelt", "댎" => "daelp", "ëŒ" => "daelh", "ëŒ" => "daem", + "댑" => "daeb", "댒" => "daebs", "댓" => "daes", "댔" => "daess", "댕" => "daeng", "댖" => "daej", + "댗" => "daec", "댘" => "daek", "댙" => "daet", "댚" => "daep", "댛" => "daeh", "댜" => "dya", + "ëŒ" => "dyag", "댞" => "dyagg", "댟" => "dyags", "댠" => "dyan", "댡" => "dyanj", "댢" => "dyanh", + "댣" => "dyad", "댤" => "dyal", "댥" => "dyalg", "댦" => "dyalm", "댧" => "dyalb", "댨" => "dyals", + "댩" => "dyalt", "댪" => "dyalp", "댫" => "dyalh", "댬" => "dyam", "댭" => "dyab", "댮" => "dyabs", + "댯" => "dyas", "댰" => "dyass", "댱" => "dyang", "댲" => "dyaj", "댳" => "dyac", "댴" => "dyak", + "댵" => "dyat", "댶" => "dyap", "댷" => "dyah", "댸" => "dyae", "댹" => "dyaeg", "댺" => "dyaegg", + "댻" => "dyaegs", "댼" => "dyaen", "댽" => "dyaenj", "댾" => "dyaenh", "댿" => "dyaed", "ë€" => "dyael", + "ë" => "dyaelg", "ë‚" => "dyaelm", "ëƒ" => "dyaelb", "ë„" => "dyaels", "ë…" => "dyaelt", "ë†" => "dyaelp", + "ë‡" => "dyaelh", "ëˆ" => "dyaem", "ë‰" => "dyaeb", "ëŠ" => "dyaebs", "ë‹" => "dyaes", "ëŒ" => "dyaess", + "ë" => "dyaeng", "ëŽ" => "dyaej", "ë" => "dyaec", "ë" => "dyaek", "ë‘" => "dyaet", "ë’" => "dyaep", + "ë“" => "dyaeh", "ë”" => "deo", "ë•" => "deog", "ë–" => "deogg", "ë—" => "deogs", "ë˜" => "deon", + "ë™" => "deonj", "ëš" => "deonh", "ë›" => "deod", "ëœ" => "deol", "ë" => "deolg", "ëž" => "deolm", + "ëŸ" => "deolb", "ë " => "deols", "ë¡" => "deolt", "ë¢" => "deolp", "ë£" => "deolh", "ë¤" => "deom", + "ë¥" => "deob", "ë¦" => "deobs", "ë§" => "deos", "ë¨" => "deoss", "ë©" => "deong", "ëª" => "deoj", + "ë«" => "deoc", "ë¬" => "deok", "ë­" => "deot", "ë®" => "deop", "ë¯" => "deoh", "ë°" => "de", + "ë±" => "deg", "ë²" => "degg", "ë³" => "degs", "ë´" => "den", "ëµ" => "denj", "ë¶" => "denh", + "ë·" => "ded", "ë¸" => "del", "ë¹" => "delg", "ëº" => "delm", "ë»" => "delb", "ë¼" => "dels", + "ë½" => "delt", "ë¾" => "delp", "ë¿" => "delh", "뎀" => "dem", "ëŽ" => "deb", "뎂" => "debs", + "뎃" => "des", "뎄" => "dess", "뎅" => "deng", "뎆" => "dej", "뎇" => "dec", "뎈" => "dek", + "뎉" => "det", "뎊" => "dep", "뎋" => "deh", "뎌" => "dyeo", "ëŽ" => "dyeog", "뎎" => "dyeogg", + "ëŽ" => "dyeogs", "ëŽ" => "dyeon", "뎑" => "dyeonj", "뎒" => "dyeonh", "뎓" => "dyeod", "뎔" => "dyeol", + "뎕" => "dyeolg", "뎖" => "dyeolm", "뎗" => "dyeolb", "뎘" => "dyeols", "뎙" => "dyeolt", "뎚" => "dyeolp", + "뎛" => "dyeolh", "뎜" => "dyeom", "ëŽ" => "dyeob", "뎞" => "dyeobs", "뎟" => "dyeos", "뎠" => "dyeoss", + "뎡" => "dyeong", "뎢" => "dyeoj", "뎣" => "dyeoc", "뎤" => "dyeok", "뎥" => "dyeot", "뎦" => "dyeop", + "뎧" => "dyeoh", "뎨" => "dye", "뎩" => "dyeg", "뎪" => "dyegg", "뎫" => "dyegs", "뎬" => "dyen", + "뎭" => "dyenj", "뎮" => "dyenh", "뎯" => "dyed", "뎰" => "dyel", "뎱" => "dyelg", "뎲" => "dyelm", + "뎳" => "dyelb", "뎴" => "dyels", "뎵" => "dyelt", "뎶" => "dyelp", "뎷" => "dyelh", "뎸" => "dyem", + "뎹" => "dyeb", "뎺" => "dyebs", "뎻" => "dyes", "뎼" => "dyess", "뎽" => "dyeng", "뎾" => "dyej", + "뎿" => "dyec", "ë€" => "dyek", "ë" => "dyet", "ë‚" => "dyep", "ëƒ" => "dyeh", "ë„" => "do", + "ë…" => "dog", "ë†" => "dogg", "ë‡" => "dogs", "ëˆ" => "don", "ë‰" => "donj", "ëŠ" => "donh", + "ë‹" => "dod", "ëŒ" => "dol", "ë" => "dolg", "ëŽ" => "dolm", "ë" => "dolb", "ë" => "dols", + "ë‘" => "dolt", "ë’" => "dolp", "ë“" => "dolh", "ë”" => "dom", "ë•" => "dob", "ë–" => "dobs", + "ë—" => "dos", "ë˜" => "doss", "ë™" => "dong", "ëš" => "doj", "ë›" => "doc", "ëœ" => "dok", + "ë" => "dot", "ëž" => "dop", "ëŸ" => "doh", "ë " => "dwa", "ë¡" => "dwag", "ë¢" => "dwagg", + "ë£" => "dwags", "ë¤" => "dwan", "ë¥" => "dwanj", "ë¦" => "dwanh", "ë§" => "dwad", "ë¨" => "dwal", + "ë©" => "dwalg", "ëª" => "dwalm", "ë«" => "dwalb", "ë¬" => "dwals", "ë­" => "dwalt", "ë®" => "dwalp", + "ë¯" => "dwalh", "ë°" => "dwam", "ë±" => "dwab", "ë²" => "dwabs", "ë³" => "dwas", "ë´" => "dwass", + "ëµ" => "dwang", "ë¶" => "dwaj", "ë·" => "dwac", "ë¸" => "dwak", "ë¹" => "dwat", "ëº" => "dwap", + "ë»" => "dwah", "ë¼" => "dwae", "ë½" => "dwaeg", "ë¾" => "dwaegg", "ë¿" => "dwaegs", "ë" => "dwaenj", + "ë‚" => "dwaenh", "ëƒ" => "dwaed", "ë„" => "dwael", "ë…" => "dwaelg", "ë†" => "dwaelm", "ë‡" => "dwaelb", + "ëˆ" => "dwaels", "ë‰" => "dwaelt", "ëŠ" => "dwaelp", "ë‹" => "dwaelh", "ëŒ" => "dwaem", "ë" => "dwaeb", + "ëŽ" => "dwaebs", "ë" => "dwaes", "ë" => "dwaess", "ë‘" => "dwaeng", "ë’" => "dwaej", "ë“" => "dwaec", + "ë”" => "dwaek", "ë•" => "dwaet", "ë–" => "dwaep", "ë—" => "dwaeh", "ë˜" => "doe", "ë™" => "doeg", + "ëš" => "doegg", "ë›" => "doegs", "ëœ" => "doen", "ë" => "doenj", "ëž" => "doenh", "ëŸ" => "doed", + "ë " => "doel", "ë¡" => "doelg", "ë¢" => "doelm", "ë£" => "doelb", "ë¤" => "doels", "ë¥" => "doelt", + "ë¦" => "doelp", "ë§" => "doelh", "ë¨" => "doem", "ë©" => "doeb", "ëª" => "doebs", "ë«" => "does", + "ë¬" => "doess", "ë­" => "doeng", "ë®" => "doej", "ë¯" => "doec", "ë°" => "doek", "ë±" => "doet", + "ë²" => "doep", "ë³" => "doeh", "ë´" => "dyo", "ëµ" => "dyog", "ë¶" => "dyogg", "ë·" => "dyogs", + "ë¸" => "dyon", "ë¹" => "dyonj", "ëº" => "dyonh", "ë»" => "dyod", "ë¼" => "dyol", "ë½" => "dyolg", + "ë¾" => "dyolm", "ë¿" => "dyolb", "ë‘€" => "dyols", "ë‘" => "dyolt", "ë‘‚" => "dyolp", "둃" => "dyolh", + "ë‘„" => "dyom", "ë‘…" => "dyob", "둆" => "dyobs", "둇" => "dyos", "둈" => "dyoss", "둉" => "dyong", + "ë‘Š" => "dyoj", "ë‘‹" => "dyoc", "ë‘Œ" => "dyok", "ë‘" => "dyot", "ë‘Ž" => "dyop", "ë‘" => "dyoh", + "ë‘" => "du", "ë‘‘" => "dug", "ë‘’" => "dugg", "ë‘“" => "dugs", "ë‘”" => "dun", "ë‘•" => "dunj", + "ë‘–" => "dunh", "ë‘—" => "dud", "둘" => "dul", "ë‘™" => "dulg", "ë‘š" => "dulm", "ë‘›" => "dulb", + "ë‘œ" => "duls", "ë‘" => "dult", "ë‘ž" => "dulp", "ë‘Ÿ" => "dulh", "ë‘ " => "dum", "ë‘¡" => "dub", + "ë‘¢" => "dubs", "ë‘£" => "dus", "둤" => "duss", "ë‘¥" => "dung", "둦" => "duj", "둧" => "duc", + "둨" => "duk", "ë‘©" => "dut", "둪" => "dup", "ë‘«" => "duh", "둬" => "dweo", "ë‘­" => "dweog", + "ë‘®" => "dweogg", "둯" => "dweogs", "ë‘°" => "dweon", "둱" => "dweonj", "둲" => "dweonh", "둳" => "dweod", + "ë‘´" => "dweol", "둵" => "dweolg", "둶" => "dweolm", "ë‘·" => "dweolb", "둸" => "dweols", "둹" => "dweolt", + "둺" => "dweolp", "ë‘»" => "dweolh", "둼" => "dweom", "둽" => "dweob", "둾" => "dweobs", "ë‘¿" => "dweos", + "ë’€" => "dweoss", "ë’" => "dweong", "ë’‚" => "dweoj", "ë’ƒ" => "dweoc", "ë’„" => "dweok", "ë’…" => "dweot", + "ë’†" => "dweop", "ë’‡" => "dweoh", "ë’ˆ" => "dwe", "ë’‰" => "dweg", "ë’Š" => "dwegg", "ë’‹" => "dwegs", + "ë’Œ" => "dwen", "ë’" => "dwenj", "ë’Ž" => "dwenh", "ë’" => "dwed", "ë’" => "dwel", "ë’‘" => "dwelg", + "ë’’" => "dwelm", "ë’“" => "dwelb", "ë’”" => "dwels", "ë’•" => "dwelt", "ë’–" => "dwelp", "ë’—" => "dwelh", + "ë’˜" => "dwem", "ë’™" => "dweb", "ë’š" => "dwebs", "ë’›" => "dwes", "ë’œ" => "dwess", "ë’" => "dweng", + "ë’ž" => "dwej", "ë’Ÿ" => "dwec", "ë’ " => "dwek", "ë’¡" => "dwet", "ë’¢" => "dwep", "ë’£" => "dweh", + "ë’¤" => "dwi", "ë’¥" => "dwig", "ë’¦" => "dwigg", "ë’§" => "dwigs", "ë’¨" => "dwin", "ë’©" => "dwinj", + "ë’ª" => "dwinh", "ë’«" => "dwid", "ë’¬" => "dwil", "ë’­" => "dwilg", "ë’®" => "dwilm", "ë’¯" => "dwilb", + "ë’°" => "dwils", "ë’±" => "dwilt", "ë’²" => "dwilp", "ë’³" => "dwilh", "ë’´" => "dwim", "ë’µ" => "dwib", + "ë’¶" => "dwibs", "ë’·" => "dwis", "ë’¸" => "dwiss", "ë’¹" => "dwing", "ë’º" => "dwij", "ë’»" => "dwic", + "ë’¼" => "dwik", "ë’½" => "dwit", "ë’¾" => "dwip", "ë’¿" => "dwih", "ë“€" => "dyu", "ë“" => "dyug", + "ë“‚" => "dyugg", "듃" => "dyugs", "ë“„" => "dyun", "ë“…" => "dyunj", "듆" => "dyunh", "듇" => "dyud", + "듈" => "dyul", "듉" => "dyulg", "ë“Š" => "dyulm", "ë“‹" => "dyulb", "ë“Œ" => "dyuls", "ë“" => "dyult", + "ë“Ž" => "dyulp", "ë“" => "dyulh", "ë“" => "dyum", "ë“‘" => "dyub", "ë“’" => "dyubs", "ë““" => "dyus", + "ë“”" => "dyuss", "ë“•" => "dyung", "ë“–" => "dyuj", "ë“—" => "dyuc", "듘" => "dyuk", "ë“™" => "dyut", + "ë“š" => "dyup", "ë“›" => "dyuh", "ë“œ" => "deu", "ë“" => "deug", "ë“ž" => "deugg", "ë“Ÿ" => "deugs", + "ë“ " => "deun", "ë“¡" => "deunj", "ë“¢" => "deunh", "ë“£" => "deud", "들" => "deul", "ë“¥" => "deulg", + "듦" => "deulm", "듧" => "deulb", "듨" => "deuls", "ë“©" => "deult", "듪" => "deulp", "ë“«" => "deulh", + "듬" => "deum", "ë“­" => "deub", "ë“®" => "deubs", "듯" => "deus", "ë“°" => "deuss", "등" => "deung", + "듲" => "deuj", "듳" => "deuc", "ë“´" => "deuk", "듵" => "deut", "듶" => "deup", "ë“·" => "deuh", + "듸" => "dyi", "듹" => "dyig", "듺" => "dyigg", "ë“»" => "dyigs", "듼" => "dyin", "듽" => "dyinj", + "듾" => "dyinh", "ë“¿" => "dyid", "ë”" => "dyilg", "딂" => "dyilm", "딃" => "dyilb", "딄" => "dyils", + "ë”…" => "dyilt", "딆" => "dyilp", "딇" => "dyilh", "딈" => "dyim", "딉" => "dyib", "딊" => "dyibs", + "딋" => "dyis", "딌" => "dyiss", "ë”" => "dying", "딎" => "dyij", "ë”" => "dyic", "ë”" => "dyik", + "딑" => "dyit", "ë”’" => "dyip", "딓" => "dyih", "ë””" => "di", "딕" => "dig", "ë”–" => "digg", + "ë”—" => "digs", "딘" => "din", "ë”™" => "dinj", "딚" => "dinh", "ë”›" => "did", "딜" => "dil", + "ë”" => "dilg", "딞" => "dilm", "딟" => "dilb", "ë” " => "dils", "딡" => "dilt", "딢" => "dilp", + "딣" => "dilh", "딤" => "dim", "딥" => "dib", "딦" => "dibs", "딧" => "dis", "딨" => "diss", + "딩" => "ding", "딪" => "dij", "딫" => "dic", "딬" => "dik", "ë”­" => "dit", "ë”®" => "dip", + "딯" => "dih", "ë”°" => "dda", "ë”±" => "ddag", "딲" => "ddagg", "딳" => "ddags", "ë”´" => "ddan", + "딵" => "ddanj", "딶" => "ddanh", "ë”·" => "ddad", "딸" => "ddal", "딹" => "ddalg", "딺" => "ddalm", + "ë”»" => "ddalb", "딼" => "ddals", "딽" => "ddalt", "딾" => "ddalp", "딿" => "ddalh", "ë•€" => "ddam", + "ë•" => "ddab", "ë•‚" => "ddabs", "땃" => "ddas", "ë•„" => "ddass", "ë•…" => "ddang", "땆" => "ddaj", + "땇" => "ddac", "땈" => "ddak", "땉" => "ddat", "ë•Š" => "ddap", "ë•‹" => "ddah", "ë•Œ" => "ddae", + "ë•" => "ddaeg", "ë•Ž" => "ddaegg", "ë•" => "ddaegs", "ë•" => "ddaen", "ë•‘" => "ddaenj", "ë•’" => "ddaenh", + "ë•“" => "ddaed", "ë•”" => "ddael", "ë••" => "ddaelg", "ë•–" => "ddaelm", "ë•—" => "ddaelb", "땘" => "ddaels", + "ë•™" => "ddaelt", "ë•š" => "ddaelp", "ë•›" => "ddaelh", "ë•œ" => "ddaem", "ë•" => "ddaeb", "ë•ž" => "ddaebs", + "ë•Ÿ" => "ddaes", "ë• " => "ddaess", "ë•¡" => "ddaeng", "ë•¢" => "ddaej", "ë•£" => "ddaec", "땤" => "ddaek", + "ë•¥" => "ddaet", "땦" => "ddaep", "땧" => "ddaeh", "땨" => "ddya", "ë•©" => "ddyag", "땪" => "ddyagg", + "ë•«" => "ddyags", "땬" => "ddyan", "ë•­" => "ddyanj", "ë•®" => "ddyanh", "땯" => "ddyad", "ë•°" => "ddyal", + "땱" => "ddyalg", "땲" => "ddyalm", "땳" => "ddyalb", "ë•´" => "ddyals", "땵" => "ddyalt", "땶" => "ddyalp", + "ë•·" => "ddyalh", "땸" => "ddyam", "땹" => "ddyab", "땺" => "ddyabs", "ë•»" => "ddyas", "땼" => "ddyass", + "땽" => "ddyang", "땾" => "ddyaj", "ë•¿" => "ddyac", "ë–€" => "ddyak", "ë–" => "ddyat", "ë–‚" => "ddyap", + "ë–ƒ" => "ddyah", "ë–„" => "ddyae", "ë–…" => "ddyaeg", "ë–†" => "ddyaegg", "ë–‡" => "ddyaegs", "ë–ˆ" => "ddyaen", + "ë–‰" => "ddyaenj", "ë–Š" => "ddyaenh", "ë–‹" => "ddyaed", "ë–Œ" => "ddyael", "ë–" => "ddyaelg", "ë–Ž" => "ddyaelm", + "ë–" => "ddyaelb", "ë–" => "ddyaels", "ë–‘" => "ddyaelt", "ë–’" => "ddyaelp", "ë–“" => "ddyaelh", "ë–”" => "ddyaem", + "ë–•" => "ddyaeb", "ë––" => "ddyaebs", "ë–—" => "ddyaes", "ë–˜" => "ddyaess", "ë–™" => "ddyaeng", "ë–š" => "ddyaej", + "ë–›" => "ddyaec", "ë–œ" => "ddyaek", "ë–" => "ddyaet", "ë–ž" => "ddyaep", "ë–Ÿ" => "ddyaeh", "ë– " => "ddeo", + "ë–¡" => "ddeog", "ë–¢" => "ddeogg", "ë–£" => "ddeogs", "ë–¤" => "ddeon", "ë–¥" => "ddeonj", "ë–¦" => "ddeonh", + "ë–§" => "ddeod", "ë–¨" => "ddeol", "ë–©" => "ddeolg", "ë–ª" => "ddeolm", "ë–«" => "ddeolb", "ë–¬" => "ddeols", + "ë–­" => "ddeolt", "ë–®" => "ddeolp", "ë–¯" => "ddeolh", "ë–°" => "ddeom", "ë–±" => "ddeob", "ë–²" => "ddeobs", + "ë–³" => "ddeos", "ë–´" => "ddeoss", "ë–µ" => "ddeong", "ë–¶" => "ddeoj", "ë–·" => "ddeoc", "ë–¸" => "ddeok", + "ë–¹" => "ddeot", "ë–º" => "ddeop", "ë–»" => "ddeoh", "ë–¼" => "dde", "ë–½" => "ddeg", "ë–¾" => "ddegg", + "ë–¿" => "ddegs", "ë—€" => "dden", "ë—" => "ddenj", "ë—‚" => "ddenh", "ë—ƒ" => "dded", "ë—„" => "ddel", + "ë—…" => "ddelg", "ë—†" => "ddelm", "ë—‡" => "ddelb", "ë—ˆ" => "ddels", "ë—‰" => "ddelt", "ë—Š" => "ddelp", + "ë—‹" => "ddelh", "ë—Œ" => "ddem", "ë—" => "ddeb", "ë—Ž" => "ddebs", "ë—" => "ddes", "ë—" => "ddess", + "ë—‘" => "ddeng", "ë—’" => "ddej", "ë—“" => "ddec", "ë—”" => "ddek", "ë—•" => "ddet", "ë—–" => "ddep", + "ë——" => "ddeh", "ë—˜" => "ddyeo", "ë—™" => "ddyeog", "ë—š" => "ddyeogg", "ë—›" => "ddyeogs", "ë—œ" => "ddyeon", + "ë—" => "ddyeonj", "ë—ž" => "ddyeonh", "ë—Ÿ" => "ddyeod", "ë— " => "ddyeol", "ë—¡" => "ddyeolg", "ë—¢" => "ddyeolm", + "ë—£" => "ddyeolb", "ë—¤" => "ddyeols", "ë—¥" => "ddyeolt", "ë—¦" => "ddyeolp", "ë—§" => "ddyeolh", "ë—¨" => "ddyeom", + "ë—©" => "ddyeob", "ë—ª" => "ddyeobs", "ë—«" => "ddyeos", "ë—¬" => "ddyeoss", "ë—­" => "ddyeong", "ë—®" => "ddyeoj", + "ë—¯" => "ddyeoc", "ë—°" => "ddyeok", "ë—±" => "ddyeot", "ë—²" => "ddyeop", "ë—³" => "ddyeoh", "ë—´" => "ddye", + "ë—µ" => "ddyeg", "ë—¶" => "ddyegg", "ë—·" => "ddyegs", "ë—¸" => "ddyen", "ë—¹" => "ddyenj", "ë—º" => "ddyenh", + "ë—»" => "ddyed", "ë—¼" => "ddyel", "ë—½" => "ddyelg", "ë—¾" => "ddyelm", "ë—¿" => "ddyelb", "ë˜" => "ddyelt", + "똂" => "ddyelp", "똃" => "ddyelh", "똄" => "ddyem", "똅" => "ddyeb", "똆" => "ddyebs", "똇" => "ddyes", + "똈" => "ddyess", "똉" => "ddyeng", "똊" => "ddyej", "똋" => "ddyec", "똌" => "ddyek", "ë˜" => "ddyet", + "똎" => "ddyep", "ë˜" => "ddyeh", "ë˜" => "ddo", "똑" => "ddog", "똒" => "ddogg", "똓" => "ddogs", + "똔" => "ddon", "똕" => "ddonj", "똖" => "ddonh", "똗" => "ddod", "똘" => "ddol", "똙" => "ddolg", + "똚" => "ddolm", "똛" => "ddolb", "똜" => "ddols", "ë˜" => "ddolt", "똞" => "ddolp", "똟" => "ddolh", + "똠" => "ddom", "똡" => "ddob", "똢" => "ddobs", "똣" => "ddos", "똤" => "ddoss", "똥" => "ddong", + "똦" => "ddoj", "똧" => "ddoc", "똨" => "ddok", "똩" => "ddot", "똪" => "ddop", "똫" => "ddoh", + "똬" => "ddwa", "똭" => "ddwag", "똮" => "ddwagg", "똯" => "ddwags", "똰" => "ddwan", "똱" => "ddwanj", + "똲" => "ddwanh", "똳" => "ddwad", "똴" => "ddwal", "똵" => "ddwalg", "똶" => "ddwalm", "똷" => "ddwalb", + "똸" => "ddwals", "똹" => "ddwalt", "똺" => "ddwalp", "똻" => "ddwalh", "똼" => "ddwam", "똽" => "ddwab", + "똾" => "ddwabs", "똿" => "ddwas", "뙀" => "ddwass", "ë™" => "ddwang", "뙂" => "ddwaj", "뙃" => "ddwac", + "뙄" => "ddwak", "ë™…" => "ddwat", "뙆" => "ddwap", "뙇" => "ddwah", "뙈" => "ddwae", "뙉" => "ddwaeg", + "뙊" => "ddwaegg", "뙋" => "ddwaegs", "뙌" => "ddwaen", "ë™" => "ddwaenj", "뙎" => "ddwaenh", "ë™" => "ddwaed", + "ë™" => "ddwael", "뙑" => "ddwaelg", "ë™’" => "ddwaelm", "뙓" => "ddwaelb", "ë™”" => "ddwaels", "뙕" => "ddwaelt", + "ë™–" => "ddwaelp", "ë™—" => "ddwaelh", "뙘" => "ddwaem", "ë™™" => "ddwaeb", "뙚" => "ddwaebs", "ë™›" => "ddwaes", + "뙜" => "ddwaess", "ë™" => "ddwaeng", "뙞" => "ddwaej", "뙟" => "ddwaec", "ë™ " => "ddwaek", "뙡" => "ddwaet", + "뙢" => "ddwaep", "뙣" => "ddwaeh", "뙤" => "ddoe", "뙥" => "ddoeg", "뙦" => "ddoegg", "뙧" => "ddoegs", + "뙨" => "ddoen", "뙩" => "ddoenj", "뙪" => "ddoenh", "뙫" => "ddoed", "뙬" => "ddoel", "ë™­" => "ddoelg", + "ë™®" => "ddoelm", "뙯" => "ddoelb", "ë™°" => "ddoels", "ë™±" => "ddoelt", "뙲" => "ddoelp", "뙳" => "ddoelh", + "ë™´" => "ddoem", "뙵" => "ddoeb", "뙶" => "ddoebs", "ë™·" => "ddoes", "뙸" => "ddoess", "뙹" => "ddoeng", + "뙺" => "ddoej", "ë™»" => "ddoec", "뙼" => "ddoek", "뙽" => "ddoet", "뙾" => "ddoep", "뙿" => "ddoeh", + "뚀" => "ddyo", "ëš" => "ddyog", "ëš‚" => "ddyogg", "뚃" => "ddyogs", "ëš„" => "ddyon", "ëš…" => "ddyonj", + "뚆" => "ddyonh", "뚇" => "ddyod", "뚈" => "ddyol", "뚉" => "ddyolg", "뚊" => "ddyolm", "ëš‹" => "ddyolb", + "뚌" => "ddyols", "ëš" => "ddyolt", "뚎" => "ddyolp", "ëš" => "ddyolh", "ëš" => "ddyom", "ëš‘" => "ddyob", + "ëš’" => "ddyobs", "ëš“" => "ddyos", "ëš”" => "ddyoss", "ëš•" => "ddyong", "ëš–" => "ddyoj", "ëš—" => "ddyoc", + "뚘" => "ddyok", "ëš™" => "ddyot", "ëšš" => "ddyop", "ëš›" => "ddyoh", "ëšœ" => "ddu", "ëš" => "ddug", + "ëšž" => "ddugg", "뚟" => "ddugs", "ëš " => "ddun", "ëš¡" => "ddunj", "뚢" => "ddunh", "뚣" => "ddud", + "뚤" => "ddul", "뚥" => "ddulg", "뚦" => "ddulm", "뚧" => "ddulb", "뚨" => "dduls", "ëš©" => "ddult", + "뚪" => "ddulp", "ëš«" => "ddulh", "뚬" => "ddum", "ëš­" => "ddub", "ëš®" => "ddubs", "뚯" => "ddus", + "ëš°" => "dduss", "ëš±" => "ddung", "ëš²" => "dduj", "ëš³" => "dduc", "ëš´" => "dduk", "ëšµ" => "ddut", + "뚶" => "ddup", "ëš·" => "dduh", "뚸" => "ddweo", "ëš¹" => "ddweog", "뚺" => "ddweogg", "ëš»" => "ddweogs", + "ëš¼" => "ddweon", "ëš½" => "ddweonj", "ëš¾" => "ddweonh", "ëš¿" => "ddweod", "뛀" => "ddweol", "ë›" => "ddweolg", + "뛂" => "ddweolm", "뛃" => "ddweolb", "뛄" => "ddweols", "ë›…" => "ddweolt", "뛆" => "ddweolp", "뛇" => "ddweolh", + "뛈" => "ddweom", "뛉" => "ddweob", "뛊" => "ddweobs", "뛋" => "ddweos", "뛌" => "ddweoss", "ë›" => "ddweong", + "뛎" => "ddweoj", "ë›" => "ddweoc", "ë›" => "ddweok", "뛑" => "ddweot", "ë›’" => "ddweop", "뛓" => "ddweoh", + "ë›”" => "ddwe", "뛕" => "ddweg", "ë›–" => "ddwegg", "ë›—" => "ddwegs", "뛘" => "ddwen", "ë›™" => "ddwenj", + "뛚" => "ddwenh", "ë››" => "ddwed", "뛜" => "ddwel", "ë›" => "ddwelg", "뛞" => "ddwelm", "뛟" => "ddwelb", + "ë› " => "ddwels", "뛡" => "ddwelt", "뛢" => "ddwelp", "뛣" => "ddwelh", "뛤" => "ddwem", "뛥" => "ddweb", + "뛦" => "ddwebs", "뛧" => "ddwes", "뛨" => "ddwess", "뛩" => "ddweng", "뛪" => "ddwej", "뛫" => "ddwec", + "뛬" => "ddwek", "ë›­" => "ddwet", "ë›®" => "ddwep", "뛯" => "ddweh", "ë›°" => "ddwi", "ë›±" => "ddwig", + "뛲" => "ddwigg", "뛳" => "ddwigs", "ë›´" => "ddwin", "뛵" => "ddwinj", "뛶" => "ddwinh", "ë›·" => "ddwid", + "뛸" => "ddwil", "뛹" => "ddwilg", "뛺" => "ddwilm", "ë›»" => "ddwilb", "뛼" => "ddwils", "뛽" => "ddwilt", + "뛾" => "ddwilp", "뛿" => "ddwilh", "ëœ" => "ddwib", "뜂" => "ddwibs", "뜃" => "ddwis", "뜄" => "ddwiss", + "뜅" => "ddwing", "뜆" => "ddwij", "뜇" => "ddwic", "뜈" => "ddwik", "뜉" => "ddwit", "뜊" => "ddwip", + "뜋" => "ddwih", "뜌" => "ddyu", "ëœ" => "ddyug", "뜎" => "ddyugg", "ëœ" => "ddyugs", "ëœ" => "ddyun", + "뜑" => "ddyunj", "뜒" => "ddyunh", "뜓" => "ddyud", "뜔" => "ddyul", "뜕" => "ddyulg", "뜖" => "ddyulm", + "뜗" => "ddyulb", "뜘" => "ddyuls", "뜙" => "ddyult", "뜚" => "ddyulp", "뜛" => "ddyulh", "뜜" => "ddyum", + "ëœ" => "ddyub", "뜞" => "ddyubs", "뜟" => "ddyus", "뜠" => "ddyuss", "뜡" => "ddyung", "뜢" => "ddyuj", + "뜣" => "ddyuc", "뜤" => "ddyuk", "뜥" => "ddyut", "뜦" => "ddyup", "뜧" => "ddyuh", "뜨" => "ddeu", + "뜩" => "ddeug", "뜪" => "ddeugg", "뜫" => "ddeugs", "뜬" => "ddeun", "뜭" => "ddeunj", "뜮" => "ddeunh", + "뜯" => "ddeud", "뜰" => "ddeul", "뜱" => "ddeulg", "뜲" => "ddeulm", "뜳" => "ddeulb", "뜴" => "ddeuls", + "뜵" => "ddeult", "뜶" => "ddeulp", "뜷" => "ddeulh", "뜸" => "ddeum", "뜹" => "ddeub", "뜺" => "ddeubs", + "뜻" => "ddeus", "뜼" => "ddeuss", "뜽" => "ddeung", "뜾" => "ddeuj", "뜿" => "ddeuc", "ë€" => "ddeuk", + "ë" => "ddeut", "ë‚" => "ddeup", "ëƒ" => "ddeuh", "ë„" => "ddyi", "ë…" => "ddyig", "ë†" => "ddyigg", + "ë‡" => "ddyigs", "ëˆ" => "ddyin", "ë‰" => "ddyinj", "ëŠ" => "ddyinh", "ë‹" => "ddyid", "ëŒ" => "ddyil", + "ë" => "ddyilg", "ëŽ" => "ddyilm", "ë" => "ddyilb", "ë" => "ddyils", "ë‘" => "ddyilt", "ë’" => "ddyilp", + "ë“" => "ddyilh", "ë”" => "ddyim", "ë•" => "ddyib", "ë–" => "ddyibs", "ë—" => "ddyis", "ë˜" => "ddyiss", + "ë™" => "ddying", "ëš" => "ddyij", "ë›" => "ddyic", "ëœ" => "ddyik", "ë" => "ddyit", "ëž" => "ddyip", + "ëŸ" => "ddyih", "ë " => "ddi", "ë¡" => "ddig", "ë¢" => "ddigg", "ë£" => "ddigs", "ë¤" => "ddin", + "ë¥" => "ddinj", "ë¦" => "ddinh", "ë§" => "ddid", "ë¨" => "ddil", "ë©" => "ddilg", "ëª" => "ddilm", + "ë«" => "ddilb", "ë¬" => "ddils", "ë­" => "ddilt", "ë®" => "ddilp", "ë¯" => "ddilh", "ë°" => "ddim", + "ë±" => "ddib", "ë²" => "ddibs", "ë³" => "ddis", "ë´" => "ddiss", "ëµ" => "dding", "ë¶" => "ddij", + "ë·" => "ddic", "ë¸" => "ddik", "ë¹" => "ddit", "ëº" => "ddip", "ë»" => "ddih", "ë¼" => "ra", + "ë½" => "rag", "ë¾" => "ragg", "ë¿" => "rags", "란" => "ran", "ëž" => "ranj", "ëž‚" => "ranh", + "랃" => "rad", "ëž„" => "ral", "ëž…" => "ralg", "랆" => "ralm", "랇" => "ralb", "랈" => "rals", + "랉" => "ralt", "랊" => "ralp", "ëž‹" => "ralh", "람" => "ram", "ëž" => "rab", "랎" => "rabs", + "ëž" => "ras", "ëž" => "rass", "ëž‘" => "rang", "ëž’" => "raj", "ëž“" => "rac", "ëž”" => "rak", + "ëž•" => "rat", "ëž–" => "rap", "ëž—" => "rah", "래" => "rae", "ëž™" => "raeg", "ëžš" => "raegg", + "ëž›" => "raegs", "ëžœ" => "raen", "ëž" => "raenj", "ëžž" => "raenh", "랟" => "raed", "ëž " => "rael", + "ëž¡" => "raelg", "랢" => "raelm", "랣" => "raelb", "랤" => "raels", "랥" => "raelt", "랦" => "raelp", + "랧" => "raelh", "램" => "raem", "ëž©" => "raeb", "랪" => "raebs", "ëž«" => "raes", "랬" => "raess", + "ëž­" => "raeng", "ëž®" => "raej", "랯" => "raec", "ëž°" => "raek", "ëž±" => "raet", "ëž²" => "raep", + "ëž³" => "raeh", "ëž´" => "rya", "ëžµ" => "ryag", "랶" => "ryagg", "ëž·" => "ryags", "랸" => "ryan", + "ëž¹" => "ryanj", "랺" => "ryanh", "ëž»" => "ryad", "ëž¼" => "ryal", "ëž½" => "ryalg", "ëž¾" => "ryalm", + "ëž¿" => "ryalb", "럀" => "ryals", "ëŸ" => "ryalt", "럂" => "ryalp", "럃" => "ryalh", "럄" => "ryam", + "럅" => "ryab", "럆" => "ryabs", "럇" => "ryas", "럈" => "ryass", "량" => "ryang", "럊" => "ryaj", + "럋" => "ryac", "럌" => "ryak", "ëŸ" => "ryat", "럎" => "ryap", "ëŸ" => "ryah", "ëŸ" => "ryae", + "럑" => "ryaeg", "럒" => "ryaegg", "럓" => "ryaegs", "럔" => "ryaen", "럕" => "ryaenj", "럖" => "ryaenh", + "럗" => "ryaed", "럘" => "ryael", "럙" => "ryaelg", "럚" => "ryaelm", "럛" => "ryaelb", "럜" => "ryaels", + "ëŸ" => "ryaelt", "럞" => "ryaelp", "럟" => "ryaelh", "럠" => "ryaem", "럡" => "ryaeb", "럢" => "ryaebs", + "럣" => "ryaes", "럤" => "ryaess", "럥" => "ryaeng", "럦" => "ryaej", "럧" => "ryaec", "럨" => "ryaek", + "럩" => "ryaet", "럪" => "ryaep", "럫" => "ryaeh", "러" => "reo", "럭" => "reog", "럮" => "reogg", + "럯" => "reogs", "런" => "reon", "럱" => "reonj", "럲" => "reonh", "럳" => "reod", "럴" => "reol", + "럵" => "reolg", "럶" => "reolm", "럷" => "reolb", "럸" => "reols", "럹" => "reolt", "럺" => "reolp", + "럻" => "reolh", "럼" => "reom", "럽" => "reob", "럾" => "reobs", "럿" => "reos", "ë " => "reong", + "ë ‚" => "reoj", "ë ƒ" => "reoc", "ë „" => "reok", "ë …" => "reot", "ë †" => "reop", "ë ‡" => "reoh", + "ë ˆ" => "re", "ë ‰" => "reg", "ë Š" => "regg", "ë ‹" => "regs", "ë Œ" => "ren", "ë " => "renj", + "ë Ž" => "renh", "ë " => "red", "ë " => "rel", "ë ‘" => "relg", "ë ’" => "relm", "ë “" => "relb", + "ë ”" => "rels", "ë •" => "relt", "ë –" => "relp", "ë —" => "relh", "ë ˜" => "rem", "ë ™" => "reb", + "ë š" => "rebs", "ë ›" => "res", "ë œ" => "ress", "ë " => "reng", "ë ž" => "rej", "ë Ÿ" => "rec", + "ë  " => "rek", "ë ¡" => "ret", "ë ¢" => "rep", "ë £" => "reh", "ë ¤" => "ryeo", "ë ¥" => "ryeog", + "ë ¦" => "ryeogg", "ë §" => "ryeogs", "ë ¨" => "ryeon", "ë ©" => "ryeonj", "ë ª" => "ryeonh", "ë «" => "ryeod", + "ë ¬" => "ryeol", "ë ­" => "ryeolg", "ë ®" => "ryeolm", "ë ¯" => "ryeolb", "ë °" => "ryeols", "ë ±" => "ryeolt", + "ë ²" => "ryeolp", "ë ³" => "ryeolh", "ë ´" => "ryeom", "ë µ" => "ryeob", "ë ¶" => "ryeobs", "ë ·" => "ryeos", + "ë ¸" => "ryeoss", "ë ¹" => "ryeong", "ë º" => "ryeoj", "ë »" => "ryeoc", "ë ¼" => "ryeok", "ë ½" => "ryeot", + "ë ¾" => "ryeop", "ë ¿" => "ryeoh", "ë¡€" => "rye", "ë¡" => "ryeg", "ë¡‚" => "ryegg", "롃" => "ryegs", + "ë¡„" => "ryen", "ë¡…" => "ryenj", "롆" => "ryenh", "롇" => "ryed", "롈" => "ryel", "롉" => "ryelg", + "ë¡Š" => "ryelm", "ë¡‹" => "ryelb", "ë¡Œ" => "ryels", "ë¡" => "ryelt", "ë¡Ž" => "ryelp", "ë¡" => "ryelh", + "ë¡" => "ryem", "ë¡‘" => "ryeb", "ë¡’" => "ryebs", "ë¡“" => "ryes", "ë¡”" => "ryess", "ë¡•" => "ryeng", + "ë¡–" => "ryej", "ë¡—" => "ryec", "롘" => "ryek", "ë¡™" => "ryet", "ë¡š" => "ryep", "ë¡›" => "ryeh", + "ë¡œ" => "ro", "ë¡" => "rog", "ë¡ž" => "rogg", "ë¡Ÿ" => "rogs", "ë¡ " => "ron", "ë¡¡" => "ronj", + "ë¡¢" => "ronh", "ë¡£" => "rod", "롤" => "rol", "ë¡¥" => "rolg", "롦" => "rolm", "롧" => "rolb", + "롨" => "rols", "ë¡©" => "rolt", "롪" => "rolp", "ë¡«" => "rolh", "롬" => "rom", "ë¡­" => "rob", + "ë¡®" => "robs", "롯" => "ros", "ë¡°" => "ross", "롱" => "rong", "롲" => "roj", "롳" => "roc", + "ë¡´" => "rok", "롵" => "rot", "롶" => "rop", "ë¡·" => "roh", "롸" => "rwa", "롹" => "rwag", + "롺" => "rwagg", "ë¡»" => "rwags", "롼" => "rwan", "롽" => "rwanj", "롾" => "rwanh", "ë¡¿" => "rwad", + "뢀" => "rwal", "ë¢" => "rwalg", "뢂" => "rwalm", "뢃" => "rwalb", "뢄" => "rwals", "뢅" => "rwalt", + "뢆" => "rwalp", "뢇" => "rwalh", "뢈" => "rwam", "뢉" => "rwab", "뢊" => "rwabs", "뢋" => "rwas", + "뢌" => "rwass", "ë¢" => "rwang", "뢎" => "rwaj", "ë¢" => "rwac", "ë¢" => "rwak", "뢑" => "rwat", + "뢒" => "rwap", "뢓" => "rwah", "뢔" => "rwae", "뢕" => "rwaeg", "뢖" => "rwaegg", "뢗" => "rwaegs", + "뢘" => "rwaen", "뢙" => "rwaenj", "뢚" => "rwaenh", "뢛" => "rwaed", "뢜" => "rwael", "ë¢" => "rwaelg", + "뢞" => "rwaelm", "뢟" => "rwaelb", "뢠" => "rwaels", "뢡" => "rwaelt", "뢢" => "rwaelp", "뢣" => "rwaelh", + "뢤" => "rwaem", "뢥" => "rwaeb", "뢦" => "rwaebs", "뢧" => "rwaes", "뢨" => "rwaess", "뢩" => "rwaeng", + "뢪" => "rwaej", "뢫" => "rwaec", "뢬" => "rwaek", "뢭" => "rwaet", "뢮" => "rwaep", "뢯" => "rwaeh", + "뢰" => "roe", "뢱" => "roeg", "뢲" => "roegg", "뢳" => "roegs", "뢴" => "roen", "뢵" => "roenj", + "뢶" => "roenh", "뢷" => "roed", "뢸" => "roel", "뢹" => "roelg", "뢺" => "roelm", "뢻" => "roelb", + "뢼" => "roels", "뢽" => "roelt", "뢾" => "roelp", "뢿" => "roelh", "룀" => "roem", "ë£" => "roeb", + "룂" => "roebs", "룃" => "roes", "룄" => "roess", "룅" => "roeng", "룆" => "roej", "룇" => "roec", + "룈" => "roek", "룉" => "roet", "룊" => "roep", "룋" => "roeh", "료" => "ryo", "ë£" => "ryog", + "룎" => "ryogg", "ë£" => "ryogs", "ë£" => "ryon", "룑" => "ryonj", "룒" => "ryonh", "룓" => "ryod", + "룔" => "ryol", "룕" => "ryolg", "룖" => "ryolm", "룗" => "ryolb", "룘" => "ryols", "룙" => "ryolt", + "룚" => "ryolp", "룛" => "ryolh", "룜" => "ryom", "ë£" => "ryob", "룞" => "ryobs", "룟" => "ryos", + "룠" => "ryoss", "룡" => "ryong", "룢" => "ryoj", "룣" => "ryoc", "룤" => "ryok", "룥" => "ryot", + "룦" => "ryop", "룧" => "ryoh", "루" => "ru", "룩" => "rug", "룪" => "rugg", "룫" => "rugs", + "룬" => "run", "룭" => "runj", "룮" => "runh", "룯" => "rud", "룰" => "rul", "룱" => "rulg", + "룲" => "rulm", "룳" => "rulb", "룴" => "ruls", "룵" => "rult", "룶" => "rulp", "룷" => "rulh", + "룸" => "rum", "룹" => "rub", "룺" => "rubs", "룻" => "rus", "룼" => "russ", "룽" => "rung", + "룾" => "ruj", "룿" => "ruc", "ë¤" => "rut", "뤂" => "rup", "뤃" => "ruh", "뤄" => "rweo", + "뤅" => "rweog", "뤆" => "rweogg", "뤇" => "rweogs", "뤈" => "rweon", "뤉" => "rweonj", "뤊" => "rweonh", + "뤋" => "rweod", "뤌" => "rweol", "ë¤" => "rweolg", "뤎" => "rweolm", "ë¤" => "rweolb", "ë¤" => "rweols", + "뤑" => "rweolt", "뤒" => "rweolp", "뤓" => "rweolh", "뤔" => "rweom", "뤕" => "rweob", "뤖" => "rweobs", + "뤗" => "rweos", "뤘" => "rweoss", "뤙" => "rweong", "뤚" => "rweoj", "뤛" => "rweoc", "뤜" => "rweok", + "ë¤" => "rweot", "뤞" => "rweop", "뤟" => "rweoh", "뤠" => "rwe", "뤡" => "rweg", "뤢" => "rwegg", + "뤣" => "rwegs", "뤤" => "rwen", "뤥" => "rwenj", "뤦" => "rwenh", "뤧" => "rwed", "뤨" => "rwel", + "뤩" => "rwelg", "뤪" => "rwelm", "뤫" => "rwelb", "뤬" => "rwels", "뤭" => "rwelt", "뤮" => "rwelp", + "뤯" => "rwelh", "뤰" => "rwem", "뤱" => "rweb", "뤲" => "rwebs", "뤳" => "rwes", "뤴" => "rwess", + "뤵" => "rweng", "뤶" => "rwej", "뤷" => "rwec", "뤸" => "rwek", "뤹" => "rwet", "뤺" => "rwep", + "뤻" => "rweh", "뤼" => "rwi", "뤽" => "rwig", "뤾" => "rwigg", "뤿" => "rwigs", "륀" => "rwin", + "ë¥" => "rwinj", "륂" => "rwinh", "륃" => "rwid", "륄" => "rwil", "륅" => "rwilg", "륆" => "rwilm", + "륇" => "rwilb", "륈" => "rwils", "륉" => "rwilt", "륊" => "rwilp", "륋" => "rwilh", "륌" => "rwim", + "ë¥" => "rwib", "륎" => "rwibs", "ë¥" => "rwis", "ë¥" => "rwiss", "륑" => "rwing", "륒" => "rwij", + "륓" => "rwic", "륔" => "rwik", "륕" => "rwit", "륖" => "rwip", "륗" => "rwih", "류" => "ryu", + "륙" => "ryug", "륚" => "ryugg", "륛" => "ryugs", "륜" => "ryun", "ë¥" => "ryunj", "륞" => "ryunh", + "륟" => "ryud", "률" => "ryul", "륡" => "ryulg", "륢" => "ryulm", "륣" => "ryulb", "륤" => "ryuls", + "륥" => "ryult", "륦" => "ryulp", "륧" => "ryulh", "륨" => "ryum", "륩" => "ryub", "륪" => "ryubs", + "륫" => "ryus", "륬" => "ryuss", "륭" => "ryung", "륮" => "ryuj", "륯" => "ryuc", "륰" => "ryuk", + "륱" => "ryut", "륲" => "ryup", "륳" => "ryuh", "르" => "reu", "륵" => "reug", "륶" => "reugg", + "륷" => "reugs", "른" => "reun", "륹" => "reunj", "륺" => "reunh", "륻" => "reud", "를" => "reul", + "륽" => "reulg", "륾" => "reulm", "륿" => "reulb", "릀" => "reuls", "ë¦" => "reult", "릂" => "reulp", + "릃" => "reulh", "름" => "reum", "릅" => "reub", "릆" => "reubs", "릇" => "reus", "릈" => "reuss", + "릉" => "reung", "릊" => "reuj", "릋" => "reuc", "릌" => "reuk", "ë¦" => "reut", "릎" => "reup", + "ë¦" => "reuh", "ë¦" => "ryi", "릑" => "ryig", "릒" => "ryigg", "릓" => "ryigs", "릔" => "ryin", + "릕" => "ryinj", "릖" => "ryinh", "릗" => "ryid", "릘" => "ryil", "릙" => "ryilg", "릚" => "ryilm", + "릛" => "ryilb", "릜" => "ryils", "ë¦" => "ryilt", "릞" => "ryilp", "릟" => "ryilh", "릠" => "ryim", + "릡" => "ryib", "릢" => "ryibs", "릣" => "ryis", "릤" => "ryiss", "릥" => "rying", "릦" => "ryij", + "릧" => "ryic", "릨" => "ryik", "릩" => "ryit", "릪" => "ryip", "릫" => "ryih", "리" => "ri", + "릭" => "rig", "릮" => "rigg", "릯" => "rigs", "린" => "rin", "릱" => "rinj", "릲" => "rinh", + "릳" => "rid", "릴" => "ril", "릵" => "rilg", "릶" => "rilm", "릷" => "rilb", "릸" => "rils", + "릹" => "rilt", "릺" => "rilp", "릻" => "rilh", "림" => "rim", "립" => "rib", "릾" => "ribs", + "릿" => "ris", "맀" => "riss", "ë§" => "ring", "맂" => "rij", "맃" => "ric", "맄" => "rik", + "맅" => "rit", "맆" => "rip", "맇" => "rih", "마" => "ma", "막" => "mag", "맊" => "magg", + "맋" => "mags", "만" => "man", "ë§" => "manj", "많" => "manh", "ë§" => "mad", "ë§" => "mal", + "맑" => "malg", "맒" => "malm", "맓" => "malb", "맔" => "mals", "맕" => "malt", "맖" => "malp", + "맗" => "malh", "맘" => "mam", "맙" => "mab", "맚" => "mabs", "맛" => "mas", "맜" => "mass", + "ë§" => "mang", "맞" => "maj", "맟" => "mac", "맠" => "mak", "맡" => "mat", "맢" => "map", + "맣" => "mah", "매" => "mae", "맥" => "maeg", "맦" => "maegg", "맧" => "maegs", "맨" => "maen", + "맩" => "maenj", "맪" => "maenh", "맫" => "maed", "맬" => "mael", "맭" => "maelg", "맮" => "maelm", + "맯" => "maelb", "맰" => "maels", "맱" => "maelt", "맲" => "maelp", "맳" => "maelh", "맴" => "maem", + "맵" => "maeb", "맶" => "maebs", "맷" => "maes", "맸" => "maess", "맹" => "maeng", "맺" => "maej", + "맻" => "maec", "맼" => "maek", "맽" => "maet", "맾" => "maep", "맿" => "maeh", "ë¨" => "myag", + "먂" => "myagg", "먃" => "myags", "먄" => "myan", "먅" => "myanj", "먆" => "myanh", "먇" => "myad", + "먈" => "myal", "먉" => "myalg", "먊" => "myalm", "먋" => "myalb", "먌" => "myals", "ë¨" => "myalt", + "먎" => "myalp", "ë¨" => "myalh", "ë¨" => "myam", "먑" => "myab", "먒" => "myabs", "먓" => "myas", + "먔" => "myass", "먕" => "myang", "먖" => "myaj", "먗" => "myac", "먘" => "myak", "먙" => "myat", + "먚" => "myap", "먛" => "myah", "먜" => "myae", "ë¨" => "myaeg", "먞" => "myaegg", "먟" => "myaegs", + "먠" => "myaen", "먡" => "myaenj", "먢" => "myaenh", "먣" => "myaed", "먤" => "myael", "먥" => "myaelg", + "먦" => "myaelm", "먧" => "myaelb", "먨" => "myaels", "먩" => "myaelt", "먪" => "myaelp", "먫" => "myaelh", + "먬" => "myaem", "먭" => "myaeb", "먮" => "myaebs", "먯" => "myaes", "먰" => "myaess", "먱" => "myaeng", + "먲" => "myaej", "먳" => "myaec", "먴" => "myaek", "먵" => "myaet", "먶" => "myaep", "먷" => "myaeh", + "머" => "meo", "먹" => "meog", "먺" => "meogg", "먻" => "meogs", "먼" => "meon", "먽" => "meonj", + "먾" => "meonh", "먿" => "meod", "ë©€" => "meol", "ë©" => "meolg", "ë©‚" => "meolm", "멃" => "meolb", + "ë©„" => "meols", "ë©…" => "meolt", "멆" => "meolp", "멇" => "meolh", "멈" => "meom", "멉" => "meob", + "ë©Š" => "meobs", "ë©‹" => "meos", "ë©Œ" => "meoss", "ë©" => "meong", "ë©Ž" => "meoj", "ë©" => "meoc", + "ë©" => "meok", "ë©‘" => "meot", "ë©’" => "meop", "ë©“" => "meoh", "ë©”" => "me", "ë©•" => "meg", + "ë©–" => "megg", "ë©—" => "megs", "멘" => "men", "ë©™" => "menj", "ë©š" => "menh", "ë©›" => "med", + "ë©œ" => "mel", "ë©" => "melg", "ë©ž" => "melm", "ë©Ÿ" => "melb", "ë© " => "mels", "ë©¡" => "melt", + "ë©¢" => "melp", "ë©£" => "melh", "멤" => "mem", "ë©¥" => "meb", "멦" => "mebs", "멧" => "mes", + "멨" => "mess", "ë©©" => "meng", "멪" => "mej", "ë©«" => "mec", "멬" => "mek", "ë©­" => "met", + "ë©®" => "mep", "멯" => "meh", "ë©°" => "myeo", "멱" => "myeog", "멲" => "myeogg", "멳" => "myeogs", + "ë©´" => "myeon", "멵" => "myeonj", "멶" => "myeonh", "ë©·" => "myeod", "멸" => "myeol", "멹" => "myeolg", + "멺" => "myeolm", "ë©»" => "myeolb", "멼" => "myeols", "멽" => "myeolt", "멾" => "myeolp", "ë©¿" => "myeolh", + "몀" => "myeom", "ëª" => "myeob", "몂" => "myeobs", "몃" => "myeos", "몄" => "myeoss", "명" => "myeong", + "몆" => "myeoj", "몇" => "myeoc", "몈" => "myeok", "몉" => "myeot", "몊" => "myeop", "몋" => "myeoh", + "몌" => "mye", "ëª" => "myeg", "몎" => "myegg", "ëª" => "myegs", "ëª" => "myen", "몑" => "myenj", + "몒" => "myenh", "몓" => "myed", "몔" => "myel", "몕" => "myelg", "몖" => "myelm", "몗" => "myelb", + "몘" => "myels", "몙" => "myelt", "몚" => "myelp", "몛" => "myelh", "몜" => "myem", "ëª" => "myeb", + "몞" => "myebs", "몟" => "myes", "몠" => "myess", "몡" => "myeng", "몢" => "myej", "몣" => "myec", + "몤" => "myek", "몥" => "myet", "몦" => "myep", "몧" => "myeh", "모" => "mo", "목" => "mog", + "몪" => "mogg", "몫" => "mogs", "몬" => "mon", "몭" => "monj", "몮" => "monh", "몯" => "mod", + "몰" => "mol", "몱" => "molg", "몲" => "molm", "몳" => "molb", "몴" => "mols", "몵" => "molt", + "몶" => "molp", "몷" => "molh", "몸" => "mom", "몹" => "mob", "몺" => "mobs", "못" => "mos", + "몼" => "moss", "몽" => "mong", "몾" => "moj", "몿" => "moc", "ë«€" => "mok", "ë«" => "mot", + "ë«‚" => "mop", "뫃" => "moh", "ë«„" => "mwa", "ë«…" => "mwag", "뫆" => "mwagg", "뫇" => "mwags", + "뫈" => "mwan", "뫉" => "mwanj", "ë«Š" => "mwanh", "ë«‹" => "mwad", "ë«Œ" => "mwal", "ë«" => "mwalg", + "ë«Ž" => "mwalm", "ë«" => "mwalb", "ë«" => "mwals", "ë«‘" => "mwalt", "ë«’" => "mwalp", "ë«“" => "mwalh", + "ë«”" => "mwam", "ë«•" => "mwab", "ë«–" => "mwabs", "ë«—" => "mwas", "뫘" => "mwass", "ë«™" => "mwang", + "ë«š" => "mwaj", "ë«›" => "mwac", "ë«œ" => "mwak", "ë«" => "mwat", "ë«ž" => "mwap", "ë«Ÿ" => "mwah", + "ë« " => "mwae", "ë«¡" => "mwaeg", "ë«¢" => "mwaegg", "ë«£" => "mwaegs", "뫤" => "mwaen", "ë«¥" => "mwaenj", + "뫦" => "mwaenh", "뫧" => "mwaed", "뫨" => "mwael", "ë«©" => "mwaelg", "뫪" => "mwaelm", "ë««" => "mwaelb", + "뫬" => "mwaels", "ë«­" => "mwaelt", "ë«®" => "mwaelp", "뫯" => "mwaelh", "ë«°" => "mwaem", "뫱" => "mwaeb", + "뫲" => "mwaebs", "뫳" => "mwaes", "ë«´" => "mwaess", "뫵" => "mwaeng", "뫶" => "mwaej", "ë«·" => "mwaec", + "뫸" => "mwaek", "뫹" => "mwaet", "뫺" => "mwaep", "ë«»" => "mwaeh", "뫼" => "moe", "뫽" => "moeg", + "뫾" => "moegg", "ë«¿" => "moegs", "ë¬" => "moenj", "묂" => "moenh", "묃" => "moed", "묄" => "moel", + "묅" => "moelg", "묆" => "moelm", "묇" => "moelb", "묈" => "moels", "묉" => "moelt", "묊" => "moelp", + "묋" => "moelh", "묌" => "moem", "ë¬" => "moeb", "묎" => "moebs", "ë¬" => "moes", "ë¬" => "moess", + "묑" => "moeng", "묒" => "moej", "묓" => "moec", "묔" => "moek", "묕" => "moet", "묖" => "moep", + "묗" => "moeh", "묘" => "myo", "묙" => "myog", "묚" => "myogg", "묛" => "myogs", "묜" => "myon", + "ë¬" => "myonj", "묞" => "myonh", "묟" => "myod", "묠" => "myol", "묡" => "myolg", "묢" => "myolm", + "묣" => "myolb", "묤" => "myols", "묥" => "myolt", "묦" => "myolp", "묧" => "myolh", "묨" => "myom", + "묩" => "myob", "묪" => "myobs", "묫" => "myos", "묬" => "myoss", "묭" => "myong", "묮" => "myoj", + "묯" => "myoc", "묰" => "myok", "묱" => "myot", "묲" => "myop", "묳" => "myoh", "무" => "mu", + "묵" => "mug", "묶" => "mugg", "묷" => "mugs", "문" => "mun", "묹" => "munj", "묺" => "munh", + "묻" => "mud", "물" => "mul", "묽" => "mulg", "묾" => "mulm", "묿" => "mulb", "ë­€" => "muls", + "ë­" => "mult", "ë­‚" => "mulp", "ë­ƒ" => "mulh", "ë­„" => "mum", "ë­…" => "mub", "ë­†" => "mubs", + "ë­‡" => "mus", "ë­ˆ" => "muss", "ë­‰" => "mung", "ë­Š" => "muj", "ë­‹" => "muc", "ë­Œ" => "muk", + "ë­" => "mut", "ë­Ž" => "mup", "ë­" => "muh", "ë­" => "mweo", "ë­‘" => "mweog", "ë­’" => "mweogg", + "ë­“" => "mweogs", "ë­”" => "mweon", "ë­•" => "mweonj", "ë­–" => "mweonh", "ë­—" => "mweod", "ë­˜" => "mweol", + "ë­™" => "mweolg", "ë­š" => "mweolm", "ë­›" => "mweolb", "ë­œ" => "mweols", "ë­" => "mweolt", "ë­ž" => "mweolp", + "ë­Ÿ" => "mweolh", "ë­ " => "mweom", "ë­¡" => "mweob", "ë­¢" => "mweobs", "ë­£" => "mweos", "ë­¤" => "mweoss", + "ë­¥" => "mweong", "ë­¦" => "mweoj", "ë­§" => "mweoc", "ë­¨" => "mweok", "ë­©" => "mweot", "ë­ª" => "mweop", + "ë­«" => "mweoh", "ë­¬" => "mwe", "ë­­" => "mweg", "ë­®" => "mwegg", "ë­¯" => "mwegs", "ë­°" => "mwen", + "ë­±" => "mwenj", "ë­²" => "mwenh", "ë­³" => "mwed", "ë­´" => "mwel", "ë­µ" => "mwelg", "ë­¶" => "mwelm", + "ë­·" => "mwelb", "ë­¸" => "mwels", "ë­¹" => "mwelt", "ë­º" => "mwelp", "ë­»" => "mwelh", "ë­¼" => "mwem", + "ë­½" => "mweb", "ë­¾" => "mwebs", "ë­¿" => "mwes", "뮀" => "mwess", "ë®" => "mweng", "뮂" => "mwej", + "뮃" => "mwec", "뮄" => "mwek", "ë®…" => "mwet", "뮆" => "mwep", "뮇" => "mweh", "뮈" => "mwi", + "뮉" => "mwig", "뮊" => "mwigg", "뮋" => "mwigs", "뮌" => "mwin", "ë®" => "mwinj", "뮎" => "mwinh", + "ë®" => "mwid", "ë®" => "mwil", "뮑" => "mwilg", "ë®’" => "mwilm", "뮓" => "mwilb", "ë®”" => "mwils", + "뮕" => "mwilt", "ë®–" => "mwilp", "ë®—" => "mwilh", "뮘" => "mwim", "ë®™" => "mwib", "뮚" => "mwibs", + "ë®›" => "mwis", "뮜" => "mwiss", "ë®" => "mwing", "뮞" => "mwij", "뮟" => "mwic", "ë® " => "mwik", + "뮡" => "mwit", "뮢" => "mwip", "뮣" => "mwih", "뮤" => "myu", "뮥" => "myug", "뮦" => "myugg", + "뮧" => "myugs", "뮨" => "myun", "뮩" => "myunj", "뮪" => "myunh", "뮫" => "myud", "뮬" => "myul", + "ë®­" => "myulg", "ë®®" => "myulm", "뮯" => "myulb", "ë®°" => "myuls", "ë®±" => "myult", "뮲" => "myulp", + "뮳" => "myulh", "ë®´" => "myum", "뮵" => "myub", "뮶" => "myubs", "ë®·" => "myus", "뮸" => "myuss", + "뮹" => "myung", "뮺" => "myuj", "ë®»" => "myuc", "뮼" => "myuk", "뮽" => "myut", "뮾" => "myup", + "뮿" => "myuh", "므" => "meu", "ë¯" => "meug", "믂" => "meugg", "믃" => "meugs", "믄" => "meun", + "믅" => "meunj", "믆" => "meunh", "믇" => "meud", "믈" => "meul", "믉" => "meulg", "믊" => "meulm", + "믋" => "meulb", "믌" => "meuls", "ë¯" => "meult", "믎" => "meulp", "ë¯" => "meulh", "ë¯" => "meum", + "믑" => "meub", "믒" => "meubs", "믓" => "meus", "믔" => "meuss", "믕" => "meung", "믖" => "meuj", + "믗" => "meuc", "믘" => "meuk", "믙" => "meut", "믚" => "meup", "믛" => "meuh", "믜" => "myi", + "ë¯" => "myig", "믞" => "myigg", "믟" => "myigs", "믠" => "myin", "믡" => "myinj", "믢" => "myinh", + "믣" => "myid", "믤" => "myil", "믥" => "myilg", "믦" => "myilm", "믧" => "myilb", "믨" => "myils", + "믩" => "myilt", "믪" => "myilp", "믫" => "myilh", "믬" => "myim", "믭" => "myib", "믮" => "myibs", + "믯" => "myis", "믰" => "myiss", "믱" => "mying", "믲" => "myij", "믳" => "myic", "믴" => "myik", + "믵" => "myit", "믶" => "myip", "믷" => "myih", "미" => "mi", "믹" => "mig", "믺" => "migg", + "믻" => "migs", "민" => "min", "믽" => "minj", "믾" => "minh", "믿" => "mid", "ë°" => "milg", + "ë°‚" => "milm", "ë°ƒ" => "milb", "ë°„" => "mils", "ë°…" => "milt", "ë°†" => "milp", "ë°‡" => "milh", + "ë°ˆ" => "mim", "ë°‰" => "mib", "ë°Š" => "mibs", "ë°‹" => "mis", "ë°Œ" => "miss", "ë°" => "ming", + "ë°Ž" => "mij", "ë°" => "mic", "ë°" => "mik", "ë°‘" => "mit", "ë°’" => "mip", "ë°“" => "mih", + "ë°”" => "ba", "ë°•" => "bag", "ë°–" => "bagg", "ë°—" => "bags", "ë°˜" => "ban", "ë°™" => "banj", + "ë°š" => "banh", "ë°›" => "bad", "ë°œ" => "bal", "ë°" => "balg", "ë°ž" => "balm", "ë°Ÿ" => "balb", + "ë° " => "bals", "ë°¡" => "balt", "ë°¢" => "balp", "ë°£" => "balh", "ë°¤" => "bam", "ë°¥" => "bab", + "ë°¦" => "babs", "ë°§" => "bas", "ë°¨" => "bass", "ë°©" => "bang", "ë°ª" => "baj", "ë°«" => "bac", + "ë°¬" => "bak", "ë°­" => "bat", "ë°®" => "bap", "ë°¯" => "bah", "ë°°" => "bae", "ë°±" => "baeg", + "ë°²" => "baegg", "ë°³" => "baegs", "ë°´" => "baen", "ë°µ" => "baenj", "ë°¶" => "baenh", "ë°·" => "baed", + "ë°¸" => "bael", "ë°¹" => "baelg", "ë°º" => "baelm", "ë°»" => "baelb", "ë°¼" => "baels", "ë°½" => "baelt", + "ë°¾" => "baelp", "ë°¿" => "baelh", "ë±€" => "baem", "ë±" => "baeb", "뱂" => "baebs", "뱃" => "baes", + "뱄" => "baess", "ë±…" => "baeng", "뱆" => "baej", "뱇" => "baec", "뱈" => "baek", "뱉" => "baet", + "뱊" => "baep", "뱋" => "baeh", "뱌" => "bya", "ë±" => "byag", "뱎" => "byagg", "ë±" => "byags", + "ë±" => "byan", "뱑" => "byanj", "ë±’" => "byanh", "뱓" => "byad", "ë±”" => "byal", "뱕" => "byalg", + "ë±–" => "byalm", "ë±—" => "byalb", "뱘" => "byals", "ë±™" => "byalt", "뱚" => "byalp", "ë±›" => "byalh", + "뱜" => "byam", "ë±" => "byab", "뱞" => "byabs", "뱟" => "byas", "ë± " => "byass", "뱡" => "byang", + "ë±¢" => "byaj", "ë±£" => "byac", "뱤" => "byak", "ë±¥" => "byat", "뱦" => "byap", "뱧" => "byah", + "뱨" => "byae", "뱩" => "byaeg", "뱪" => "byaegg", "뱫" => "byaegs", "뱬" => "byaen", "ë±­" => "byaenj", + "ë±®" => "byaenh", "뱯" => "byaed", "ë±°" => "byael", "ë±±" => "byaelg", "ë±²" => "byaelm", "ë±³" => "byaelb", + "ë±´" => "byaels", "ë±µ" => "byaelt", "뱶" => "byaelp", "ë±·" => "byaelh", "뱸" => "byaem", "ë±¹" => "byaeb", + "뱺" => "byaebs", "ë±»" => "byaes", "ë±¼" => "byaess", "ë±½" => "byaeng", "ë±¾" => "byaej", "뱿" => "byaec", + "ë²€" => "byaek", "ë²" => "byaet", "벂" => "byaep", "벃" => "byaeh", "버" => "beo", "ë²…" => "beog", + "벆" => "beogg", "벇" => "beogs", "번" => "beon", "벉" => "beonj", "벊" => "beonh", "벋" => "beod", + "벌" => "beol", "ë²" => "beolg", "벎" => "beolm", "ë²" => "beolb", "ë²" => "beols", "벑" => "beolt", + "ë²’" => "beolp", "벓" => "beolh", "ë²”" => "beom", "법" => "beob", "ë²–" => "beobs", "ë²—" => "beos", + "벘" => "beoss", "ë²™" => "beong", "벚" => "beoj", "ë²›" => "beoc", "벜" => "beok", "ë²" => "beot", + "벞" => "beop", "벟" => "beoh", "ë² " => "be", "벡" => "beg", "ë²¢" => "begg", "ë²£" => "begs", + "벤" => "ben", "ë²¥" => "benj", "벦" => "benh", "벧" => "bed", "벨" => "bel", "벩" => "belg", + "벪" => "belm", "벫" => "belb", "벬" => "bels", "ë²­" => "belt", "ë²®" => "belp", "벯" => "belh", + "ë²°" => "bem", "ë²±" => "beb", "ë²²" => "bebs", "ë²³" => "bes", "ë²´" => "bess", "ë²µ" => "beng", + "벶" => "bej", "ë²·" => "bec", "벸" => "bek", "ë²¹" => "bet", "벺" => "bep", "ë²»" => "beh", + "ë²¼" => "byeo", "ë²½" => "byeog", "ë²¾" => "byeogg", "벿" => "byeogs", "ë³€" => "byeon", "ë³" => "byeonj", + "볂" => "byeonh", "볃" => "byeod", "별" => "byeol", "ë³…" => "byeolg", "볆" => "byeolm", "볇" => "byeolb", + "볈" => "byeols", "볉" => "byeolt", "볊" => "byeolp", "볋" => "byeolh", "볌" => "byeom", "ë³" => "byeob", + "볎" => "byeobs", "ë³" => "byeos", "ë³" => "byeoss", "병" => "byeong", "ë³’" => "byeoj", "볓" => "byeoc", + "ë³”" => "byeok", "볕" => "byeot", "ë³–" => "byeop", "ë³—" => "byeoh", "볘" => "bye", "ë³™" => "byeg", + "볚" => "byegg", "ë³›" => "byegs", "볜" => "byen", "ë³" => "byenj", "볞" => "byenh", "볟" => "byed", + "ë³ " => "byel", "볡" => "byelg", "ë³¢" => "byelm", "ë³£" => "byelb", "볤" => "byels", "ë³¥" => "byelt", + "볦" => "byelp", "볧" => "byelh", "볨" => "byem", "볩" => "byeb", "볪" => "byebs", "볫" => "byes", + "볬" => "byess", "ë³­" => "byeng", "ë³®" => "byej", "볯" => "byec", "ë³°" => "byek", "ë³±" => "byet", + "ë³²" => "byep", "ë³³" => "byeh", "ë³´" => "bo", "ë³µ" => "bog", "볶" => "bogg", "ë³·" => "bogs", + "본" => "bon", "ë³¹" => "bonj", "볺" => "bonh", "ë³»" => "bod", "ë³¼" => "bol", "ë³½" => "bolg", + "ë³¾" => "bolm", "볿" => "bolb", "ë´" => "bolt", "ë´‚" => "bolp", "ë´ƒ" => "bolh", "ë´„" => "bom", + "ë´…" => "bob", "ë´†" => "bobs", "ë´‡" => "bos", "ë´ˆ" => "boss", "ë´‰" => "bong", "ë´Š" => "boj", + "ë´‹" => "boc", "ë´Œ" => "bok", "ë´" => "bot", "ë´Ž" => "bop", "ë´" => "boh", "ë´" => "bwa", + "ë´‘" => "bwag", "ë´’" => "bwagg", "ë´“" => "bwags", "ë´”" => "bwan", "ë´•" => "bwanj", "ë´–" => "bwanh", + "ë´—" => "bwad", "ë´˜" => "bwal", "ë´™" => "bwalg", "ë´š" => "bwalm", "ë´›" => "bwalb", "ë´œ" => "bwals", + "ë´" => "bwalt", "ë´ž" => "bwalp", "ë´Ÿ" => "bwalh", "ë´ " => "bwam", "ë´¡" => "bwab", "ë´¢" => "bwabs", + "ë´£" => "bwas", "ë´¤" => "bwass", "ë´¥" => "bwang", "ë´¦" => "bwaj", "ë´§" => "bwac", "ë´¨" => "bwak", + "ë´©" => "bwat", "ë´ª" => "bwap", "ë´«" => "bwah", "ë´¬" => "bwae", "ë´­" => "bwaeg", "ë´®" => "bwaegg", + "ë´¯" => "bwaegs", "ë´°" => "bwaen", "ë´±" => "bwaenj", "ë´²" => "bwaenh", "ë´³" => "bwaed", "ë´´" => "bwael", + "ë´µ" => "bwaelg", "ë´¶" => "bwaelm", "ë´·" => "bwaelb", "ë´¸" => "bwaels", "ë´¹" => "bwaelt", "ë´º" => "bwaelp", + "ë´»" => "bwaelh", "ë´¼" => "bwaem", "ë´½" => "bwaeb", "ë´¾" => "bwaebs", "ë´¿" => "bwaes", "ëµ€" => "bwaess", + "ëµ" => "bwaeng", "뵂" => "bwaej", "뵃" => "bwaec", "뵄" => "bwaek", "ëµ…" => "bwaet", "뵆" => "bwaep", + "뵇" => "bwaeh", "뵈" => "boe", "뵉" => "boeg", "뵊" => "boegg", "뵋" => "boegs", "뵌" => "boen", + "ëµ" => "boenj", "뵎" => "boenh", "ëµ" => "boed", "ëµ" => "boel", "뵑" => "boelg", "ëµ’" => "boelm", + "뵓" => "boelb", "ëµ”" => "boels", "뵕" => "boelt", "ëµ–" => "boelp", "ëµ—" => "boelh", "뵘" => "boem", + "ëµ™" => "boeb", "뵚" => "boebs", "ëµ›" => "boes", "뵜" => "boess", "ëµ" => "boeng", "뵞" => "boej", + "뵟" => "boec", "ëµ " => "boek", "뵡" => "boet", "ëµ¢" => "boep", "ëµ£" => "boeh", "뵤" => "byo", + "ëµ¥" => "byog", "뵦" => "byogg", "뵧" => "byogs", "뵨" => "byon", "뵩" => "byonj", "뵪" => "byonh", + "뵫" => "byod", "뵬" => "byol", "ëµ­" => "byolg", "ëµ®" => "byolm", "뵯" => "byolb", "ëµ°" => "byols", + "ëµ±" => "byolt", "ëµ²" => "byolp", "ëµ³" => "byolh", "ëµ´" => "byom", "ëµµ" => "byob", "뵶" => "byobs", + "ëµ·" => "byos", "뵸" => "byoss", "ëµ¹" => "byong", "뵺" => "byoj", "ëµ»" => "byoc", "ëµ¼" => "byok", + "ëµ½" => "byot", "ëµ¾" => "byop", "뵿" => "byoh", "부" => "bu", "ë¶" => "bug", "붂" => "bugg", + "붃" => "bugs", "분" => "bun", "붅" => "bunj", "붆" => "bunh", "붇" => "bud", "불" => "bul", + "붉" => "bulg", "붊" => "bulm", "붋" => "bulb", "붌" => "buls", "ë¶" => "bult", "붎" => "bulp", + "ë¶" => "bulh", "ë¶" => "bum", "붑" => "bub", "붒" => "bubs", "붓" => "bus", "붔" => "buss", + "붕" => "bung", "붖" => "buj", "붗" => "buc", "붘" => "buk", "붙" => "but", "붚" => "bup", + "붛" => "buh", "붜" => "bweo", "ë¶" => "bweog", "붞" => "bweogg", "붟" => "bweogs", "붠" => "bweon", + "붡" => "bweonj", "붢" => "bweonh", "붣" => "bweod", "붤" => "bweol", "붥" => "bweolg", "붦" => "bweolm", + "붧" => "bweolb", "붨" => "bweols", "붩" => "bweolt", "붪" => "bweolp", "붫" => "bweolh", "붬" => "bweom", + "붭" => "bweob", "붮" => "bweobs", "붯" => "bweos", "붰" => "bweoss", "붱" => "bweong", "붲" => "bweoj", + "붳" => "bweoc", "붴" => "bweok", "붵" => "bweot", "붶" => "bweop", "붷" => "bweoh", "붸" => "bwe", + "붹" => "bweg", "붺" => "bwegg", "붻" => "bwegs", "붼" => "bwen", "붽" => "bwenj", "붾" => "bwenh", + "붿" => "bwed", "ë·€" => "bwel", "ë·" => "bwelg", "ë·‚" => "bwelm", "ë·ƒ" => "bwelb", "ë·„" => "bwels", + "ë·…" => "bwelt", "ë·†" => "bwelp", "ë·‡" => "bwelh", "ë·ˆ" => "bwem", "ë·‰" => "bweb", "ë·Š" => "bwebs", + "ë·‹" => "bwes", "ë·Œ" => "bwess", "ë·" => "bweng", "ë·Ž" => "bwej", "ë·" => "bwec", "ë·" => "bwek", + "ë·‘" => "bwet", "ë·’" => "bwep", "ë·“" => "bweh", "ë·”" => "bwi", "ë·•" => "bwig", "ë·–" => "bwigg", + "ë·—" => "bwigs", "ë·˜" => "bwin", "ë·™" => "bwinj", "ë·š" => "bwinh", "ë·›" => "bwid", "ë·œ" => "bwil", + "ë·" => "bwilg", "ë·ž" => "bwilm", "ë·Ÿ" => "bwilb", "ë· " => "bwils", "ë·¡" => "bwilt", "ë·¢" => "bwilp", + "ë·£" => "bwilh", "ë·¤" => "bwim", "ë·¥" => "bwib", "ë·¦" => "bwibs", "ë·§" => "bwis", "ë·¨" => "bwiss", + "ë·©" => "bwing", "ë·ª" => "bwij", "ë·«" => "bwic", "ë·¬" => "bwik", "ë·­" => "bwit", "ë·®" => "bwip", + "ë·¯" => "bwih", "ë·°" => "byu", "ë·±" => "byug", "ë·²" => "byugg", "ë·³" => "byugs", "ë·´" => "byun", + "ë·µ" => "byunj", "ë·¶" => "byunh", "ë··" => "byud", "ë·¸" => "byul", "ë·¹" => "byulg", "ë·º" => "byulm", + "ë·»" => "byulb", "ë·¼" => "byuls", "ë·½" => "byult", "ë·¾" => "byulp", "ë·¿" => "byulh", "ë¸" => "byub", + "븂" => "byubs", "븃" => "byus", "븄" => "byuss", "븅" => "byung", "븆" => "byuj", "븇" => "byuc", + "븈" => "byuk", "븉" => "byut", "븊" => "byup", "븋" => "byuh", "브" => "beu", "ë¸" => "beug", + "븎" => "beugg", "ë¸" => "beugs", "ë¸" => "beun", "븑" => "beunj", "븒" => "beunh", "븓" => "beud", + "블" => "beul", "븕" => "beulg", "븖" => "beulm", "븗" => "beulb", "븘" => "beuls", "븙" => "beult", + "븚" => "beulp", "븛" => "beulh", "븜" => "beum", "ë¸" => "beub", "븞" => "beubs", "븟" => "beus", + "븠" => "beuss", "븡" => "beung", "븢" => "beuj", "븣" => "beuc", "븤" => "beuk", "븥" => "beut", + "븦" => "beup", "븧" => "beuh", "븨" => "byi", "븩" => "byig", "븪" => "byigg", "븫" => "byigs", + "븬" => "byin", "븭" => "byinj", "븮" => "byinh", "븯" => "byid", "븰" => "byil", "븱" => "byilg", + "븲" => "byilm", "븳" => "byilb", "븴" => "byils", "븵" => "byilt", "븶" => "byilp", "븷" => "byilh", + "븸" => "byim", "븹" => "byib", "븺" => "byibs", "븻" => "byis", "븼" => "byiss", "븽" => "bying", + "븾" => "byij", "븿" => "byic", "ë¹€" => "byik", "ë¹" => "byit", "빂" => "byip", "빃" => "byih", + "비" => "bi", "ë¹…" => "big", "빆" => "bigg", "빇" => "bigs", "빈" => "bin", "빉" => "binj", + "빊" => "binh", "빋" => "bid", "빌" => "bil", "ë¹" => "bilg", "빎" => "bilm", "ë¹" => "bilb", + "ë¹" => "bils", "빑" => "bilt", "ë¹’" => "bilp", "빓" => "bilh", "ë¹”" => "bim", "빕" => "bib", + "ë¹–" => "bibs", "ë¹—" => "bis", "빘" => "biss", "ë¹™" => "bing", "빚" => "bij", "ë¹›" => "bic", + "빜" => "bik", "ë¹" => "bit", "빞" => "bip", "빟" => "bih", "ë¹ " => "bba", "빡" => "bbag", + "ë¹¢" => "bbagg", "ë¹£" => "bbags", "빤" => "bban", "ë¹¥" => "bbanj", "빦" => "bbanh", "빧" => "bbad", + "빨" => "bbal", "빩" => "bbalg", "빪" => "bbalm", "빫" => "bbalb", "빬" => "bbals", "ë¹­" => "bbalt", + "ë¹®" => "bbalp", "빯" => "bbalh", "ë¹°" => "bbam", "ë¹±" => "bbab", "ë¹²" => "bbabs", "ë¹³" => "bbas", + "ë¹´" => "bbass", "ë¹µ" => "bbang", "빶" => "bbaj", "ë¹·" => "bbac", "빸" => "bbak", "ë¹¹" => "bbat", + "빺" => "bbap", "ë¹»" => "bbah", "ë¹¼" => "bbae", "ë¹½" => "bbaeg", "ë¹¾" => "bbaegg", "빿" => "bbaegs", + "뺀" => "bbaen", "ëº" => "bbaenj", "뺂" => "bbaenh", "뺃" => "bbaed", "뺄" => "bbael", "뺅" => "bbaelg", + "뺆" => "bbaelm", "뺇" => "bbaelb", "뺈" => "bbaels", "뺉" => "bbaelt", "뺊" => "bbaelp", "뺋" => "bbaelh", + "뺌" => "bbaem", "ëº" => "bbaeb", "뺎" => "bbaebs", "ëº" => "bbaes", "ëº" => "bbaess", "뺑" => "bbaeng", + "뺒" => "bbaej", "뺓" => "bbaec", "뺔" => "bbaek", "뺕" => "bbaet", "뺖" => "bbaep", "뺗" => "bbaeh", + "뺘" => "bbya", "뺙" => "bbyag", "뺚" => "bbyagg", "뺛" => "bbyags", "뺜" => "bbyan", "ëº" => "bbyanj", + "뺞" => "bbyanh", "뺟" => "bbyad", "뺠" => "bbyal", "뺡" => "bbyalg", "뺢" => "bbyalm", "뺣" => "bbyalb", + "뺤" => "bbyals", "뺥" => "bbyalt", "뺦" => "bbyalp", "뺧" => "bbyalh", "뺨" => "bbyam", "뺩" => "bbyab", + "뺪" => "bbyabs", "뺫" => "bbyas", "뺬" => "bbyass", "뺭" => "bbyang", "뺮" => "bbyaj", "뺯" => "bbyac", + "뺰" => "bbyak", "뺱" => "bbyat", "뺲" => "bbyap", "뺳" => "bbyah", "뺴" => "bbyae", "뺵" => "bbyaeg", + "뺶" => "bbyaegg", "뺷" => "bbyaegs", "뺸" => "bbyaen", "뺹" => "bbyaenj", "뺺" => "bbyaenh", "뺻" => "bbyaed", + "뺼" => "bbyael", "뺽" => "bbyaelg", "뺾" => "bbyaelm", "뺿" => "bbyaelb", "뻀" => "bbyaels", "ë»" => "bbyaelt", + "뻂" => "bbyaelp", "뻃" => "bbyaelh", "뻄" => "bbyaem", "ë»…" => "bbyaeb", "뻆" => "bbyaebs", "뻇" => "bbyaes", + "뻈" => "bbyaess", "뻉" => "bbyaeng", "뻊" => "bbyaej", "뻋" => "bbyaec", "뻌" => "bbyaek", "ë»" => "bbyaet", + "뻎" => "bbyaep", "ë»" => "bbyaeh", "ë»" => "bbeo", "뻑" => "bbeog", "ë»’" => "bbeogg", "뻓" => "bbeogs", + "ë»”" => "bbeon", "뻕" => "bbeonj", "ë»–" => "bbeonh", "ë»—" => "bbeod", "뻘" => "bbeol", "ë»™" => "bbeolg", + "뻚" => "bbeolm", "ë»›" => "bbeolb", "뻜" => "bbeols", "ë»" => "bbeolt", "뻞" => "bbeolp", "뻟" => "bbeolh", + "ë» " => "bbeom", "뻡" => "bbeob", "뻢" => "bbeobs", "뻣" => "bbeos", "뻤" => "bbeoss", "뻥" => "bbeong", + "뻦" => "bbeoj", "뻧" => "bbeoc", "뻨" => "bbeok", "뻩" => "bbeot", "뻪" => "bbeop", "뻫" => "bbeoh", + "뻬" => "bbe", "ë»­" => "bbeg", "ë»®" => "bbegg", "뻯" => "bbegs", "ë»°" => "bben", "ë»±" => "bbenj", + "뻲" => "bbenh", "뻳" => "bbed", "ë»´" => "bbel", "뻵" => "bbelg", "뻶" => "bbelm", "ë»·" => "bbelb", + "뻸" => "bbels", "뻹" => "bbelt", "뻺" => "bbelp", "ë»»" => "bbelh", "뻼" => "bbem", "뻽" => "bbeb", + "뻾" => "bbebs", "뻿" => "bbes", "ë¼" => "bbeng", "뼂" => "bbej", "뼃" => "bbec", "뼄" => "bbek", + "ë¼…" => "bbet", "뼆" => "bbep", "뼇" => "bbeh", "뼈" => "bbyeo", "뼉" => "bbyeog", "뼊" => "bbyeogg", + "뼋" => "bbyeogs", "뼌" => "bbyeon", "ë¼" => "bbyeonj", "뼎" => "bbyeonh", "ë¼" => "bbyeod", "ë¼" => "bbyeol", + "뼑" => "bbyeolg", "ë¼’" => "bbyeolm", "뼓" => "bbyeolb", "ë¼”" => "bbyeols", "뼕" => "bbyeolt", "ë¼–" => "bbyeolp", + "ë¼—" => "bbyeolh", "뼘" => "bbyeom", "ë¼™" => "bbyeob", "뼚" => "bbyeobs", "ë¼›" => "bbyeos", "뼜" => "bbyeoss", + "ë¼" => "bbyeong", "뼞" => "bbyeoj", "뼟" => "bbyeoc", "ë¼ " => "bbyeok", "뼡" => "bbyeot", "ë¼¢" => "bbyeop", + "ë¼£" => "bbyeoh", "뼤" => "bbye", "ë¼¥" => "bbyeg", "뼦" => "bbyegg", "뼧" => "bbyegs", "뼨" => "bbyen", + "뼩" => "bbyenj", "뼪" => "bbyenh", "뼫" => "bbyed", "뼬" => "bbyel", "ë¼­" => "bbyelg", "ë¼®" => "bbyelm", + "뼯" => "bbyelb", "ë¼°" => "bbyels", "ë¼±" => "bbyelt", "ë¼²" => "bbyelp", "ë¼³" => "bbyelh", "ë¼´" => "bbyem", + "ë¼µ" => "bbyeb", "뼶" => "bbyebs", "ë¼·" => "bbyes", "뼸" => "bbyess", "ë¼¹" => "bbyeng", "뼺" => "bbyej", + "ë¼»" => "bbyec", "ë¼¼" => "bbyek", "ë¼½" => "bbyet", "ë¼¾" => "bbyep", "뼿" => "bbyeh", "ë½€" => "bbo", + "ë½" => "bbog", "뽂" => "bbogg", "뽃" => "bbogs", "뽄" => "bbon", "ë½…" => "bbonj", "뽆" => "bbonh", + "뽇" => "bbod", "뽈" => "bbol", "뽉" => "bbolg", "뽊" => "bbolm", "뽋" => "bbolb", "뽌" => "bbols", + "ë½" => "bbolt", "뽎" => "bbolp", "ë½" => "bbolh", "ë½" => "bbom", "뽑" => "bbob", "ë½’" => "bbobs", + "뽓" => "bbos", "ë½”" => "bboss", "뽕" => "bbong", "ë½–" => "bboj", "ë½—" => "bboc", "뽘" => "bbok", + "ë½™" => "bbot", "뽚" => "bbop", "ë½›" => "bboh", "뽜" => "bbwa", "ë½" => "bbwag", "뽞" => "bbwagg", + "뽟" => "bbwags", "ë½ " => "bbwan", "뽡" => "bbwanj", "ë½¢" => "bbwanh", "ë½£" => "bbwad", "뽤" => "bbwal", + "ë½¥" => "bbwalg", "뽦" => "bbwalm", "뽧" => "bbwalb", "뽨" => "bbwals", "뽩" => "bbwalt", "뽪" => "bbwalp", + "뽫" => "bbwalh", "뽬" => "bbwam", "ë½­" => "bbwab", "ë½®" => "bbwabs", "뽯" => "bbwas", "ë½°" => "bbwass", + "ë½±" => "bbwang", "ë½²" => "bbwaj", "ë½³" => "bbwac", "ë½´" => "bbwak", "ë½µ" => "bbwat", "뽶" => "bbwap", + "ë½·" => "bbwah", "뽸" => "bbwae", "ë½¹" => "bbwaeg", "뽺" => "bbwaegg", "ë½»" => "bbwaegs", "ë½¼" => "bbwaen", + "ë½½" => "bbwaenj", "ë½¾" => "bbwaenh", "뽿" => "bbwaed", "ë¾€" => "bbwael", "ë¾" => "bbwaelg", "뾂" => "bbwaelm", + "뾃" => "bbwaelb", "뾄" => "bbwaels", "ë¾…" => "bbwaelt", "뾆" => "bbwaelp", "뾇" => "bbwaelh", "뾈" => "bbwaem", + "뾉" => "bbwaeb", "뾊" => "bbwaebs", "뾋" => "bbwaes", "뾌" => "bbwaess", "ë¾" => "bbwaeng", "뾎" => "bbwaej", + "ë¾" => "bbwaec", "ë¾" => "bbwaek", "뾑" => "bbwaet", "ë¾’" => "bbwaep", "뾓" => "bbwaeh", "ë¾”" => "bboe", + "뾕" => "bboeg", "ë¾–" => "bboegg", "ë¾—" => "bboegs", "뾘" => "bboen", "ë¾™" => "bboenj", "뾚" => "bboenh", + "ë¾›" => "bboed", "뾜" => "bboel", "ë¾" => "bboelg", "뾞" => "bboelm", "뾟" => "bboelb", "ë¾ " => "bboels", + "뾡" => "bboelt", "ë¾¢" => "bboelp", "ë¾£" => "bboelh", "뾤" => "bboem", "ë¾¥" => "bboeb", "뾦" => "bboebs", + "뾧" => "bboes", "뾨" => "bboess", "뾩" => "bboeng", "뾪" => "bboej", "뾫" => "bboec", "뾬" => "bboek", + "ë¾­" => "bboet", "ë¾®" => "bboep", "뾯" => "bboeh", "ë¾°" => "bbyo", "ë¾±" => "bbyog", "ë¾²" => "bbyogg", + "ë¾³" => "bbyogs", "ë¾´" => "bbyon", "ë¾µ" => "bbyonj", "뾶" => "bbyonh", "ë¾·" => "bbyod", "뾸" => "bbyol", + "ë¾¹" => "bbyolg", "뾺" => "bbyolm", "ë¾»" => "bbyolb", "ë¾¼" => "bbyols", "ë¾½" => "bbyolt", "ë¾¾" => "bbyolp", + "뾿" => "bbyolh", "ë¿€" => "bbyom", "ë¿" => "bbyob", "ë¿‚" => "bbyobs", "뿃" => "bbyos", "ë¿„" => "bbyoss", + "ë¿…" => "bbyong", "뿆" => "bbyoj", "뿇" => "bbyoc", "뿈" => "bbyok", "뿉" => "bbyot", "ë¿Š" => "bbyop", + "ë¿‹" => "bbyoh", "ë¿Œ" => "bbu", "ë¿" => "bbug", "ë¿Ž" => "bbugg", "ë¿" => "bbugs", "ë¿" => "bbun", + "ë¿‘" => "bbunj", "ë¿’" => "bbunh", "ë¿“" => "bbud", "ë¿”" => "bbul", "ë¿•" => "bbulg", "ë¿–" => "bbulm", + "ë¿—" => "bbulb", "뿘" => "bbuls", "ë¿™" => "bbult", "ë¿š" => "bbulp", "ë¿›" => "bbulh", "ë¿œ" => "bbum", + "ë¿" => "bbub", "ë¿ž" => "bbubs", "ë¿Ÿ" => "bbus", "ë¿ " => "bbuss", "ë¿¡" => "bbung", "ë¿¢" => "bbuj", + "ë¿£" => "bbuc", "뿤" => "bbuk", "ë¿¥" => "bbut", "뿦" => "bbup", "뿧" => "bbuh", "뿨" => "bbweo", + "ë¿©" => "bbweog", "뿪" => "bbweogg", "ë¿«" => "bbweogs", "뿬" => "bbweon", "ë¿­" => "bbweonj", "ë¿®" => "bbweonh", + "뿯" => "bbweod", "ë¿°" => "bbweol", "뿱" => "bbweolg", "뿲" => "bbweolm", "뿳" => "bbweolb", "ë¿´" => "bbweols", + "뿵" => "bbweolt", "뿶" => "bbweolp", "ë¿·" => "bbweolh", "뿸" => "bbweom", "뿹" => "bbweob", "뿺" => "bbweobs", + "ë¿»" => "bbweos", "뿼" => "bbweoss", "뿽" => "bbweong", "뿾" => "bbweoj", "ë¿¿" => "bbweoc", "ì€" => "bbweot", + "쀂" => "bbweop", "쀃" => "bbweoh", "쀄" => "bbwe", "쀅" => "bbweg", "쀆" => "bbwegg", "쀇" => "bbwegs", + "쀈" => "bbwen", "쀉" => "bbwenj", "쀊" => "bbwenh", "쀋" => "bbwed", "쀌" => "bbwel", "ì€" => "bbwelg", + "쀎" => "bbwelm", "ì€" => "bbwelb", "ì€" => "bbwels", "쀑" => "bbwelt", "쀒" => "bbwelp", "쀓" => "bbwelh", + "쀔" => "bbwem", "쀕" => "bbweb", "쀖" => "bbwebs", "쀗" => "bbwes", "쀘" => "bbwess", "쀙" => "bbweng", + "쀚" => "bbwej", "쀛" => "bbwec", "쀜" => "bbwek", "ì€" => "bbwet", "쀞" => "bbwep", "쀟" => "bbweh", + "쀠" => "bbwi", "쀡" => "bbwig", "쀢" => "bbwigg", "쀣" => "bbwigs", "쀤" => "bbwin", "쀥" => "bbwinj", + "쀦" => "bbwinh", "쀧" => "bbwid", "쀨" => "bbwil", "쀩" => "bbwilg", "쀪" => "bbwilm", "쀫" => "bbwilb", + "쀬" => "bbwils", "쀭" => "bbwilt", "쀮" => "bbwilp", "쀯" => "bbwilh", "쀰" => "bbwim", "쀱" => "bbwib", + "쀲" => "bbwibs", "쀳" => "bbwis", "쀴" => "bbwiss", "쀵" => "bbwing", "쀶" => "bbwij", "쀷" => "bbwic", + "쀸" => "bbwik", "쀹" => "bbwit", "쀺" => "bbwip", "쀻" => "bbwih", "쀼" => "bbyu", "쀽" => "bbyug", + "쀾" => "bbyugg", "쀿" => "bbyugs", "ì€" => "bbyun", "ì" => "bbyunj", "ì‚" => "bbyunh", "ìƒ" => "bbyud", + "ì„" => "bbyul", "ì…" => "bbyulg", "ì†" => "bbyulm", "ì‡" => "bbyulb", "ìˆ" => "bbyuls", "ì‰" => "bbyult", + "ìŠ" => "bbyulp", "ì‹" => "bbyulh", "ìŒ" => "bbyum", "ì" => "bbyub", "ìŽ" => "bbyubs", "ì" => "bbyus", + "ì" => "bbyuss", "ì‘" => "bbyung", "ì’" => "bbyuj", "ì“" => "bbyuc", "ì”" => "bbyuk", "ì•" => "bbyut", + "ì–" => "bbyup", "ì—" => "bbyuh", "ì˜" => "bbeu", "ì™" => "bbeug", "ìš" => "bbeugg", "ì›" => "bbeugs", + "ìœ" => "bbeun", "ì" => "bbeunj", "ìž" => "bbeunh", "ìŸ" => "bbeud", "ì " => "bbeul", "ì¡" => "bbeulg", + "ì¢" => "bbeulm", "ì£" => "bbeulb", "ì¤" => "bbeuls", "ì¥" => "bbeult", "ì¦" => "bbeulp", "ì§" => "bbeulh", + "ì¨" => "bbeum", "ì©" => "bbeub", "ìª" => "bbeubs", "ì«" => "bbeus", "ì¬" => "bbeuss", "ì­" => "bbeung", + "ì®" => "bbeuj", "ì¯" => "bbeuc", "ì°" => "bbeuk", "ì±" => "bbeut", "ì²" => "bbeup", "ì³" => "bbeuh", + "ì´" => "bbyi", "ìµ" => "bbyig", "ì¶" => "bbyigg", "ì·" => "bbyigs", "ì¸" => "bbyin", "ì¹" => "bbyinj", + "ìº" => "bbyinh", "ì»" => "bbyid", "ì¼" => "bbyil", "ì½" => "bbyilg", "ì¾" => "bbyilm", "ì¿" => "bbyilb", + "ì‚€" => "bbyils", "ì‚" => "bbyilt", "ì‚‚" => "bbyilp", "삃" => "bbyilh", "ì‚„" => "bbyim", "ì‚…" => "bbyib", + "삆" => "bbyibs", "삇" => "bbyis", "삈" => "bbyiss", "삉" => "bbying", "ì‚Š" => "bbyij", "ì‚‹" => "bbyic", + "ì‚Œ" => "bbyik", "ì‚" => "bbyit", "ì‚Ž" => "bbyip", "ì‚" => "bbyih", "ì‚" => "bbi", "ì‚‘" => "bbig", + "ì‚’" => "bbigg", "ì‚“" => "bbigs", "ì‚”" => "bbin", "ì‚•" => "bbinj", "ì‚–" => "bbinh", "ì‚—" => "bbid", + "삘" => "bbil", "ì‚™" => "bbilg", "ì‚š" => "bbilm", "ì‚›" => "bbilb", "ì‚œ" => "bbils", "ì‚" => "bbilt", + "ì‚ž" => "bbilp", "ì‚Ÿ" => "bbilh", "ì‚ " => "bbim", "ì‚¡" => "bbib", "ì‚¢" => "bbibs", "ì‚£" => "bbis", + "삤" => "bbiss", "ì‚¥" => "bbing", "삦" => "bbij", "삧" => "bbic", "삨" => "bbik", "ì‚©" => "bbit", + "삪" => "bbip", "ì‚«" => "bbih", "사" => "sa", "ì‚­" => "sag", "ì‚®" => "sagg", "삯" => "sags", + "ì‚°" => "san", "삱" => "sanj", "삲" => "sanh", "삳" => "sad", "ì‚´" => "sal", "삵" => "salg", + "삶" => "salm", "ì‚·" => "salb", "삸" => "sals", "삹" => "salt", "삺" => "salp", "ì‚»" => "salh", + "삼" => "sam", "삽" => "sab", "삾" => "sabs", "ì‚¿" => "sas", "샀" => "sass", "ìƒ" => "sang", + "샂" => "saj", "샃" => "sac", "샄" => "sak", "샅" => "sat", "샆" => "sap", "샇" => "sah", + "새" => "sae", "색" => "saeg", "샊" => "saegg", "샋" => "saegs", "샌" => "saen", "ìƒ" => "saenj", + "샎" => "saenh", "ìƒ" => "saed", "ìƒ" => "sael", "샑" => "saelg", "샒" => "saelm", "샓" => "saelb", + "샔" => "saels", "샕" => "saelt", "샖" => "saelp", "샗" => "saelh", "샘" => "saem", "샙" => "saeb", + "샚" => "saebs", "샛" => "saes", "샜" => "saess", "ìƒ" => "saeng", "샞" => "saej", "샟" => "saec", + "샠" => "saek", "샡" => "saet", "샢" => "saep", "샣" => "saeh", "샤" => "sya", "샥" => "syag", + "샦" => "syagg", "샧" => "syags", "샨" => "syan", "샩" => "syanj", "샪" => "syanh", "샫" => "syad", + "샬" => "syal", "샭" => "syalg", "샮" => "syalm", "샯" => "syalb", "샰" => "syals", "샱" => "syalt", + "샲" => "syalp", "샳" => "syalh", "샴" => "syam", "샵" => "syab", "샶" => "syabs", "샷" => "syas", + "샸" => "syass", "샹" => "syang", "샺" => "syaj", "샻" => "syac", "샼" => "syak", "샽" => "syat", + "샾" => "syap", "샿" => "syah", "ì„" => "syaeg", "ì„‚" => "syaegg", "섃" => "syaegs", "ì„„" => "syaen", + "ì„…" => "syaenj", "섆" => "syaenh", "섇" => "syaed", "섈" => "syael", "섉" => "syaelg", "ì„Š" => "syaelm", + "ì„‹" => "syaelb", "ì„Œ" => "syaels", "ì„" => "syaelt", "ì„Ž" => "syaelp", "ì„" => "syaelh", "ì„" => "syaem", + "ì„‘" => "syaeb", "ì„’" => "syaebs", "ì„“" => "syaes", "ì„”" => "syaess", "ì„•" => "syaeng", "ì„–" => "syaej", + "ì„—" => "syaec", "섘" => "syaek", "ì„™" => "syaet", "ì„š" => "syaep", "ì„›" => "syaeh", "ì„œ" => "seo", + "ì„" => "seog", "ì„ž" => "seogg", "ì„Ÿ" => "seogs", "ì„ " => "seon", "ì„¡" => "seonj", "ì„¢" => "seonh", + "ì„£" => "seod", "설" => "seol", "ì„¥" => "seolg", "섦" => "seolm", "섧" => "seolb", "섨" => "seols", + "ì„©" => "seolt", "섪" => "seolp", "ì„«" => "seolh", "섬" => "seom", "ì„­" => "seob", "ì„®" => "seobs", + "섯" => "seos", "ì„°" => "seoss", "성" => "seong", "섲" => "seoj", "섳" => "seoc", "ì„´" => "seok", + "섵" => "seot", "섶" => "seop", "ì„·" => "seoh", "세" => "se", "섹" => "seg", "섺" => "segg", + "ì„»" => "segs", "센" => "sen", "섽" => "senj", "섾" => "senh", "ì„¿" => "sed", "ì…€" => "sel", + "ì…" => "selg", "ì…‚" => "selm", "ì…ƒ" => "selb", "ì…„" => "sels", "ì……" => "selt", "ì…†" => "selp", + "ì…‡" => "selh", "ì…ˆ" => "sem", "ì…‰" => "seb", "ì…Š" => "sebs", "ì…‹" => "ses", "ì…Œ" => "sess", + "ì…" => "seng", "ì…Ž" => "sej", "ì…" => "sec", "ì…" => "sek", "ì…‘" => "set", "ì…’" => "sep", + "ì…“" => "seh", "ì…”" => "syeo", "ì…•" => "syeog", "ì…–" => "syeogg", "ì…—" => "syeogs", "ì…˜" => "syeon", + "ì…™" => "syeonj", "ì…š" => "syeonh", "ì…›" => "syeod", "ì…œ" => "syeol", "ì…" => "syeolg", "ì…ž" => "syeolm", + "ì…Ÿ" => "syeolb", "ì… " => "syeols", "ì…¡" => "syeolt", "ì…¢" => "syeolp", "ì…£" => "syeolh", "ì…¤" => "syeom", + "ì…¥" => "syeob", "ì…¦" => "syeobs", "ì…§" => "syeos", "ì…¨" => "syeoss", "ì…©" => "syeong", "ì…ª" => "syeoj", + "ì…«" => "syeoc", "ì…¬" => "syeok", "ì…­" => "syeot", "ì…®" => "syeop", "ì…¯" => "syeoh", "ì…°" => "sye", + "ì…±" => "syeg", "ì…²" => "syegg", "ì…³" => "syegs", "ì…´" => "syen", "ì…µ" => "syenj", "ì…¶" => "syenh", + "ì…·" => "syed", "ì…¸" => "syel", "ì…¹" => "syelg", "ì…º" => "syelm", "ì…»" => "syelb", "ì…¼" => "syels", + "ì…½" => "syelt", "ì…¾" => "syelp", "ì…¿" => "syelh", "솀" => "syem", "ì†" => "syeb", "솂" => "syebs", + "솃" => "syes", "솄" => "syess", "솅" => "syeng", "솆" => "syej", "솇" => "syec", "솈" => "syek", + "솉" => "syet", "솊" => "syep", "솋" => "syeh", "소" => "so", "ì†" => "sog", "솎" => "sogg", + "ì†" => "sogs", "ì†" => "son", "솑" => "sonj", "솒" => "sonh", "솓" => "sod", "솔" => "sol", + "솕" => "solg", "솖" => "solm", "솗" => "solb", "솘" => "sols", "솙" => "solt", "솚" => "solp", + "솛" => "solh", "솜" => "som", "ì†" => "sob", "솞" => "sobs", "솟" => "sos", "솠" => "soss", + "송" => "song", "솢" => "soj", "솣" => "soc", "솤" => "sok", "솥" => "sot", "솦" => "sop", + "솧" => "soh", "솨" => "swa", "솩" => "swag", "솪" => "swagg", "솫" => "swags", "솬" => "swan", + "솭" => "swanj", "솮" => "swanh", "솯" => "swad", "솰" => "swal", "솱" => "swalg", "솲" => "swalm", + "솳" => "swalb", "솴" => "swals", "솵" => "swalt", "솶" => "swalp", "솷" => "swalh", "솸" => "swam", + "솹" => "swab", "솺" => "swabs", "솻" => "swas", "솼" => "swass", "솽" => "swang", "솾" => "swaj", + "솿" => "swac", "쇀" => "swak", "ì‡" => "swat", "쇂" => "swap", "쇃" => "swah", "쇄" => "swae", + "쇅" => "swaeg", "쇆" => "swaegg", "쇇" => "swaegs", "쇈" => "swaen", "쇉" => "swaenj", "쇊" => "swaenh", + "쇋" => "swaed", "쇌" => "swael", "ì‡" => "swaelg", "쇎" => "swaelm", "ì‡" => "swaelb", "ì‡" => "swaels", + "쇑" => "swaelt", "쇒" => "swaelp", "쇓" => "swaelh", "쇔" => "swaem", "쇕" => "swaeb", "쇖" => "swaebs", + "쇗" => "swaes", "쇘" => "swaess", "쇙" => "swaeng", "쇚" => "swaej", "쇛" => "swaec", "쇜" => "swaek", + "ì‡" => "swaet", "쇞" => "swaep", "쇟" => "swaeh", "쇠" => "soe", "쇡" => "soeg", "쇢" => "soegg", + "쇣" => "soegs", "쇤" => "soen", "쇥" => "soenj", "쇦" => "soenh", "쇧" => "soed", "쇨" => "soel", + "쇩" => "soelg", "쇪" => "soelm", "쇫" => "soelb", "쇬" => "soels", "쇭" => "soelt", "쇮" => "soelp", + "쇯" => "soelh", "쇰" => "soem", "쇱" => "soeb", "쇲" => "soebs", "쇳" => "soes", "쇴" => "soess", + "쇵" => "soeng", "쇶" => "soej", "쇷" => "soec", "쇸" => "soek", "쇹" => "soet", "쇺" => "soep", + "쇻" => "soeh", "쇼" => "syo", "쇽" => "syog", "쇾" => "syogg", "쇿" => "syogs", "ìˆ" => "syonj", + "숂" => "syonh", "숃" => "syod", "숄" => "syol", "숅" => "syolg", "숆" => "syolm", "숇" => "syolb", + "숈" => "syols", "숉" => "syolt", "숊" => "syolp", "숋" => "syolh", "숌" => "syom", "ìˆ" => "syob", + "숎" => "syobs", "ìˆ" => "syos", "ìˆ" => "syoss", "숑" => "syong", "숒" => "syoj", "숓" => "syoc", + "숔" => "syok", "숕" => "syot", "숖" => "syop", "숗" => "syoh", "수" => "su", "숙" => "sug", + "숚" => "sugg", "숛" => "sugs", "순" => "sun", "ìˆ" => "sunj", "숞" => "sunh", "숟" => "sud", + "술" => "sul", "숡" => "sulg", "숢" => "sulm", "숣" => "sulb", "숤" => "suls", "숥" => "sult", + "숦" => "sulp", "숧" => "sulh", "숨" => "sum", "숩" => "sub", "숪" => "subs", "숫" => "sus", + "숬" => "suss", "숭" => "sung", "숮" => "suj", "숯" => "suc", "숰" => "suk", "숱" => "sut", + "숲" => "sup", "숳" => "suh", "숴" => "sweo", "숵" => "sweog", "숶" => "sweogg", "숷" => "sweogs", + "숸" => "sweon", "숹" => "sweonj", "숺" => "sweonh", "숻" => "sweod", "숼" => "sweol", "숽" => "sweolg", + "숾" => "sweolm", "숿" => "sweolb", "쉀" => "sweols", "ì‰" => "sweolt", "쉂" => "sweolp", "쉃" => "sweolh", + "쉄" => "sweom", "쉅" => "sweob", "쉆" => "sweobs", "쉇" => "sweos", "쉈" => "sweoss", "쉉" => "sweong", + "쉊" => "sweoj", "쉋" => "sweoc", "쉌" => "sweok", "ì‰" => "sweot", "쉎" => "sweop", "ì‰" => "sweoh", + "ì‰" => "swe", "쉑" => "sweg", "쉒" => "swegg", "쉓" => "swegs", "쉔" => "swen", "쉕" => "swenj", + "쉖" => "swenh", "쉗" => "swed", "쉘" => "swel", "쉙" => "swelg", "쉚" => "swelm", "쉛" => "swelb", + "쉜" => "swels", "ì‰" => "swelt", "쉞" => "swelp", "쉟" => "swelh", "쉠" => "swem", "쉡" => "sweb", + "쉢" => "swebs", "쉣" => "swes", "쉤" => "swess", "쉥" => "sweng", "쉦" => "swej", "쉧" => "swec", + "쉨" => "swek", "쉩" => "swet", "쉪" => "swep", "쉫" => "sweh", "쉬" => "swi", "쉭" => "swig", + "쉮" => "swigg", "쉯" => "swigs", "쉰" => "swin", "쉱" => "swinj", "쉲" => "swinh", "쉳" => "swid", + "쉴" => "swil", "쉵" => "swilg", "쉶" => "swilm", "쉷" => "swilb", "쉸" => "swils", "쉹" => "swilt", + "쉺" => "swilp", "쉻" => "swilh", "쉼" => "swim", "쉽" => "swib", "쉾" => "swibs", "쉿" => "swis", + "슀" => "swiss", "ìŠ" => "swing", "슂" => "swij", "슃" => "swic", "슄" => "swik", "슅" => "swit", + "슆" => "swip", "슇" => "swih", "슈" => "syu", "슉" => "syug", "슊" => "syugg", "슋" => "syugs", + "슌" => "syun", "ìŠ" => "syunj", "슎" => "syunh", "ìŠ" => "syud", "ìŠ" => "syul", "슑" => "syulg", + "슒" => "syulm", "슓" => "syulb", "슔" => "syuls", "슕" => "syult", "슖" => "syulp", "슗" => "syulh", + "슘" => "syum", "슙" => "syub", "슚" => "syubs", "슛" => "syus", "슜" => "syuss", "ìŠ" => "syung", + "슞" => "syuj", "슟" => "syuc", "슠" => "syuk", "슡" => "syut", "슢" => "syup", "슣" => "syuh", + "스" => "seu", "슥" => "seug", "슦" => "seugg", "슧" => "seugs", "슨" => "seun", "슩" => "seunj", + "슪" => "seunh", "슫" => "seud", "슬" => "seul", "슭" => "seulg", "슮" => "seulm", "슯" => "seulb", + "슰" => "seuls", "슱" => "seult", "슲" => "seulp", "슳" => "seulh", "슴" => "seum", "습" => "seub", + "슶" => "seubs", "슷" => "seus", "슸" => "seuss", "승" => "seung", "슺" => "seuj", "슻" => "seuc", + "슼" => "seuk", "슽" => "seut", "슾" => "seup", "슿" => "seuh", "ì‹€" => "syi", "ì‹" => "syig", + "ì‹‚" => "syigg", "싃" => "syigs", "ì‹„" => "syin", "ì‹…" => "syinj", "싆" => "syinh", "싇" => "syid", + "싈" => "syil", "싉" => "syilg", "ì‹Š" => "syilm", "ì‹‹" => "syilb", "ì‹Œ" => "syils", "ì‹" => "syilt", + "ì‹Ž" => "syilp", "ì‹" => "syilh", "ì‹" => "syim", "ì‹‘" => "syib", "ì‹’" => "syibs", "ì‹“" => "syis", + "ì‹”" => "syiss", "ì‹•" => "sying", "ì‹–" => "syij", "ì‹—" => "syic", "싘" => "syik", "ì‹™" => "syit", + "ì‹š" => "syip", "ì‹›" => "syih", "ì‹œ" => "si", "ì‹" => "sig", "ì‹ž" => "sigg", "ì‹Ÿ" => "sigs", + "ì‹ " => "sin", "ì‹¡" => "sinj", "ì‹¢" => "sinh", "ì‹£" => "sid", "실" => "sil", "ì‹¥" => "silg", + "싦" => "silm", "싧" => "silb", "싨" => "sils", "ì‹©" => "silt", "싪" => "silp", "ì‹«" => "silh", + "심" => "sim", "ì‹­" => "sib", "ì‹®" => "sibs", "싯" => "sis", "ì‹°" => "siss", "싱" => "sing", + "싲" => "sij", "싳" => "sic", "ì‹´" => "sik", "싵" => "sit", "싶" => "sip", "ì‹·" => "sih", + "싸" => "ssa", "싹" => "ssag", "싺" => "ssagg", "ì‹»" => "ssags", "싼" => "ssan", "싽" => "ssanj", + "싾" => "ssanh", "ì‹¿" => "ssad", "ìŒ" => "ssalg", "쌂" => "ssalm", "쌃" => "ssalb", "쌄" => "ssals", + "쌅" => "ssalt", "쌆" => "ssalp", "쌇" => "ssalh", "쌈" => "ssam", "쌉" => "ssab", "쌊" => "ssabs", + "쌋" => "ssas", "쌌" => "ssass", "ìŒ" => "ssang", "쌎" => "ssaj", "ìŒ" => "ssac", "ìŒ" => "ssak", + "쌑" => "ssat", "쌒" => "ssap", "쌓" => "ssah", "쌔" => "ssae", "쌕" => "ssaeg", "쌖" => "ssaegg", + "쌗" => "ssaegs", "쌘" => "ssaen", "쌙" => "ssaenj", "쌚" => "ssaenh", "쌛" => "ssaed", "쌜" => "ssael", + "ìŒ" => "ssaelg", "쌞" => "ssaelm", "쌟" => "ssaelb", "쌠" => "ssaels", "쌡" => "ssaelt", "쌢" => "ssaelp", + "쌣" => "ssaelh", "쌤" => "ssaem", "쌥" => "ssaeb", "쌦" => "ssaebs", "쌧" => "ssaes", "쌨" => "ssaess", + "쌩" => "ssaeng", "쌪" => "ssaej", "쌫" => "ssaec", "쌬" => "ssaek", "쌭" => "ssaet", "쌮" => "ssaep", + "쌯" => "ssaeh", "쌰" => "ssya", "쌱" => "ssyag", "쌲" => "ssyagg", "쌳" => "ssyags", "쌴" => "ssyan", + "쌵" => "ssyanj", "쌶" => "ssyanh", "쌷" => "ssyad", "쌸" => "ssyal", "쌹" => "ssyalg", "쌺" => "ssyalm", + "쌻" => "ssyalb", "쌼" => "ssyals", "쌽" => "ssyalt", "쌾" => "ssyalp", "쌿" => "ssyalh", "ì€" => "ssyam", + "ì" => "ssyab", "ì‚" => "ssyabs", "ìƒ" => "ssyas", "ì„" => "ssyass", "ì…" => "ssyang", "ì†" => "ssyaj", + "ì‡" => "ssyac", "ìˆ" => "ssyak", "ì‰" => "ssyat", "ìŠ" => "ssyap", "ì‹" => "ssyah", "ìŒ" => "ssyae", + "ì" => "ssyaeg", "ìŽ" => "ssyaegg", "ì" => "ssyaegs", "ì" => "ssyaen", "ì‘" => "ssyaenj", "ì’" => "ssyaenh", + "ì“" => "ssyaed", "ì”" => "ssyael", "ì•" => "ssyaelg", "ì–" => "ssyaelm", "ì—" => "ssyaelb", "ì˜" => "ssyaels", + "ì™" => "ssyaelt", "ìš" => "ssyaelp", "ì›" => "ssyaelh", "ìœ" => "ssyaem", "ì" => "ssyaeb", "ìž" => "ssyaebs", + "ìŸ" => "ssyaes", "ì " => "ssyaess", "ì¡" => "ssyaeng", "ì¢" => "ssyaej", "ì£" => "ssyaec", "ì¤" => "ssyaek", + "ì¥" => "ssyaet", "ì¦" => "ssyaep", "ì§" => "ssyaeh", "ì¨" => "sseo", "ì©" => "sseog", "ìª" => "sseogg", + "ì«" => "sseogs", "ì¬" => "sseon", "ì­" => "sseonj", "ì®" => "sseonh", "ì¯" => "sseod", "ì°" => "sseol", + "ì±" => "sseolg", "ì²" => "sseolm", "ì³" => "sseolb", "ì´" => "sseols", "ìµ" => "sseolt", "ì¶" => "sseolp", + "ì·" => "sseolh", "ì¸" => "sseom", "ì¹" => "sseob", "ìº" => "sseobs", "ì»" => "sseos", "ì¼" => "sseoss", + "ì½" => "sseong", "ì¾" => "sseoj", "ì¿" => "sseoc", "쎀" => "sseok", "ìŽ" => "sseot", "쎂" => "sseop", + "쎃" => "sseoh", "쎄" => "sse", "쎅" => "sseg", "쎆" => "ssegg", "쎇" => "ssegs", "쎈" => "ssen", + "쎉" => "ssenj", "쎊" => "ssenh", "쎋" => "ssed", "쎌" => "ssel", "ìŽ" => "sselg", "쎎" => "sselm", + "ìŽ" => "sselb", "ìŽ" => "ssels", "쎑" => "sselt", "쎒" => "sselp", "쎓" => "sselh", "쎔" => "ssem", + "쎕" => "sseb", "쎖" => "ssebs", "쎗" => "sses", "쎘" => "ssess", "쎙" => "sseng", "쎚" => "ssej", + "쎛" => "ssec", "쎜" => "ssek", "ìŽ" => "sset", "쎞" => "ssep", "쎟" => "sseh", "쎠" => "ssyeo", + "쎡" => "ssyeog", "쎢" => "ssyeogg", "쎣" => "ssyeogs", "쎤" => "ssyeon", "쎥" => "ssyeonj", "쎦" => "ssyeonh", + "쎧" => "ssyeod", "쎨" => "ssyeol", "쎩" => "ssyeolg", "쎪" => "ssyeolm", "쎫" => "ssyeolb", "쎬" => "ssyeols", + "쎭" => "ssyeolt", "쎮" => "ssyeolp", "쎯" => "ssyeolh", "쎰" => "ssyeom", "쎱" => "ssyeob", "쎲" => "ssyeobs", + "쎳" => "ssyeos", "쎴" => "ssyeoss", "쎵" => "ssyeong", "쎶" => "ssyeoj", "쎷" => "ssyeoc", "쎸" => "ssyeok", + "쎹" => "ssyeot", "쎺" => "ssyeop", "쎻" => "ssyeoh", "쎼" => "ssye", "쎽" => "ssyeg", "쎾" => "ssyegg", + "쎿" => "ssyegs", "ì€" => "ssyen", "ì" => "ssyenj", "ì‚" => "ssyenh", "ìƒ" => "ssyed", "ì„" => "ssyel", + "ì…" => "ssyelg", "ì†" => "ssyelm", "ì‡" => "ssyelb", "ìˆ" => "ssyels", "ì‰" => "ssyelt", "ìŠ" => "ssyelp", + "ì‹" => "ssyelh", "ìŒ" => "ssyem", "ì" => "ssyeb", "ìŽ" => "ssyebs", "ì" => "ssyes", "ì" => "ssyess", + "ì‘" => "ssyeng", "ì’" => "ssyej", "ì“" => "ssyec", "ì”" => "ssyek", "ì•" => "ssyet", "ì–" => "ssyep", + "ì—" => "ssyeh", "ì˜" => "sso", "ì™" => "ssog", "ìš" => "ssogg", "ì›" => "ssogs", "ìœ" => "sson", + "ì" => "ssonj", "ìž" => "ssonh", "ìŸ" => "ssod", "ì " => "ssol", "ì¡" => "ssolg", "ì¢" => "ssolm", + "ì£" => "ssolb", "ì¤" => "ssols", "ì¥" => "ssolt", "ì¦" => "ssolp", "ì§" => "ssolh", "ì¨" => "ssom", + "ì©" => "ssob", "ìª" => "ssobs", "ì«" => "ssos", "ì¬" => "ssoss", "ì­" => "ssong", "ì®" => "ssoj", + "ì¯" => "ssoc", "ì°" => "ssok", "ì±" => "ssot", "ì²" => "ssop", "ì³" => "ssoh", "ì´" => "sswa", + "ìµ" => "sswag", "ì¶" => "sswagg", "ì·" => "sswags", "ì¸" => "sswan", "ì¹" => "sswanj", "ìº" => "sswanh", + "ì»" => "sswad", "ì¼" => "sswal", "ì½" => "sswalg", "ì¾" => "sswalm", "ì¿" => "sswalb", "ì" => "sswalt", + "ì‚" => "sswalp", "ìƒ" => "sswalh", "ì„" => "sswam", "ì…" => "sswab", "ì†" => "sswabs", "ì‡" => "sswas", + "ìˆ" => "sswass", "ì‰" => "sswang", "ìŠ" => "sswaj", "ì‹" => "sswac", "ìŒ" => "sswak", "ì" => "sswat", + "ìŽ" => "sswap", "ì" => "sswah", "ì" => "sswae", "ì‘" => "sswaeg", "ì’" => "sswaegg", "ì“" => "sswaegs", + "ì”" => "sswaen", "ì•" => "sswaenj", "ì–" => "sswaenh", "ì—" => "sswaed", "ì˜" => "sswael", "ì™" => "sswaelg", + "ìš" => "sswaelm", "ì›" => "sswaelb", "ìœ" => "sswaels", "ì" => "sswaelt", "ìž" => "sswaelp", "ìŸ" => "sswaelh", + "ì " => "sswaem", "ì¡" => "sswaeb", "ì¢" => "sswaebs", "ì£" => "sswaes", "ì¤" => "sswaess", "ì¥" => "sswaeng", + "ì¦" => "sswaej", "ì§" => "sswaec", "ì¨" => "sswaek", "ì©" => "sswaet", "ìª" => "sswaep", "ì«" => "sswaeh", + "ì¬" => "ssoe", "ì­" => "ssoeg", "ì®" => "ssoegg", "ì¯" => "ssoegs", "ì°" => "ssoen", "ì±" => "ssoenj", + "ì²" => "ssoenh", "ì³" => "ssoed", "ì´" => "ssoel", "ìµ" => "ssoelg", "ì¶" => "ssoelm", "ì·" => "ssoelb", + "ì¸" => "ssoels", "ì¹" => "ssoelt", "ìº" => "ssoelp", "ì»" => "ssoelh", "ì¼" => "ssoem", "ì½" => "ssoeb", + "ì¾" => "ssoebs", "ì¿" => "ssoes", "ì‘€" => "ssoess", "ì‘" => "ssoeng", "ì‘‚" => "ssoej", "쑃" => "ssoec", + "ì‘„" => "ssoek", "ì‘…" => "ssoet", "쑆" => "ssoep", "쑇" => "ssoeh", "쑈" => "ssyo", "쑉" => "ssyog", + "ì‘Š" => "ssyogg", "ì‘‹" => "ssyogs", "ì‘Œ" => "ssyon", "ì‘" => "ssyonj", "ì‘Ž" => "ssyonh", "ì‘" => "ssyod", + "ì‘" => "ssyol", "ì‘‘" => "ssyolg", "ì‘’" => "ssyolm", "ì‘“" => "ssyolb", "ì‘”" => "ssyols", "ì‘•" => "ssyolt", + "ì‘–" => "ssyolp", "ì‘—" => "ssyolh", "쑘" => "ssyom", "ì‘™" => "ssyob", "ì‘š" => "ssyobs", "ì‘›" => "ssyos", + "ì‘œ" => "ssyoss", "ì‘" => "ssyong", "ì‘ž" => "ssyoj", "ì‘Ÿ" => "ssyoc", "ì‘ " => "ssyok", "ì‘¡" => "ssyot", + "ì‘¢" => "ssyop", "ì‘£" => "ssyoh", "쑤" => "ssu", "ì‘¥" => "ssug", "쑦" => "ssugg", "쑧" => "ssugs", + "쑨" => "ssun", "ì‘©" => "ssunj", "쑪" => "ssunh", "ì‘«" => "ssud", "쑬" => "ssul", "ì‘­" => "ssulg", + "ì‘®" => "ssulm", "쑯" => "ssulb", "ì‘°" => "ssuls", "쑱" => "ssult", "쑲" => "ssulp", "쑳" => "ssulh", + "ì‘´" => "ssum", "쑵" => "ssub", "쑶" => "ssubs", "ì‘·" => "ssus", "쑸" => "ssuss", "쑹" => "ssung", + "쑺" => "ssuj", "ì‘»" => "ssuc", "쑼" => "ssuk", "쑽" => "ssut", "쑾" => "ssup", "ì‘¿" => "ssuh", + "ì’€" => "ssweo", "ì’" => "ssweog", "ì’‚" => "ssweogg", "ì’ƒ" => "ssweogs", "ì’„" => "ssweon", "ì’…" => "ssweonj", + "ì’†" => "ssweonh", "ì’‡" => "ssweod", "ì’ˆ" => "ssweol", "ì’‰" => "ssweolg", "ì’Š" => "ssweolm", "ì’‹" => "ssweolb", + "ì’Œ" => "ssweols", "ì’" => "ssweolt", "ì’Ž" => "ssweolp", "ì’" => "ssweolh", "ì’" => "ssweom", "ì’‘" => "ssweob", + "ì’’" => "ssweobs", "ì’“" => "ssweos", "ì’”" => "ssweoss", "ì’•" => "ssweong", "ì’–" => "ssweoj", "ì’—" => "ssweoc", + "ì’˜" => "ssweok", "ì’™" => "ssweot", "ì’š" => "ssweop", "ì’›" => "ssweoh", "ì’œ" => "sswe", "ì’" => "ssweg", + "ì’ž" => "sswegg", "ì’Ÿ" => "sswegs", "ì’ " => "sswen", "ì’¡" => "sswenj", "ì’¢" => "sswenh", "ì’£" => "sswed", + "ì’¤" => "sswel", "ì’¥" => "sswelg", "ì’¦" => "sswelm", "ì’§" => "sswelb", "ì’¨" => "sswels", "ì’©" => "sswelt", + "ì’ª" => "sswelp", "ì’«" => "sswelh", "ì’¬" => "sswem", "ì’­" => "ssweb", "ì’®" => "sswebs", "ì’¯" => "sswes", + "ì’°" => "sswess", "ì’±" => "ssweng", "ì’²" => "sswej", "ì’³" => "sswec", "ì’´" => "sswek", "ì’µ" => "sswet", + "ì’¶" => "sswep", "ì’·" => "ssweh", "ì’¸" => "sswi", "ì’¹" => "sswig", "ì’º" => "sswigg", "ì’»" => "sswigs", + "ì’¼" => "sswin", "ì’½" => "sswinj", "ì’¾" => "sswinh", "ì’¿" => "sswid", "ì“€" => "sswil", "ì“" => "sswilg", + "ì“‚" => "sswilm", "쓃" => "sswilb", "ì“„" => "sswils", "ì“…" => "sswilt", "쓆" => "sswilp", "쓇" => "sswilh", + "쓈" => "sswim", "쓉" => "sswib", "ì“Š" => "sswibs", "ì“‹" => "sswis", "ì“Œ" => "sswiss", "ì“" => "sswing", + "ì“Ž" => "sswij", "ì“" => "sswic", "ì“" => "sswik", "ì“‘" => "sswit", "ì“’" => "sswip", "ì““" => "sswih", + "ì“”" => "ssyu", "ì“•" => "ssyug", "ì“–" => "ssyugg", "ì“—" => "ssyugs", "쓘" => "ssyun", "ì“™" => "ssyunj", + "ì“š" => "ssyunh", "ì“›" => "ssyud", "ì“œ" => "ssyul", "ì“" => "ssyulg", "ì“ž" => "ssyulm", "ì“Ÿ" => "ssyulb", + "ì“ " => "ssyuls", "ì“¡" => "ssyult", "ì“¢" => "ssyulp", "ì“£" => "ssyulh", "쓤" => "ssyum", "ì“¥" => "ssyub", + "쓦" => "ssyubs", "쓧" => "ssyus", "쓨" => "ssyuss", "ì“©" => "ssyung", "쓪" => "ssyuj", "ì“«" => "ssyuc", + "쓬" => "ssyuk", "ì“­" => "ssyut", "ì“®" => "ssyup", "쓯" => "ssyuh", "ì“°" => "sseu", "쓱" => "sseug", + "쓲" => "sseugg", "쓳" => "sseugs", "ì“´" => "sseun", "쓵" => "sseunj", "쓶" => "sseunh", "ì“·" => "sseud", + "쓸" => "sseul", "쓹" => "sseulg", "쓺" => "sseulm", "ì“»" => "sseulb", "쓼" => "sseuls", "쓽" => "sseult", + "쓾" => "sseulp", "ì“¿" => "sseulh", "ì”" => "sseub", "씂" => "sseubs", "씃" => "sseus", "씄" => "sseuss", + "ì”…" => "sseung", "씆" => "sseuj", "씇" => "sseuc", "씈" => "sseuk", "씉" => "sseut", "씊" => "sseup", + "씋" => "sseuh", "씌" => "ssyi", "ì”" => "ssyig", "씎" => "ssyigg", "ì”" => "ssyigs", "ì”" => "ssyin", + "씑" => "ssyinj", "ì”’" => "ssyinh", "씓" => "ssyid", "ì””" => "ssyil", "씕" => "ssyilg", "ì”–" => "ssyilm", + "ì”—" => "ssyilb", "씘" => "ssyils", "ì”™" => "ssyilt", "씚" => "ssyilp", "ì”›" => "ssyilh", "씜" => "ssyim", + "ì”" => "ssyib", "씞" => "ssyibs", "씟" => "ssyis", "ì” " => "ssyiss", "씡" => "ssying", "씢" => "ssyij", + "씣" => "ssyic", "씤" => "ssyik", "씥" => "ssyit", "씦" => "ssyip", "씧" => "ssyih", "씨" => "ssi", + "씩" => "ssig", "씪" => "ssigg", "씫" => "ssigs", "씬" => "ssin", "ì”­" => "ssinj", "ì”®" => "ssinh", + "씯" => "ssid", "ì”°" => "ssil", "ì”±" => "ssilg", "씲" => "ssilm", "씳" => "ssilb", "ì”´" => "ssils", + "씵" => "ssilt", "씶" => "ssilp", "ì”·" => "ssilh", "씸" => "ssim", "씹" => "ssib", "씺" => "ssibs", + "ì”»" => "ssis", "씼" => "ssiss", "씽" => "ssing", "씾" => "ssij", "씿" => "ssic", "ì•€" => "ssik", + "ì•" => "ssit", "ì•‚" => "ssip", "앃" => "ssih", "ì•„" => "a", "ì•…" => "ag", "앆" => "agg", + "앇" => "ags", "안" => "an", "앉" => "anj", "ì•Š" => "anh", "ì•‹" => "ad", "ì•Œ" => "al", + "ì•" => "alg", "ì•Ž" => "alm", "ì•" => "alb", "ì•" => "als", "ì•‘" => "alt", "ì•’" => "alp", + "ì•“" => "alh", "ì•”" => "am", "ì••" => "ab", "ì•–" => "abs", "ì•—" => "as", "았" => "ass", + "ì•™" => "ang", "ì•š" => "aj", "ì•›" => "ac", "ì•œ" => "ak", "ì•" => "at", "ì•ž" => "ap", + "ì•Ÿ" => "ah", "ì• " => "ae", "ì•¡" => "aeg", "ì•¢" => "aegg", "ì•£" => "aegs", "앤" => "aen", + "ì•¥" => "aenj", "앦" => "aenh", "앧" => "aed", "앨" => "ael", "ì•©" => "aelg", "앪" => "aelm", + "ì•«" => "aelb", "앬" => "aels", "ì•­" => "aelt", "ì•®" => "aelp", "앯" => "aelh", "ì•°" => "aem", + "앱" => "aeb", "앲" => "aebs", "앳" => "aes", "ì•´" => "aess", "앵" => "aeng", "앶" => "aej", + "ì•·" => "aec", "앸" => "aek", "앹" => "aet", "앺" => "aep", "ì•»" => "aeh", "야" => "ya", + "약" => "yag", "앾" => "yagg", "ì•¿" => "yags", "ì–€" => "yan", "ì–" => "yanj", "ì–‚" => "yanh", + "ì–ƒ" => "yad", "ì–„" => "yal", "ì–…" => "yalg", "ì–†" => "yalm", "ì–‡" => "yalb", "ì–ˆ" => "yals", + "ì–‰" => "yalt", "ì–Š" => "yalp", "ì–‹" => "yalh", "ì–Œ" => "yam", "ì–" => "yab", "ì–Ž" => "yabs", + "ì–" => "yas", "ì–" => "yass", "ì–‘" => "yang", "ì–’" => "yaj", "ì–“" => "yac", "ì–”" => "yak", + "ì–•" => "yat", "ì––" => "yap", "ì–—" => "yah", "ì–˜" => "yae", "ì–™" => "yaeg", "ì–š" => "yaegg", + "ì–›" => "yaegs", "ì–œ" => "yaen", "ì–" => "yaenj", "ì–ž" => "yaenh", "ì–Ÿ" => "yaed", "ì– " => "yael", + "ì–¡" => "yaelg", "ì–¢" => "yaelm", "ì–£" => "yaelb", "ì–¤" => "yaels", "ì–¥" => "yaelt", "ì–¦" => "yaelp", + "ì–§" => "yaelh", "ì–¨" => "yaem", "ì–©" => "yaeb", "ì–ª" => "yaebs", "ì–«" => "yaes", "ì–¬" => "yaess", + "ì–­" => "yaeng", "ì–®" => "yaej", "ì–¯" => "yaec", "ì–°" => "yaek", "ì–±" => "yaet", "ì–²" => "yaep", + "ì–³" => "yaeh", "ì–´" => "eo", "ì–µ" => "eog", "ì–¶" => "eogg", "ì–·" => "eogs", "ì–¸" => "eon", + "ì–¹" => "eonj", "ì–º" => "eonh", "ì–»" => "eod", "ì–¼" => "eol", "ì–½" => "eolg", "ì–¾" => "eolm", + "ì–¿" => "eolb", "ì—€" => "eols", "ì—" => "eolt", "ì—‚" => "eolp", "ì—ƒ" => "eolh", "ì—„" => "eom", + "ì—…" => "eob", "ì—†" => "eobs", "ì—‡" => "eos", "ì—ˆ" => "eoss", "ì—‰" => "eong", "ì—Š" => "eoj", + "ì—‹" => "eoc", "ì—Œ" => "eok", "ì—" => "eot", "ì—Ž" => "eop", "ì—" => "eoh", "ì—" => "e", + "ì—‘" => "eg", "ì—’" => "egg", "ì—“" => "egs", "ì—”" => "en", "ì—•" => "enj", "ì—–" => "enh", + "ì——" => "ed", "ì—˜" => "el", "ì—™" => "elg", "ì—š" => "elm", "ì—›" => "elb", "ì—œ" => "els", + "ì—" => "elt", "ì—ž" => "elp", "ì—Ÿ" => "elh", "ì— " => "em", "ì—¡" => "eb", "ì—¢" => "ebs", + "ì—£" => "es", "ì—¤" => "ess", "ì—¥" => "eng", "ì—¦" => "ej", "ì—§" => "ec", "ì—¨" => "ek", + "ì—©" => "et", "ì—ª" => "ep", "ì—«" => "eh", "ì—¬" => "yeo", "ì—­" => "yeog", "ì—®" => "yeogg", + "ì—¯" => "yeogs", "ì—°" => "yeon", "ì—±" => "yeonj", "ì—²" => "yeonh", "ì—³" => "yeod", "ì—´" => "yeol", + "ì—µ" => "yeolg", "ì—¶" => "yeolm", "ì—·" => "yeolb", "ì—¸" => "yeols", "ì—¹" => "yeolt", "ì—º" => "yeolp", + "ì—»" => "yeolh", "ì—¼" => "yeom", "ì—½" => "yeob", "ì—¾" => "yeobs", "ì—¿" => "yeos", "ì˜" => "yeong", + "옂" => "yeoj", "옃" => "yeoc", "옄" => "yeok", "옅" => "yeot", "옆" => "yeop", "옇" => "yeoh", + "예" => "ye", "옉" => "yeg", "옊" => "yegg", "옋" => "yegs", "옌" => "yen", "ì˜" => "yenj", + "옎" => "yenh", "ì˜" => "yed", "ì˜" => "yel", "옑" => "yelg", "옒" => "yelm", "옓" => "yelb", + "옔" => "yels", "옕" => "yelt", "옖" => "yelp", "옗" => "yelh", "옘" => "yem", "옙" => "yeb", + "옚" => "yebs", "옛" => "yes", "옜" => "yess", "ì˜" => "yeng", "옞" => "yej", "옟" => "yec", + "옠" => "yek", "옡" => "yet", "옢" => "yep", "옣" => "yeh", "오" => "o", "옥" => "og", + "옦" => "ogg", "옧" => "ogs", "온" => "on", "옩" => "onj", "옪" => "onh", "옫" => "od", + "올" => "ol", "옭" => "olg", "옮" => "olm", "옯" => "olb", "옰" => "ols", "옱" => "olt", + "옲" => "olp", "옳" => "olh", "옴" => "om", "옵" => "ob", "옶" => "obs", "옷" => "os", + "옸" => "oss", "옹" => "ong", "옺" => "oj", "옻" => "oc", "옼" => "ok", "옽" => "ot", + "옾" => "op", "옿" => "oh", "와" => "wa", "ì™" => "wag", "왂" => "wagg", "왃" => "wags", + "완" => "wan", "ì™…" => "wanj", "왆" => "wanh", "왇" => "wad", "왈" => "wal", "왉" => "walg", + "왊" => "walm", "왋" => "walb", "왌" => "wals", "ì™" => "walt", "왎" => "walp", "ì™" => "walh", + "ì™" => "wam", "왑" => "wab", "ì™’" => "wabs", "왓" => "was", "ì™”" => "wass", "왕" => "wang", + "ì™–" => "waj", "ì™—" => "wac", "왘" => "wak", "ì™™" => "wat", "왚" => "wap", "ì™›" => "wah", + "왜" => "wae", "ì™" => "waeg", "왞" => "waegg", "왟" => "waegs", "ì™ " => "waen", "왡" => "waenj", + "왢" => "waenh", "왣" => "waed", "왤" => "wael", "왥" => "waelg", "왦" => "waelm", "왧" => "waelb", + "왨" => "waels", "왩" => "waelt", "왪" => "waelp", "왫" => "waelh", "왬" => "waem", "ì™­" => "waeb", + "ì™®" => "waebs", "왯" => "waes", "ì™°" => "waess", "ì™±" => "waeng", "왲" => "waej", "왳" => "waec", + "ì™´" => "waek", "왵" => "waet", "왶" => "waep", "ì™·" => "waeh", "외" => "oe", "왹" => "oeg", + "왺" => "oegg", "ì™»" => "oegs", "왼" => "oen", "왽" => "oenj", "왾" => "oenh", "왿" => "oed", + "욀" => "oel", "ìš" => "oelg", "ìš‚" => "oelm", "욃" => "oelb", "ìš„" => "oels", "ìš…" => "oelt", + "욆" => "oelp", "욇" => "oelh", "욈" => "oem", "욉" => "oeb", "욊" => "oebs", "ìš‹" => "oes", + "욌" => "oess", "ìš" => "oeng", "욎" => "oej", "ìš" => "oec", "ìš" => "oek", "ìš‘" => "oet", + "ìš’" => "oep", "ìš“" => "oeh", "ìš”" => "yo", "ìš•" => "yog", "ìš–" => "yogg", "ìš—" => "yogs", + "욘" => "yon", "ìš™" => "yonj", "ìšš" => "yonh", "ìš›" => "yod", "ìšœ" => "yol", "ìš" => "yolg", + "ìšž" => "yolm", "욟" => "yolb", "ìš " => "yols", "ìš¡" => "yolt", "욢" => "yolp", "욣" => "yolh", + "욤" => "yom", "욥" => "yob", "욦" => "yobs", "욧" => "yos", "욨" => "yoss", "ìš©" => "yong", + "욪" => "yoj", "ìš«" => "yoc", "욬" => "yok", "ìš­" => "yot", "ìš®" => "yop", "욯" => "yoh", + "ìš°" => "u", "ìš±" => "ug", "ìš²" => "ugg", "ìš³" => "ugs", "ìš´" => "un", "ìšµ" => "unj", + "욶" => "unh", "ìš·" => "ud", "울" => "ul", "ìš¹" => "ulg", "욺" => "ulm", "ìš»" => "ulb", + "ìš¼" => "uls", "ìš½" => "ult", "ìš¾" => "ulp", "ìš¿" => "ulh", "움" => "um", "ì›" => "ub", + "웂" => "ubs", "웃" => "us", "웄" => "uss", "ì›…" => "ung", "웆" => "uj", "웇" => "uc", + "웈" => "uk", "웉" => "ut", "웊" => "up", "웋" => "uh", "워" => "weo", "ì›" => "weog", + "웎" => "weogg", "ì›" => "weogs", "ì›" => "weon", "웑" => "weonj", "ì›’" => "weonh", "웓" => "weod", + "ì›”" => "weol", "웕" => "weolg", "ì›–" => "weolm", "ì›—" => "weolb", "웘" => "weols", "ì›™" => "weolt", + "웚" => "weolp", "ì››" => "weolh", "웜" => "weom", "ì›" => "weob", "웞" => "weobs", "웟" => "weos", + "ì› " => "weoss", "웡" => "weong", "웢" => "weoj", "웣" => "weoc", "웤" => "weok", "웥" => "weot", + "웦" => "weop", "웧" => "weoh", "웨" => "we", "웩" => "weg", "웪" => "wegg", "웫" => "wegs", + "웬" => "wen", "ì›­" => "wenj", "ì›®" => "wenh", "웯" => "wed", "ì›°" => "wel", "ì›±" => "welg", + "웲" => "welm", "웳" => "welb", "ì›´" => "wels", "웵" => "welt", "웶" => "welp", "ì›·" => "welh", + "웸" => "wem", "웹" => "web", "웺" => "webs", "ì›»" => "wes", "웼" => "wess", "웽" => "weng", + "웾" => "wej", "웿" => "wec", "ìœ" => "wet", "윂" => "wep", "윃" => "weh", "위" => "wi", + "윅" => "wig", "윆" => "wigg", "윇" => "wigs", "윈" => "win", "윉" => "winj", "윊" => "winh", + "윋" => "wid", "윌" => "wil", "ìœ" => "wilg", "윎" => "wilm", "ìœ" => "wilb", "ìœ" => "wils", + "윑" => "wilt", "윒" => "wilp", "윓" => "wilh", "윔" => "wim", "윕" => "wib", "윖" => "wibs", + "윗" => "wis", "윘" => "wiss", "윙" => "wing", "윚" => "wij", "윛" => "wic", "윜" => "wik", + "ìœ" => "wit", "윞" => "wip", "윟" => "wih", "유" => "yu", "육" => "yug", "윢" => "yugg", + "윣" => "yugs", "윤" => "yun", "윥" => "yunj", "윦" => "yunh", "윧" => "yud", "율" => "yul", + "윩" => "yulg", "윪" => "yulm", "윫" => "yulb", "윬" => "yuls", "윭" => "yult", "윮" => "yulp", + "윯" => "yulh", "윰" => "yum", "윱" => "yub", "윲" => "yubs", "윳" => "yus", "윴" => "yuss", + "융" => "yung", "윶" => "yuj", "윷" => "yuc", "윸" => "yuk", "윹" => "yut", "윺" => "yup", + "윻" => "yuh", "으" => "eu", "윽" => "eug", "윾" => "eugg", "윿" => "eugs", "ì€" => "eun", + "ì" => "eunj", "ì‚" => "eunh", "ìƒ" => "eud", "ì„" => "eul", "ì…" => "eulg", "ì†" => "eulm", + "ì‡" => "eulb", "ìˆ" => "euls", "ì‰" => "eult", "ìŠ" => "eulp", "ì‹" => "eulh", "ìŒ" => "eum", + "ì" => "eub", "ìŽ" => "eubs", "ì" => "eus", "ì" => "euss", "ì‘" => "eung", "ì’" => "euj", + "ì“" => "euc", "ì”" => "euk", "ì•" => "eut", "ì–" => "eup", "ì—" => "euh", "ì˜" => "yi", + "ì™" => "yig", "ìš" => "yigg", "ì›" => "yigs", "ìœ" => "yin", "ì" => "yinj", "ìž" => "yinh", + "ìŸ" => "yid", "ì " => "yil", "ì¡" => "yilg", "ì¢" => "yilm", "ì£" => "yilb", "ì¤" => "yils", + "ì¥" => "yilt", "ì¦" => "yilp", "ì§" => "yilh", "ì¨" => "yim", "ì©" => "yib", "ìª" => "yibs", + "ì«" => "yis", "ì¬" => "yiss", "ì­" => "ying", "ì®" => "yij", "ì¯" => "yic", "ì°" => "yik", + "ì±" => "yit", "ì²" => "yip", "ì³" => "yih", "ì´" => "i", "ìµ" => "ig", "ì¶" => "igg", + "ì·" => "igs", "ì¸" => "in", "ì¹" => "inj", "ìº" => "inh", "ì»" => "id", "ì¼" => "il", + "ì½" => "ilg", "ì¾" => "ilm", "ì¿" => "ilb", "잀" => "ils", "ìž" => "ilt", "ìž‚" => "ilp", + "잃" => "ilh", "ìž„" => "im", "ìž…" => "ib", "잆" => "ibs", "잇" => "is", "있" => "iss", + "잉" => "ing", "잊" => "ij", "ìž‹" => "ic", "잌" => "ik", "ìž" => "it", "잎" => "ip", + "ìž" => "ih", "ìž" => "ja", "ìž‘" => "jag", "ìž’" => "jagg", "ìž“" => "jags", "ìž”" => "jan", + "ìž•" => "janj", "ìž–" => "janh", "ìž—" => "jad", "잘" => "jal", "ìž™" => "jalg", "ìžš" => "jalm", + "ìž›" => "jalb", "ìžœ" => "jals", "ìž" => "jalt", "ìžž" => "jalp", "잟" => "jalh", "ìž " => "jam", + "ìž¡" => "jab", "잢" => "jabs", "잣" => "jas", "잤" => "jass", "장" => "jang", "잦" => "jaj", + "잧" => "jac", "잨" => "jak", "ìž©" => "jat", "잪" => "jap", "ìž«" => "jah", "재" => "jae", + "ìž­" => "jaeg", "ìž®" => "jaegg", "잯" => "jaegs", "ìž°" => "jaen", "ìž±" => "jaenj", "ìž²" => "jaenh", + "ìž³" => "jaed", "ìž´" => "jael", "ìžµ" => "jaelg", "잶" => "jaelm", "ìž·" => "jaelb", "잸" => "jaels", + "ìž¹" => "jaelt", "잺" => "jaelp", "ìž»" => "jaelh", "ìž¼" => "jaem", "ìž½" => "jaeb", "ìž¾" => "jaebs", + "ìž¿" => "jaes", "쟀" => "jaess", "ìŸ" => "jaeng", "쟂" => "jaej", "쟃" => "jaec", "쟄" => "jaek", + "쟅" => "jaet", "쟆" => "jaep", "쟇" => "jaeh", "쟈" => "jya", "쟉" => "jyag", "쟊" => "jyagg", + "쟋" => "jyags", "쟌" => "jyan", "ìŸ" => "jyanj", "쟎" => "jyanh", "ìŸ" => "jyad", "ìŸ" => "jyal", + "쟑" => "jyalg", "쟒" => "jyalm", "쟓" => "jyalb", "쟔" => "jyals", "쟕" => "jyalt", "쟖" => "jyalp", + "쟗" => "jyalh", "쟘" => "jyam", "쟙" => "jyab", "쟚" => "jyabs", "쟛" => "jyas", "쟜" => "jyass", + "ìŸ" => "jyang", "쟞" => "jyaj", "쟟" => "jyac", "쟠" => "jyak", "쟡" => "jyat", "쟢" => "jyap", + "쟣" => "jyah", "쟤" => "jyae", "쟥" => "jyaeg", "쟦" => "jyaegg", "쟧" => "jyaegs", "쟨" => "jyaen", + "쟩" => "jyaenj", "쟪" => "jyaenh", "쟫" => "jyaed", "쟬" => "jyael", "쟭" => "jyaelg", "쟮" => "jyaelm", + "쟯" => "jyaelb", "쟰" => "jyaels", "쟱" => "jyaelt", "쟲" => "jyaelp", "쟳" => "jyaelh", "쟴" => "jyaem", + "쟵" => "jyaeb", "쟶" => "jyaebs", "쟷" => "jyaes", "쟸" => "jyaess", "쟹" => "jyaeng", "쟺" => "jyaej", + "쟻" => "jyaec", "쟼" => "jyaek", "쟽" => "jyaet", "쟾" => "jyaep", "쟿" => "jyaeh", "ì " => "jeog", + "ì ‚" => "jeogg", "ì ƒ" => "jeogs", "ì „" => "jeon", "ì …" => "jeonj", "ì †" => "jeonh", "ì ‡" => "jeod", + "ì ˆ" => "jeol", "ì ‰" => "jeolg", "ì Š" => "jeolm", "ì ‹" => "jeolb", "ì Œ" => "jeols", "ì " => "jeolt", + "ì Ž" => "jeolp", "ì " => "jeolh", "ì " => "jeom", "ì ‘" => "jeob", "ì ’" => "jeobs", "ì “" => "jeos", + "ì ”" => "jeoss", "ì •" => "jeong", "ì –" => "jeoj", "ì —" => "jeoc", "ì ˜" => "jeok", "ì ™" => "jeot", + "ì š" => "jeop", "ì ›" => "jeoh", "ì œ" => "je", "ì " => "jeg", "ì ž" => "jegg", "ì Ÿ" => "jegs", + "ì  " => "jen", "ì ¡" => "jenj", "ì ¢" => "jenh", "ì £" => "jed", "ì ¤" => "jel", "ì ¥" => "jelg", + "ì ¦" => "jelm", "ì §" => "jelb", "ì ¨" => "jels", "ì ©" => "jelt", "ì ª" => "jelp", "ì «" => "jelh", + "ì ¬" => "jem", "ì ­" => "jeb", "ì ®" => "jebs", "ì ¯" => "jes", "ì °" => "jess", "ì ±" => "jeng", + "ì ²" => "jej", "ì ³" => "jec", "ì ´" => "jek", "ì µ" => "jet", "ì ¶" => "jep", "ì ·" => "jeh", + "ì ¸" => "jyeo", "ì ¹" => "jyeog", "ì º" => "jyeogg", "ì »" => "jyeogs", "ì ¼" => "jyeon", "ì ½" => "jyeonj", + "ì ¾" => "jyeonh", "ì ¿" => "jyeod", "ì¡€" => "jyeol", "ì¡" => "jyeolg", "ì¡‚" => "jyeolm", "졃" => "jyeolb", + "ì¡„" => "jyeols", "ì¡…" => "jyeolt", "졆" => "jyeolp", "졇" => "jyeolh", "졈" => "jyeom", "졉" => "jyeob", + "ì¡Š" => "jyeobs", "ì¡‹" => "jyeos", "ì¡Œ" => "jyeoss", "ì¡" => "jyeong", "ì¡Ž" => "jyeoj", "ì¡" => "jyeoc", + "ì¡" => "jyeok", "ì¡‘" => "jyeot", "ì¡’" => "jyeop", "ì¡“" => "jyeoh", "ì¡”" => "jye", "ì¡•" => "jyeg", + "ì¡–" => "jyegg", "ì¡—" => "jyegs", "졘" => "jyen", "ì¡™" => "jyenj", "ì¡š" => "jyenh", "ì¡›" => "jyed", + "ì¡œ" => "jyel", "ì¡" => "jyelg", "ì¡ž" => "jyelm", "ì¡Ÿ" => "jyelb", "ì¡ " => "jyels", "ì¡¡" => "jyelt", + "ì¡¢" => "jyelp", "ì¡£" => "jyelh", "졤" => "jyem", "ì¡¥" => "jyeb", "졦" => "jyebs", "졧" => "jyes", + "졨" => "jyess", "ì¡©" => "jyeng", "졪" => "jyej", "ì¡«" => "jyec", "졬" => "jyek", "ì¡­" => "jyet", + "ì¡®" => "jyep", "졯" => "jyeh", "ì¡°" => "jo", "족" => "jog", "졲" => "jogg", "졳" => "jogs", + "ì¡´" => "jon", "졵" => "jonj", "졶" => "jonh", "ì¡·" => "jod", "졸" => "jol", "졹" => "jolg", + "졺" => "jolm", "ì¡»" => "jolb", "졼" => "jols", "졽" => "jolt", "졾" => "jolp", "ì¡¿" => "jolh", + "좀" => "jom", "ì¢" => "job", "좂" => "jobs", "좃" => "jos", "좄" => "joss", "종" => "jong", + "좆" => "joj", "좇" => "joc", "좈" => "jok", "좉" => "jot", "좊" => "jop", "좋" => "joh", + "좌" => "jwa", "ì¢" => "jwag", "좎" => "jwagg", "ì¢" => "jwags", "ì¢" => "jwan", "좑" => "jwanj", + "좒" => "jwanh", "좓" => "jwad", "좔" => "jwal", "좕" => "jwalg", "좖" => "jwalm", "좗" => "jwalb", + "좘" => "jwals", "좙" => "jwalt", "좚" => "jwalp", "좛" => "jwalh", "좜" => "jwam", "ì¢" => "jwab", + "좞" => "jwabs", "좟" => "jwas", "좠" => "jwass", "좡" => "jwang", "좢" => "jwaj", "좣" => "jwac", + "좤" => "jwak", "좥" => "jwat", "좦" => "jwap", "좧" => "jwah", "좨" => "jwae", "좩" => "jwaeg", + "좪" => "jwaegg", "좫" => "jwaegs", "좬" => "jwaen", "좭" => "jwaenj", "좮" => "jwaenh", "좯" => "jwaed", + "좰" => "jwael", "좱" => "jwaelg", "좲" => "jwaelm", "좳" => "jwaelb", "좴" => "jwaels", "좵" => "jwaelt", + "좶" => "jwaelp", "좷" => "jwaelh", "좸" => "jwaem", "좹" => "jwaeb", "좺" => "jwaebs", "좻" => "jwaes", + "좼" => "jwaess", "좽" => "jwaeng", "좾" => "jwaej", "좿" => "jwaec", "죀" => "jwaek", "ì£" => "jwaet", + "죂" => "jwaep", "죃" => "jwaeh", "죄" => "joe", "죅" => "joeg", "죆" => "joegg", "죇" => "joegs", + "죈" => "joen", "죉" => "joenj", "죊" => "joenh", "죋" => "joed", "죌" => "joel", "ì£" => "joelg", + "죎" => "joelm", "ì£" => "joelb", "ì£" => "joels", "죑" => "joelt", "죒" => "joelp", "죓" => "joelh", + "죔" => "joem", "죕" => "joeb", "죖" => "joebs", "죗" => "joes", "죘" => "joess", "죙" => "joeng", + "죚" => "joej", "죛" => "joec", "죜" => "joek", "ì£" => "joet", "죞" => "joep", "죟" => "joeh", + "죠" => "jyo", "죡" => "jyog", "죢" => "jyogg", "죣" => "jyogs", "죤" => "jyon", "죥" => "jyonj", + "죦" => "jyonh", "죧" => "jyod", "죨" => "jyol", "죩" => "jyolg", "죪" => "jyolm", "죫" => "jyolb", + "죬" => "jyols", "죭" => "jyolt", "죮" => "jyolp", "죯" => "jyolh", "죰" => "jyom", "죱" => "jyob", + "죲" => "jyobs", "죳" => "jyos", "죴" => "jyoss", "죵" => "jyong", "죶" => "jyoj", "죷" => "jyoc", + "죸" => "jyok", "죹" => "jyot", "죺" => "jyop", "죻" => "jyoh", "주" => "ju", "죽" => "jug", + "죾" => "jugg", "죿" => "jugs", "ì¤" => "junj", "줂" => "junh", "줃" => "jud", "줄" => "jul", + "줅" => "julg", "줆" => "julm", "줇" => "julb", "줈" => "juls", "줉" => "jult", "줊" => "julp", + "줋" => "julh", "줌" => "jum", "ì¤" => "jub", "줎" => "jubs", "ì¤" => "jus", "ì¤" => "juss", + "중" => "jung", "줒" => "juj", "줓" => "juc", "줔" => "juk", "줕" => "jut", "줖" => "jup", + "줗" => "juh", "줘" => "jweo", "줙" => "jweog", "줚" => "jweogg", "줛" => "jweogs", "줜" => "jweon", + "ì¤" => "jweonj", "줞" => "jweonh", "줟" => "jweod", "줠" => "jweol", "줡" => "jweolg", "줢" => "jweolm", + "줣" => "jweolb", "줤" => "jweols", "줥" => "jweolt", "줦" => "jweolp", "줧" => "jweolh", "줨" => "jweom", + "줩" => "jweob", "줪" => "jweobs", "줫" => "jweos", "줬" => "jweoss", "줭" => "jweong", "줮" => "jweoj", + "줯" => "jweoc", "줰" => "jweok", "줱" => "jweot", "줲" => "jweop", "줳" => "jweoh", "줴" => "jwe", + "줵" => "jweg", "줶" => "jwegg", "줷" => "jwegs", "줸" => "jwen", "줹" => "jwenj", "줺" => "jwenh", + "줻" => "jwed", "줼" => "jwel", "줽" => "jwelg", "줾" => "jwelm", "줿" => "jwelb", "쥀" => "jwels", + "ì¥" => "jwelt", "쥂" => "jwelp", "쥃" => "jwelh", "쥄" => "jwem", "쥅" => "jweb", "쥆" => "jwebs", + "쥇" => "jwes", "쥈" => "jwess", "쥉" => "jweng", "쥊" => "jwej", "쥋" => "jwec", "쥌" => "jwek", + "ì¥" => "jwet", "쥎" => "jwep", "ì¥" => "jweh", "ì¥" => "jwi", "쥑" => "jwig", "쥒" => "jwigg", + "쥓" => "jwigs", "쥔" => "jwin", "쥕" => "jwinj", "쥖" => "jwinh", "쥗" => "jwid", "쥘" => "jwil", + "쥙" => "jwilg", "쥚" => "jwilm", "쥛" => "jwilb", "쥜" => "jwils", "ì¥" => "jwilt", "쥞" => "jwilp", + "쥟" => "jwilh", "쥠" => "jwim", "쥡" => "jwib", "쥢" => "jwibs", "쥣" => "jwis", "쥤" => "jwiss", + "쥥" => "jwing", "쥦" => "jwij", "쥧" => "jwic", "쥨" => "jwik", "쥩" => "jwit", "쥪" => "jwip", + "쥫" => "jwih", "쥬" => "jyu", "쥭" => "jyug", "쥮" => "jyugg", "쥯" => "jyugs", "쥰" => "jyun", + "쥱" => "jyunj", "쥲" => "jyunh", "쥳" => "jyud", "쥴" => "jyul", "쥵" => "jyulg", "쥶" => "jyulm", + "쥷" => "jyulb", "쥸" => "jyuls", "쥹" => "jyult", "쥺" => "jyulp", "쥻" => "jyulh", "쥼" => "jyum", + "쥽" => "jyub", "쥾" => "jyubs", "쥿" => "jyus", "즀" => "jyuss", "ì¦" => "jyung", "즂" => "jyuj", + "즃" => "jyuc", "즄" => "jyuk", "즅" => "jyut", "즆" => "jyup", "즇" => "jyuh", "즈" => "jeu", + "즉" => "jeug", "즊" => "jeugg", "즋" => "jeugs", "즌" => "jeun", "ì¦" => "jeunj", "즎" => "jeunh", + "ì¦" => "jeud", "ì¦" => "jeul", "즑" => "jeulg", "즒" => "jeulm", "즓" => "jeulb", "즔" => "jeuls", + "즕" => "jeult", "즖" => "jeulp", "즗" => "jeulh", "즘" => "jeum", "즙" => "jeub", "즚" => "jeubs", + "즛" => "jeus", "즜" => "jeuss", "ì¦" => "jeung", "즞" => "jeuj", "즟" => "jeuc", "즠" => "jeuk", + "즡" => "jeut", "즢" => "jeup", "즣" => "jeuh", "즤" => "jyi", "즥" => "jyig", "즦" => "jyigg", + "즧" => "jyigs", "즨" => "jyin", "즩" => "jyinj", "즪" => "jyinh", "즫" => "jyid", "즬" => "jyil", + "즭" => "jyilg", "즮" => "jyilm", "즯" => "jyilb", "즰" => "jyils", "즱" => "jyilt", "즲" => "jyilp", + "즳" => "jyilh", "즴" => "jyim", "즵" => "jyib", "즶" => "jyibs", "즷" => "jyis", "즸" => "jyiss", + "즹" => "jying", "즺" => "jyij", "즻" => "jyic", "즼" => "jyik", "즽" => "jyit", "즾" => "jyip", + "즿" => "jyih", "지" => "ji", "ì§" => "jig", "짂" => "jigg", "짃" => "jigs", "진" => "jin", + "짅" => "jinj", "짆" => "jinh", "짇" => "jid", "질" => "jil", "짉" => "jilg", "짊" => "jilm", + "짋" => "jilb", "짌" => "jils", "ì§" => "jilt", "짎" => "jilp", "ì§" => "jilh", "ì§" => "jim", + "집" => "jib", "짒" => "jibs", "짓" => "jis", "짔" => "jiss", "징" => "jing", "짖" => "jij", + "짗" => "jic", "짘" => "jik", "짙" => "jit", "짚" => "jip", "짛" => "jih", "짜" => "jja", + "ì§" => "jjag", "짞" => "jjagg", "짟" => "jjags", "짠" => "jjan", "짡" => "jjanj", "짢" => "jjanh", + "짣" => "jjad", "짤" => "jjal", "짥" => "jjalg", "짦" => "jjalm", "짧" => "jjalb", "짨" => "jjals", + "짩" => "jjalt", "짪" => "jjalp", "짫" => "jjalh", "짬" => "jjam", "짭" => "jjab", "짮" => "jjabs", + "짯" => "jjas", "짰" => "jjass", "짱" => "jjang", "짲" => "jjaj", "짳" => "jjac", "짴" => "jjak", + "짵" => "jjat", "짶" => "jjap", "짷" => "jjah", "째" => "jjae", "짹" => "jjaeg", "짺" => "jjaegg", + "짻" => "jjaegs", "짼" => "jjaen", "짽" => "jjaenj", "짾" => "jjaenh", "짿" => "jjaed", "ì¨" => "jjaelg", + "쨂" => "jjaelm", "쨃" => "jjaelb", "쨄" => "jjaels", "쨅" => "jjaelt", "쨆" => "jjaelp", "쨇" => "jjaelh", + "쨈" => "jjaem", "쨉" => "jjaeb", "쨊" => "jjaebs", "쨋" => "jjaes", "쨌" => "jjaess", "ì¨" => "jjaeng", + "쨎" => "jjaej", "ì¨" => "jjaec", "ì¨" => "jjaek", "쨑" => "jjaet", "쨒" => "jjaep", "쨓" => "jjaeh", + "쨔" => "jjya", "쨕" => "jjyag", "쨖" => "jjyagg", "쨗" => "jjyags", "쨘" => "jjyan", "쨙" => "jjyanj", + "쨚" => "jjyanh", "쨛" => "jjyad", "쨜" => "jjyal", "ì¨" => "jjyalg", "쨞" => "jjyalm", "쨟" => "jjyalb", + "쨠" => "jjyals", "쨡" => "jjyalt", "쨢" => "jjyalp", "쨣" => "jjyalh", "쨤" => "jjyam", "쨥" => "jjyab", + "쨦" => "jjyabs", "쨧" => "jjyas", "쨨" => "jjyass", "쨩" => "jjyang", "쨪" => "jjyaj", "쨫" => "jjyac", + "쨬" => "jjyak", "쨭" => "jjyat", "쨮" => "jjyap", "쨯" => "jjyah", "쨰" => "jjyae", "쨱" => "jjyaeg", + "쨲" => "jjyaegg", "쨳" => "jjyaegs", "쨴" => "jjyaen", "쨵" => "jjyaenj", "쨶" => "jjyaenh", "쨷" => "jjyaed", + "쨸" => "jjyael", "쨹" => "jjyaelg", "쨺" => "jjyaelm", "쨻" => "jjyaelb", "쨼" => "jjyaels", "쨽" => "jjyaelt", + "쨾" => "jjyaelp", "쨿" => "jjyaelh", "ì©€" => "jjyaem", "ì©" => "jjyaeb", "ì©‚" => "jjyaebs", "쩃" => "jjyaes", + "ì©„" => "jjyaess", "ì©…" => "jjyaeng", "쩆" => "jjyaej", "쩇" => "jjyaec", "쩈" => "jjyaek", "쩉" => "jjyaet", + "ì©Š" => "jjyaep", "ì©‹" => "jjyaeh", "ì©Œ" => "jjeo", "ì©" => "jjeog", "ì©Ž" => "jjeogg", "ì©" => "jjeogs", + "ì©" => "jjeon", "ì©‘" => "jjeonj", "ì©’" => "jjeonh", "ì©“" => "jjeod", "ì©”" => "jjeol", "ì©•" => "jjeolg", + "ì©–" => "jjeolm", "ì©—" => "jjeolb", "쩘" => "jjeols", "ì©™" => "jjeolt", "ì©š" => "jjeolp", "ì©›" => "jjeolh", + "ì©œ" => "jjeom", "ì©" => "jjeob", "ì©ž" => "jjeobs", "ì©Ÿ" => "jjeos", "ì© " => "jjeoss", "ì©¡" => "jjeong", + "ì©¢" => "jjeoj", "ì©£" => "jjeoc", "쩤" => "jjeok", "ì©¥" => "jjeot", "쩦" => "jjeop", "쩧" => "jjeoh", + "쩨" => "jje", "ì©©" => "jjeg", "쩪" => "jjegg", "ì©«" => "jjegs", "쩬" => "jjen", "ì©­" => "jjenj", + "ì©®" => "jjenh", "쩯" => "jjed", "ì©°" => "jjel", "쩱" => "jjelg", "쩲" => "jjelm", "쩳" => "jjelb", + "ì©´" => "jjels", "쩵" => "jjelt", "쩶" => "jjelp", "ì©·" => "jjelh", "쩸" => "jjem", "쩹" => "jjeb", + "쩺" => "jjebs", "ì©»" => "jjes", "쩼" => "jjess", "쩽" => "jjeng", "쩾" => "jjej", "ì©¿" => "jjec", + "쪀" => "jjek", "ìª" => "jjet", "쪂" => "jjep", "쪃" => "jjeh", "쪄" => "jjyeo", "쪅" => "jjyeog", + "쪆" => "jjyeogg", "쪇" => "jjyeogs", "쪈" => "jjyeon", "쪉" => "jjyeonj", "쪊" => "jjyeonh", "쪋" => "jjyeod", + "쪌" => "jjyeol", "ìª" => "jjyeolg", "쪎" => "jjyeolm", "ìª" => "jjyeolb", "ìª" => "jjyeols", "쪑" => "jjyeolt", + "쪒" => "jjyeolp", "쪓" => "jjyeolh", "쪔" => "jjyeom", "쪕" => "jjyeob", "쪖" => "jjyeobs", "쪗" => "jjyeos", + "쪘" => "jjyeoss", "쪙" => "jjyeong", "쪚" => "jjyeoj", "쪛" => "jjyeoc", "쪜" => "jjyeok", "ìª" => "jjyeot", + "쪞" => "jjyeop", "쪟" => "jjyeoh", "쪠" => "jjye", "쪡" => "jjyeg", "쪢" => "jjyegg", "쪣" => "jjyegs", + "쪤" => "jjyen", "쪥" => "jjyenj", "쪦" => "jjyenh", "쪧" => "jjyed", "쪨" => "jjyel", "쪩" => "jjyelg", + "쪪" => "jjyelm", "쪫" => "jjyelb", "쪬" => "jjyels", "쪭" => "jjyelt", "쪮" => "jjyelp", "쪯" => "jjyelh", + "쪰" => "jjyem", "쪱" => "jjyeb", "쪲" => "jjyebs", "쪳" => "jjyes", "쪴" => "jjyess", "쪵" => "jjyeng", + "쪶" => "jjyej", "쪷" => "jjyec", "쪸" => "jjyek", "쪹" => "jjyet", "쪺" => "jjyep", "쪻" => "jjyeh", + "쪼" => "jjo", "쪽" => "jjog", "쪾" => "jjogg", "쪿" => "jjogs", "ì«€" => "jjon", "ì«" => "jjonj", + "ì«‚" => "jjonh", "쫃" => "jjod", "ì«„" => "jjol", "ì«…" => "jjolg", "쫆" => "jjolm", "쫇" => "jjolb", + "쫈" => "jjols", "쫉" => "jjolt", "ì«Š" => "jjolp", "ì«‹" => "jjolh", "ì«Œ" => "jjom", "ì«" => "jjob", + "ì«Ž" => "jjobs", "ì«" => "jjos", "ì«" => "jjoss", "ì«‘" => "jjong", "ì«’" => "jjoj", "ì«“" => "jjoc", + "ì«”" => "jjok", "ì«•" => "jjot", "ì«–" => "jjop", "ì«—" => "jjoh", "쫘" => "jjwa", "ì«™" => "jjwag", + "ì«š" => "jjwagg", "ì«›" => "jjwags", "ì«œ" => "jjwan", "ì«" => "jjwanj", "ì«ž" => "jjwanh", "ì«Ÿ" => "jjwad", + "ì« " => "jjwal", "ì«¡" => "jjwalg", "ì«¢" => "jjwalm", "ì«£" => "jjwalb", "쫤" => "jjwals", "ì«¥" => "jjwalt", + "쫦" => "jjwalp", "쫧" => "jjwalh", "쫨" => "jjwam", "ì«©" => "jjwab", "쫪" => "jjwabs", "ì««" => "jjwas", + "쫬" => "jjwass", "ì«­" => "jjwang", "ì«®" => "jjwaj", "쫯" => "jjwac", "ì«°" => "jjwak", "쫱" => "jjwat", + "쫲" => "jjwap", "쫳" => "jjwah", "ì«´" => "jjwae", "쫵" => "jjwaeg", "쫶" => "jjwaegg", "ì«·" => "jjwaegs", + "쫸" => "jjwaen", "쫹" => "jjwaenj", "쫺" => "jjwaenh", "ì«»" => "jjwaed", "쫼" => "jjwael", "쫽" => "jjwaelg", + "쫾" => "jjwaelm", "ì«¿" => "jjwaelb", "ì¬" => "jjwaelt", "쬂" => "jjwaelp", "쬃" => "jjwaelh", "쬄" => "jjwaem", + "쬅" => "jjwaeb", "쬆" => "jjwaebs", "쬇" => "jjwaes", "쬈" => "jjwaess", "쬉" => "jjwaeng", "쬊" => "jjwaej", + "쬋" => "jjwaec", "쬌" => "jjwaek", "ì¬" => "jjwaet", "쬎" => "jjwaep", "ì¬" => "jjwaeh", "ì¬" => "jjoe", + "쬑" => "jjoeg", "쬒" => "jjoegg", "쬓" => "jjoegs", "쬔" => "jjoen", "쬕" => "jjoenj", "쬖" => "jjoenh", + "쬗" => "jjoed", "쬘" => "jjoel", "쬙" => "jjoelg", "쬚" => "jjoelm", "쬛" => "jjoelb", "쬜" => "jjoels", + "ì¬" => "jjoelt", "쬞" => "jjoelp", "쬟" => "jjoelh", "쬠" => "jjoem", "쬡" => "jjoeb", "쬢" => "jjoebs", + "쬣" => "jjoes", "쬤" => "jjoess", "쬥" => "jjoeng", "쬦" => "jjoej", "쬧" => "jjoec", "쬨" => "jjoek", + "쬩" => "jjoet", "쬪" => "jjoep", "쬫" => "jjoeh", "쬬" => "jjyo", "쬭" => "jjyog", "쬮" => "jjyogg", + "쬯" => "jjyogs", "쬰" => "jjyon", "쬱" => "jjyonj", "쬲" => "jjyonh", "쬳" => "jjyod", "쬴" => "jjyol", + "쬵" => "jjyolg", "쬶" => "jjyolm", "쬷" => "jjyolb", "쬸" => "jjyols", "쬹" => "jjyolt", "쬺" => "jjyolp", + "쬻" => "jjyolh", "쬼" => "jjyom", "쬽" => "jjyob", "쬾" => "jjyobs", "쬿" => "jjyos", "ì­€" => "jjyoss", + "ì­" => "jjyong", "ì­‚" => "jjyoj", "ì­ƒ" => "jjyoc", "ì­„" => "jjyok", "ì­…" => "jjyot", "ì­†" => "jjyop", + "ì­‡" => "jjyoh", "ì­ˆ" => "jju", "ì­‰" => "jjug", "ì­Š" => "jjugg", "ì­‹" => "jjugs", "ì­Œ" => "jjun", + "ì­" => "jjunj", "ì­Ž" => "jjunh", "ì­" => "jjud", "ì­" => "jjul", "ì­‘" => "jjulg", "ì­’" => "jjulm", + "ì­“" => "jjulb", "ì­”" => "jjuls", "ì­•" => "jjult", "ì­–" => "jjulp", "ì­—" => "jjulh", "ì­˜" => "jjum", + "ì­™" => "jjub", "ì­š" => "jjubs", "ì­›" => "jjus", "ì­œ" => "jjuss", "ì­" => "jjung", "ì­ž" => "jjuj", + "ì­Ÿ" => "jjuc", "ì­ " => "jjuk", "ì­¡" => "jjut", "ì­¢" => "jjup", "ì­£" => "jjuh", "ì­¤" => "jjweo", + "ì­¥" => "jjweog", "ì­¦" => "jjweogg", "ì­§" => "jjweogs", "ì­¨" => "jjweon", "ì­©" => "jjweonj", "ì­ª" => "jjweonh", + "ì­«" => "jjweod", "ì­¬" => "jjweol", "ì­­" => "jjweolg", "ì­®" => "jjweolm", "ì­¯" => "jjweolb", "ì­°" => "jjweols", + "ì­±" => "jjweolt", "ì­²" => "jjweolp", "ì­³" => "jjweolh", "ì­´" => "jjweom", "ì­µ" => "jjweob", "ì­¶" => "jjweobs", + "ì­·" => "jjweos", "ì­¸" => "jjweoss", "ì­¹" => "jjweong", "ì­º" => "jjweoj", "ì­»" => "jjweoc", "ì­¼" => "jjweok", + "ì­½" => "jjweot", "ì­¾" => "jjweop", "ì­¿" => "jjweoh", "쮀" => "jjwe", "ì®" => "jjweg", "쮂" => "jjwegg", + "쮃" => "jjwegs", "쮄" => "jjwen", "ì®…" => "jjwenj", "쮆" => "jjwenh", "쮇" => "jjwed", "쮈" => "jjwel", + "쮉" => "jjwelg", "쮊" => "jjwelm", "쮋" => "jjwelb", "쮌" => "jjwels", "ì®" => "jjwelt", "쮎" => "jjwelp", + "ì®" => "jjwelh", "ì®" => "jjwem", "쮑" => "jjweb", "ì®’" => "jjwebs", "쮓" => "jjwes", "ì®”" => "jjwess", + "쮕" => "jjweng", "ì®–" => "jjwej", "ì®—" => "jjwec", "쮘" => "jjwek", "ì®™" => "jjwet", "쮚" => "jjwep", + "ì®›" => "jjweh", "쮜" => "jjwi", "ì®" => "jjwig", "쮞" => "jjwigg", "쮟" => "jjwigs", "ì® " => "jjwin", + "쮡" => "jjwinj", "쮢" => "jjwinh", "쮣" => "jjwid", "쮤" => "jjwil", "쮥" => "jjwilg", "쮦" => "jjwilm", + "쮧" => "jjwilb", "쮨" => "jjwils", "쮩" => "jjwilt", "쮪" => "jjwilp", "쮫" => "jjwilh", "쮬" => "jjwim", + "ì®­" => "jjwib", "ì®®" => "jjwibs", "쮯" => "jjwis", "ì®°" => "jjwiss", "ì®±" => "jjwing", "쮲" => "jjwij", + "쮳" => "jjwic", "ì®´" => "jjwik", "쮵" => "jjwit", "쮶" => "jjwip", "ì®·" => "jjwih", "쮸" => "jjyu", + "쮹" => "jjyug", "쮺" => "jjyugg", "ì®»" => "jjyugs", "쮼" => "jjyun", "쮽" => "jjyunj", "쮾" => "jjyunh", + "쮿" => "jjyud", "쯀" => "jjyul", "ì¯" => "jjyulg", "쯂" => "jjyulm", "쯃" => "jjyulb", "쯄" => "jjyuls", + "쯅" => "jjyult", "쯆" => "jjyulp", "쯇" => "jjyulh", "쯈" => "jjyum", "쯉" => "jjyub", "쯊" => "jjyubs", + "쯋" => "jjyus", "쯌" => "jjyuss", "ì¯" => "jjyung", "쯎" => "jjyuj", "ì¯" => "jjyuc", "ì¯" => "jjyuk", + "쯑" => "jjyut", "쯒" => "jjyup", "쯓" => "jjyuh", "쯔" => "jjeu", "쯕" => "jjeug", "쯖" => "jjeugg", + "쯗" => "jjeugs", "쯘" => "jjeun", "쯙" => "jjeunj", "쯚" => "jjeunh", "쯛" => "jjeud", "쯜" => "jjeul", + "ì¯" => "jjeulg", "쯞" => "jjeulm", "쯟" => "jjeulb", "쯠" => "jjeuls", "쯡" => "jjeult", "쯢" => "jjeulp", + "쯣" => "jjeulh", "쯤" => "jjeum", "쯥" => "jjeub", "쯦" => "jjeubs", "쯧" => "jjeus", "쯨" => "jjeuss", + "쯩" => "jjeung", "쯪" => "jjeuj", "쯫" => "jjeuc", "쯬" => "jjeuk", "쯭" => "jjeut", "쯮" => "jjeup", + "쯯" => "jjeuh", "쯰" => "jjyi", "쯱" => "jjyig", "쯲" => "jjyigg", "쯳" => "jjyigs", "쯴" => "jjyin", + "쯵" => "jjyinj", "쯶" => "jjyinh", "쯷" => "jjyid", "쯸" => "jjyil", "쯹" => "jjyilg", "쯺" => "jjyilm", + "쯻" => "jjyilb", "쯼" => "jjyils", "쯽" => "jjyilt", "쯾" => "jjyilp", "쯿" => "jjyilh", "ì°" => "jjyib", + "ì°‚" => "jjyibs", "ì°ƒ" => "jjyis", "ì°„" => "jjyiss", "ì°…" => "jjying", "ì°†" => "jjyij", "ì°‡" => "jjyic", + "ì°ˆ" => "jjyik", "ì°‰" => "jjyit", "ì°Š" => "jjyip", "ì°‹" => "jjyih", "ì°Œ" => "jji", "ì°" => "jjig", + "ì°Ž" => "jjigg", "ì°" => "jjigs", "ì°" => "jjin", "ì°‘" => "jjinj", "ì°’" => "jjinh", "ì°“" => "jjid", + "ì°”" => "jjil", "ì°•" => "jjilg", "ì°–" => "jjilm", "ì°—" => "jjilb", "ì°˜" => "jjils", "ì°™" => "jjilt", + "ì°š" => "jjilp", "ì°›" => "jjilh", "ì°œ" => "jjim", "ì°" => "jjib", "ì°ž" => "jjibs", "ì°Ÿ" => "jjis", + "ì° " => "jjiss", "ì°¡" => "jjing", "ì°¢" => "jjij", "ì°£" => "jjic", "ì°¤" => "jjik", "ì°¥" => "jjit", + "ì°¦" => "jjip", "ì°§" => "jjih", "ì°¨" => "ca", "ì°©" => "cag", "ì°ª" => "cagg", "ì°«" => "cags", + "ì°¬" => "can", "ì°­" => "canj", "ì°®" => "canh", "ì°¯" => "cad", "ì°°" => "cal", "ì°±" => "calg", + "ì°²" => "calm", "ì°³" => "calb", "ì°´" => "cals", "ì°µ" => "calt", "ì°¶" => "calp", "ì°·" => "calh", + "ì°¸" => "cam", "ì°¹" => "cab", "ì°º" => "cabs", "ì°»" => "cas", "ì°¼" => "cass", "ì°½" => "cang", + "ì°¾" => "caj", "ì°¿" => "cac", "ì±€" => "cak", "ì±" => "cat", "챂" => "cap", "챃" => "cah", + "채" => "cae", "ì±…" => "caeg", "챆" => "caegg", "챇" => "caegs", "챈" => "caen", "챉" => "caenj", + "챊" => "caenh", "챋" => "caed", "챌" => "cael", "ì±" => "caelg", "챎" => "caelm", "ì±" => "caelb", + "ì±" => "caels", "챑" => "caelt", "ì±’" => "caelp", "챓" => "caelh", "ì±”" => "caem", "챕" => "caeb", + "ì±–" => "caebs", "ì±—" => "caes", "챘" => "caess", "ì±™" => "caeng", "챚" => "caej", "ì±›" => "caec", + "챜" => "caek", "ì±" => "caet", "챞" => "caep", "챟" => "caeh", "ì± " => "cya", "챡" => "cyag", + "ì±¢" => "cyagg", "ì±£" => "cyags", "챤" => "cyan", "ì±¥" => "cyanj", "챦" => "cyanh", "챧" => "cyad", + "챨" => "cyal", "챩" => "cyalg", "챪" => "cyalm", "챫" => "cyalb", "챬" => "cyals", "ì±­" => "cyalt", + "ì±®" => "cyalp", "챯" => "cyalh", "ì±°" => "cyam", "ì±±" => "cyab", "ì±²" => "cyabs", "ì±³" => "cyas", + "ì±´" => "cyass", "ì±µ" => "cyang", "챶" => "cyaj", "ì±·" => "cyac", "챸" => "cyak", "ì±¹" => "cyat", + "챺" => "cyap", "ì±»" => "cyah", "ì±¼" => "cyae", "ì±½" => "cyaeg", "ì±¾" => "cyaegg", "챿" => "cyaegs", + "ì²€" => "cyaen", "ì²" => "cyaenj", "첂" => "cyaenh", "첃" => "cyaed", "첄" => "cyael", "ì²…" => "cyaelg", + "첆" => "cyaelm", "첇" => "cyaelb", "첈" => "cyaels", "첉" => "cyaelt", "첊" => "cyaelp", "첋" => "cyaelh", + "첌" => "cyaem", "ì²" => "cyaeb", "첎" => "cyaebs", "ì²" => "cyaes", "ì²" => "cyaess", "첑" => "cyaeng", + "ì²’" => "cyaej", "첓" => "cyaec", "ì²”" => "cyaek", "첕" => "cyaet", "ì²–" => "cyaep", "ì²—" => "cyaeh", + "처" => "ceo", "ì²™" => "ceog", "첚" => "ceogg", "ì²›" => "ceogs", "천" => "ceon", "ì²" => "ceonj", + "첞" => "ceonh", "첟" => "ceod", "ì² " => "ceol", "첡" => "ceolg", "ì²¢" => "ceolm", "ì²£" => "ceolb", + "첤" => "ceols", "ì²¥" => "ceolt", "첦" => "ceolp", "첧" => "ceolh", "첨" => "ceom", "첩" => "ceob", + "첪" => "ceobs", "첫" => "ceos", "첬" => "ceoss", "ì²­" => "ceong", "ì²®" => "ceoj", "첯" => "ceoc", + "ì²°" => "ceok", "ì²±" => "ceot", "ì²²" => "ceop", "ì²³" => "ceoh", "ì²´" => "ce", "ì²µ" => "ceg", + "첶" => "cegg", "ì²·" => "cegs", "첸" => "cen", "ì²¹" => "cenj", "첺" => "cenh", "ì²»" => "ced", + "ì²¼" => "cel", "ì²½" => "celg", "ì²¾" => "celm", "첿" => "celb", "ì³€" => "cels", "ì³" => "celt", + "쳂" => "celp", "쳃" => "celh", "쳄" => "cem", "ì³…" => "ceb", "쳆" => "cebs", "쳇" => "ces", + "쳈" => "cess", "쳉" => "ceng", "쳊" => "cej", "쳋" => "cec", "쳌" => "cek", "ì³" => "cet", + "쳎" => "cep", "ì³" => "ceh", "ì³" => "cyeo", "쳑" => "cyeog", "ì³’" => "cyeogg", "쳓" => "cyeogs", + "ì³”" => "cyeon", "쳕" => "cyeonj", "ì³–" => "cyeonh", "ì³—" => "cyeod", "쳘" => "cyeol", "ì³™" => "cyeolg", + "쳚" => "cyeolm", "ì³›" => "cyeolb", "쳜" => "cyeols", "ì³" => "cyeolt", "쳞" => "cyeolp", "쳟" => "cyeolh", + "ì³ " => "cyeom", "쳡" => "cyeob", "ì³¢" => "cyeobs", "ì³£" => "cyeos", "쳤" => "cyeoss", "ì³¥" => "cyeong", + "쳦" => "cyeoj", "쳧" => "cyeoc", "쳨" => "cyeok", "쳩" => "cyeot", "쳪" => "cyeop", "쳫" => "cyeoh", + "쳬" => "cye", "ì³­" => "cyeg", "ì³®" => "cyegg", "쳯" => "cyegs", "ì³°" => "cyen", "ì³±" => "cyenj", + "ì³²" => "cyenh", "ì³³" => "cyed", "ì³´" => "cyel", "ì³µ" => "cyelg", "쳶" => "cyelm", "ì³·" => "cyelb", + "쳸" => "cyels", "ì³¹" => "cyelt", "쳺" => "cyelp", "ì³»" => "cyelh", "ì³¼" => "cyem", "ì³½" => "cyeb", + "ì³¾" => "cyebs", "쳿" => "cyes", "ì´" => "cyeng", "ì´‚" => "cyej", "ì´ƒ" => "cyec", "ì´„" => "cyek", + "ì´…" => "cyet", "ì´†" => "cyep", "ì´‡" => "cyeh", "ì´ˆ" => "co", "ì´‰" => "cog", "ì´Š" => "cogg", + "ì´‹" => "cogs", "ì´Œ" => "con", "ì´" => "conj", "ì´Ž" => "conh", "ì´" => "cod", "ì´" => "col", + "ì´‘" => "colg", "ì´’" => "colm", "ì´“" => "colb", "ì´”" => "cols", "ì´•" => "colt", "ì´–" => "colp", + "ì´—" => "colh", "ì´˜" => "com", "ì´™" => "cob", "ì´š" => "cobs", "ì´›" => "cos", "ì´œ" => "coss", + "ì´" => "cong", "ì´ž" => "coj", "ì´Ÿ" => "coc", "ì´ " => "cok", "ì´¡" => "cot", "ì´¢" => "cop", + "ì´£" => "coh", "ì´¤" => "cwa", "ì´¥" => "cwag", "ì´¦" => "cwagg", "ì´§" => "cwags", "ì´¨" => "cwan", + "ì´©" => "cwanj", "ì´ª" => "cwanh", "ì´«" => "cwad", "ì´¬" => "cwal", "ì´­" => "cwalg", "ì´®" => "cwalm", + "ì´¯" => "cwalb", "ì´°" => "cwals", "ì´±" => "cwalt", "ì´²" => "cwalp", "ì´³" => "cwalh", "ì´´" => "cwam", + "ì´µ" => "cwab", "ì´¶" => "cwabs", "ì´·" => "cwas", "ì´¸" => "cwass", "ì´¹" => "cwang", "ì´º" => "cwaj", + "ì´»" => "cwac", "ì´¼" => "cwak", "ì´½" => "cwat", "ì´¾" => "cwap", "ì´¿" => "cwah", "ìµ€" => "cwae", + "ìµ" => "cwaeg", "쵂" => "cwaegg", "쵃" => "cwaegs", "쵄" => "cwaen", "ìµ…" => "cwaenj", "쵆" => "cwaenh", + "쵇" => "cwaed", "쵈" => "cwael", "쵉" => "cwaelg", "쵊" => "cwaelm", "쵋" => "cwaelb", "쵌" => "cwaels", + "ìµ" => "cwaelt", "쵎" => "cwaelp", "ìµ" => "cwaelh", "ìµ" => "cwaem", "쵑" => "cwaeb", "ìµ’" => "cwaebs", + "쵓" => "cwaes", "ìµ”" => "cwaess", "쵕" => "cwaeng", "ìµ–" => "cwaej", "ìµ—" => "cwaec", "쵘" => "cwaek", + "ìµ™" => "cwaet", "쵚" => "cwaep", "ìµ›" => "cwaeh", "최" => "coe", "ìµ" => "coeg", "쵞" => "coegg", + "쵟" => "coegs", "ìµ " => "coen", "쵡" => "coenj", "ìµ¢" => "coenh", "ìµ£" => "coed", "쵤" => "coel", + "ìµ¥" => "coelg", "쵦" => "coelm", "쵧" => "coelb", "쵨" => "coels", "쵩" => "coelt", "쵪" => "coelp", + "쵫" => "coelh", "쵬" => "coem", "ìµ­" => "coeb", "ìµ®" => "coebs", "쵯" => "coes", "ìµ°" => "coess", + "ìµ±" => "coeng", "ìµ²" => "coej", "ìµ³" => "coec", "ìµ´" => "coek", "ìµµ" => "coet", "쵶" => "coep", + "ìµ·" => "coeh", "쵸" => "cyo", "ìµ¹" => "cyog", "쵺" => "cyogg", "ìµ»" => "cyogs", "ìµ¼" => "cyon", + "ìµ½" => "cyonj", "ìµ¾" => "cyonh", "쵿" => "cyod", "춀" => "cyol", "ì¶" => "cyolg", "춂" => "cyolm", + "춃" => "cyolb", "춄" => "cyols", "춅" => "cyolt", "춆" => "cyolp", "춇" => "cyolh", "춈" => "cyom", + "춉" => "cyob", "춊" => "cyobs", "춋" => "cyos", "춌" => "cyoss", "ì¶" => "cyong", "춎" => "cyoj", + "ì¶" => "cyoc", "ì¶" => "cyok", "춑" => "cyot", "춒" => "cyop", "춓" => "cyoh", "추" => "cu", + "축" => "cug", "춖" => "cugg", "춗" => "cugs", "춘" => "cun", "춙" => "cunj", "춚" => "cunh", + "춛" => "cud", "출" => "cul", "ì¶" => "culg", "춞" => "culm", "춟" => "culb", "춠" => "culs", + "춡" => "cult", "춢" => "culp", "춣" => "culh", "춤" => "cum", "춥" => "cub", "춦" => "cubs", + "춧" => "cus", "춨" => "cuss", "충" => "cung", "춪" => "cuj", "춫" => "cuc", "춬" => "cuk", + "춭" => "cut", "춮" => "cup", "춯" => "cuh", "춰" => "cweo", "춱" => "cweog", "춲" => "cweogg", + "춳" => "cweogs", "춴" => "cweon", "춵" => "cweonj", "춶" => "cweonh", "춷" => "cweod", "춸" => "cweol", + "춹" => "cweolg", "춺" => "cweolm", "춻" => "cweolb", "춼" => "cweols", "춽" => "cweolt", "춾" => "cweolp", + "춿" => "cweolh", "ì·€" => "cweom", "ì·" => "cweob", "ì·‚" => "cweobs", "ì·ƒ" => "cweos", "ì·„" => "cweoss", + "ì·…" => "cweong", "ì·†" => "cweoj", "ì·‡" => "cweoc", "ì·ˆ" => "cweok", "ì·‰" => "cweot", "ì·Š" => "cweop", + "ì·‹" => "cweoh", "ì·Œ" => "cwe", "ì·" => "cweg", "ì·Ž" => "cwegg", "ì·" => "cwegs", "ì·" => "cwen", + "ì·‘" => "cwenj", "ì·’" => "cwenh", "ì·“" => "cwed", "ì·”" => "cwel", "ì·•" => "cwelg", "ì·–" => "cwelm", + "ì·—" => "cwelb", "ì·˜" => "cwels", "ì·™" => "cwelt", "ì·š" => "cwelp", "ì·›" => "cwelh", "ì·œ" => "cwem", + "ì·" => "cweb", "ì·ž" => "cwebs", "ì·Ÿ" => "cwes", "ì· " => "cwess", "ì·¡" => "cweng", "ì·¢" => "cwej", + "ì·£" => "cwec", "ì·¤" => "cwek", "ì·¥" => "cwet", "ì·¦" => "cwep", "ì·§" => "cweh", "ì·¨" => "cwi", + "ì·©" => "cwig", "ì·ª" => "cwigg", "ì·«" => "cwigs", "ì·¬" => "cwin", "ì·­" => "cwinj", "ì·®" => "cwinh", + "ì·¯" => "cwid", "ì·°" => "cwil", "ì·±" => "cwilg", "ì·²" => "cwilm", "ì·³" => "cwilb", "ì·´" => "cwils", + "ì·µ" => "cwilt", "ì·¶" => "cwilp", "ì··" => "cwilh", "ì·¸" => "cwim", "ì·¹" => "cwib", "ì·º" => "cwibs", + "ì·»" => "cwis", "ì·¼" => "cwiss", "ì·½" => "cwing", "ì·¾" => "cwij", "ì·¿" => "cwic", "ì¸" => "cwit", + "츂" => "cwip", "츃" => "cwih", "츄" => "cyu", "츅" => "cyug", "츆" => "cyugg", "츇" => "cyugs", + "츈" => "cyun", "츉" => "cyunj", "츊" => "cyunh", "츋" => "cyud", "츌" => "cyul", "ì¸" => "cyulg", + "츎" => "cyulm", "ì¸" => "cyulb", "ì¸" => "cyuls", "츑" => "cyult", "츒" => "cyulp", "츓" => "cyulh", + "츔" => "cyum", "츕" => "cyub", "츖" => "cyubs", "츗" => "cyus", "츘" => "cyuss", "츙" => "cyung", + "츚" => "cyuj", "츛" => "cyuc", "츜" => "cyuk", "ì¸" => "cyut", "츞" => "cyup", "츟" => "cyuh", + "츠" => "ceu", "측" => "ceug", "츢" => "ceugg", "츣" => "ceugs", "츤" => "ceun", "츥" => "ceunj", + "츦" => "ceunh", "츧" => "ceud", "츨" => "ceul", "츩" => "ceulg", "츪" => "ceulm", "츫" => "ceulb", + "츬" => "ceuls", "츭" => "ceult", "츮" => "ceulp", "츯" => "ceulh", "츰" => "ceum", "츱" => "ceub", + "츲" => "ceubs", "츳" => "ceus", "츴" => "ceuss", "층" => "ceung", "츶" => "ceuj", "츷" => "ceuc", + "츸" => "ceuk", "츹" => "ceut", "츺" => "ceup", "츻" => "ceuh", "츼" => "cyi", "츽" => "cyig", + "츾" => "cyigg", "츿" => "cyigs", "ì¹€" => "cyin", "ì¹" => "cyinj", "칂" => "cyinh", "칃" => "cyid", + "칄" => "cyil", "ì¹…" => "cyilg", "칆" => "cyilm", "칇" => "cyilb", "칈" => "cyils", "칉" => "cyilt", + "칊" => "cyilp", "칋" => "cyilh", "칌" => "cyim", "ì¹" => "cyib", "칎" => "cyibs", "ì¹" => "cyis", + "ì¹" => "cyiss", "칑" => "cying", "ì¹’" => "cyij", "칓" => "cyic", "ì¹”" => "cyik", "칕" => "cyit", + "ì¹–" => "cyip", "ì¹—" => "cyih", "치" => "ci", "ì¹™" => "cig", "칚" => "cigg", "ì¹›" => "cigs", + "친" => "cin", "ì¹" => "cinj", "칞" => "cinh", "칟" => "cid", "ì¹ " => "cil", "칡" => "cilg", + "ì¹¢" => "cilm", "ì¹£" => "cilb", "칤" => "cils", "ì¹¥" => "cilt", "칦" => "cilp", "칧" => "cilh", + "침" => "cim", "칩" => "cib", "칪" => "cibs", "칫" => "cis", "칬" => "ciss", "ì¹­" => "cing", + "ì¹®" => "cij", "칯" => "cic", "ì¹°" => "cik", "ì¹±" => "cit", "ì¹²" => "cip", "ì¹³" => "cih", + "ì¹´" => "ka", "ì¹µ" => "kag", "칶" => "kagg", "ì¹·" => "kags", "칸" => "kan", "ì¹¹" => "kanj", + "칺" => "kanh", "ì¹»" => "kad", "ì¹¼" => "kal", "ì¹½" => "kalg", "ì¹¾" => "kalm", "칿" => "kalb", + "캀" => "kals", "ìº" => "kalt", "캂" => "kalp", "캃" => "kalh", "캄" => "kam", "캅" => "kab", + "캆" => "kabs", "캇" => "kas", "캈" => "kass", "캉" => "kang", "캊" => "kaj", "캋" => "kac", + "캌" => "kak", "ìº" => "kat", "캎" => "kap", "ìº" => "kah", "ìº" => "kae", "캑" => "kaeg", + "캒" => "kaegg", "캓" => "kaegs", "캔" => "kaen", "캕" => "kaenj", "캖" => "kaenh", "캗" => "kaed", + "캘" => "kael", "캙" => "kaelg", "캚" => "kaelm", "캛" => "kaelb", "캜" => "kaels", "ìº" => "kaelt", + "캞" => "kaelp", "캟" => "kaelh", "캠" => "kaem", "캡" => "kaeb", "캢" => "kaebs", "캣" => "kaes", + "캤" => "kaess", "캥" => "kaeng", "캦" => "kaej", "캧" => "kaec", "캨" => "kaek", "캩" => "kaet", + "캪" => "kaep", "캫" => "kaeh", "캬" => "kya", "캭" => "kyag", "캮" => "kyagg", "캯" => "kyags", + "캰" => "kyan", "캱" => "kyanj", "캲" => "kyanh", "캳" => "kyad", "캴" => "kyal", "캵" => "kyalg", + "캶" => "kyalm", "캷" => "kyalb", "캸" => "kyals", "캹" => "kyalt", "캺" => "kyalp", "캻" => "kyalh", + "캼" => "kyam", "캽" => "kyab", "캾" => "kyabs", "캿" => "kyas", "컀" => "kyass", "ì»" => "kyang", + "컂" => "kyaj", "컃" => "kyac", "컄" => "kyak", "ì»…" => "kyat", "컆" => "kyap", "컇" => "kyah", + "컈" => "kyae", "컉" => "kyaeg", "컊" => "kyaegg", "컋" => "kyaegs", "컌" => "kyaen", "ì»" => "kyaenj", + "컎" => "kyaenh", "ì»" => "kyaed", "ì»" => "kyael", "컑" => "kyaelg", "ì»’" => "kyaelm", "컓" => "kyaelb", + "ì»”" => "kyaels", "컕" => "kyaelt", "ì»–" => "kyaelp", "ì»—" => "kyaelh", "컘" => "kyaem", "ì»™" => "kyaeb", + "컚" => "kyaebs", "ì»›" => "kyaes", "컜" => "kyaess", "ì»" => "kyaeng", "컞" => "kyaej", "컟" => "kyaec", + "ì» " => "kyaek", "컡" => "kyaet", "컢" => "kyaep", "컣" => "kyaeh", "커" => "keo", "컥" => "keog", + "컦" => "keogg", "컧" => "keogs", "컨" => "keon", "컩" => "keonj", "컪" => "keonh", "컫" => "keod", + "컬" => "keol", "ì»­" => "keolg", "ì»®" => "keolm", "컯" => "keolb", "ì»°" => "keols", "ì»±" => "keolt", + "컲" => "keolp", "컳" => "keolh", "ì»´" => "keom", "컵" => "keob", "컶" => "keobs", "ì»·" => "keos", + "컸" => "keoss", "컹" => "keong", "컺" => "keoj", "ì»»" => "keoc", "컼" => "keok", "컽" => "keot", + "컾" => "keop", "컿" => "keoh", "ì¼" => "keg", "켂" => "kegg", "켃" => "kegs", "켄" => "ken", + "ì¼…" => "kenj", "켆" => "kenh", "켇" => "ked", "켈" => "kel", "켉" => "kelg", "켊" => "kelm", + "켋" => "kelb", "켌" => "kels", "ì¼" => "kelt", "켎" => "kelp", "ì¼" => "kelh", "ì¼" => "kem", + "켑" => "keb", "ì¼’" => "kebs", "켓" => "kes", "ì¼”" => "kess", "켕" => "keng", "ì¼–" => "kej", + "ì¼—" => "kec", "켘" => "kek", "ì¼™" => "ket", "켚" => "kep", "ì¼›" => "keh", "켜" => "kyeo", + "ì¼" => "kyeog", "켞" => "kyeogg", "켟" => "kyeogs", "ì¼ " => "kyeon", "켡" => "kyeonj", "ì¼¢" => "kyeonh", + "ì¼£" => "kyeod", "켤" => "kyeol", "ì¼¥" => "kyeolg", "켦" => "kyeolm", "켧" => "kyeolb", "켨" => "kyeols", + "켩" => "kyeolt", "켪" => "kyeolp", "켫" => "kyeolh", "켬" => "kyeom", "ì¼­" => "kyeob", "ì¼®" => "kyeobs", + "켯" => "kyeos", "ì¼°" => "kyeoss", "ì¼±" => "kyeong", "ì¼²" => "kyeoj", "ì¼³" => "kyeoc", "ì¼´" => "kyeok", + "ì¼µ" => "kyeot", "켶" => "kyeop", "ì¼·" => "kyeoh", "켸" => "kye", "ì¼¹" => "kyeg", "켺" => "kyegg", + "ì¼»" => "kyegs", "ì¼¼" => "kyen", "ì¼½" => "kyenj", "ì¼¾" => "kyenh", "켿" => "kyed", "ì½€" => "kyel", + "ì½" => "kyelg", "콂" => "kyelm", "콃" => "kyelb", "콄" => "kyels", "ì½…" => "kyelt", "콆" => "kyelp", + "콇" => "kyelh", "콈" => "kyem", "콉" => "kyeb", "콊" => "kyebs", "콋" => "kyes", "콌" => "kyess", + "ì½" => "kyeng", "콎" => "kyej", "ì½" => "kyec", "ì½" => "kyek", "콑" => "kyet", "ì½’" => "kyep", + "콓" => "kyeh", "ì½”" => "ko", "콕" => "kog", "ì½–" => "kogg", "ì½—" => "kogs", "콘" => "kon", + "ì½™" => "konj", "콚" => "konh", "ì½›" => "kod", "콜" => "kol", "ì½" => "kolg", "콞" => "kolm", + "콟" => "kolb", "ì½ " => "kols", "콡" => "kolt", "ì½¢" => "kolp", "ì½£" => "kolh", "콤" => "kom", + "ì½¥" => "kob", "콦" => "kobs", "콧" => "kos", "콨" => "koss", "콩" => "kong", "콪" => "koj", + "콫" => "koc", "콬" => "kok", "ì½­" => "kot", "ì½®" => "kop", "콯" => "koh", "ì½°" => "kwa", + "ì½±" => "kwag", "ì½²" => "kwagg", "ì½³" => "kwags", "ì½´" => "kwan", "ì½µ" => "kwanj", "콶" => "kwanh", + "ì½·" => "kwad", "콸" => "kwal", "ì½¹" => "kwalg", "콺" => "kwalm", "ì½»" => "kwalb", "ì½¼" => "kwals", + "ì½½" => "kwalt", "ì½¾" => "kwalp", "콿" => "kwalh", "ì¾€" => "kwam", "ì¾" => "kwab", "쾂" => "kwabs", + "쾃" => "kwas", "쾄" => "kwass", "ì¾…" => "kwang", "쾆" => "kwaj", "쾇" => "kwac", "쾈" => "kwak", + "쾉" => "kwat", "쾊" => "kwap", "쾋" => "kwah", "쾌" => "kwae", "ì¾" => "kwaeg", "쾎" => "kwaegg", + "ì¾" => "kwaegs", "ì¾" => "kwaen", "쾑" => "kwaenj", "ì¾’" => "kwaenh", "쾓" => "kwaed", "ì¾”" => "kwael", + "쾕" => "kwaelg", "ì¾–" => "kwaelm", "ì¾—" => "kwaelb", "쾘" => "kwaels", "ì¾™" => "kwaelt", "쾚" => "kwaelp", + "ì¾›" => "kwaelh", "쾜" => "kwaem", "ì¾" => "kwaeb", "쾞" => "kwaebs", "쾟" => "kwaes", "ì¾ " => "kwaess", + "쾡" => "kwaeng", "ì¾¢" => "kwaej", "ì¾£" => "kwaec", "쾤" => "kwaek", "ì¾¥" => "kwaet", "쾦" => "kwaep", + "쾧" => "kwaeh", "쾨" => "koe", "쾩" => "koeg", "쾪" => "koegg", "쾫" => "koegs", "쾬" => "koen", + "ì¾­" => "koenj", "ì¾®" => "koenh", "쾯" => "koed", "ì¾°" => "koel", "ì¾±" => "koelg", "ì¾²" => "koelm", + "ì¾³" => "koelb", "ì¾´" => "koels", "ì¾µ" => "koelt", "쾶" => "koelp", "ì¾·" => "koelh", "쾸" => "koem", + "ì¾¹" => "koeb", "쾺" => "koebs", "ì¾»" => "koes", "ì¾¼" => "koess", "ì¾½" => "koeng", "ì¾¾" => "koej", + "쾿" => "koec", "ì¿€" => "koek", "ì¿" => "koet", "ì¿‚" => "koep", "쿃" => "koeh", "ì¿„" => "kyo", + "ì¿…" => "kyog", "쿆" => "kyogg", "쿇" => "kyogs", "쿈" => "kyon", "쿉" => "kyonj", "ì¿Š" => "kyonh", + "ì¿‹" => "kyod", "ì¿Œ" => "kyol", "ì¿" => "kyolg", "ì¿Ž" => "kyolm", "ì¿" => "kyolb", "ì¿" => "kyols", + "ì¿‘" => "kyolt", "ì¿’" => "kyolp", "ì¿“" => "kyolh", "ì¿”" => "kyom", "ì¿•" => "kyob", "ì¿–" => "kyobs", + "ì¿—" => "kyos", "쿘" => "kyoss", "ì¿™" => "kyong", "ì¿š" => "kyoj", "ì¿›" => "kyoc", "ì¿œ" => "kyok", + "ì¿" => "kyot", "ì¿ž" => "kyop", "ì¿Ÿ" => "kyoh", "ì¿ " => "ku", "ì¿¡" => "kug", "ì¿¢" => "kugg", + "ì¿£" => "kugs", "쿤" => "kun", "ì¿¥" => "kunj", "쿦" => "kunh", "쿧" => "kud", "쿨" => "kul", + "ì¿©" => "kulg", "쿪" => "kulm", "ì¿«" => "kulb", "쿬" => "kuls", "ì¿­" => "kult", "ì¿®" => "kulp", + "쿯" => "kulh", "ì¿°" => "kum", "쿱" => "kub", "쿲" => "kubs", "쿳" => "kus", "ì¿´" => "kuss", + "쿵" => "kung", "쿶" => "kuj", "ì¿·" => "kuc", "쿸" => "kuk", "쿹" => "kut", "쿺" => "kup", + "ì¿»" => "kuh", "쿼" => "kweo", "쿽" => "kweog", "쿾" => "kweogg", "ì¿¿" => "kweogs", "í€" => "kweonj", + "퀂" => "kweonh", "퀃" => "kweod", "퀄" => "kweol", "퀅" => "kweolg", "퀆" => "kweolm", "퀇" => "kweolb", + "퀈" => "kweols", "퀉" => "kweolt", "퀊" => "kweolp", "퀋" => "kweolh", "퀌" => "kweom", "í€" => "kweob", + "퀎" => "kweobs", "í€" => "kweos", "í€" => "kweoss", "퀑" => "kweong", "퀒" => "kweoj", "퀓" => "kweoc", + "퀔" => "kweok", "퀕" => "kweot", "퀖" => "kweop", "퀗" => "kweoh", "퀘" => "kwe", "퀙" => "kweg", + "퀚" => "kwegg", "퀛" => "kwegs", "퀜" => "kwen", "í€" => "kwenj", "퀞" => "kwenh", "퀟" => "kwed", + "퀠" => "kwel", "퀡" => "kwelg", "퀢" => "kwelm", "퀣" => "kwelb", "퀤" => "kwels", "퀥" => "kwelt", + "퀦" => "kwelp", "퀧" => "kwelh", "퀨" => "kwem", "퀩" => "kweb", "퀪" => "kwebs", "퀫" => "kwes", + "퀬" => "kwess", "퀭" => "kweng", "퀮" => "kwej", "퀯" => "kwec", "퀰" => "kwek", "퀱" => "kwet", + "퀲" => "kwep", "퀳" => "kweh", "퀴" => "kwi", "퀵" => "kwig", "퀶" => "kwigg", "퀷" => "kwigs", + "퀸" => "kwin", "퀹" => "kwinj", "퀺" => "kwinh", "퀻" => "kwid", "퀼" => "kwil", "퀽" => "kwilg", + "퀾" => "kwilm", "퀿" => "kwilb", "í€" => "kwils", "í" => "kwilt", "í‚" => "kwilp", "íƒ" => "kwilh", + "í„" => "kwim", "í…" => "kwib", "í†" => "kwibs", "í‡" => "kwis", "íˆ" => "kwiss", "í‰" => "kwing", + "íŠ" => "kwij", "í‹" => "kwic", "íŒ" => "kwik", "í" => "kwit", "íŽ" => "kwip", "í" => "kwih", + "í" => "kyu", "í‘" => "kyug", "í’" => "kyugg", "í“" => "kyugs", "í”" => "kyun", "í•" => "kyunj", + "í–" => "kyunh", "í—" => "kyud", "í˜" => "kyul", "í™" => "kyulg", "íš" => "kyulm", "í›" => "kyulb", + "íœ" => "kyuls", "í" => "kyult", "íž" => "kyulp", "íŸ" => "kyulh", "í " => "kyum", "í¡" => "kyub", + "í¢" => "kyubs", "í£" => "kyus", "í¤" => "kyuss", "í¥" => "kyung", "í¦" => "kyuj", "í§" => "kyuc", + "í¨" => "kyuk", "í©" => "kyut", "íª" => "kyup", "í«" => "kyuh", "í¬" => "keu", "í­" => "keug", + "í®" => "keugg", "í¯" => "keugs", "í°" => "keun", "í±" => "keunj", "í²" => "keunh", "í³" => "keud", + "í´" => "keul", "íµ" => "keulg", "í¶" => "keulm", "í·" => "keulb", "í¸" => "keuls", "í¹" => "keult", + "íº" => "keulp", "í»" => "keulh", "í¼" => "keum", "í½" => "keub", "í¾" => "keubs", "í¿" => "keus", + "í‚€" => "keuss", "í‚" => "keung", "í‚‚" => "keuj", "킃" => "keuc", "í‚„" => "keuk", "í‚…" => "keut", + "킆" => "keup", "킇" => "keuh", "킈" => "kyi", "킉" => "kyig", "í‚Š" => "kyigg", "í‚‹" => "kyigs", + "í‚Œ" => "kyin", "í‚" => "kyinj", "í‚Ž" => "kyinh", "í‚" => "kyid", "í‚" => "kyil", "í‚‘" => "kyilg", + "í‚’" => "kyilm", "í‚“" => "kyilb", "í‚”" => "kyils", "í‚•" => "kyilt", "í‚–" => "kyilp", "í‚—" => "kyilh", + "킘" => "kyim", "í‚™" => "kyib", "í‚š" => "kyibs", "í‚›" => "kyis", "í‚œ" => "kyiss", "í‚" => "kying", + "í‚ž" => "kyij", "í‚Ÿ" => "kyic", "í‚ " => "kyik", "í‚¡" => "kyit", "í‚¢" => "kyip", "í‚£" => "kyih", + "키" => "ki", "í‚¥" => "kig", "킦" => "kigg", "킧" => "kigs", "킨" => "kin", "í‚©" => "kinj", + "킪" => "kinh", "í‚«" => "kid", "킬" => "kil", "í‚­" => "kilg", "í‚®" => "kilm", "킯" => "kilb", + "í‚°" => "kils", "킱" => "kilt", "킲" => "kilp", "킳" => "kilh", "í‚´" => "kim", "킵" => "kib", + "킶" => "kibs", "í‚·" => "kis", "킸" => "kiss", "킹" => "king", "킺" => "kij", "í‚»" => "kic", + "킼" => "kik", "킽" => "kit", "킾" => "kip", "í‚¿" => "kih", "타" => "ta", "íƒ" => "tag", + "탂" => "tagg", "탃" => "tags", "탄" => "tan", "탅" => "tanj", "탆" => "tanh", "탇" => "tad", + "탈" => "tal", "탉" => "talg", "탊" => "talm", "탋" => "talb", "탌" => "tals", "íƒ" => "talt", + "탎" => "talp", "íƒ" => "talh", "íƒ" => "tam", "탑" => "tab", "탒" => "tabs", "탓" => "tas", + "탔" => "tass", "탕" => "tang", "탖" => "taj", "탗" => "tac", "탘" => "tak", "탙" => "tat", + "탚" => "tap", "탛" => "tah", "태" => "tae", "íƒ" => "taeg", "탞" => "taegg", "탟" => "taegs", + "탠" => "taen", "탡" => "taenj", "탢" => "taenh", "탣" => "taed", "탤" => "tael", "탥" => "taelg", + "탦" => "taelm", "탧" => "taelb", "탨" => "taels", "탩" => "taelt", "탪" => "taelp", "탫" => "taelh", + "탬" => "taem", "탭" => "taeb", "탮" => "taebs", "탯" => "taes", "탰" => "taess", "탱" => "taeng", + "탲" => "taej", "탳" => "taec", "탴" => "taek", "탵" => "taet", "탶" => "taep", "탷" => "taeh", + "탸" => "tya", "탹" => "tyag", "탺" => "tyagg", "탻" => "tyags", "탼" => "tyan", "탽" => "tyanj", + "탾" => "tyanh", "탿" => "tyad", "í„" => "tyalg", "í„‚" => "tyalm", "턃" => "tyalb", "í„„" => "tyals", + "í„…" => "tyalt", "턆" => "tyalp", "턇" => "tyalh", "턈" => "tyam", "턉" => "tyab", "í„Š" => "tyabs", + "í„‹" => "tyas", "í„Œ" => "tyass", "í„" => "tyang", "í„Ž" => "tyaj", "í„" => "tyac", "í„" => "tyak", + "í„‘" => "tyat", "í„’" => "tyap", "í„“" => "tyah", "í„”" => "tyae", "í„•" => "tyaeg", "í„–" => "tyaegg", + "í„—" => "tyaegs", "턘" => "tyaen", "í„™" => "tyaenj", "í„š" => "tyaenh", "í„›" => "tyaed", "í„œ" => "tyael", + "í„" => "tyaelg", "í„ž" => "tyaelm", "í„Ÿ" => "tyaelb", "í„ " => "tyaels", "í„¡" => "tyaelt", "í„¢" => "tyaelp", + "í„£" => "tyaelh", "턤" => "tyaem", "í„¥" => "tyaeb", "턦" => "tyaebs", "턧" => "tyaes", "턨" => "tyaess", + "í„©" => "tyaeng", "턪" => "tyaej", "í„«" => "tyaec", "턬" => "tyaek", "í„­" => "tyaet", "í„®" => "tyaep", + "턯" => "tyaeh", "í„°" => "teo", "턱" => "teog", "턲" => "teogg", "턳" => "teogs", "í„´" => "teon", + "턵" => "teonj", "턶" => "teonh", "í„·" => "teod", "털" => "teol", "턹" => "teolg", "턺" => "teolm", + "í„»" => "teolb", "턼" => "teols", "턽" => "teolt", "턾" => "teolp", "í„¿" => "teolh", "í…€" => "teom", + "í…" => "teob", "í…‚" => "teobs", "í…ƒ" => "teos", "í…„" => "teoss", "í……" => "teong", "í…†" => "teoj", + "í…‡" => "teoc", "í…ˆ" => "teok", "í…‰" => "teot", "í…Š" => "teop", "í…‹" => "teoh", "í…Œ" => "te", + "í…" => "teg", "í…Ž" => "tegg", "í…" => "tegs", "í…" => "ten", "í…‘" => "tenj", "í…’" => "tenh", + "í…“" => "ted", "í…”" => "tel", "í…•" => "telg", "í…–" => "telm", "í…—" => "telb", "í…˜" => "tels", + "í…™" => "telt", "í…š" => "telp", "í…›" => "telh", "í…œ" => "tem", "í…" => "teb", "í…ž" => "tebs", + "í…Ÿ" => "tes", "í… " => "tess", "í…¡" => "teng", "í…¢" => "tej", "í…£" => "tec", "í…¤" => "tek", + "í…¥" => "tet", "í…¦" => "tep", "í…§" => "teh", "í…¨" => "tyeo", "í…©" => "tyeog", "í…ª" => "tyeogg", + "í…«" => "tyeogs", "í…¬" => "tyeon", "í…­" => "tyeonj", "í…®" => "tyeonh", "í…¯" => "tyeod", "í…°" => "tyeol", + "í…±" => "tyeolg", "í…²" => "tyeolm", "í…³" => "tyeolb", "í…´" => "tyeols", "í…µ" => "tyeolt", "í…¶" => "tyeolp", + "í…·" => "tyeolh", "í…¸" => "tyeom", "í…¹" => "tyeob", "í…º" => "tyeobs", "í…»" => "tyeos", "í…¼" => "tyeoss", + "í…½" => "tyeong", "í…¾" => "tyeoj", "í…¿" => "tyeoc", "톀" => "tyeok", "í†" => "tyeot", "톂" => "tyeop", + "톃" => "tyeoh", "톄" => "tye", "톅" => "tyeg", "톆" => "tyegg", "톇" => "tyegs", "톈" => "tyen", + "톉" => "tyenj", "톊" => "tyenh", "톋" => "tyed", "톌" => "tyel", "í†" => "tyelg", "톎" => "tyelm", + "í†" => "tyelb", "í†" => "tyels", "톑" => "tyelt", "톒" => "tyelp", "톓" => "tyelh", "톔" => "tyem", + "톕" => "tyeb", "톖" => "tyebs", "톗" => "tyes", "톘" => "tyess", "톙" => "tyeng", "톚" => "tyej", + "톛" => "tyec", "톜" => "tyek", "í†" => "tyet", "톞" => "tyep", "톟" => "tyeh", "토" => "to", + "톡" => "tog", "톢" => "togg", "톣" => "togs", "톤" => "ton", "톥" => "tonj", "톦" => "tonh", + "톧" => "tod", "톨" => "tol", "톩" => "tolg", "톪" => "tolm", "톫" => "tolb", "톬" => "tols", + "톭" => "tolt", "톮" => "tolp", "톯" => "tolh", "톰" => "tom", "톱" => "tob", "톲" => "tobs", + "톳" => "tos", "톴" => "toss", "통" => "tong", "톶" => "toj", "톷" => "toc", "톸" => "tok", + "톹" => "tot", "톺" => "top", "톻" => "toh", "톼" => "twa", "톽" => "twag", "톾" => "twagg", + "톿" => "twags", "퇀" => "twan", "í‡" => "twanj", "퇂" => "twanh", "퇃" => "twad", "퇄" => "twal", + "퇅" => "twalg", "퇆" => "twalm", "퇇" => "twalb", "퇈" => "twals", "퇉" => "twalt", "퇊" => "twalp", + "퇋" => "twalh", "퇌" => "twam", "í‡" => "twab", "퇎" => "twabs", "í‡" => "twas", "í‡" => "twass", + "퇑" => "twang", "퇒" => "twaj", "퇓" => "twac", "퇔" => "twak", "퇕" => "twat", "퇖" => "twap", + "퇗" => "twah", "퇘" => "twae", "퇙" => "twaeg", "퇚" => "twaegg", "퇛" => "twaegs", "퇜" => "twaen", + "í‡" => "twaenj", "퇞" => "twaenh", "퇟" => "twaed", "퇠" => "twael", "퇡" => "twaelg", "퇢" => "twaelm", + "퇣" => "twaelb", "퇤" => "twaels", "퇥" => "twaelt", "퇦" => "twaelp", "퇧" => "twaelh", "퇨" => "twaem", + "퇩" => "twaeb", "퇪" => "twaebs", "퇫" => "twaes", "퇬" => "twaess", "퇭" => "twaeng", "퇮" => "twaej", + "퇯" => "twaec", "퇰" => "twaek", "퇱" => "twaet", "퇲" => "twaep", "퇳" => "twaeh", "퇴" => "toe", + "퇵" => "toeg", "퇶" => "toegg", "퇷" => "toegs", "퇸" => "toen", "퇹" => "toenj", "퇺" => "toenh", + "퇻" => "toed", "퇼" => "toel", "퇽" => "toelg", "퇾" => "toelm", "퇿" => "toelb", "íˆ" => "toelt", + "툂" => "toelp", "툃" => "toelh", "툄" => "toem", "툅" => "toeb", "툆" => "toebs", "툇" => "toes", + "툈" => "toess", "툉" => "toeng", "툊" => "toej", "툋" => "toec", "툌" => "toek", "íˆ" => "toet", + "툎" => "toep", "íˆ" => "toeh", "íˆ" => "tyo", "툑" => "tyog", "툒" => "tyogg", "툓" => "tyogs", + "툔" => "tyon", "툕" => "tyonj", "툖" => "tyonh", "툗" => "tyod", "툘" => "tyol", "툙" => "tyolg", + "툚" => "tyolm", "툛" => "tyolb", "툜" => "tyols", "íˆ" => "tyolt", "툞" => "tyolp", "툟" => "tyolh", + "툠" => "tyom", "툡" => "tyob", "툢" => "tyobs", "툣" => "tyos", "툤" => "tyoss", "툥" => "tyong", + "툦" => "tyoj", "툧" => "tyoc", "툨" => "tyok", "툩" => "tyot", "툪" => "tyop", "툫" => "tyoh", + "투" => "tu", "툭" => "tug", "툮" => "tugg", "툯" => "tugs", "툰" => "tun", "툱" => "tunj", + "툲" => "tunh", "툳" => "tud", "툴" => "tul", "툵" => "tulg", "툶" => "tulm", "툷" => "tulb", + "툸" => "tuls", "툹" => "tult", "툺" => "tulp", "툻" => "tulh", "툼" => "tum", "툽" => "tub", + "툾" => "tubs", "툿" => "tus", "퉀" => "tuss", "í‰" => "tung", "퉂" => "tuj", "퉃" => "tuc", + "퉄" => "tuk", "퉅" => "tut", "퉆" => "tup", "퉇" => "tuh", "퉈" => "tweo", "퉉" => "tweog", + "퉊" => "tweogg", "퉋" => "tweogs", "퉌" => "tweon", "í‰" => "tweonj", "퉎" => "tweonh", "í‰" => "tweod", + "í‰" => "tweol", "퉑" => "tweolg", "퉒" => "tweolm", "퉓" => "tweolb", "퉔" => "tweols", "퉕" => "tweolt", + "퉖" => "tweolp", "퉗" => "tweolh", "퉘" => "tweom", "퉙" => "tweob", "퉚" => "tweobs", "퉛" => "tweos", + "퉜" => "tweoss", "í‰" => "tweong", "퉞" => "tweoj", "퉟" => "tweoc", "퉠" => "tweok", "퉡" => "tweot", + "퉢" => "tweop", "퉣" => "tweoh", "퉤" => "twe", "퉥" => "tweg", "퉦" => "twegg", "퉧" => "twegs", + "퉨" => "twen", "퉩" => "twenj", "퉪" => "twenh", "퉫" => "twed", "퉬" => "twel", "퉭" => "twelg", + "퉮" => "twelm", "퉯" => "twelb", "퉰" => "twels", "퉱" => "twelt", "퉲" => "twelp", "퉳" => "twelh", + "퉴" => "twem", "퉵" => "tweb", "퉶" => "twebs", "퉷" => "twes", "퉸" => "twess", "퉹" => "tweng", + "퉺" => "twej", "퉻" => "twec", "퉼" => "twek", "퉽" => "twet", "퉾" => "twep", "퉿" => "tweh", + "튀" => "twi", "íŠ" => "twig", "튂" => "twigg", "튃" => "twigs", "튄" => "twin", "튅" => "twinj", + "튆" => "twinh", "튇" => "twid", "튈" => "twil", "튉" => "twilg", "튊" => "twilm", "튋" => "twilb", + "튌" => "twils", "íŠ" => "twilt", "튎" => "twilp", "íŠ" => "twilh", "íŠ" => "twim", "튑" => "twib", + "튒" => "twibs", "튓" => "twis", "튔" => "twiss", "튕" => "twing", "튖" => "twij", "튗" => "twic", + "튘" => "twik", "튙" => "twit", "튚" => "twip", "튛" => "twih", "튜" => "tyu", "íŠ" => "tyug", + "튞" => "tyugg", "튟" => "tyugs", "튠" => "tyun", "튡" => "tyunj", "튢" => "tyunh", "튣" => "tyud", + "튤" => "tyul", "튥" => "tyulg", "튦" => "tyulm", "튧" => "tyulb", "튨" => "tyuls", "튩" => "tyult", + "튪" => "tyulp", "튫" => "tyulh", "튬" => "tyum", "튭" => "tyub", "튮" => "tyubs", "튯" => "tyus", + "튰" => "tyuss", "튱" => "tyung", "튲" => "tyuj", "튳" => "tyuc", "튴" => "tyuk", "튵" => "tyut", + "튶" => "tyup", "튷" => "tyuh", "트" => "teu", "특" => "teug", "튺" => "teugg", "튻" => "teugs", + "튼" => "teun", "튽" => "teunj", "튾" => "teunh", "튿" => "teud", "í‹€" => "teul", "í‹" => "teulg", + "í‹‚" => "teulm", "틃" => "teulb", "í‹„" => "teuls", "í‹…" => "teult", "틆" => "teulp", "틇" => "teulh", + "틈" => "teum", "틉" => "teub", "í‹Š" => "teubs", "í‹‹" => "teus", "í‹Œ" => "teuss", "í‹" => "teung", + "í‹Ž" => "teuj", "í‹" => "teuc", "í‹" => "teuk", "í‹‘" => "teut", "í‹’" => "teup", "í‹“" => "teuh", + "í‹”" => "tyi", "í‹•" => "tyig", "í‹–" => "tyigg", "í‹—" => "tyigs", "틘" => "tyin", "í‹™" => "tyinj", + "í‹š" => "tyinh", "í‹›" => "tyid", "í‹œ" => "tyil", "í‹" => "tyilg", "í‹ž" => "tyilm", "í‹Ÿ" => "tyilb", + "í‹ " => "tyils", "í‹¡" => "tyilt", "í‹¢" => "tyilp", "í‹£" => "tyilh", "틤" => "tyim", "í‹¥" => "tyib", + "틦" => "tyibs", "틧" => "tyis", "틨" => "tyiss", "í‹©" => "tying", "틪" => "tyij", "í‹«" => "tyic", + "틬" => "tyik", "í‹­" => "tyit", "í‹®" => "tyip", "틯" => "tyih", "í‹°" => "ti", "틱" => "tig", + "틲" => "tigg", "틳" => "tigs", "í‹´" => "tin", "틵" => "tinj", "틶" => "tinh", "í‹·" => "tid", + "틸" => "til", "틹" => "tilg", "틺" => "tilm", "í‹»" => "tilb", "틼" => "tils", "틽" => "tilt", + "틾" => "tilp", "í‹¿" => "tilh", "íŒ" => "tib", "팂" => "tibs", "팃" => "tis", "팄" => "tiss", + "팅" => "ting", "팆" => "tij", "팇" => "tic", "팈" => "tik", "팉" => "tit", "팊" => "tip", + "팋" => "tih", "파" => "pa", "íŒ" => "pag", "팎" => "pagg", "íŒ" => "pags", "íŒ" => "pan", + "팑" => "panj", "팒" => "panh", "팓" => "pad", "팔" => "pal", "팕" => "palg", "팖" => "palm", + "팗" => "palb", "팘" => "pals", "팙" => "palt", "팚" => "palp", "팛" => "palh", "팜" => "pam", + "íŒ" => "pab", "팞" => "pabs", "팟" => "pas", "팠" => "pass", "팡" => "pang", "팢" => "paj", + "팣" => "pac", "팤" => "pak", "팥" => "pat", "팦" => "pap", "팧" => "pah", "패" => "pae", + "팩" => "paeg", "팪" => "paegg", "팫" => "paegs", "팬" => "paen", "팭" => "paenj", "팮" => "paenh", + "팯" => "paed", "팰" => "pael", "팱" => "paelg", "팲" => "paelm", "팳" => "paelb", "팴" => "paels", + "팵" => "paelt", "팶" => "paelp", "팷" => "paelh", "팸" => "paem", "팹" => "paeb", "팺" => "paebs", + "팻" => "paes", "팼" => "paess", "팽" => "paeng", "팾" => "paej", "팿" => "paec", "í€" => "paek", + "í" => "paet", "í‚" => "paep", "íƒ" => "paeh", "í„" => "pya", "í…" => "pyag", "í†" => "pyagg", + "í‡" => "pyags", "íˆ" => "pyan", "í‰" => "pyanj", "íŠ" => "pyanh", "í‹" => "pyad", "íŒ" => "pyal", + "í" => "pyalg", "íŽ" => "pyalm", "í" => "pyalb", "í" => "pyals", "í‘" => "pyalt", "í’" => "pyalp", + "í“" => "pyalh", "í”" => "pyam", "í•" => "pyab", "í–" => "pyabs", "í—" => "pyas", "í˜" => "pyass", + "í™" => "pyang", "íš" => "pyaj", "í›" => "pyac", "íœ" => "pyak", "í" => "pyat", "íž" => "pyap", + "íŸ" => "pyah", "í " => "pyae", "í¡" => "pyaeg", "í¢" => "pyaegg", "í£" => "pyaegs", "í¤" => "pyaen", + "í¥" => "pyaenj", "í¦" => "pyaenh", "í§" => "pyaed", "í¨" => "pyael", "í©" => "pyaelg", "íª" => "pyaelm", + "í«" => "pyaelb", "í¬" => "pyaels", "í­" => "pyaelt", "í®" => "pyaelp", "í¯" => "pyaelh", "í°" => "pyaem", + "í±" => "pyaeb", "í²" => "pyaebs", "í³" => "pyaes", "í´" => "pyaess", "íµ" => "pyaeng", "í¶" => "pyaej", + "í·" => "pyaec", "í¸" => "pyaek", "í¹" => "pyaet", "íº" => "pyaep", "í»" => "pyaeh", "í¼" => "peo", + "í½" => "peog", "í¾" => "peogg", "í¿" => "peogs", "펀" => "peon", "íŽ" => "peonj", "펂" => "peonh", + "펃" => "peod", "펄" => "peol", "펅" => "peolg", "펆" => "peolm", "펇" => "peolb", "펈" => "peols", + "펉" => "peolt", "펊" => "peolp", "펋" => "peolh", "펌" => "peom", "íŽ" => "peob", "펎" => "peobs", + "íŽ" => "peos", "íŽ" => "peoss", "펑" => "peong", "펒" => "peoj", "펓" => "peoc", "펔" => "peok", + "펕" => "peot", "펖" => "peop", "펗" => "peoh", "페" => "pe", "펙" => "peg", "펚" => "pegg", + "펛" => "pegs", "펜" => "pen", "íŽ" => "penj", "펞" => "penh", "펟" => "ped", "펠" => "pel", + "펡" => "pelg", "펢" => "pelm", "펣" => "pelb", "펤" => "pels", "펥" => "pelt", "펦" => "pelp", + "펧" => "pelh", "펨" => "pem", "펩" => "peb", "펪" => "pebs", "펫" => "pes", "펬" => "pess", + "펭" => "peng", "펮" => "pej", "펯" => "pec", "펰" => "pek", "펱" => "pet", "펲" => "pep", + "펳" => "peh", "펴" => "pyeo", "펵" => "pyeog", "펶" => "pyeogg", "펷" => "pyeogs", "편" => "pyeon", + "펹" => "pyeonj", "펺" => "pyeonh", "펻" => "pyeod", "펼" => "pyeol", "펽" => "pyeolg", "펾" => "pyeolm", + "펿" => "pyeolb", "í€" => "pyeols", "í" => "pyeolt", "í‚" => "pyeolp", "íƒ" => "pyeolh", "í„" => "pyeom", + "í…" => "pyeob", "í†" => "pyeobs", "í‡" => "pyeos", "íˆ" => "pyeoss", "í‰" => "pyeong", "íŠ" => "pyeoj", + "í‹" => "pyeoc", "íŒ" => "pyeok", "í" => "pyeot", "íŽ" => "pyeop", "í" => "pyeoh", "í" => "pye", + "í‘" => "pyeg", "í’" => "pyegg", "í“" => "pyegs", "í”" => "pyen", "í•" => "pyenj", "í–" => "pyenh", + "í—" => "pyed", "í˜" => "pyel", "í™" => "pyelg", "íš" => "pyelm", "í›" => "pyelb", "íœ" => "pyels", + "í" => "pyelt", "íž" => "pyelp", "íŸ" => "pyelh", "í " => "pyem", "í¡" => "pyeb", "í¢" => "pyebs", + "í£" => "pyes", "í¤" => "pyess", "í¥" => "pyeng", "í¦" => "pyej", "í§" => "pyec", "í¨" => "pyek", + "í©" => "pyet", "íª" => "pyep", "í«" => "pyeh", "í¬" => "po", "í­" => "pog", "í®" => "pogg", + "í¯" => "pogs", "í°" => "pon", "í±" => "ponj", "í²" => "ponh", "í³" => "pod", "í´" => "pol", + "íµ" => "polg", "í¶" => "polm", "í·" => "polb", "í¸" => "pols", "í¹" => "polt", "íº" => "polp", + "í»" => "polh", "í¼" => "pom", "í½" => "pob", "í¾" => "pobs", "í¿" => "pos", "í" => "pong", + "í‚" => "poj", "íƒ" => "poc", "í„" => "pok", "í…" => "pot", "í†" => "pop", "í‡" => "poh", + "íˆ" => "pwa", "í‰" => "pwag", "íŠ" => "pwagg", "í‹" => "pwags", "íŒ" => "pwan", "í" => "pwanj", + "íŽ" => "pwanh", "í" => "pwad", "í" => "pwal", "í‘" => "pwalg", "í’" => "pwalm", "í“" => "pwalb", + "í”" => "pwals", "í•" => "pwalt", "í–" => "pwalp", "í—" => "pwalh", "í˜" => "pwam", "í™" => "pwab", + "íš" => "pwabs", "í›" => "pwas", "íœ" => "pwass", "í" => "pwang", "íž" => "pwaj", "íŸ" => "pwac", + "í " => "pwak", "í¡" => "pwat", "í¢" => "pwap", "í£" => "pwah", "í¤" => "pwae", "í¥" => "pwaeg", + "í¦" => "pwaegg", "í§" => "pwaegs", "í¨" => "pwaen", "í©" => "pwaenj", "íª" => "pwaenh", "í«" => "pwaed", + "í¬" => "pwael", "í­" => "pwaelg", "í®" => "pwaelm", "í¯" => "pwaelb", "í°" => "pwaels", "í±" => "pwaelt", + "í²" => "pwaelp", "í³" => "pwaelh", "í´" => "pwaem", "íµ" => "pwaeb", "í¶" => "pwaebs", "í·" => "pwaes", + "í¸" => "pwaess", "í¹" => "pwaeng", "íº" => "pwaej", "í»" => "pwaec", "í¼" => "pwaek", "í½" => "pwaet", + "í¾" => "pwaep", "í¿" => "pwaeh", "í‘€" => "poe", "í‘" => "poeg", "í‘‚" => "poegg", "푃" => "poegs", + "í‘„" => "poen", "í‘…" => "poenj", "푆" => "poenh", "푇" => "poed", "푈" => "poel", "푉" => "poelg", + "í‘Š" => "poelm", "í‘‹" => "poelb", "í‘Œ" => "poels", "í‘" => "poelt", "í‘Ž" => "poelp", "í‘" => "poelh", + "í‘" => "poem", "í‘‘" => "poeb", "í‘’" => "poebs", "í‘“" => "poes", "í‘”" => "poess", "í‘•" => "poeng", + "í‘–" => "poej", "í‘—" => "poec", "푘" => "poek", "í‘™" => "poet", "í‘š" => "poep", "í‘›" => "poeh", + "í‘œ" => "pyo", "í‘" => "pyog", "í‘ž" => "pyogg", "í‘Ÿ" => "pyogs", "í‘ " => "pyon", "í‘¡" => "pyonj", + "í‘¢" => "pyonh", "í‘£" => "pyod", "푤" => "pyol", "í‘¥" => "pyolg", "푦" => "pyolm", "푧" => "pyolb", + "푨" => "pyols", "í‘©" => "pyolt", "푪" => "pyolp", "í‘«" => "pyolh", "푬" => "pyom", "í‘­" => "pyob", + "í‘®" => "pyobs", "푯" => "pyos", "í‘°" => "pyoss", "푱" => "pyong", "푲" => "pyoj", "푳" => "pyoc", + "í‘´" => "pyok", "푵" => "pyot", "푶" => "pyop", "í‘·" => "pyoh", "푸" => "pu", "푹" => "pug", + "푺" => "pugg", "í‘»" => "pugs", "푼" => "pun", "푽" => "punj", "푾" => "punh", "í‘¿" => "pud", + "í’€" => "pul", "í’" => "pulg", "í’‚" => "pulm", "í’ƒ" => "pulb", "í’„" => "puls", "í’…" => "pult", + "í’†" => "pulp", "í’‡" => "pulh", "í’ˆ" => "pum", "í’‰" => "pub", "í’Š" => "pubs", "í’‹" => "pus", + "í’Œ" => "puss", "í’" => "pung", "í’Ž" => "puj", "í’" => "puc", "í’" => "puk", "í’‘" => "put", + "í’’" => "pup", "í’“" => "puh", "í’”" => "pweo", "í’•" => "pweog", "í’–" => "pweogg", "í’—" => "pweogs", + "í’˜" => "pweon", "í’™" => "pweonj", "í’š" => "pweonh", "í’›" => "pweod", "í’œ" => "pweol", "í’" => "pweolg", + "í’ž" => "pweolm", "í’Ÿ" => "pweolb", "í’ " => "pweols", "í’¡" => "pweolt", "í’¢" => "pweolp", "í’£" => "pweolh", + "í’¤" => "pweom", "í’¥" => "pweob", "í’¦" => "pweobs", "í’§" => "pweos", "í’¨" => "pweoss", "í’©" => "pweong", + "í’ª" => "pweoj", "í’«" => "pweoc", "í’¬" => "pweok", "í’­" => "pweot", "í’®" => "pweop", "í’¯" => "pweoh", + "í’°" => "pwe", "í’±" => "pweg", "í’²" => "pwegg", "í’³" => "pwegs", "í’´" => "pwen", "í’µ" => "pwenj", + "í’¶" => "pwenh", "í’·" => "pwed", "í’¸" => "pwel", "í’¹" => "pwelg", "í’º" => "pwelm", "í’»" => "pwelb", + "í’¼" => "pwels", "í’½" => "pwelt", "í’¾" => "pwelp", "í’¿" => "pwelh", "í“€" => "pwem", "í“" => "pweb", + "í“‚" => "pwebs", "퓃" => "pwes", "í“„" => "pwess", "í“…" => "pweng", "퓆" => "pwej", "퓇" => "pwec", + "퓈" => "pwek", "퓉" => "pwet", "í“Š" => "pwep", "í“‹" => "pweh", "í“Œ" => "pwi", "í“" => "pwig", + "í“Ž" => "pwigg", "í“" => "pwigs", "í“" => "pwin", "í“‘" => "pwinj", "í“’" => "pwinh", "í““" => "pwid", + "í“”" => "pwil", "í“•" => "pwilg", "í“–" => "pwilm", "í“—" => "pwilb", "퓘" => "pwils", "í“™" => "pwilt", + "í“š" => "pwilp", "í“›" => "pwilh", "í“œ" => "pwim", "í“" => "pwib", "í“ž" => "pwibs", "í“Ÿ" => "pwis", + "í“ " => "pwiss", "í“¡" => "pwing", "í“¢" => "pwij", "í“£" => "pwic", "퓤" => "pwik", "í“¥" => "pwit", + "퓦" => "pwip", "퓧" => "pwih", "퓨" => "pyu", "í“©" => "pyug", "퓪" => "pyugg", "í“«" => "pyugs", + "퓬" => "pyun", "í“­" => "pyunj", "í“®" => "pyunh", "퓯" => "pyud", "í“°" => "pyul", "퓱" => "pyulg", + "퓲" => "pyulm", "퓳" => "pyulb", "í“´" => "pyuls", "퓵" => "pyult", "퓶" => "pyulp", "í“·" => "pyulh", + "퓸" => "pyum", "퓹" => "pyub", "퓺" => "pyubs", "í“»" => "pyus", "퓼" => "pyuss", "퓽" => "pyung", + "퓾" => "pyuj", "í“¿" => "pyuc", "í”" => "pyut", "픂" => "pyup", "픃" => "pyuh", "프" => "peu", + "í”…" => "peug", "픆" => "peugg", "픇" => "peugs", "픈" => "peun", "픉" => "peunj", "픊" => "peunh", + "픋" => "peud", "플" => "peul", "í”" => "peulg", "픎" => "peulm", "í”" => "peulb", "í”" => "peuls", + "픑" => "peult", "í”’" => "peulp", "픓" => "peulh", "í””" => "peum", "픕" => "peub", "í”–" => "peubs", + "í”—" => "peus", "픘" => "peuss", "í”™" => "peung", "픚" => "peuj", "í”›" => "peuc", "픜" => "peuk", + "í”" => "peut", "픞" => "peup", "픟" => "peuh", "í” " => "pyi", "픡" => "pyig", "픢" => "pyigg", + "픣" => "pyigs", "픤" => "pyin", "픥" => "pyinj", "픦" => "pyinh", "픧" => "pyid", "픨" => "pyil", + "픩" => "pyilg", "픪" => "pyilm", "픫" => "pyilb", "픬" => "pyils", "í”­" => "pyilt", "í”®" => "pyilp", + "픯" => "pyilh", "í”°" => "pyim", "í”±" => "pyib", "픲" => "pyibs", "픳" => "pyis", "í”´" => "pyiss", + "픵" => "pying", "픶" => "pyij", "í”·" => "pyic", "픸" => "pyik", "픹" => "pyit", "픺" => "pyip", + "í”»" => "pyih", "피" => "pi", "픽" => "pig", "픾" => "pigg", "픿" => "pigs", "í•€" => "pin", + "í•" => "pinj", "í•‚" => "pinh", "핃" => "pid", "í•„" => "pil", "í•…" => "pilg", "핆" => "pilm", + "핇" => "pilb", "핈" => "pils", "핉" => "pilt", "í•Š" => "pilp", "í•‹" => "pilh", "í•Œ" => "pim", + "í•" => "pib", "í•Ž" => "pibs", "í•" => "pis", "í•" => "piss", "í•‘" => "ping", "í•’" => "pij", + "í•“" => "pic", "í•”" => "pik", "í••" => "pit", "í•–" => "pip", "í•—" => "pih", "하" => "ha", + "í•™" => "hag", "í•š" => "hagg", "í•›" => "hags", "í•œ" => "han", "í•" => "hanj", "í•ž" => "hanh", + "í•Ÿ" => "had", "í• " => "hal", "í•¡" => "halg", "í•¢" => "halm", "í•£" => "halb", "핤" => "hals", + "í•¥" => "halt", "핦" => "halp", "핧" => "halh", "함" => "ham", "í•©" => "hab", "핪" => "habs", + "í•«" => "has", "핬" => "hass", "í•­" => "hang", "í•®" => "haj", "핯" => "hac", "í•°" => "hak", + "핱" => "hat", "핲" => "hap", "핳" => "hah", "í•´" => "hae", "핵" => "haeg", "핶" => "haegg", + "í•·" => "haegs", "핸" => "haen", "핹" => "haenj", "핺" => "haenh", "í•»" => "haed", "핼" => "hael", + "핽" => "haelg", "핾" => "haelm", "í•¿" => "haelb", "í–€" => "haels", "í–" => "haelt", "í–‚" => "haelp", + "í–ƒ" => "haelh", "í–„" => "haem", "í–…" => "haeb", "í–†" => "haebs", "í–‡" => "haes", "í–ˆ" => "haess", + "í–‰" => "haeng", "í–Š" => "haej", "í–‹" => "haec", "í–Œ" => "haek", "í–" => "haet", "í–Ž" => "haep", + "í–" => "haeh", "í–" => "hya", "í–‘" => "hyag", "í–’" => "hyagg", "í–“" => "hyags", "í–”" => "hyan", + "í–•" => "hyanj", "í––" => "hyanh", "í–—" => "hyad", "í–˜" => "hyal", "í–™" => "hyalg", "í–š" => "hyalm", + "í–›" => "hyalb", "í–œ" => "hyals", "í–" => "hyalt", "í–ž" => "hyalp", "í–Ÿ" => "hyalh", "í– " => "hyam", + "í–¡" => "hyab", "í–¢" => "hyabs", "í–£" => "hyas", "í–¤" => "hyass", "í–¥" => "hyang", "í–¦" => "hyaj", + "í–§" => "hyac", "í–¨" => "hyak", "í–©" => "hyat", "í–ª" => "hyap", "í–«" => "hyah", "í–¬" => "hyae", + "í–­" => "hyaeg", "í–®" => "hyaegg", "í–¯" => "hyaegs", "í–°" => "hyaen", "í–±" => "hyaenj", "í–²" => "hyaenh", + "í–³" => "hyaed", "í–´" => "hyael", "í–µ" => "hyaelg", "í–¶" => "hyaelm", "í–·" => "hyaelb", "í–¸" => "hyaels", + "í–¹" => "hyaelt", "í–º" => "hyaelp", "í–»" => "hyaelh", "í–¼" => "hyaem", "í–½" => "hyaeb", "í–¾" => "hyaebs", + "í–¿" => "hyaes", "í—€" => "hyaess", "í—" => "hyaeng", "í—‚" => "hyaej", "í—ƒ" => "hyaec", "í—„" => "hyaek", + "í—…" => "hyaet", "í—†" => "hyaep", "í—‡" => "hyaeh", "í—ˆ" => "heo", "í—‰" => "heog", "í—Š" => "heogg", + "í—‹" => "heogs", "í—Œ" => "heon", "í—" => "heonj", "í—Ž" => "heonh", "í—" => "heod", "í—" => "heol", + "í—‘" => "heolg", "í—’" => "heolm", "í—“" => "heolb", "í—”" => "heols", "í—•" => "heolt", "í—–" => "heolp", + "í——" => "heolh", "í—˜" => "heom", "í—™" => "heob", "í—š" => "heobs", "í—›" => "heos", "í—œ" => "heoss", + "í—" => "heong", "í—ž" => "heoj", "í—Ÿ" => "heoc", "í— " => "heok", "í—¡" => "heot", "í—¢" => "heop", + "í—£" => "heoh", "í—¤" => "he", "í—¥" => "heg", "í—¦" => "hegg", "í—§" => "hegs", "í—¨" => "hen", + "í—©" => "henj", "í—ª" => "henh", "í—«" => "hed", "í—¬" => "hel", "í—­" => "helg", "í—®" => "helm", + "í—¯" => "helb", "í—°" => "hels", "í—±" => "helt", "í—²" => "help", "í—³" => "helh", "í—´" => "hem", + "í—µ" => "heb", "í—¶" => "hebs", "í—·" => "hes", "í—¸" => "hess", "í—¹" => "heng", "í—º" => "hej", + "í—»" => "hec", "í—¼" => "hek", "í—½" => "het", "í—¾" => "hep", "í—¿" => "heh", "í˜" => "hyeog", + "혂" => "hyeogg", "혃" => "hyeogs", "현" => "hyeon", "혅" => "hyeonj", "혆" => "hyeonh", "혇" => "hyeod", + "혈" => "hyeol", "혉" => "hyeolg", "혊" => "hyeolm", "혋" => "hyeolb", "혌" => "hyeols", "í˜" => "hyeolt", + "혎" => "hyeolp", "í˜" => "hyeolh", "í˜" => "hyeom", "협" => "hyeob", "혒" => "hyeobs", "혓" => "hyeos", + "혔" => "hyeoss", "형" => "hyeong", "혖" => "hyeoj", "혗" => "hyeoc", "혘" => "hyeok", "혙" => "hyeot", + "혚" => "hyeop", "혛" => "hyeoh", "혜" => "hye", "í˜" => "hyeg", "혞" => "hyegg", "혟" => "hyegs", + "혠" => "hyen", "혡" => "hyenj", "혢" => "hyenh", "혣" => "hyed", "혤" => "hyel", "혥" => "hyelg", + "혦" => "hyelm", "혧" => "hyelb", "혨" => "hyels", "혩" => "hyelt", "혪" => "hyelp", "혫" => "hyelh", + "혬" => "hyem", "혭" => "hyeb", "혮" => "hyebs", "혯" => "hyes", "혰" => "hyess", "혱" => "hyeng", + "혲" => "hyej", "혳" => "hyec", "혴" => "hyek", "혵" => "hyet", "혶" => "hyep", "혷" => "hyeh", + "호" => "ho", "혹" => "hog", "혺" => "hogg", "혻" => "hogs", "혼" => "hon", "혽" => "honj", + "혾" => "honh", "혿" => "hod", "홀" => "hol", "í™" => "holg", "홂" => "holm", "홃" => "holb", + "홄" => "hols", "í™…" => "holt", "홆" => "holp", "홇" => "holh", "홈" => "hom", "홉" => "hob", + "홊" => "hobs", "홋" => "hos", "홌" => "hoss", "í™" => "hong", "홎" => "hoj", "í™" => "hoc", + "í™" => "hok", "홑" => "hot", "í™’" => "hop", "홓" => "hoh", "í™”" => "hwa", "확" => "hwag", + "í™–" => "hwagg", "í™—" => "hwags", "환" => "hwan", "í™™" => "hwanj", "홚" => "hwanh", "í™›" => "hwad", + "활" => "hwal", "í™" => "hwalg", "홞" => "hwalm", "홟" => "hwalb", "í™ " => "hwals", "홡" => "hwalt", + "홢" => "hwalp", "홣" => "hwalh", "홤" => "hwam", "홥" => "hwab", "홦" => "hwabs", "홧" => "hwas", + "홨" => "hwass", "황" => "hwang", "홪" => "hwaj", "홫" => "hwac", "홬" => "hwak", "í™­" => "hwat", + "í™®" => "hwap", "홯" => "hwah", "í™°" => "hwae", "í™±" => "hwaeg", "홲" => "hwaegg", "홳" => "hwaegs", + "í™´" => "hwaen", "홵" => "hwaenj", "홶" => "hwaenh", "í™·" => "hwaed", "홸" => "hwael", "홹" => "hwaelg", + "홺" => "hwaelm", "í™»" => "hwaelb", "홼" => "hwaels", "홽" => "hwaelt", "홾" => "hwaelp", "홿" => "hwaelh", + "횀" => "hwaem", "íš" => "hwaeb", "íš‚" => "hwaebs", "횃" => "hwaes", "íš„" => "hwaess", "íš…" => "hwaeng", + "횆" => "hwaej", "횇" => "hwaec", "횈" => "hwaek", "횉" => "hwaet", "횊" => "hwaep", "íš‹" => "hwaeh", + "회" => "hoe", "íš" => "hoeg", "횎" => "hoegg", "íš" => "hoegs", "íš" => "hoen", "íš‘" => "hoenj", + "íš’" => "hoenh", "íš“" => "hoed", "íš”" => "hoel", "íš•" => "hoelg", "íš–" => "hoelm", "íš—" => "hoelb", + "횘" => "hoels", "íš™" => "hoelt", "íšš" => "hoelp", "íš›" => "hoelh", "íšœ" => "hoem", "íš" => "hoeb", + "íšž" => "hoebs", "횟" => "hoes", "íš " => "hoess", "íš¡" => "hoeng", "횢" => "hoej", "횣" => "hoec", + "횤" => "hoek", "횥" => "hoet", "횦" => "hoep", "횧" => "hoeh", "효" => "hyo", "íš©" => "hyog", + "횪" => "hyogg", "íš«" => "hyogs", "횬" => "hyon", "íš­" => "hyonj", "íš®" => "hyonh", "횯" => "hyod", + "íš°" => "hyol", "íš±" => "hyolg", "íš²" => "hyolm", "íš³" => "hyolb", "íš´" => "hyols", "íšµ" => "hyolt", + "횶" => "hyolp", "íš·" => "hyolh", "횸" => "hyom", "íš¹" => "hyob", "횺" => "hyobs", "íš»" => "hyos", + "íš¼" => "hyoss", "íš½" => "hyong", "íš¾" => "hyoj", "íš¿" => "hyoc", "훀" => "hyok", "í›" => "hyot", + "훂" => "hyop", "훃" => "hyoh", "후" => "hu", "í›…" => "hug", "훆" => "hugg", "훇" => "hugs", + "훈" => "hun", "훉" => "hunj", "훊" => "hunh", "훋" => "hud", "훌" => "hul", "í›" => "hulg", + "훎" => "hulm", "í›" => "hulb", "í›" => "huls", "훑" => "hult", "í›’" => "hulp", "훓" => "hulh", + "í›”" => "hum", "훕" => "hub", "í›–" => "hubs", "í›—" => "hus", "훘" => "huss", "í›™" => "hung", + "훚" => "huj", "í››" => "huc", "훜" => "huk", "í›" => "hut", "훞" => "hup", "훟" => "huh", + "í› " => "hweo", "훡" => "hweog", "훢" => "hweogg", "훣" => "hweogs", "훤" => "hweon", "훥" => "hweonj", + "훦" => "hweonh", "훧" => "hweod", "훨" => "hweol", "훩" => "hweolg", "훪" => "hweolm", "훫" => "hweolb", + "훬" => "hweols", "í›­" => "hweolt", "í›®" => "hweolp", "훯" => "hweolh", "í›°" => "hweom", "í›±" => "hweob", + "훲" => "hweobs", "훳" => "hweos", "í›´" => "hweoss", "훵" => "hweong", "훶" => "hweoj", "í›·" => "hweoc", + "훸" => "hweok", "훹" => "hweot", "훺" => "hweop", "í›»" => "hweoh", "훼" => "hwe", "훽" => "hweg", + "훾" => "hwegg", "훿" => "hwegs", "íœ" => "hwenj", "휂" => "hwenh", "휃" => "hwed", "휄" => "hwel", + "휅" => "hwelg", "휆" => "hwelm", "휇" => "hwelb", "휈" => "hwels", "휉" => "hwelt", "휊" => "hwelp", + "휋" => "hwelh", "휌" => "hwem", "íœ" => "hweb", "휎" => "hwebs", "íœ" => "hwes", "íœ" => "hwess", + "휑" => "hweng", "휒" => "hwej", "휓" => "hwec", "휔" => "hwek", "휕" => "hwet", "휖" => "hwep", + "휗" => "hweh", "휘" => "hwi", "휙" => "hwig", "휚" => "hwigg", "휛" => "hwigs", "휜" => "hwin", + "íœ" => "hwinj", "휞" => "hwinh", "휟" => "hwid", "휠" => "hwil", "휡" => "hwilg", "휢" => "hwilm", + "휣" => "hwilb", "휤" => "hwils", "휥" => "hwilt", "휦" => "hwilp", "휧" => "hwilh", "휨" => "hwim", + "휩" => "hwib", "휪" => "hwibs", "휫" => "hwis", "휬" => "hwiss", "휭" => "hwing", "휮" => "hwij", + "휯" => "hwic", "휰" => "hwik", "휱" => "hwit", "휲" => "hwip", "휳" => "hwih", "휴" => "hyu", + "휵" => "hyug", "휶" => "hyugg", "휷" => "hyugs", "휸" => "hyun", "휹" => "hyunj", "휺" => "hyunh", + "휻" => "hyud", "휼" => "hyul", "휽" => "hyulg", "휾" => "hyulm", "휿" => "hyulb", "í€" => "hyuls", + "í" => "hyult", "í‚" => "hyulp", "íƒ" => "hyulh", "í„" => "hyum", "í…" => "hyub", "í†" => "hyubs", + "í‡" => "hyus", "íˆ" => "hyuss", "í‰" => "hyung", "íŠ" => "hyuj", "í‹" => "hyuc", "íŒ" => "hyuk", + "í" => "hyut", "íŽ" => "hyup", "í" => "hyuh", "í" => "heu", "í‘" => "heug", "í’" => "heugg", + "í“" => "heugs", "í”" => "heun", "í•" => "heunj", "í–" => "heunh", "í—" => "heud", "í˜" => "heul", + "í™" => "heulg", "íš" => "heulm", "í›" => "heulb", "íœ" => "heuls", "í" => "heult", "íž" => "heulp", + "íŸ" => "heulh", "í " => "heum", "í¡" => "heub", "í¢" => "heubs", "í£" => "heus", "í¤" => "heuss", + "í¥" => "heung", "í¦" => "heuj", "í§" => "heuc", "í¨" => "heuk", "í©" => "heut", "íª" => "heup", + "í«" => "heuh", "í¬" => "hyi", "í­" => "hyig", "í®" => "hyigg", "í¯" => "hyigs", "í°" => "hyin", + "í±" => "hyinj", "í²" => "hyinh", "í³" => "hyid", "í´" => "hyil", "íµ" => "hyilg", "í¶" => "hyilm", + "í·" => "hyilb", "í¸" => "hyils", "í¹" => "hyilt", "íº" => "hyilp", "í»" => "hyilh", "í¼" => "hyim", + "í½" => "hyib", "í¾" => "hyibs", "í¿" => "hyis", "힀" => "hyiss", "íž" => "hying", "íž‚" => "hyij", + "힃" => "hyic", "íž„" => "hyik", "íž…" => "hyit", "힆" => "hyip", "힇" => "hyih", "히" => "hi", + "힉" => "hig", "힊" => "higg", "íž‹" => "higs", "힌" => "hin", "íž" => "hinj", "힎" => "hinh", + "íž" => "hid", "íž" => "hil", "íž‘" => "hilg", "íž’" => "hilm", "íž“" => "hilb", "íž”" => "hils", + "íž•" => "hilt", "íž–" => "hilp", "íž—" => "hilh", "힘" => "him", "íž™" => "hib", "ížš" => "hibs", + "íž›" => "his", "ížœ" => "hiss", "íž" => "hing", "ížž" => "hij", "힟" => "hic", "íž " => "hik", + "íž¡" => "hit", "힢" => "hip", "힣" => "hih", "ï¤" => "Kayng", "車" => "Ke", "賈" => "Ko", + "滑" => "Kol", "串" => "Koc", "句" => "Kwi", "龜" => "Kwi", "龜" => "Kyun", "契" => "Kul", + "金" => "Kum", "喇" => "Na", "奈" => "Na", "ï¤" => "Na", "癩" => "La", "ï¤" => "Na", + "ï¤" => "Na", "螺" => "Na", "裸" => "Na", "邏" => "Na", "樂" => "Nak", "洛" => "Nak", + "烙" => "Nak", "珞" => "Nak", "落" => "Nak", "酪" => "Nak", "駱" => "Nak", "亂" => "Nan", + "卵" => "Nan", "ï¤" => "Nan", "爛" => "Nan", "蘭" => "Nan", "鸞" => "Nan", "嵐" => "Nam", + "濫" => "Nam", "藍" => "Nam", "襤" => "Nam", "拉" => "Nap", "臘" => "Nap", "蠟" => "Nap", + "廊" => "Nang", "朗" => "Nang", "浪" => "Nang", "狼" => "Nang", "郎" => "Nang", "來" => "Nay", + "冷" => "Nayng", "勞" => "No", "擄" => "No", "櫓" => "No", "爐" => "No", "盧" => "No", + "老" => "No", "蘆" => "No", "虜" => "No", "路" => "No", "露" => "No", "魯" => "No", + "鷺" => "No", "碌" => "Nok", "祿" => "Nok", "綠" => "Nok", "菉" => "Nok", "錄" => "Nok", + "鹿" => "Nok", "ï¥" => "Non", "壟" => "Nong", "弄" => "Nong", "籠" => "Nong", "聾" => "Nong", + "牢" => "Noy", "磊" => "Noy", "賂" => "Noy", "雷" => "Noy", "壘" => "Nwu", "屢" => "Nwu", + "樓" => "Nwu", "ï¥" => "Nwu", "漏" => "Nwu", "ï¥" => "Nwu", "ï¥" => "Nwu", "陋" => "Nwu", + "勒" => "Nuk", "肋" => "Nuk", "凜" => "Num", "凌" => "Nung", "稜" => "Nung", "綾" => "Nung", + "菱" => "Nung", "陵" => "Nung", "讀" => "Twu", "拏" => "La", "樂" => "Lak", "ï¥" => "Lak", + "丹" => "Lan", "寧" => "Lyeng", "怒" => "Lo", "率" => "Lyul", "異" => "Li", "北" => "Pey", + "磻" => "Pen", "便" => "Pyen", "復" => "Pwu", "不" => "Pwul", "泌" => "Pi", "數" => "Sak", + "索" => "Sak", "參" => "Sam", "塞" => "Sayk", "省" => "Sayng", "葉" => "Sep", "說" => "Sey", + "殺" => "Sway", "辰" => "Sin", "沈" => "Sim", "拾" => "Sip", "若" => "Ya", "掠" => "Yak", + "略" => "Yak", "亮" => "Yang", "兩" => "Yang", "凉" => "Yang", "梁" => "Yang", "糧" => "Yang", + "良" => "Yang", "諒" => "Yang", "量" => "Yang", "勵" => "Ye", "呂" => "Ye", "ï¦" => "Ye", + "廬" => "Ye", "旅" => "Ye", "濾" => "Ye", "礪" => "Ye", "閭" => "Ye", "驪" => "Ye", + "麗" => "Ye", "黎" => "Ye", "力" => "Yek", "曆" => "Yek", "歷" => "Yek", "ï¦" => "Yek", + "年" => "Yen", "ï¦" => "Yen", "ï¦" => "Yen", "撚" => "Yen", "漣" => "Yen", "煉" => "Yen", + "璉" => "Yen", "秊" => "Yen", "練" => "Yen", "聯" => "Yen", "輦" => "Yen", "蓮" => "Yen", + "連" => "Yen", "鍊" => "Yen", "列" => "Yel", "ï¦" => "Yel", "咽" => "Yel", "烈" => "Yel", + "裂" => "Yel", "說" => "Yel", "廉" => "Yem", "念" => "Yem", "捻" => "Yem", "殮" => "Yem", + "簾" => "Yem", "獵" => "Yep", "令" => "Yeng", "囹" => "Yeng", "寧" => "Yeng", "嶺" => "Yeng", + "怜" => "Yeng", "玲" => "Yeng", "瑩" => "Yeng", "羚" => "Yeng", "聆" => "Yeng", "鈴" => "Yeng", + "零" => "Yeng", "靈" => "Yeng", "領" => "Yeng", "例" => "Yey", "禮" => "Yey", "醴" => "Yey", + "隸" => "Yey", "惡" => "O", "了" => "Yo", "僚" => "Yo", "寮" => "Yo", "尿" => "Yo", + "料" => "Yo", "樂" => "Yo", "燎" => "Yo", "ï§" => "Yo", "蓼" => "Yo", "遼" => "Yo", + "龍" => "Yong", "暈" => "Wun", "阮" => "Wen", "劉" => "Yu", "杻" => "Yu", "柳" => "Yu", + "流" => "Yu", "溜" => "Yu", "琉" => "Yu", "ï§" => "Yu", "硫" => "Yu", "ï§" => "Yu", + "ï§" => "Yu", "六" => "Yuk", "戮" => "Yuk", "陸" => "Yuk", "倫" => "Yun", "崙" => "Yun", + "淪" => "Yun", "輪" => "Yun", "律" => "Yul", "慄" => "Yul", "栗" => "Yul", "率" => "Yul", + "隆" => "Yung", "ï§" => "I", "吏" => "I", "履" => "I", "易" => "I", "李" => "I", + "梨" => "I", "泥" => "I", "理" => "I", "痢" => "I", "罹" => "I", "裏" => "I", + "裡" => "I", "里" => "I", "離" => "I", "匿" => "Ik", "溺" => "Ik", "吝" => "In", + "燐" => "In", "璘" => "In", "藺" => "In", "隣" => "In", "鱗" => "In", "麟" => "In", + "林" => "Im", "淋" => "Im", "臨" => "Im", "立" => "Ip", "笠" => "Ip", "粒" => "Ip", + "狀" => "Cang", "炙" => "Cek", "識" => "Ci", "什" => "Cip", "茶" => "Cha", "刺" => "Chek", + "ï¨" => "Thak", "拓" => "Thak", "糖" => "Thang", "宅" => "Thayk", "洞" => "Thong", "暴" => "Pho", + "輻" => "Phok", "行" => "Hang", "降" => "Hang", "見" => "Hyen", "廓" => "Hwak", "兀" => "Wu", + "ï¨" => "Huo", "ï¨" => "Zhong", "晴" => "Qing", "凞" => "Xi", "猪" => "Zhu", "益" => "Yi", + "礼" => "Li", "神" => "Shen", "祥" => "Xiang", "福" => "Fu", "靖" => "Jing", "ï¨" => "Jing", + "羽" => "Yu", "蘒" => "Hagi", "諸" => "Zhu", "逸" => "Yi", "都" => "Du", "飯" => "Fan", + "飼" => "Si", "館" => "Guan", "ï¬" => "fi", "fl" => "fl", "ffi" => "ffi", "ffl" => "ffl", + "ſt" => "st", "st" => "st", "ﬓ" => "mn", "ﬔ" => "me", "ﬕ" => "mi", "ﬖ" => "vn", + "ﬗ" => "mkh", "ï¬" => "yi", "ײַ" => "ay", "ﬢ" => "d", "ﬣ" => "h", "ﬤ" => "k", + "ﬥ" => "l", "ﬦ" => "m", "ﬧ" => "m", "ﬨ" => "t", "שׁ" => "sh", "שׂ" => "s", + "שּׁ" => "sh", "שּׂ" => "s", "אַ" => "a", "אָ" => "a", "בּ" => "b", "גּ" => "g", + "דּ" => "d", "הּ" => "h", "וּ" => "v", "זּ" => "z", "טּ" => "t", "יּ" => "y", + "ךּ" => "k", "כּ" => "k", "לּ" => "l", "מּ" => "l", "ï­€" => "n", "ï­" => "n", + "ï­ƒ" => "p", "ï­„" => "p", "ï­†" => "ts", "ï­‡" => "ts", "ï­ˆ" => "r", "ï­‰" => "sh", + "ï­Š" => "t", "ï­‹" => "vo", "ï­Œ" => "b", "ï­" => "k", "ï­Ž" => "p", "ï­" => "l", + "1" => "1", "ï¼’" => "2", "3" => "3", "ï¼”" => "4", "5" => "5", "ï¼–" => "6", + "ï¼—" => "7", "8" => "8", "ï¼™" => "9", "A" => "A", "ï¼¢" => "B", "ï¼£" => "C", + "D" => "D", "ï¼¥" => "E", "F" => "F", "G" => "G", "H" => "H", "I" => "I", + "J" => "J", "K" => "K", "L" => "L", "ï¼­" => "M", "ï¼®" => "N", "O" => "O", + "ï¼°" => "P", "ï¼±" => "Q", "ï¼²" => "R", "ï¼³" => "S", "ï¼´" => "T", "ï¼µ" => "U", + "V" => "V", "ï¼·" => "W", "X" => "X", "ï¼¹" => "Y", "Z" => "Z", "ï½" => "a", + "b" => "b", "c" => "c", "d" => "d", "ï½…" => "e", "f" => "f", "g" => "g", + "h" => "h", "i" => "i", "j" => "j", "k" => "k", "l" => "l", "ï½" => "m", + "n" => "n", "ï½" => "o", "ï½" => "p", "q" => "q", "ï½’" => "r", "s" => "s", + "ï½”" => "t", "u" => "u", "ï½–" => "v", "ï½—" => "w", "x" => "x", "ï½™" => "y", + "z" => "z", "ヲ" => "wo", "ァ" => "a", "ィ" => "i", "ゥ" => "u", "ェ" => "e", + "ォ" => "o", "ャ" => "ya", "ï½­" => "yu", "ï½®" => "yo", "ッ" => "tu", "ï½±" => "a", + "ï½²" => "i", "ï½³" => "u", "ï½´" => "e", "ï½µ" => "o", "カ" => "ka", "ï½·" => "ki", + "ク" => "ku", "ï½¹" => "ke", "コ" => "ko", "ï½»" => "sa", "ï½¼" => "si", "ï½½" => "su", + "ï½¾" => "se", "ソ" => "so", "ï¾€" => "ta", "ï¾" => "ti", "ツ" => "tu", "テ" => "te", + "ト" => "to", "ï¾…" => "na", "ニ" => "ni", "ヌ" => "nu", "ネ" => "ne", "ノ" => "no", + "ハ" => "ha", "ヒ" => "hi", "フ" => "hu", "ï¾" => "he", "ホ" => "ho", "ï¾" => "ma", + "ï¾" => "mi", "ム" => "mu", "ï¾’" => "me", "モ" => "mo", "ï¾”" => "ya", "ユ" => "yu", + "ï¾–" => "yo", "ï¾—" => "ra", "リ" => "ri", "ï¾™" => "ru", "レ" => "re", "ï¾›" => "ro", + "ワ" => "wa", "ï¾" => "n", "ᄀ" => "g", "ï¾¢" => "gg", "ï¾£" => "gs", "ᄂ" => "n", + "ï¾¥" => "nj", "ᆭ" => "nh", "ᄃ" => "d", "ᄄ" => "dd", "ᄅ" => "r", "ᆰ" => "lg", + "ᆱ" => "lm", "ᆲ" => "lb", "ï¾­" => "ls", "ï¾®" => "lt", "ᆵ" => "lp", "ï¾°" => "rh", + "ï¾±" => "m", "ï¾²" => "b", "ï¾³" => "bb", "ï¾´" => "bs", "ï¾µ" => "s", "ᄊ" => "ss", + "ᄌ" => "j", "ï¾¹" => "jj", "ᄎ" => "c", "ï¾»" => "k", "ï¾¼" => "t", "ï¾½" => "p", + "ï¾¾" => "h", "ï¿‚" => "a", "ᅢ" => "ae", "ï¿„" => "ya", "ï¿…" => "yae", "ᅥ" => "eo", + "ᅦ" => "e", "ï¿Š" => "yeo", "ï¿‹" => "ye", "ï¿Œ" => "o", "ï¿" => "wa", "ï¿Ž" => "wae", + "ï¿" => "oe", "ï¿’" => "yo", "ï¿“" => "u", "ï¿”" => "weo", "ï¿•" => "we", "ï¿–" => "wi", + "ï¿—" => "yu", "ï¿š" => "eu", "ï¿›" => "yi", "ï¿œ" => "i", "ï¿ " => "C", "ï¿¡" => "PS", + "ï¿¥" => "Y=", "₩" => "W=", "ï¿®" => "O" + ); + + static function utf8_to_ascii($str) { + static $keys = null; + static $values = null; + if (!$keys) { + $keys = array_keys(self::$UTF8_TRANSLATE); + $values = array_values(self::$UTF8_TRANSLATE); + } + + return str_replace($keys, $values, $str); + } +} diff --git a/3.0/modules/transliterate/module.info b/3.0/modules/transliterate/module.info new file mode 100644 index 00000000..fd01e44c --- /dev/null +++ b/3.0/modules/transliterate/module.info @@ -0,0 +1,7 @@ +name = "Transliterate" +description = "Transliterate UTF8 text to ASCII equivalents." +version = 1 +author_name = "" +author_url = "" +info_url = "http://codex.gallery2.org/Gallery3:Modules:transliterate" +discuss_url = "http://gallery.menalto.com/forum_module_transliterate" diff --git a/3.0/themes/greydragon/controllers/greydragon.php b/3.0/modules/transliterate/tests/Transliterate_Helper_Test.php similarity index 50% rename from 3.0/themes/greydragon/controllers/greydragon.php rename to 3.0/modules/transliterate/tests/Transliterate_Helper_Test.php index 0796d801..f4b82102 100644 --- a/3.0/themes/greydragon/controllers/greydragon.php +++ b/3.0/modules/transliterate/tests/Transliterate_Helper_Test.php @@ -1,7 +1,7 @@ page_title = t("%name Profile", array("name" => $user->display_name())); - $v->content = new View("user_profile.html"); - - $v->content->user = $user; - $v->content->contactable = - !$user->guest && $user->id != identity::active_user()->id && $user->email; - $v->content->editable = - identity::is_writable() && !$user->guest && $user->id == identity::active_user()->id; - - $event_data = (object)array("user" => $user, "content" => array()); - module::event("show_user_profile", $event_data); - $v->content->info_parts = $event_data->content; - - print $v; +class Transliterate_Helper_Test extends Gallery_Unit_Test_Case { + public function utf8_to_ascii_test() { + $this->assert_equal("Te glossa mou edosan ellenike", + transliterate::utf8_to_ascii("Τη γλώσσα μου έδωσαν ελληνική")); + $this->assert_equal("Na bierieghu pustynnykh voln", + transliterate::utf8_to_ascii("Ðа берегу пуÑтынных волн")); + $this->assert_equal("vepxis tqaosani shot`a rust`aveli", + transliterate::utf8_to_ascii("ვეპხის ტყáƒáƒáƒ¡áƒáƒœáƒ˜ შáƒáƒ—რრუსთáƒáƒ•áƒ”ლი")); + $this->assert_equal("WoNengTunXiaBoLiErBuShangShenTi", + transliterate::utf8_to_ascii("我能åžä¸‹çŽ»ç’ƒè€Œä¸ä¼¤èº«ä½“")); } -*/ } diff --git a/3.0/modules/unrest/helpers/unrest.php b/3.0/modules/unrest/helpers/unrest.php new file mode 100644 index 00000000..d81b9038 --- /dev/null +++ b/3.0/modules/unrest/helpers/unrest.php @@ -0,0 +1,22 @@ + \ No newline at end of file diff --git a/3.0/modules/unrest/helpers/unrest_rest.php b/3.0/modules/unrest/helpers/unrest_rest.php new file mode 100644 index 00000000..3e82a47c --- /dev/null +++ b/3.0/modules/unrest/helpers/unrest_rest.php @@ -0,0 +1,308 @@ + 'name', + 'description' => 'description' + ); + foreach ($likeMapping as $key => $col) + { + if (isset($request->params->$key)) { $limit[$col] = array('op' => 'LIKE', 'value' => '%' . $request->params->$key . '%'); } + } + + return $limit; + } + + private static function getBasicLimiters($request, $limit = array()) + { + $directMapping = array( + 'type' => 'type', + 'id' => 'items.id', + 'parent' => 'parent_id', + 'mime' => 'mime_type'); + foreach ($directMapping as $key => $col) + { + if (isset($request->params->$key)) { $limit[$col] = array('op' => '=', 'value' => unrest_rest::resolveLimitOption($request->params->$key)); } + } + + return $limit; + } + + private static function albumsICanAccess() + { + $db = db::build(); + $gids = identity::group_ids_for_active_user(); + $q = $db->select('id')->from('items'); + foreach ($gids as $gid) { $q->or_where('view_' . $gid, '=', 1); } + + $q->where('type', '=', 'album'); + $permitted = array(); + foreach($q->execute() as $row) { $permitted[] = $row->id; } + + return $permitted; + } + + static function queryLimitByPermission(&$query, $permitted) + { + $query->and_open()->and_open()->where('type', '=', 'album')->and_where('items.id', 'IN', $permitted)->close(); + $query->or_open()->where('type', '!=', 'album')->and_where('parent_id', 'IN', $permitted)->close()->close(); + } + + static function baseItemQuery($db) + { + $fields = array( + 'items.id', 'title', 'album_cover_item_id', 'description', 'height', 'width', 'left_ptr', 'right_ptr', + 'level', 'mime_type', 'name', 'owner_id', 'parent_id', 'relative_path_cache', 'relative_url_cache', + 'resize_dirty', 'slug', 'sort_column', 'sort_order', 'thumb_dirty','thumb_height', 'view_1', 'type', + 'resize_height', 'resize_width', 'thumb_height', 'thumb_width', 'slug', 'name', 'relative_path_cache' + ); + + $permfields = array('view_', 'view_full_', 'edit_', 'add_'); + + foreach (identity::group_ids_for_active_user() as $album) + { + foreach ($permfields as $field) + { + $fields[] = $field . $album; + } + } + + return($db->select($fields)->from('items')->join('access_caches', 'access_caches.item_id', 'items.id')); +/* + return($db->select(array( + 'id', 'title', 'album_cover_item_id', 'description', 'height', 'width', 'left_ptr', 'right_ptr', + 'level', 'mime_type', 'name', 'owner_id', 'parent_id', 'relative_path_cache', 'relative_url_cache', + 'resize_dirty', 'slug', 'sort_column', 'sort_order', 'thumb_dirty','thumb_height', 'view_1', 'type', + 'resize_height', 'resize_width', 'thumb_height', 'thumb_width', 'slug', 'name', 'relative_path_cache' + ))->from('items')); + */ + } + + static function queryLimitByLimiter(&$query, $limit) + { + foreach ($limit as $key => $block) + { + if (gettype($block['value']) == 'array') { $query->and_where($key, 'IN', $block['value']); } + else { $query->and_where($key, $block['op'], $block['value']); } + } + } + + static function getDisplayOptions($request) + { + if (isset($request->params->display)) { + return(split(',', $request->params->display)); + } else { + return(array('uiimage','uitext','ownership','members')); + }; + } + + static function queryOrder(&$query, $request) + { + if (isset($request->params->order)) { + $order = $request->params->order; + $direction = 'asc'; + if (isset($request->params->direction)) + { + if ($request->params->direction == 'desc') { $direction = 'desc'; } + } + + switch ($order) + { + case 'tree': + $query->order_by(array('level' => 'ASC', 'left_ptr' => 'ASC')); + break; + case 'created': + $query->order_by(array('created' => $direction)); + break; + case 'updated': + $query->order_by(array('updated' => $direction)); + break; + case 'views': + $query->order_by(array('view_count' => $direction)); + break; + case 'type': + $query->order_by(array('type' => $direction)); + break; + } + } + } + + static function addChildren($request, $db, $filler, $permitted, $display, &$return, $rest_base) + { + $children = $db->select('parent_id', 'id')->from('items')->where('parent_id', 'IN', $filler['children_of']); + if (isset($request->params->childtypes)) + { + $types = split(',', $request->params->childtypes); + $children->where('type', 'IN', $types); + } + + /* We shouldn't have any albums we don't have access to by default in this query, but just in case.. */ + unrest_rest::queryLimitByPermission(&$children, $permitted); + + + $childBlock = array(); + foreach($children->execute() as $item) + { + $childBlock[$item->parent_id][] = intval($item->id); + } + + foreach ($return as &$data) + { + if (array_key_exists($data['entity']['id'], $childBlock)) + { + if (in_array('terse', $display)) { + $data['members'] = $childBlock[ $data['id'] ]; + } + else { + $members = array(); + foreach ($childBlock[ $data['entity']['id'] ] as $child) { + $members[] = unrest_rest::makeRestURL('item', $child, $rest_base); + } + $data['members'] = $members; + } + } + else + { + $data['members'] = array(); + } + } + } + + private static function makeRestURL($resource, $identifier, $base) + { + return $base . '/' . $resource . '/' . $identifier; + } + + public static function size_url($size, $relative_path_cache, $type, $file_base) { + $base = $file_base . 'var/' . $size . '/' . $relative_path_cache; + if ($type == 'photo') { + return $base; + } else if ($type == 'album') { + return $base . "/.album.jpg"; + } else if ($type == 'movie') { + // Replace the extension with jpg + return preg_replace("/...$/", "jpg", $base); + } + } + + + static function get($request) { + $db = db::build(); + + $start = microtime(true); + $rest_base = url::abs_site("rest"); + $file_base = url::abs_file(''); #'var/' . $size . '/' + /* Build basic limiters */ + $limit = unrest_rest::getBasicLimiters($request); + $limit = unrest_rest::getFreetextLimiters($request,$limit); + + /* Build numeric limiters */ + /* ...at some point. */ + + /* Figure out an array of albums we got permissions to access */ + $permitted = unrest_rest::albumsICanAccess(); + + $display = unrest_rest::getDisplayOptions($request); + $items = unrest_rest::baseItemQuery($db); + + /* + Introduce some WHERE statements that'll make sure that we don't get to see stuff we + shouldn't be seeing. + */ + unrest_rest::queryLimitByPermission(&$items, $permitted); + unrest_rest::queryLimitByLimiter(&$items, $limit); + unrest_rest::queryOrder(&$items, $request); + + $return = array(); + $filler = array(); + $relationshipCandidates = array(); + + foreach($items->execute() as $item) + { + $data = array( + 'id' => intval($item->id), + 'parent' => intval($item->parent_id), + 'owner_id' => intval($item->{'owner_id'}), + 'public' => ($item->view_1)?true:false, + 'type' => $item->type // Grmbl + ); + + if (in_array('uitext', $display)) { + $ui = array( + 'title' => $item->title, + 'description' => $item->description, + 'name' => $item->name, + 'slug' => $item->slug + ); + + $data = array_merge($data, $ui); + } + + + if (in_array('uiimage', $display)) { + $ui = array( + 'height' => $item->height, + 'width' => $item->width, + 'resize_height' => $item->resize_height, + 'resize_width' => $item->resize_width, + 'thumb_height' => $item->resize_height, + 'thumb_width' => $item->resize_width + ); + + $ui['thumb_url_public'] = unrest_rest::size_url('thumbs', $item->relative_path_cache, $item->type, $file_base); + $public = $item->view_1?true:false; + $fullPublic = $item->view_full_1?true:false; + + if ($item->type != 'album') + { + $ui['file_url'] = unrest_rest::makeRestURL('data', $item->id . '?size=full', $rest_base); + $ui['thumb_url'] = unrest_rest::makeRestURL('data', $item->id . '?size=thumb', $rest_base); + $ui['resize_url'] = unrest_rest::makeRestURL('data', $item->id . '?size=resize', $rest_base); + + if ($public) { + $ui['resize_url_public'] = unrest_rest::size_url('resizes', $item->relative_path_cache, $item->type, $file_base); + + if ($fullPublic) { + $ui['file_url_public'] = unrest_rest::size_url('albums', $item->relative_path_cache, $item->type, $file_base); + } + } + } + + $data = array_merge($data, $ui); + } + + if (in_array('members', $display)) { + $filler['children_of'][] = $item->id; + } + + $return[] = array( + 'url' => unrest_rest::makeRestURL('item', $item->id, $rest_base ), + 'entity' => $data + ); + } + + + /* Do we need to fetch children? */ + if (array_key_exists('children_of', $filler)) + { + unrest_rest::addChildren($request, $db, $filler, $permitted, $display, &$return, $rest_base); + } + + $end = microtime(true); + error_log("Inner " . ($end - $start) . " seconds taken"); + + return $return; + } +} + + +?> \ No newline at end of file diff --git a/3.0/modules/unrest/module.info b/3.0/modules/unrest/module.info new file mode 100644 index 00000000..84be9620 --- /dev/null +++ b/3.0/modules/unrest/module.info @@ -0,0 +1,7 @@ +name = "Un-Rest API module" +description = "Shorter invocations for the Rest API" +version = 1 +author_name = "" +author_url = "" +info_url = "http://codex.gallery2.org/Gallery3:Modules:unrest" +discuss_url = "http://gallery.menalto.com/forum_module_unrest" diff --git a/3.0/modules/user_albums/helpers/user_albums_event.php b/3.0/modules/user_albums/helpers/user_albums_event.php index d11e5ac5..1d852e80 100644 --- a/3.0/modules/user_albums/helpers/user_albums_event.php +++ b/3.0/modules/user_albums/helpers/user_albums_event.php @@ -1,7 +1,7 @@ id == identity::active_user()->id && user_chroot::album() ) { + if( $item->left_ptr < user_chroot::album()->left_ptr || user_chroot::album()->right_ptr < $item->right_ptr ) { + return false; + } + } + + return parent::user_can($user, $perm_name, $item); + } + + /** + * Copied from modules/gallery/helpers/access.php because of the usage of self:: + */ + static function can($perm_name, $item) { + return self::user_can(identity::active_user(), $perm_name, $item); + } + + /** + * Copied from modules/gallery/helpers/access.php because of the usage of self:: + */ + static function required($perm_name, $item) { + if (!self::can($perm_name, $item)) { + if ($perm_name == "view") { + // Treat as if the item didn't exist, don't leak any information. + throw new Kohana_404_Exception(); + } else { + self::forbidden(); + } + } + } +} diff --git a/3.0/modules/user_chroot/helpers/MY_item.php b/3.0/modules/user_chroot/helpers/MY_item.php new file mode 100644 index 00000000..c0c27f9c --- /dev/null +++ b/3.0/modules/user_chroot/helpers/MY_item.php @@ -0,0 +1,40 @@ +and_open() + ->and_where('items.left_ptr', '>=', user_chroot::album()->left_ptr) + ->and_where('items.right_ptr', '<=', user_chroot::album()->right_ptr) + ->close(); + } + + return $model; + } + + static function root() { + return ( user_chroot::album() ) + ? user_chroot::album() + : parent::root(); + } +} diff --git a/3.0/modules/user_chroot/helpers/MY_url.php b/3.0/modules/user_chroot/helpers/MY_url.php new file mode 100644 index 00000000..5a0958f9 --- /dev/null +++ b/3.0/modules/user_chroot/helpers/MY_url.php @@ -0,0 +1,62 @@ +relative_url().'/'.Router::$current_uri, '/'); + + } else if( is_null(Router::$controller) && Router::$current_uri != '' ) { + // Non-root album requested + Router::$current_uri = trim(user_chroot::album()->relative_url().'/'.Router::$current_uri, '/'); + } + } + + return parent::parse_url(); + } + + /** + * Remove the chroot part of the URI. + */ + static function site($uri = '', $protocol = FALSE) { + if( user_chroot::album() ) { + $uri = preg_replace('#^'.user_chroot::album()->relative_url().'#', '', $uri); + } + + return parent::site($uri, $protocol); + } +} \ No newline at end of file diff --git a/3.1/themes/greydragon/helpers/exif_event.php b/3.0/modules/user_chroot/helpers/user_chroot.php similarity index 59% rename from 3.1/themes/greydragon/helpers/exif_event.php rename to 3.0/modules/user_chroot/helpers/user_chroot.php index 27b617a6..12445a38 100644 --- a/3.1/themes/greydragon/helpers/exif_event.php +++ b/3.0/modules/user_chroot/helpers/user_chroot.php @@ -1,7 +1,7 @@ is_album()) { - exif::extract($item); + +class user_chroot_Core { + private static $_album = null; + + /** + * Return the root album of the current user, or false if the user is not + * chrooted. + */ + public static function album() { + if( is_null(self::$_album) ) { + self::$_album = false; + + $item = ORM::factory('item') + ->join('user_chroots', 'items.id', 'user_chroots.album_id') + ->where('user_chroots.id', '=', identity::active_user()->id) + ->find(); + + if( $item->loaded() ) { + self::$_album = $item; + } } - } - static function item_deleted($item) { - db::build() - ->delete("exif_records") - ->where("item_id", "=", $item->id) - ->execute(); + return self::$_album; } - - static function photo_menu($menu, $theme) { - $item = $theme->item(); - $menu->append( - Menu::factory("link") - ->id("exifdata-link") - ->label(t("Photo Details")) - ->url(url::site("exif/show/$item->id")) - ->css_id("g-exifdata-link")); - } -} +} \ No newline at end of file diff --git a/3.0/modules/user_chroot/helpers/user_chroot_event.php b/3.0/modules/user_chroot/helpers/user_chroot_event.php new file mode 100644 index 00000000..6e97bd1e --- /dev/null +++ b/3.0/modules/user_chroot/helpers/user_chroot_event.php @@ -0,0 +1,114 @@ +id)->delete(); + } + + /** + * Called just before an item deletion. + */ + public static function item_before_delete($item) { + if( $item->is_album() ) { + ORM::factory('user_chroot')->where('album_id', '=', $item->id)->delete(); + } + } + + /** + * Called when building the 'Add user' form for an admin. + */ + static function user_add_form_admin($user, $form) { + $form->add_user->dropdown('user_chroot') + ->label(t("Root Album")) + ->options(self::albumsTreeArray()) + ->selected(1); + } + + /** + * Called just after a user has been added by an admin. + */ + public static function user_add_form_admin_completed($user, $form) { + if( $form->add_user->user_chroot->value > 1 ) { + $user_chroot = ORM::factory('user_chroot'); + $user_chroot->id = $user->id; + $user_chroot->album_id = $form->add_user->user_chroot->value; + $user_chroot->save(); + } + } + + /** + * Called when building the 'Edit user' form for an admin. + */ + public static function user_edit_form_admin($user, $form) { + $user_chroot = ORM::factory('user_chroot', $user->id); + + $selected = ( $user_chroot->loaded() ) + ? $user_chroot->album_id + : 1; + + $form->edit_user->dropdown('user_chroot') + ->label(t("Root Album")) + ->options(self::albumsTreeArray()) + ->selected($selected); + } + + /** + * Called just after a user has been edited by an admin. + */ + public static function user_edit_form_admin_completed($user, $form) { + if( $form->edit_user->user_chroot->value <= 1 ) { + ORM::factory('user_chroot')->delete($user->id); + + } else { + $user_chroot = ORM::factory('user_chroot', $user->id); + + if( !$user_chroot->loaded() ) { + $user_chroot = ORM::factory('user_chroot'); + $user_chroot->id = $user->id; + } + + $user_chroot->album_id = $form->edit_user->user_chroot->value; + $user_chroot->save(); + } + } + + /** + * Generate an array representing the hierarchy of albums. + */ + private static function albumsTreeArray($level_marker = '    ') { + $tree = array(); + $albums = ORM::factory('item') + ->where('type', '=', 'album') + ->order_by('left_ptr', 'ASC') + ->find_all(); + + foreach($albums as $album) { + $tree[$album->id] = html::clean( + str_repeat($level_marker, $album->level - 1).' '.$album->title ); + } + + return $tree; + } +} diff --git a/3.0/modules/user_chroot/helpers/user_chroot_installer.php b/3.0/modules/user_chroot/helpers/user_chroot_installer.php new file mode 100644 index 00000000..621ea333 --- /dev/null +++ b/3.0/modules/user_chroot/helpers/user_chroot_installer.php @@ -0,0 +1,43 @@ +query('CREATE TABLE IF NOT EXISTS {user_chroots} ( + `id` int(9) NOT NULL, + `album_id` int(9) default NULL, + PRIMARY KEY (`id`), + UNIQUE KEY(`id`)) + DEFAULT CHARSET=utf8;'); + module::set_version('user_chroot', 1); + } + + /** + * Drops the table user_chroot when uninstalling the module. + */ + public static function uninstall() { + $db = Database::instance(); + $db->query('DROP TABLE IF EXISTS {user_chroots};'); + } +} diff --git a/3.0/modules/user_chroot/libraries/MY_ORM_MPTT.php b/3.0/modules/user_chroot/libraries/MY_ORM_MPTT.php new file mode 100644 index 00000000..320e482f --- /dev/null +++ b/3.0/modules/user_chroot/libraries/MY_ORM_MPTT.php @@ -0,0 +1,63 @@ +model_name = inflector::singular($this->table_name); + } + + /** + * Return the parent of this node + * + * @return ORM + */ + function parent() { + if( user_chroot::album() && user_chroot::album()->id == $this->id ) { + return null; + } else { + return parent::parent(); + } + } + + /** + * Return all the parents of this node, in order from root to this node's immediate parent. + * + * @return array ORM + */ + function parents() { + $select = $this + ->where('left_ptr', '<=', $this->left_ptr) + ->where('right_ptr', '>=', $this->right_ptr) + ->where('id', '<>', $this->id) + ->order_by('left_ptr', 'ASC'); + + if( user_chroot::album() ) { + $select->where('left_ptr', '>=', user_chroot::album()->left_ptr); + $select->where('right_ptr', '<=', user_chroot::album()->right_ptr); + } + + return $select->find_all(); + } +} diff --git a/3.0/modules/videos/models/videos_file.php b/3.0/modules/user_chroot/models/user_chroot.php similarity index 91% rename from 3.0/modules/videos/models/videos_file.php rename to 3.0/modules/user_chroot/models/user_chroot.php index 8104db66..656dceb1 100644 --- a/3.0/modules/videos/models/videos_file.php +++ b/3.0/modules/user_chroot/models/user_chroot.php @@ -1,7 +1,7 @@ page_title = t("User Information Settings"); + $view->content = new View("admin_user_info.html"); + $view->content->user_info_form = $this->_get_admin_form(); + print $view; + } + + public function saveprefs() { + // Prevent Cross Site Request Forgery + access::verify_csrf(); + + // Figure out the values of the text boxes + $str_per_page = Input::instance()->post("per_page"); + $str_default_sort_column = Input::instance()->post("default_sort_column"); + $str_default_sort_order = Input::instance()->post("default_sort_order"); + $str_use_default_gallery_date_format = Input::instance()->post("use_default_gallery_date_format"); + $str_date_format = Input::instance()->post("date_format"); + $str_log_logins = Input::instance()->post("log_logins"); + $str_color_login = Input::instance()->post("color_login"); + $str_log_logouts = Input::instance()->post("log_logouts"); + $str_color_logout = Input::instance()->post("color_logout"); + $str_log_failed_logins = Input::instance()->post("log_failed_logins"); + $str_color_failed_login = Input::instance()->post("color_failed_login"); + $str_log_re_authenticate_logins = Input::instance()->post("log_re_authenticate_logins"); + $str_color_re_authenticate_login = Input::instance()->post("color_re_authenticate_login"); + $str_log_user_created = Input::instance()->post("log_user_created"); + $str_color_user_created = Input::instance()->post("color_user_created"); + + // Save Settings. + module::set_var("user_info", "per_page", $str_per_page); + module::set_var("user_info", "default_sort_column", $str_default_sort_column); + module::set_var("user_info", "default_sort_order", $str_default_sort_order); + module::set_var("user_info", "use_default_gallery_date_format", $str_use_default_gallery_date_format); + module::set_var("user_info", "date_format", $str_date_format); + module::set_var("user_info", "log_logins", $str_log_logins); + module::set_var("user_info", "color_login", $str_color_login); + module::set_var("user_info", "log_logouts", $str_log_logouts); + module::set_var("user_info", "color_logout", $str_color_logout); + module::set_var("user_info", "log_failed_logins", $str_log_failed_logins); + module::set_var("user_info", "color_failed_login", $str_color_failed_login); + module::set_var("user_info", "log_re_authenticate_logins", $str_log_re_authenticate_logins); + module::set_var("user_info", "color_re_authenticate_login", $str_color_re_authenticate_login); + module::set_var("user_info", "log_user_created", $str_log_user_created); + module::set_var("user_info", "color_user_created", $str_color_user_created); + message::success(t("Your Settings Have Been Saved.")); + + // Load Admin page. + $view = new Admin_View("admin.html"); + $view->page_title = t("User Information Settings"); + $view->content = new View("admin_user_info.html"); + $view->content->user_info_form = $this->_get_admin_form(); + print $view; + } + + private function _get_admin_form() { + // Make a new Form. + $form = new Forge("admin/user_info/saveprefs", "", "post", + array("id" => "g-user_info-admin-form")); + + // Create the input boxes for the User Information Settings + $user_infoGroup = $form->group("UserInformationSettings"); + $user_infoGroup->dropdown("per_page") + ->label(t("Number of records to display per page")) + ->options(array("5" => t("5"), + "10" => t("10"), + "15" => t("15"), + "25" => t("25"), + "50" => t("50"), + "75" => t("75"), + "100" => t("100"), + "125" => t("125"))) + ->selected(module::get_var("user_info", "per_page")); + $user_infoGroup->dropdown("default_sort_column") + ->label(t("Default Column to Sort By")) + ->options(array("id" => t("id"), + "user_id" => t("user_id"), + "user_name" => t("user_name"), + "ip_address" => t("ip_address"), + "time_stamp" => t("time_stamp"), + "action" => t("action"))) + ->selected(module::get_var("user_info", "default_sort_column")); + $user_infoGroup->dropdown("default_sort_order") + ->label(t("Default Sort Order")) + ->options(array("ASC" => t("Ascending"), + "DESC" => t("Descending"))) + ->selected(module::get_var("user_info", "default_sort_order")); + $user_infoGroup->dropdown("use_default_gallery_date_format") + ->label(t("Use Default Gallery Date/Time Format")) + ->options(array("Yes" => t("Yes"), + "No" => t("No"))) + ->selected(module::get_var("user_info", "use_default_gallery_date_format")); + $user_infoGroup->input("date_format") + ->label(t("Format of the Date & Time - PHP Date")) + ->value(module::get_var("user_info", "date_format")); + $user_infoGroup->dropdown("log_logins") + ->label(t("Log Logins")) + ->options(array("Yes" => t("Yes"), + "No" => t("No"))) + ->selected(module::get_var("user_info", "log_logins")); + $user_infoGroup->input("color_login") + ->label(t("Login Color - Hex Only - HTML Colors",array("color_login" => module::get_var("user_info", "color_login")))) + ->value(module::get_var("user_info", "color_login")); + $user_infoGroup->dropdown("log_logouts") + ->label(t("Log Logouts")) + ->options(array("Yes" => t("Yes"), + "No" => t("No"))) + ->selected(module::get_var("user_info", "log_logouts")); + $user_infoGroup->input("color_logout") + ->label(t("Logout Color - Hex Only - HTML Colors",array("color_logout" => module::get_var("user_info", "color_logout")))) + ->value(module::get_var("user_info", "color_logout")); + $user_infoGroup->dropdown("log_failed_logins") + ->label(t("Log Failed Logins")) + ->options(array("Yes" => t("Yes"), + "No" => t("No"))) + ->selected(module::get_var("user_info", "log_failed_logins")); + $user_infoGroup->input("color_failed_login") + ->label(t("Failed Login Color - Hex Only - HTML Colors",array("color_failed_login" => module::get_var("user_info", "color_failed_login")))) + ->value(module::get_var("user_info", "color_failed_login")); + $user_infoGroup->dropdown("log_re_authenticate_logins") + ->label(t("Log Re-Authenticate Logins")) + ->options(array("Yes" => t("Yes"), + "No" => t("No"))) + ->selected(module::get_var("user_info", "log_re_authenticate_logins")); + $user_infoGroup->input("color_re_authenticate_login") + ->label(t("Re-Authenticate Login Color - Hex Only - HTML Colors",array("color_re_authenticate_login" => module::get_var("user_info", "color_re_authenticate_login")))) + ->value(module::get_var("user_info", "color_re_authenticate_login")); + $user_infoGroup->dropdown("log_user_created") + ->label(t("Log User Created")) + ->options(array("Yes" => t("Yes"), + "No" => t("No"))) + ->selected(module::get_var("user_info", "log_user_created")); + $user_infoGroup->input("color_user_created") + ->label(t("User Created Color - Hex Only - HTML Colors",array("color_user_created" => module::get_var("user_info", "color_user_created")))) + ->value(module::get_var("user_info", "color_user_created")); + + // Add a save button to the form. + $form->submit("SaveSettings")->value(t("Save")); + + // Return the newly generated form. + return $form; + } + + + + + + + public function lookupip() { + // Generate a new admin page. + $view = new Admin_View("admin.html"); + $view->page_title = t("User Info: Lookup IP Address"); + $view->content = new View("admin_user_info_lookupip.html"); +// $view->content->block_ip_address = $this->_get_block_ip_address_form(); + print $view; + } + + + + + + + public function blockip() { + // Prevent Cross Site Request Forgery + access::verify_csrf(); + + // Figure out the values of the text boxes + // Figure out the ip address to block + $str_per_page = Input::instance()->post("per_page"); + $str_default_sort_column = Input::instance()->post("default_sort_column"); + + // Block IP Addresss. + module::set_var("user_info", "per_page", $str_per_page); + message::success(t("Your Settings Have Been Saved.")); + + // Load Admin page. + // $view = new Admin_View("admin.html"); + // $view->page_title = t("User Information Settings"); + // $view->content = new View("admin_user_info.html"); + // $view->content->user_info_form = $this->_get_admin_form(); + // print $view; + + $view = new Admin_View("admin.html"); + $view->page_title = t("User Info: Lookup IP Address"); + $view->content = new View("admin_user_info_lookupip.html"); + $view->content->block_ip_address = $this->_get_block_ip_address_form(); + + print $view; + + } + + + private function _get_block_ip_address_form() { + // Make a new Form. +// $form = new Forge("admin/user_info/blockip", "", "post", +// array("id" => "g-user_info-block-ip-address-form")); +// +// // Create the input boxes for the User Information Settings +// $block_ipGroup = $form->group("BlockIPAddress"); +// $block_ipGroup->dropdown("per_page") +// ->label(t("Number of records to display per page")) +// ->options(array("25" => t("25"), +// "50" => t("50"), +// "75" => t("75"), +// "100" => t("100"), +// "125" => t("125"), +// "150" => t("150"))) +// ->selected(module::get_var("user_info", "per_page")); +// $block_ipGroup->input("date_format") +// ->label(t("Format of the Date & Time - PHP Date")) +// ->value(module::get_var("user_info", "date_format")); +// $block_ipGroup->input("color_login") +// ->label(t("Login Color - HTML Colors")) +// ->value(module::get_var("user_info", "color_login")); +// ->value(module::get_var("user_info", "color_failed_login")); +// +// // Add a save button to the form. +// $form->submit("SaveSettings")->value(t("Block IP Address")); +// +// // Return the newly generated form. +// return $form; + } + + + + +} + diff --git a/3.0/modules/user_info/helpers/user_info_block.php b/3.0/modules/user_info/helpers/user_info_block.php new file mode 100644 index 00000000..86820c9c --- /dev/null +++ b/3.0/modules/user_info/helpers/user_info_block.php @@ -0,0 +1,56 @@ + t("User Information")); + } + + static function get($block_id) { + $block = new Block(); + switch ($block_id) { + case "user_info": + $block->css_id = "g-user_info"; + $block->title = t("User Information"); + $block->content = new View("admin_block_user_info.html"); + $block->content->number_of_records = ORM::factory("user_info")->count_all(); + + // helps build the pagniation + $page_size = module::get_var("user_info", "per_page"); + $page = Input::instance()->get("page", "1"); + $builder = db::build(); + $user_count = $builder->from("user_infos")->count_records(); + $block->content->pager = new Pagination(); + $block->content->pager->initialize( + array("query_string" => "page", + "total_items" => $user_count, + "items_per_page" => $page_size, + "style" => "classic")); + // Make sure that the page references a valid offset + if ($page < 1) { +// This prevents the admin page from displaying if there are no records in the database, commented out to temp. fix +// url::redirect(url::merge(array("page" => 1))); + url::site("admin"); //This should fix the issue I think + } else if ($page > $block->content->pager->total_pages) { + url::redirect(url::merge(array("page" => $block->content->pager->total_pages))); + } + // Get the user defined settings for sort by and sort order + $default_sort_column = module::get_var("user_info", "default_sort_column"); + $default_sort_order = module::get_var("user_info", "default_sort_order"); + $block->content->data = ORM::factory("user_info") + ->order_by($default_sort_column, $default_sort_order) + ->find_all($page_size, $block->content->pager->sql_offset); + +// $block->content->data = ORM::factory("user_info")->find_all(); + + $block->content->use_default_gallery_date_format = module::get_var("user_info", "use_default_gallery_date_format"); + $block->content->date_format = module::get_var("user_info", "date_format"); + $block->content->color_login = module::get_var("user_info", "color_login"); + $block->content->color_logout = module::get_var("user_info", "color_logout"); + $block->content->color_failed_login = module::get_var("user_info", "color_failed_login"); + $block->content->color_re_authenticate_login = module::get_var("user_info", "color_re_authenticate_login"); + $block->content->color_user_created = module::get_var("user_info", "color_user_created"); + + break; + } + return $block; + } +} diff --git a/3.0/modules/user_info/helpers/user_info_event.php b/3.0/modules/user_info/helpers/user_info_event.php new file mode 100644 index 00000000..c2958a63 --- /dev/null +++ b/3.0/modules/user_info/helpers/user_info_event.php @@ -0,0 +1,100 @@ +get("settings_menu") + ->append(Menu::factory("link") + ->id("user_info") + ->label(t("User Info")) + ->url(url::site("admin/user_info"))); + } + + static function user_login() { + $log_logins = module::get_var("user_info", "log_logins"); + if ($log_logins == "Yes") { + $user_info = ORM::factory("user_info"); + $user_info->user_id = identity::active_user()->id; + $user_info->user_name = identity::active_user()->name; + $user_info->ip_address = $_SERVER['REMOTE_ADDR']; + $user_info->time_stamp = time(); + $user_info->action = "Login"; + $user_info->save(); + } + } + + static function user_logout($user) { + $log_logouts = module::get_var("user_info", "log_logouts"); + if ($log_logouts == "Yes") { + $user_info = ORM::factory("user_info"); + $user_info->user_id = $user->id; + $user_info->user_name = $user->name; + $user_info->ip_address = $_SERVER['REMOTE_ADDR']; + $user_info->time_stamp = time(); + $user_info->action = "Logout"; + $user_info->save(); + } + } + + static function user_auth_failed($user_name) { + $log_failed_logins = module::get_var("user_info", "log_failed_logins"); + if ($log_failed_logins == "Yes") { + $user_info = ORM::factory("user_info"); + if (identity::lookup_user_by_name($user_name)) { + $user_info->user_id = identity::lookup_user_by_name($user_name)->id; + } else { + $user_info->user_id = ""; + } + $user_info->user_name = $user_name; + $user_info->ip_address = $_SERVER['REMOTE_ADDR']; + $user_info->time_stamp = time(); + $user_info->action = "Failed Login"; + $user_info->save(); + } + } + + static function user_auth($user) { + $log_re_authenticate_logins = module::get_var("user_info", "log_re_authenticate_logins"); + if ($log_re_authenticate_logins == "Yes") { + $user_info = ORM::factory("user_info"); + $user_info->user_id = $user->id; + $user_info->user_name = $user->name; + $user_info->ip_address = $_SERVER['REMOTE_ADDR']; + $user_info->time_stamp = time(); + $user_info->action = "Re-Authenticate Login"; + $user_info->save(); + } + } + + static function user_created($pending_user) { + $log_user_created = module::get_var("user_info", "log_user_created"); + if ($log_user_created == "Yes") { + $user_info = ORM::factory("user_info"); + $user_info->user_id = $pending_user->id; + $user_info->user_name = $pending_user->name; + $user_info->ip_address = $_SERVER['REMOTE_ADDR']; + $user_info->time_stamp = time(); + $user_info->action = "User Created"; + $user_info->save(); + } + } + + +} diff --git a/3.0/modules/user_info/helpers/user_info_installer.php b/3.0/modules/user_info/helpers/user_info_installer.php new file mode 100644 index 00000000..5ad3cbdd --- /dev/null +++ b/3.0/modules/user_info/helpers/user_info_installer.php @@ -0,0 +1,82 @@ +query("CREATE TABLE IF NOT EXISTS {user_infos} ( + `id` int(11) NOT NULL auto_increment, + `user_id` varchar(128) default NULL, + `user_name` varchar(128) default NULL, + `ip_address` varchar(255) default NULL, + `time_stamp` varchar(128) default NULL, + `action` varchar(128) default NULL, + PRIMARY KEY (`id`)) + DEFAULT CHARSET=utf8;"); + + module::set_var("user_info", "per_page", 25); + module::set_var("user_info", "default_sort_column", "id"); + module::set_var("user_info", "default_sort_order", "DESC"); + module::set_var("user_info", "use_default_gallery_date_format", "Yes"); + module::set_var("user_info", "date_format", "D d M Y h:i:s A T"); + module::set_var("user_info", "log_logins", "Yes"); + module::set_var("user_info", "color_login", "#008000"); + module::set_var("user_info", "log_logouts", "Yes"); + module::set_var("user_info", "color_logout", "#0000FF"); + module::set_var("user_info", "log_failed_logins", "Yes"); + module::set_var("user_info", "color_failed_login", "#FF0000"); + module::set_var("user_info", "log_re_authenticate_logins", "No"); + module::set_var("user_info", "color_re_authenticate_login", "#800080"); + module::set_var("user_info", "log_user_created", "No"); + module::set_var("user_info", "color_user_created", "#FF8C00"); + module::set_version("user_info", 1); + } + + + static function upgrade($version) { +// $db = Database::instance(); + if ($version == 1) { +// $db->query("ALTER TABLE {comments} CHANGE `state` `state` varchar(15) default 'unpublished'"); + module::set_version("user_info", $version = 2); + } +// +// if ($version == 2) { +// module::set_var("comment", "access_permissions", "everybody"); +// module::set_version("comment", $version = 3); +// } + } + + + + static function uninstall() { +// $db = Database::instance(); +// $db->query("DROP TABLE IF EXISTS {userinfo};"); +// /* @todo Put database table drops here */ +// module::delete("userinfo"); + } + + +// static function deactivate() { +// site_status::clear("user_info"); +// $db = Database::instance(); +// $db->query("DROP TABLE IF EXISTS {user_infos};"); +// } + + +} diff --git a/3.0/modules/user_info/models/user_info.php b/3.0/modules/user_info/models/user_info.php new file mode 100644 index 00000000..bf55be22 --- /dev/null +++ b/3.0/modules/user_info/models/user_info.php @@ -0,0 +1,21 @@ + + +
    +

    here.

    User Created - Logs users that the Admin creates and can log the users that are created by visitors when using the Registration Module and the Registration Module is set to 'Visitors can create accounts and no administrator approval is required'.", + array("user_info_configure" => html::mark_clean(url::site("admin/user_info")))) ?>

    +
    + +
    + + + + + 0) { ?> + + + + + + + + + + + + + + + + + + + + + + + + + 0) { ?> + + + + + + + + + + + + + + + + + + + + + +
    $number_of_records)) ?>
    id ?>user_id ?> + user_id){ ?> + user_id") ?>" target="_blank">user_name) ?> + + user_name ?>
    + +
    + ip_address") ?>" target="_blank">ip_address) ?> + + + time_stamp) ?> + time_stamp); + } + ?> + + action) + { + case "Failed Login": + echo ""; + echo $myData->action; + echo ""; + break; + + case "Login": + echo ""; + echo $myData->action; + echo ""; + break; + + case "Logout": + echo ""; + echo $myData->action; + echo ""; + break; + + case "Re-Authenticate Login": + echo ""; + echo $myData->action; + echo ""; + break; + + case "User Created": + echo ""; + echo $myData->action; + echo ""; + break; + + default: + echo ""; + echo $myData->action; + echo ""; + } + ?> +
    +
    diff --git a/3.0/modules/user_info/views/admin_user_info.html.php b/3.0/modules/user_info/views/admin_user_info.html.php new file mode 100644 index 00000000..3ae6986c --- /dev/null +++ b/3.0/modules/user_info/views/admin_user_info.html.php @@ -0,0 +1,6 @@ + +
    +

    + +
    + diff --git a/3.0/modules/user_info/views/admin_user_info_lookupip.html.php b/3.0/modules/user_info/views/admin_user_info_lookupip.html.php new file mode 100644 index 00000000..4be1b297 --- /dev/null +++ b/3.0/modules/user_info/views/admin_user_info_lookupip.html.php @@ -0,0 +1,8 @@ + + +

    +

    +

    [x]

    + diff --git a/3.0/modules/user_rest/helpers/user_rest_installer.php b/3.0/modules/user_rest/helpers/user_rest_installer.php new file mode 100644 index 00000000..32c800f2 --- /dev/null +++ b/3.0/modules/user_rest/helpers/user_rest_installer.php @@ -0,0 +1,30 @@ +page_title = t("Add videos from server"); + $view->page_title = t("Add from server"); $view->content = new View("admin_videos.html"); $view->content->form = $this->_get_admin_form(); $paths = unserialize(module::get_var("videos", "authorized_paths", "a:0:{}")); diff --git a/3.0/modules/videos/controllers/file_proxy.php b/3.0/modules/videos/controllers/file_proxy.php new file mode 100644 index 00000000..f69bff1b --- /dev/null +++ b/3.0/modules/videos/controllers/file_proxy.php @@ -0,0 +1,144 @@ +server("REQUEST_URI")); + + // get rid of query parameters + // request_uri: gallery3/var/albums/foo/bar.jpg + $request_uri = preg_replace("/\?.*/", "", $request_uri); + + // var_uri: gallery3/var/ + $var_uri = url::file("var/"); + + // Make sure that the request is for a file inside var + $offset = strpos(rawurldecode($request_uri), $var_uri); + if ($offset !== 0) { + throw new Kohana_404_Exception(); + } + + // file_uri: albums/foo/bar.jpg + $file_uri = substr($request_uri, strlen($var_uri)); + + // type: albums + // path: foo/bar.jpg + list ($type, $path) = explode("/", $file_uri, 2); + if ($type != "resizes" && $type != "albums" && $type != "thumbs") { + throw new Kohana_404_Exception(); + } + + // If the last element is .album.jpg, pop that off since it's not a real item + $path = preg_replace("|/.album.jpg$|", "", $path); + + $item = item::find_by_path($path); + if (!$item->loaded()) { + // We didn't turn it up. If we're looking for a .jpg then it's it's possible that we're + // requesting the thumbnail for a movie. In that case, the .flv, .mp4 or .m4v file would + // have been converted to a .jpg. So try some alternate types: + if (preg_match('/.jpg$/', $path)) { + // rWatcher Mod: look for videos with file extensions supported by the videos module in addition to flv mp4 and m4v + // Original Line: foreach (array("flv", "mp4", "m4v") as $ext) { + foreach (array_merge(array("flv", "mp4", "m4v"), unserialize(module::get_var("videos", "allowed_extensions"))) as $ext) { + $movie_path = preg_replace('/.jpg$/', ".$ext", $path); + $item = item::find_by_path($movie_path); + if ($item->loaded()) { + break; + } + } + } + // rWatcher Mod: + // If we're looking for a .flv then it's it's possible that we're requesting a flash resize + // for a movie. + if (strtolower(substr($path, strlen($path)-4)) == ".flv") { + $movie_path = str_ireplace(".flv", "", $path); + $item = ORM::factory("item")->where("relative_path_cache", "=", $movie_path)->find(); + } + // END rWatcher Mod + } + + if (!$item->loaded()) { + throw new Kohana_404_Exception(); + } + + // Make sure we have access to the item + if (!access::can("view", $item)) { + throw new Kohana_404_Exception(); + } + + // Make sure we have view_full access to the original + if ($type == "albums" && !access::can("view_full", $item)) { + throw new Kohana_404_Exception(); + } + + // Don't try to load a directory + if ($type == "albums" && $item->is_album()) { + throw new Kohana_404_Exception(); + } + + if ($type == "albums") { + $file = $item->file_path(); + } else if ($type == "resizes") { + $file = $item->resize_path(); + // rWatcher MOD + // If the resize is for a movie, assume it needs a .flv extension. + if ($item->is_movie()) { + $file = $file . ".flv"; + } + // End rWatcher MOD + } else { + $file = $item->thumb_path(); + } + + if (!file_exists($file)) { + throw new Kohana_404_Exception(); + } + + header("Content-Length: " . filesize($file)); + + header("Pragma:"); + // Check that the content hasn't expired or it wasn't changed since cached + expires::check(2592000, $item->updated); + + // We don't need to save the session for this request + Session::instance()->abort_save(); + + expires::set(2592000, $item->updated); // 30 days + + // Dump out the image. If the item is a movie, then its thumbnail will be a JPG. + if ($item->is_movie() && $type != "albums") { + header("Content-Type: image/jpeg"); + } else { + header("Content-Type: $item->mime_type"); + } + Kohana::close_buffers(false); + readfile($file); + } +} diff --git a/3.0/modules/videos/controllers/videos.php b/3.0/modules/videos/controllers/videos.php index 020817ff..34461b3e 100644 --- a/3.0/modules/videos/controllers/videos.php +++ b/3.0/modules/videos/controllers/videos.php @@ -1,7 +1,7 @@ where("task_id", "NOT IN", db::build()->select("id")->from("tasks")) + ->delete("videos_entries") + ->execute(); + $item = ORM::factory("item", $id); $view = new View("videos_tree_dialog.html"); $view->item = $item; @@ -55,6 +67,7 @@ class Videos_Controller extends Admin_Controller { } if (!is_dir($file)) { $ext = strtolower(pathinfo($file, PATHINFO_EXTENSION)); + // rWatcher Edit //if (!in_array($ext, array("gif", "jpeg", "jpg", "png", "flv", "mp4", "m4v"))) { if (!in_array($ext, unserialize(module::get_var("videos", "allowed_extensions")))) { continue; @@ -74,23 +87,28 @@ class Videos_Controller extends Admin_Controller { } /** - * Begin the task of adding files. + * Begin the task of adding photos. */ public function start() { access::verify_csrf(); $item = ORM::factory("item", Input::instance()->get("item_id")); - foreach (Input::instance()->post("paths") as $path) { - if (videos::is_valid_path($path)) { - $paths[] = array($path, null); - } - } - $task_def = Task_Definition::factory() ->callback("Videos_Controller::add") - ->description(t("Add videos from the local server")) + ->description(t("Add photos or movies from the local server")) ->name(t("Add from server")); - $task = task::create($task_def, array("item_id" => $item->id, "queue" => $paths)); + $task = task::create($task_def, array("item_id" => $item->id)); + + foreach (Input::instance()->post("paths") as $path) { + if (videos::is_valid_path($path)) { + $entry = ORM::factory("videos_entry"); + $entry->path = $path; + $entry->is_directory = intval(is_dir($path)); + $entry->parent_id = null; + $entry->task_id = $task->id; + $entry->save(); + } + } json::reply( array("result" => "started", @@ -99,7 +117,7 @@ class Videos_Controller extends Admin_Controller { } /** - * Run the task of adding files + * Run the task of adding photos */ function run($task_id) { access::verify_csrf(); @@ -119,7 +137,7 @@ class Videos_Controller extends Admin_Controller { /** * This is the task code that adds photos and albums. It first examines all the target files - * and creates a set of Server_Add_File_Models, then runs through the list of models and adds + * and creates a set of Server_Add_Entry_Models, then runs through the list of models and adds * them one at a time. */ static function add($task) { @@ -129,6 +147,7 @@ class Videos_Controller extends Admin_Controller { switch ($mode) { case "init": $task->set("mode", "build-file-list"); + $task->set("dirs_scanned", 0); $task->percent_complete = 0; $task->status = t("Starting up"); batch::start(); @@ -137,59 +156,64 @@ class Videos_Controller extends Admin_Controller { case "build-file-list": // 0% to 10% // We can't fit an arbitrary number of paths in a task, so store them in a separate table. // Don't use an iterator here because we can't get enough control over it when we're dealing - // with a deep hierarchy and we don't want to go over our time quota. The queue is in the - // form [path, parent_id] where the parent_id refers to another Server_Add_File_Model. We - // have this extra level of abstraction because we don't know its Item_Model id yet. - $queue = $task->get("queue"); + // with a deep hierarchy and we don't want to go over our time quota. $paths = unserialize(module::get_var("videos", "authorized_paths")); + $dirs_scanned = $task->get("dirs_scanned"); + while (microtime(true) - $start < 0.5) { + // Process every directory that doesn't yet have a parent id, these are the + // paths that we're importing. + $entry = ORM::factory("videos_entry") + ->where("task_id", "=", $task->id) + ->where("is_directory", "=", 1) + ->where("checked", "=", 0) + ->order_by("id", "ASC") + ->find(); - while ($queue && microtime(true) - $start < 0.5) { - list($file, $parent_entry_id) = array_shift($queue); - // Ignore the staging directories as directories to be imported. - if (empty($paths[$file])) { - $entry = ORM::factory("videos_file"); - $entry->task_id = $task->id; - $entry->file = $file; - $entry->parent_id = $parent_entry_id; - $entry->save(); - $entry_id = $entry->id; - } else { - $entry_id = null; - } - - $file = preg_quote($file); - foreach (glob("$file/*") as $child) { - if (is_dir($child)) { - $queue[] = array($child, $entry_id); - } else { - $ext = strtolower(pathinfo($child, PATHINFO_EXTENSION)); - //if (in_array($ext, array("gif", "jpeg", "jpg", "png", "flv", "mp4", "m4v")) && - if (in_array($ext, unserialize(module::get_var("videos", "allowed_extensions"))) && - filesize($child) > 0) { - $child_entry = ORM::factory("videos_file"); - $child_entry->task_id = $task->id; - $child_entry->file = $child; - $child_entry->parent_id = $entry_id; - $child_entry->save(); - } + if ($entry->loaded()) { + $child_paths = glob(preg_quote($entry->path) . "/*"); + if (!$child_paths) { + $child_paths = glob("{$entry->path}/*"); } + foreach ($child_paths as $child_path) { + if (!is_dir($child_path)) { + $ext = strtolower(pathinfo($child_path, PATHINFO_EXTENSION)); + // rWatcher Edit. + //if (!in_array($ext, array("gif", "jpeg", "jpg", "png", "flv", "mp4", "m4v")) || + // !filesize($child_path)) { + if (!in_array($ext, unserialize(module::get_var("videos", "allowed_extensions"))) || + !filesize($child_path)) { + // Not importable, skip it. + continue; + } + } + + $child_entry = ORM::factory("videos_entry"); + $child_entry->task_id = $task->id; + $child_entry->path = $child_path; + $child_entry->parent_id = $entry->id; // null if the parent was a staging dir + $child_entry->is_directory = is_dir($child_path); + $child_entry->save(); + } + + // We've processed this entry, mark it as done. + $entry->checked = 1; + $entry->save(); + $dirs_scanned++; } } // We have no idea how long this can take because we have no idea how deep the tree // hierarchy rabbit hole goes. Leave ourselves room here for 100 iterations and don't go // over 10% in percent_complete. - $task->set("queue", $queue); + $task->set("dirs_scanned", $dirs_scanned); $task->percent_complete = min($task->percent_complete + 0.1, 10); - $task->status = t2( - "Found one file", "Found %count files", - ORM::factory("videos_file")->where("task_id", "=", $task->id)->count_all()); + $task->status = t2("Scanned one directory", "Scanned %count directories", $dirs_scanned); - if (!$queue) { + if (!$entry->loaded()) { $task->set("mode", "add-files"); $task->set( "total_files", - ORM::factory("videos_file")->where("task_id", "=", $task->id)->count_all()); + ORM::factory("videos_entry")->where("task_id", "=", $task->id)->count_all()); $task->percent_complete = 10; } break; @@ -201,7 +225,7 @@ class Videos_Controller extends Admin_Controller { // Ordering by id ensures that we add them in the order that we created the entries, which // will create albums first. Ignore entries which already have an Item_Model attached, // they're done. - $entries = ORM::factory("videos_file") + $entries = ORM::factory("videos_entry") ->where("task_id", "=", $task->id) ->where("item_id", "IS", null) ->order_by("id", "ASC") @@ -220,43 +244,59 @@ class Videos_Controller extends Admin_Controller { // Look up the parent item for this entry. By now it should exist, but if none was // specified, then this belongs as a child of the current item. - $parent_entry = ORM::factory("videos_file", $entry->parent_id); + $parent_entry = ORM::factory("videos_entry", $entry->parent_id); if (!$parent_entry->loaded()) { $parent = ORM::factory("item", $task->get("item_id")); } else { $parent = ORM::factory("item", $parent_entry->item_id); } - $name = basename($entry->file); + $name = basename($entry->path); $title = item::convert_filename_to_title($name); - if (is_dir($entry->file)) { + if ($entry->is_directory) { $album = ORM::factory("item"); $album->type = "album"; $album->parent_id = $parent->id; $album->name = $name; $album->title = $title; $album->owner_id = $owner_id; + $album->sort_order = $parent->sort_order; + $album->sort_column = $parent->sort_column; $album->save(); $entry->item_id = $album->id; } else { try { $extension = strtolower(pathinfo($name, PATHINFO_EXTENSION)); - if (in_array($extension, unserialize(module::get_var("videos", "allowed_extensions")))) { + if (in_array($extension, array("gif", "png", "jpg", "jpeg"))) { + $photo = ORM::factory("item"); + $photo->type = "photo"; + $photo->parent_id = $parent->id; + $photo->set_data_file($entry->path); + $photo->name = $name; + $photo->title = $title; + $photo->owner_id = $owner_id; + $photo->save(); + $entry->item_id = $photo->id; + // rWatcher EDIT + //} else if (in_array($extension, array("flv", "mp4", "m4v"))) { + } else if (in_array($extension, unserialize(module::get_var("videos", "allowed_extensions")))) { $movie = ORM::factory("item"); $movie->type = "movie"; $movie->parent_id = $parent->id; - $movie->set_data_file($entry->file); + $movie->set_data_file($entry->path); $movie->name = $name; $movie->title = $title; $movie->owner_id = $owner_id; $movie->save(); $entry->item_id = $movie->id; + // rWatcher EDIT: Add record to items_video db. $items_video = ORM::factory("items_video"); $items_video->item_id = $movie->id; $items_video->save(); - if (file_exists($entry->file . ".flv")) { - copy($entry->file . ".flv", $movie->resize_path() . ".flv"); - list ($vid_width, $vid_height, $mime_type) = movie::get_file_metadata($entry->file . ".flv"); + // rWatcher EDIT: Scan for flv resizes and copy to resize directory. + if (file_exists($entry->path . ".flv")) { + copy($entry->path . ".flv", $movie->resize_path() . ".flv"); + list ($vid_width, $vid_height, $mime_type) = movie::get_file_metadata($entry->path . ".flv"); $movie->height = $vid_height; $movie->width = $vid_width; $movie->save(); @@ -266,12 +306,12 @@ class Videos_Controller extends Admin_Controller { // process. But just in, case.. set this to a non-null value so that we skip this // entry. $entry->item_id = 0; - $task->log("Skipping unknown file type: $entry->file"); + $task->log("Skipping unknown file type: {$entry->path}"); } } catch (Exception $e) { // This can happen if a photo file is invalid, like a BMP masquerading as a .jpg $entry->item_id = 0; - $task->log("Skipping invalid file: $entry->file"); + $task->log("Skipping invalid file: {$entry->file}"); } } @@ -290,12 +330,11 @@ class Videos_Controller extends Admin_Controller { $task->done = true; $task->state = "success"; $task->percent_complete = 100; - db::build() - ->delete("videos_files") + ORM::factory("videos_entry") ->where("task_id", "=", $task->id) - ->execute(); - message::info(t2("Successfully added one file", - "Successfully added %count files", + ->delete_all(); + message::info(t2("Successfully added one photo / album", + "Successfully added %count photos / albums", $task->get("completed_files"))); } } diff --git a/3.0/modules/videos/css/videos.css b/3.0/modules/videos/css/videos.css index 36746ab5..559e5481 100644 --- a/3.0/modules/videos/css/videos.css +++ b/3.0/modules/videos/css/videos.css @@ -1,23 +1,23 @@ -#g-server-add button { +#g-videos button { margin-bottom: .5em; } -#g-server-add-tree { +#g-videos-tree { cursor: pointer; padding-left: 4px; width: 95%; } -#g-server-add-tree li { +#g-videos-tree li { padding: 0; float: none; } -#g-server-add-tree span.selected { +#g-videos-tree span.selected { background: #ddd; } -#g-server-add-tree { +#g-videos-tree { border: 1px solid #ccc; height: 20em; overflow: auto; @@ -25,14 +25,14 @@ padding: .5em; } -#g-server-add ul ul li { +#g-videos ul ul li { padding-left: 1.2em; } -#g-server-add-paths li .ui-icon { +#g-videos-paths li .ui-icon { margin-top: .4em; } -#g-server-add-admin-form .textbox { +#g-videos-admin-form .textbox { width: 400px; } diff --git a/3.0/modules/videos/helpers/videos.php b/3.0/modules/videos/helpers/videos.php index b75e4658..f6f3240d 100644 --- a/3.0/modules/videos/helpers/videos.php +++ b/3.0/modules/videos/helpers/videos.php @@ -1,7 +1,7 @@ get("settings_menu") @@ -34,7 +38,7 @@ class videos_event_Core { is_writable($item->is_album() ? $item->file_path() : $item->parent()->file_path())) { $menu->get("add_menu") ->append(Menu::factory("dialog") - ->id("videos") + ->id("Videos") ->label(t("Add videos")) ->url(url::site("videos/browse/$item->id"))); } diff --git a/3.0/modules/videos/helpers/videos_installer.php b/3.0/modules/videos/helpers/videos_installer.php index 137df9cb..36a1b423 100644 --- a/3.0/modules/videos/helpers/videos_installer.php +++ b/3.0/modules/videos/helpers/videos_installer.php @@ -1,7 +1,7 @@ query("CREATE TABLE {videos_files} ( + $db->query("CREATE TABLE {videos_entries} ( `id` int(9) NOT NULL auto_increment, - `file` varchar(255) NOT NULL, + `checked` boolean default 0, + `is_directory` boolean default 0, `item_id` int(9), `parent_id` int(9), + `path` varchar(255) NOT NULL, `task_id` int(9) NOT NULL, PRIMARY KEY (`id`)) DEFAULT CHARSET=utf8;"); + + // rWatcher Edit: My Table. $db->query("CREATE TABLE {items_videos} ( `id` int(9) NOT NULL auto_increment, `item_id` int(9) NOT NULL, PRIMARY KEY (`id`), KEY (`item_id`, `id`)) DEFAULT CHARSET=utf8;"); + // rWatcher Edit: My Variable. module::set_var("videos", "allowed_extensions", serialize(array("avi", "mpg", "mpeg", "mov", "wmv", "asf", "mts"))); - module::set_version("videos", 1); + + module::set_version("videos", 4); videos::check_config(); } + static function upgrade($version) { + $db = Database::instance(); + + if ($version < 4) { + $db->query("DROP TABLE {videos_files}"); + $db->query("CREATE TABLE {videos_entries} ( + `id` int(9) NOT NULL auto_increment, + `checked` boolean default 0, + `is_directory` boolean default 0, + `item_id` int(9), + `parent_id` int(9), + `path` varchar(255) NOT NULL, + `task_id` int(9) NOT NULL, + PRIMARY KEY (`id`)) + DEFAULT CHARSET=utf8;"); + module::set_version("videos", $version = 4); + } + } + static function deactivate() { site_status::clear("videos_configuration"); } - - static function uninstall() { - $db = Database::instance(); - $db->query("DROP TABLE IF EXISTS {videos_files};"); - $db->query("DROP TABLE IF EXISTS {items_videos};"); - module::delete("videos"); - } } diff --git a/3.0/modules/videos/helpers/videos_theme.php b/3.0/modules/videos/helpers/videos_theme.php index 9e994591..61200985 100644 --- a/3.0/modules/videos/helpers/videos_theme.php +++ b/3.0/modules/videos/helpers/videos_theme.php @@ -1,7 +1,7 @@ admin) { - $theme->css("videos.css"); - $theme->script("videos.js"); + $buf .= $theme->css("videos.css"); + $buf .= $theme->script("videos.js"); } $item = $theme->item(); @@ -29,27 +36,26 @@ class videos_theme_Core { $items_video = ORM::factory("items_video") ->where("item_id", "=", $item->id) ->find(); - if ($items_video->loaded()) { - $view = new View("videos_display_js.html"); - //$view->embed_code = addslashes($embedded_video->embed_code); - return $view; + if (($items_video->loaded()) && (!file_exists($item->resize_path() . ".flv"))) { + $buf .= $theme->script("videos_download.js"); } } + return $buf; } static function admin_head($theme) { - $head = array(); + $buf = ""; if (strpos(Router::$current_uri, "admin/videos") !== false) { - $theme->css("videos.css"); - $theme->css("jquery.autocomplete.css"); + $buf .= $theme->css("videos.css") + . $theme->css("jquery.autocomplete.css"); $base = url::site("__ARGS__"); $csrf = access::csrf_token(); - $head[] = ""; + $buf .= ""; - $theme->script("jquery.autocomplete.js"); - $theme->script("admin_videos.js"); + $buf .= $theme->script("jquery.autocomplete.js") + . $theme->script("admin_videos.js"); // rWatcher edit. } - return implode("\n", $head); - } -} \ No newline at end of file + return $buf; + } +} diff --git a/3.0/modules/videos/js/admin_videos.js b/3.0/modules/videos/js/admin_videos.js index 9bb61ed1..2a4f462c 100644 --- a/3.0/modules/videos/js/admin_videos.js +++ b/3.0/modules/videos/js/admin_videos.js @@ -2,6 +2,11 @@ * Set up autocomplete on the server path list * */ +/** + * rWatcher Edit: This file used to be admin.js from server_add module. + * All occurences of server_add have been replaced with videos + * + */ $("document").ready(function() { $("#g-path").autocomplete( base_url.replace("__ARGS__", "admin/videos/autocomplete"), {max: 256}); diff --git a/3.0/modules/videos/js/videos.js b/3.0/modules/videos/js/videos.js index 02dda4c0..27627193 100644 --- a/3.0/modules/videos/js/videos.js +++ b/3.0/modules/videos/js/videos.js @@ -1,36 +1,41 @@ +/** + * rWatcher Edit: This file used to be server_add.js from server_add module. + * All occurences of server-add have been replaced with videos + * + */ (function($) { - $.widget("ui.gallery_server_add", { + $.widget("ui.gallery_videos", { _init: function() { var self = this; - $("#g-server-add-add-button", this.element).click(function(event) { + $("#g-videos-add-button", this.element).click(function(event) { event.preventDefault(); $(".g-progress-bar", this.element). progressbar(). progressbar("value", 0); - $("#g-server-add-progress", this.element).slideDown("fast", function() { self.start_add(); }); + $("#g-videos-progress", this.element).slideDown("fast", function() { self.start_add(); }); }); - $("#g-server-add-pause-button", this.element).click(function(event) { + $("#g-videos-pause-button", this.element).click(function(event) { self.pause = true; - $("#g-server-add-pause-button", this.element).hide(); - $("#g-server-add-continue-button", this.element).show(); + $("#g-videos-pause-button", this.element).hide(); + $("#g-videos-continue-button", this.element).show(); }); - $("#g-server-add-continue-button", this.element).click(function(event) { + $("#g-videos-continue-button", this.element).click(function(event) { self.pause = false; - $("#g-server-add-pause-button", this.element).show(); - $("#g-server-add-continue-button", this.element).hide(); + $("#g-videos-pause-button", this.element).show(); + $("#g-videos-continue-button", this.element).hide(); self.run_add(); }); - $("#g-server-add-close-button", this.element).click(function(event) { + $("#g-videos-close-button", this.element).click(function(event) { $("#g-dialog").dialog("close"); window.location.reload(); }); - $("#g-server-add-tree span.g-directory", this.element).dblclick(function(event) { + $("#g-videos-tree span.g-directory", this.element).dblclick(function(event) { self.open_dir(event); }); - $("#g-server-add-tree span.g-file, #g-server-add-tree span.g-directory", this.element).click(function(event) { + $("#g-videos-tree span.g-file, #g-videos-tree span.g-directory", this.element).click(function(event) { self.select_file(event); }); - $("#g-server-add-tree span.g-directory", this.element).dblclick(function(event) { + $("#g-videos-tree span.g-directory", this.element).dblclick(function(event) { self.open_dir(event); }); $("#g-dialog").bind("dialogclose", function(event, ui) { @@ -48,8 +53,8 @@ paths.push($(this).attr("ref")); }); - $("#g-server-add-add-button", this.element).hide(); - $("#g-server-add-pause-button", this.element).show(); + $("#g-videos-add-button", this.element).hide(); + $("#g-videos-pause-button", this.element).show(); $.ajax({ url: START_URL, @@ -77,10 +82,10 @@ $("#g-status").html(data.status); $(".g-progress-bar", self.element).progressbar("value", data.percent_complete); if (data.done) { - $("#g-server-add-progress", this.element).slideUp(); - $("#g-server-add-add-button", this.element).show(); - $("#g-server-add-pause-button", this.element).hide(); - $("#g-server-add-continue-button", this.element).hide(); + $("#g-videos-progress", this.element).slideUp(); + $("#g-videos-add-button", this.element).show(); + $("#g-videos-pause-button", this.element).hide(); + $("#g-videos-continue-button", this.element).hide(); } else { if (!self.pause) { setTimeout(function() { self.run_add(); }, 25); @@ -99,11 +104,11 @@ $.ajax({ url: GET_CHILDREN_URL.replace("__PATH__", path), success: function(data, textStatus) { - $("#g-server-add-tree", self.element).html(data); - $("#g-server-add-tree span.g-directory", self.element).dblclick(function(event) { + $("#g-videos-tree", self.element).html(data); + $("#g-videos-tree span.g-directory", self.element).dblclick(function(event) { self.open_dir(event); }); - $("#g-server-add-tree span.g-file, #g-server-add-tree span.g-directory", this.element).click(function(event) { + $("#g-videos-tree span.g-file, #g-videos-tree span.g-directory", this.element).click(function(event) { self.select_file(event); }); } @@ -115,10 +120,10 @@ */ select_file: function (event) { $(event.target).toggleClass("selected"); - if ($("#g-server-add span.selected").length) { - $("#g-server-add-add-button").enable(true).removeClass("ui-state-disabled"); + if ($("#g-videos span.selected").length) { + $("#g-videos-add-button").enable(true).removeClass("ui-state-disabled"); } else { - $("#g-server-add-add-button").enable(false).addClass("ui-state-disabled"); + $("#g-videos-add-button").enable(false).addClass("ui-state-disabled"); } } }); diff --git a/3.0/modules/videos/js/videos_download.js b/3.0/modules/videos/js/videos_download.js new file mode 100644 index 00000000..b0777ec2 --- /dev/null +++ b/3.0/modules/videos/js/videos_download.js @@ -0,0 +1,8 @@ +/** + * rWatcher Edit: This file is one of mine. + * + */ +$("document").ready(function() { + var original_url = document.getElementById('g-videos-full-url'); + $("#g-movie").replaceWith(""); +}); diff --git a/3.0/modules/videos/models/item.php b/3.0/modules/videos/models/item.php new file mode 100644 index 00000000..171d664c --- /dev/null +++ b/3.0/modules/videos/models/item.php @@ -0,0 +1,1030 @@ +loaded()) { + // Set reasonable defaults + $this->created = time(); + $this->rand_key = random::percent(); + $this->thumb_dirty = 1; + $this->resize_dirty = 1; + $this->sort_column = "created"; + $this->sort_order = "ASC"; + $this->owner_id = identity::active_user()->id; + } + } + + /** + * Add a set of restrictions to any following queries to restrict access only to items + * viewable by the active user. + * @chainable + */ + public function viewable() { + return item::viewable($this); + } + + /** + * Is this item an album? + * @return true if it's an album + */ + public function is_album() { + return $this->type == 'album'; + } + + /** + * Is this item a photo? + * @return true if it's a photo + */ + public function is_photo() { + return $this->type == 'photo'; + } + + /** + * Is this item a movie? + * @return true if it's a movie + */ + public function is_movie() { + return $this->type == 'movie'; + } + + public function delete($ignored_id=null) { + if (!$this->loaded()) { + // Concurrent deletes may result in this item already being gone. Ignore it. + return; + } + + if ($this->id == 1) { + $v = new Validation(array("id")); + $v->add_error("id", "cant_delete_root_album"); + ORM_Validation_Exception::handle_validation($this->table_name, $v); + } + + $old = clone $this; + module::event("item_before_delete", $this); + + $parent = $this->parent(); + if ($parent->album_cover_item_id == $this->id) { + item::remove_album_cover($parent); + } + + $path = $this->file_path(); + $resize_path = $this->resize_path(); + $thumb_path = $this->thumb_path(); + + parent::delete(); + if (is_dir($path)) { + // Take some precautions against accidentally deleting way too much + $delete_resize_path = dirname($resize_path); + $delete_thumb_path = dirname($thumb_path); + if ($delete_resize_path == VARPATH . "resizes" || + $delete_thumb_path == VARPATH . "thumbs" || + $path == VARPATH . "albums") { + throw new Exception( + "@todo DELETING_TOO_MUCH ($delete_resize_path, $delete_thumb_path, $path)"); + } + @dir::unlink($path); + @dir::unlink($delete_resize_path); + @dir::unlink($delete_thumb_path); + } else { + @unlink($path); + @unlink($resize_path); + @unlink($thumb_path); + } + + module::event("item_deleted", $old); + } + + /** + * Specify the path to the data file associated with this item. To actually associate it, + * you still have to call save(). + * @chainable + */ + public function set_data_file($data_file) { + $this->data_file = $data_file; + return $this; + } + + /** + * Return the server-relative url to this item, eg: + * /gallery3/index.php/BobsWedding?page=2 + * /gallery3/index.php/BobsWedding/Eating-Cake.jpg + * + * @param string $query the query string (eg "show=3") + */ + public function url($query=null) { + $url = url::site($this->relative_url()); + if ($query) { + $url .= "?$query"; + } + return $url; + } + + /** + * Return the full url to this item, eg: + * http://example.com/gallery3/index.php/BobsWedding?page=2 + * http://example.com/gallery3/index.php/BobsWedding/Eating-Cake.jpg + * + * @param string $query the query string (eg "show=3") + */ + public function abs_url($query=null) { + $url = url::abs_site($this->relative_url()); + if ($query) { + $url .= "?$query"; + } + return $url; + } + + /** + * album: /var/albums/album1/album2 + * photo: /var/albums/album1/album2/photo.jpg + */ + public function file_path() { + return VARPATH . "albums/" . urldecode($this->relative_path()); + } + + /** + * album: http://example.com/gallery3/var/resizes/album1/ + * photo: http://example.com/gallery3/var/albums/album1/photo.jpg + */ + public function file_url($full_uri=false) { + $relative_path = "var/albums/" . $this->relative_path(); + $cache_buster = $this->_cache_buster($this->file_path()); + return ($full_uri ? url::abs_file($relative_path) : url::file($relative_path)) + . $cache_buster; + } + + /** + * album: /var/resizes/album1/.thumb.jpg + * photo: /var/albums/album1/photo.thumb.jpg + */ + public function thumb_path() { + $base = VARPATH . "thumbs/" . urldecode($this->relative_path()); + if ($this->is_photo()) { + return $base; + } else if ($this->is_album()) { + return $base . "/.album.jpg"; + } else if ($this->is_movie()) { + // Replace the extension with jpg + return preg_replace("/...$/", "jpg", $base); + } + } + + /** + * Return true if there is a thumbnail for this item. + */ + public function has_thumb() { + return $this->thumb_width && $this->thumb_height; + } + + /** + * album: http://example.com/gallery3/var/resizes/album1/.thumb.jpg + * photo: http://example.com/gallery3/var/albums/album1/photo.thumb.jpg + */ + public function thumb_url($full_uri=false) { + $cache_buster = $this->_cache_buster($this->thumb_path()); + $relative_path = "var/thumbs/" . $this->relative_path(); + $base = ($full_uri ? url::abs_file($relative_path) : url::file($relative_path)); + if ($this->is_photo()) { + return $base . $cache_buster; + } else if ($this->is_album()) { + return $base . "/.album.jpg" . $cache_buster; + } else if ($this->is_movie()) { + // Replace the extension with jpg + $base = preg_replace("/...$/", "jpg", $base); + return $base . $cache_buster; + } + } + + /** + * album: /var/resizes/album1/.resize.jpg + * photo: /var/albums/album1/photo.resize.jpg + */ + public function resize_path() { + return VARPATH . "resizes/" . urldecode($this->relative_path()) . + ($this->is_album() ? "/.album.jpg" : ""); + } + + /** + * album: http://example.com/gallery3/var/resizes/album1/.resize.jpg + * photo: http://example.com/gallery3/var/albums/album1/photo.resize.jpg + */ + public function resize_url($full_uri=false) { + $relative_path = "var/resizes/" . $this->relative_path(); + $cache_buster = $this->_cache_buster($this->resize_path()); + return ($full_uri ? url::abs_file($relative_path) : url::file($relative_path)) . + ($this->is_album() ? "/.album.jpg" : "") . $cache_buster; + } + + /** + * Rebuild the relative_path_cache and relative_url_cache. + */ + private function _build_relative_caches() { + $names = array(); + $slugs = array(); + foreach (db::build() + ->select(array("name", "slug")) + ->from("items") + ->where("left_ptr", "<=", $this->left_ptr) + ->where("right_ptr", ">=", $this->right_ptr) + ->where("id", "<>", 1) + ->order_by("left_ptr", "ASC") + ->execute() as $row) { + // Don't encode the names segment + $names[] = rawurlencode($row->name); + $slugs[] = rawurlencode($row->slug); + } + $this->relative_path_cache = implode($names, "/"); + $this->relative_url_cache = implode($slugs, "/"); + return $this; + } + + /** + * Return the relative path to this item's file. Note that the components of the path are + * urlencoded so if you want to use this as a filesystem path, you need to call urldecode + * on it. + * @return string + */ + public function relative_path() { + if (!$this->loaded()) { + return; + } + + if (!isset($this->relative_path_cache)) { + $this->_build_relative_caches()->save(); + } + return $this->relative_path_cache; + } + + /** + * Return the relative url to this item's file. + * @return string + */ + public function relative_url() { + if (!$this->loaded()) { + return; + } + + if (!isset($this->relative_url_cache)) { + $this->_build_relative_caches()->save(); + } + return $this->relative_url_cache; + } + + /** + * @see ORM::__get() + */ + public function __get($column) { + if ($column == "owner") { + // This relationship depends on an outside module, which may not be present so handle + // failures gracefully. + try { + return identity::lookup_user($this->owner_id); + } catch (Exception $e) { + return null; + } + } else { + return parent::__get($column); + } + } + + /** + * Handle any business logic necessary to create or modify an item. + * @see ORM::save() + * + * @return ORM Item_Model + */ + public function save() { + $significant_changes = $this->changed; + unset($significant_changes["view_count"]); + unset($significant_changes["relative_url_cache"]); + unset($significant_changes["relative_path_cache"]); + + if ((!empty($this->changed) && $significant_changes) || isset($this->data_file)) { + $this->updated = time(); + if (!$this->loaded()) { + // Create a new item. + module::event("item_before_create", $this); + + // Set a weight if it's missing. We don't do this in the constructor because it's not a + // simple assignment. + if (empty($this->weight)) { + $this->weight = item::get_max_weight(); + } + + // Make an url friendly slug from the name, if necessary + if (empty($this->slug)) { + $tmp = pathinfo($this->name, PATHINFO_FILENAME); + $tmp = preg_replace("/[^A-Za-z0-9-_]+/", "-", $tmp); + $this->slug = trim($tmp, "-"); + + // If the filename is all invalid characters, then the slug may be empty here. Pick a + // random value. + if (empty($this->slug)) { + $this->slug = (string)rand(1000, 9999); + } + } + + // Get the width, height and mime type from our data file for photos and movies. + if ($this->is_photo() || $this->is_movie()) { + if ($this->is_photo()) { + list ($this->width, $this->height, $this->mime_type, $extension) = + photo::get_file_metadata($this->data_file); + } else if ($this->is_movie()) { + list ($this->width, $this->height, $this->mime_type, $extension) = + movie::get_file_metadata($this->data_file); + } + + // Force an extension onto the name if necessary + $pi = pathinfo($this->data_file); + if (empty($pi["extension"])) { + $this->name = "{$this->name}.$extension"; + } + } + + $this->_randomize_name_or_slug_on_conflict(); + + parent::save(); + + // Build our url caches, then save again. We have to do this after it's already been + // saved once because we use only information from the database to build the paths. If we + // could depend on a save happening later we could defer this 2nd save. + $this->_build_relative_caches(); + parent::save(); + + // Take any actions that we can only do once all our paths are set correctly after saving. + switch ($this->type) { + case "album": + mkdir($this->file_path()); + mkdir(dirname($this->thumb_path())); + mkdir(dirname($this->resize_path())); + break; + + case "photo": + case "movie": + // The thumb or resize may already exist in the case where a movie and a photo generate + // a thumbnail of the same name (eg, foo.flv movie and foo.jpg photo will generate + // foo.jpg thumbnail). If that happens, randomize and save again. + if (file_exists($this->resize_path()) || + file_exists($this->thumb_path())) { + $pi = pathinfo($this->name); + $this->name = $pi["filename"] . "-" . random::int() . "." . $pi["extension"]; + parent::save(); + } + + copy($this->data_file, $this->file_path()); + break; + } + + // This will almost definitely trigger another save, so put it at the end so that we're + // tail recursive. Null out the data file variable first, otherwise the next save will + // trigger an item_updated_data_file event. + $this->data_file = null; + module::event("item_created", $this); + } else { + // Update an existing item + module::event("item_before_update", $item); + + // If any significant fields have changed, load up a copy of the original item and + // keep it around. + $original = ORM::factory("item", $this->id); + if (array_intersect($this->changed, array("parent_id", "name", "slug"))) { + $original->_build_relative_caches(); + $this->relative_path_cache = null; + $this->relative_url_cache = null; + } + + $this->_randomize_name_or_slug_on_conflict(); + + parent::save(); + + // Now update the filesystem and any database caches if there were significant value + // changes. If anything past this point fails, then we'll have an inconsistent database + // so this code should be as robust as we can make it. + + // Update the MPTT pointers, if necessary. We have to do this before we generate any + // cached paths! + if ($original->parent_id != $this->parent_id) { + parent::move_to($this->parent()); + } + + if ($original->parent_id != $this->parent_id || $original->name != $this->name) { + // Move all of the items associated data files + @rename($original->file_path(), $this->file_path()); + if ($this->is_album()) { + @rename(dirname($original->resize_path()), dirname($this->resize_path())); + @rename(dirname($original->thumb_path()), dirname($this->thumb_path())); + } else { + @rename($original->resize_path(), $this->resize_path()); + @rename($original->thumb_path(), $this->thumb_path()); + } + + if ($original->parent_id != $this->parent_id) { + // This will result in 2 events since we'll still fire the item_updated event below + module::event("item_moved", $this, $original->parent()); + } + } + + // Changing the name, slug or parent ripples downwards + if ($this->is_album() && + ($original->name != $this->name || + $original->slug != $this->slug || + $original->parent_id != $this->parent_id)) { + db::build() + ->update("items") + ->set("relative_url_cache", null) + ->set("relative_path_cache", null) + ->where("left_ptr", ">", $this->left_ptr) + ->where("right_ptr", "<", $this->right_ptr) + ->execute(); + } + + // Replace the data file, if requested. + // @todo: we don't handle the case where you swap in a file of a different mime type + // should we prevent that in validation? or in set_data_file() + if ($this->data_file && ($this->is_photo() || $this->is_movie())) { + copy($this->data_file, $this->file_path()); + + // Get the width, height and mime type from our data file for photos and movies. + if ($this->is_photo()) { + list ($this->width, $this->height) = photo::get_file_metadata($this->file_path()); + } else if ($this->is_movie()) { + list ($this->width, $this->height) = movie::get_file_metadata($this->file_path()); + } + $this->thumb_dirty = 1; + $this->resize_dirty = 1; + } + + module::event("item_updated", $original, $this); + + if ($this->data_file) { + // Null out the data file variable here, otherwise this event will trigger another + // save() which will think that we're doing another file move. + $this->data_file = null; + module::event("item_updated_data_file", $this); + } + } + } else if (!empty($this->changed)) { + // Insignificant changes only. Don't fire events or do any special checking to try to keep + // this lightweight. + parent::save(); + } + + return $this; + } + + /** + * Check to see if there's another item that occupies the same name or slug that this item + * intends to use, and if so choose a new name/slug while preserving the extension. + * @todo Improve this. Random numbers are not user friendly + */ + private function _randomize_name_or_slug_on_conflict() { + $base_name = pathinfo($this->name, PATHINFO_FILENAME); + $base_ext = pathinfo($this->name, PATHINFO_EXTENSION); + $base_slug = $this->slug; + while (ORM::factory("item") + ->where("parent_id", "=", $this->parent_id) + ->where("id", $this->id ? "<>" : "IS NOT", $this->id) + ->and_open() + ->where("name", "=", $this->name) + ->or_where("slug", "=", $this->slug) + ->close() + ->find()->id) { + $rand = random::int(); + if ($base_ext) { + $this->name = "$base_name-$rand.$base_ext"; + } else { + $this->name = "$base_name-$rand"; + } + $this->slug = "$base_slug-$rand"; + } + } + + /** + * Return the Item_Model representing the cover for this album. + * @return Item_Model or null if there's no cover + */ + public function album_cover() { + if (!$this->is_album()) { + return null; + } + + if (empty($this->album_cover_item_id)) { + return null; + } + + try { + return model_cache::get("item", $this->album_cover_item_id); + } catch (Exception $e) { + // It's possible (unlikely) that the item was deleted, if so keep going. + return null; + } + } + + /** + * Find the position of the given child id in this album. The resulting value is 1-indexed, so + * the first child in the album is at position 1. + * + * This method stands as a backward compatibility for gallery 3.0, and will + * be deprecated in version 3.1. + */ + public function get_position($child, $where=array()) { + return item::get_position($child, $where); + } + + /** + * Return an tag for the thumbnail. + * @param array $extra_attrs Extra attributes to add to the img tag + * @param int (optional) $max Maximum size of the thumbnail (default: null) + * @param boolean (optional) $center_vertically Center vertically (default: false) + * @return string + */ + public function thumb_img($extra_attrs=array(), $max=null, $center_vertically=false) { + list ($height, $width) = $this->scale_dimensions($max); + if ($center_vertically && $max) { + // The constant is divide by 2 to calculate the file and 10 to convert to em + $margin_top = (int)(($max - $height) / 20); + $extra_attrs["style"] = "margin-top: {$margin_top}em"; + $extra_attrs["title"] = $this->title; + } + $attrs = array_merge($extra_attrs, + array( + "src" => $this->thumb_url(), + "alt" => $this->title, + "width" => $width, + "height" => $height) + ); + // html::image forces an absolute url which we don't want + return ""; + } + + /** + * Calculate the largest width/height that fits inside the given maximum, while preserving the + * aspect ratio. Don't upscale. + * @param int $max Maximum size of the largest dimension + * @return array + */ + public function scale_dimensions($max) { + $width = $this->thumb_width; + $height = $this->thumb_height; + + if ($width <= $max && $height <= $max) { + return array($height, $width); + } + + if ($height) { + if (isset($max)) { + if ($width > $height) { + $height = (int)($max * $height / $width); + $width = $max; + } else { + $width = (int)($max * $width / $height); + $height = $max; + } + } + } else { + // Missing thumbnail, can happen on albums with no photos yet. + // @todo we should enforce a placeholder for those albums. + $width = 0; + $height = 0; + } + return array($height, $width); + } + + /** + * Return an tag for the resize. + * @param array $extra_attrs Extra attributes to add to the img tag + * @return string + */ + public function resize_img($extra_attrs) { + $attrs = array_merge($extra_attrs, + array("src" => $this->resize_url(), + "alt" => $this->title, + "width" => $this->resize_width, + "height" => $this->resize_height) + ); + // html::image forces an absolute url which we don't want + return ""; + } + + /** + * Return a flowplayer - diff --git a/3.0/modules/videos/views/videos_tree.html.php b/3.0/modules/videos/views/videos_tree.html.php index 91354329..366d4fb4 100644 --- a/3.0/modules/videos/views/videos_tree.html.php +++ b/3.0/modules/videos/views/videos_tree.html.php @@ -1,4 +1,5 @@ +
  • diff --git a/3.0/modules/videos/views/videos_tree_dialog.html.php b/3.0/modules/videos/views/videos_tree_dialog.html.php index a235ffbf..a0c0f7b7 100644 --- a/3.0/modules/videos/views/videos_tree_dialog.html.php +++ b/3.0/modules/videos/views/videos_tree_dialog.html.php @@ -1,13 +1,14 @@ + -
    -

    html::purify($item->title))) ?>

    +
    +

    html::purify($item->title))) ?>

    -

    +

      parents() as $parent): ?> @@ -17,35 +18,35 @@
    • title) ?>
    -
      +
      - '; - $content .= $this->thumb_bottom($item); - $content .= ''; - - return $content; - } - - // $mode: bit 1 - use mix mode ($mode in [1, 3]), bit 2 - strips bbcode ($mode in [2, 3]) - public function bb2html($text, $mode) { - // Syntax Sample: - // -------------- - // [img]http://elouai.com/images/star.gif[/img] - // [url="http://elouai.com"]eLouai[/url] - // [size="25"]HUGE[/size] - // [color="red"]RED[/color] - // [b]bold[/b] - // [i]italic[/i] - // [u]underline[/u] - // [list][*]item[*]item[*]item[/list] - // [code]value="123";[/code] - // [quote]John said yadda yadda yadda[/quote] - - static $bbcode_mappings = array( - "#\\[b\\](.*?)\\[/b\\]#" => "$1", - "#\\[i\\](.*?)\\[/i\\]#" => "$1", - "#\\[u\\](.*?)\\[/u\\]#" => "$1", - "#\\[s\\](.*?)\\[/s\\]#" => "$1", - "#\\[o\\](.*?)\\[/o\\]#" => "$1", - "#\\[url\\](.*?)\[/url\\]#" => "$1", - "#\\[url=(.*?)\\](.*?)\[/url\\]#" => "$2", - "#\\[mail=(.*?)\\](.*?)\[/mail\\]#" => "$2", - "#\\[img\\](.*?)\\[/img\\]#" => "\"\"", - "#\\[img=(.*?)\\](.*?)\[/img\\]#" => "\"$2\"", - "#\\[quote\\](.*?)\\[/quote\\]#" => "

      $1

      ", - "#\\[code\\](.*?)\\[/code\\]#" => "
      $1
      ", - "#\\[size=([^\\[]*)\\]([^\\[]*)\\[/size\\]#" => "$2", - "#\\[color=([^\\[]*)\\]([^\\[]*)\\[/color\\]#" => "$2", - "#\\[class=([^\\[]*)\\]([^\\[]*)\\[/class\\]#" => "$2", - "#\\[center\\](.*?)\\[/center\\]#" => "
      $1
      ", - "#\\[list\\](.*?)\\[/list\\]#" => "
        $1
      ", - "#\\[ul\\](.*?)\\[/ul\\]#" => "
        $1
      ", - "#\\[li\\](.*?)\\[/li\\]#" => "
    • $1
    • ", - ); - - static $bbcode_strip = '|[[\/\!]*?[^\[\]]*?]|si'; - - // Replace any html brackets with HTML Entities to prevent executing HTML or script - // Don't use strip_tags here because it breaks [url] search by replacing & with amp - if (($mode == 1) or ($mode == 3)): - $newtext = str_replace("<", "<", $text); - $newtext = str_replace(">", ">", $newtext); - $newtext = str_replace(""", "\"", $newtext); - else: - $newtext = str_replace("<", "<", $text); - $newtext = str_replace(">", ">", $newtext); - $newtext = str_replace("&quot;", """, $newtext); - endif; - - // Convert new line chars to html
      tags - $newtext = nl2br($newtext); - - if (strpos($text, "[") !== false): - if (($mode == 2) or ($mode == 3)): - $newtext = preg_replace($bbcode_strip, '', $newtext); - else: - $newtext = preg_replace(array_keys($bbcode_mappings), array_values($bbcode_mappings), $newtext); - endif; - endif; - - return stripslashes($newtext); //stops slashing, useful when pulling from db - } -} - -?> \ No newline at end of file diff --git a/3.0/themes/greydragon/theme.info b/3.0/themes/greydragon/theme.info deleted file mode 100644 index cea1d8d0..00000000 --- a/3.0/themes/greydragon/theme.info +++ /dev/null @@ -1,6 +0,0 @@ -name = "Grey Dragon Theme" -description = "A Crisp flexible theme with support of Color Packs and minimized on JS overhead" -version = 2.3.1 -author = "2010 Serguei Dosyukov" -site = 1 -admin = 0 diff --git a/3.0/themes/greydragon/thumbnail.png b/3.0/themes/greydragon/thumbnail.png deleted file mode 100644 index 4b80ecaf..00000000 Binary files a/3.0/themes/greydragon/thumbnail.png and /dev/null differ diff --git a/3.0/themes/greydragon/views/album.html.php b/3.0/themes/greydragon/views/album.html.php deleted file mode 100644 index 49fa5cf4..00000000 --- a/3.0/themes/greydragon/views/album.html.php +++ /dev/null @@ -1,55 +0,0 @@ - -
      - album_top() ?> -

      bb2html(html::purify($item->title), 1) ?>

      -
      - -add_paginator("top"); ?> - -photo_descmode == "top") and ($item->description)): ?> -
      bb2html(html::purify($item->description), 1) ?>
      - - -
        - - $child): ?> - get_thumb_element($child, TRUE) ?> - - - admin || access::can("add", $item)): ?> - id") ?> -
      • Add some.", - array("attrs" => html::mark_clean("href=\"$addurl\" class=\"g-dialog-link\""))) ?>
      • - -
      • - - -
      -album_bottom() ?> - -photo_descmode == "bottom") and ($item->description)): ?> -
      bb2html(html::purify($item->description), 1) ?>
      - - -add_paginator("bottom"); ?> diff --git a/3.0/themes/greydragon/views/block.html.php b/3.0/themes/greydragon/views/block.html.php deleted file mode 100644 index af29546f..00000000 --- a/3.0/themes/greydragon/views/block.html.php +++ /dev/null @@ -1,33 +0,0 @@ - - - - -
      - is_blockheader_visible): ?> -

      - -
      - -
      -
      diff --git a/3.0/themes/greydragon/views/dynamic.html.php b/3.0/themes/greydragon/views/dynamic.html.php deleted file mode 100644 index 1f787cf3..00000000 --- a/3.0/themes/greydragon/views/dynamic.html.php +++ /dev/null @@ -1,39 +0,0 @@ - -
      -
      - dynamic_top() ?> -
      -

      -
      - -add_paginator("top"); ?> - -
        - $child): ?> - get_thumb_element($child) ?> - -
      -dynamic_bottom() ?> - -add_paginator("bottom"); ?> diff --git a/3.0/themes/greydragon/views/info_block.html.php b/3.0/themes/greydragon/views/info_block.html.php deleted file mode 100644 index d3860584..00000000 --- a/3.0/themes/greydragon/views/info_block.html.php +++ /dev/null @@ -1,24 +0,0 @@ - -
        - owner): ?> -
      • - - owner->url): ?> - owner->display_name()) ?> - - owner->display_name()) ?> - -
      • - - captured): ?> -
      • - - captured)?> -
      • - - description): ?> -
      • - bb2html(html::purify($item->description), 1) ?> -
      • - -
      diff --git a/3.0/themes/greydragon/views/login_ajax.html.php b/3.0/themes/greydragon/views/login_ajax.html.php deleted file mode 100644 index 76028c4e..00000000 --- a/3.0/themes/greydragon/views/login_ajax.html.php +++ /dev/null @@ -1,41 +0,0 @@ - - - -
      - - - - -
      - diff --git a/3.0/themes/greydragon/views/movie.html.php b/3.0/themes/greydragon/views/movie.html.php deleted file mode 100644 index ec870608..00000000 --- a/3.0/themes/greydragon/views/movie.html.php +++ /dev/null @@ -1,43 +0,0 @@ - -
      - photo_top() ?> - -
      -

      bb2html(html::purify($item->title), 1) ?>

      -
      bb2html(html::purify($item->description), 1) ?>
      -
      - - add_paginator("top"); ?> - -
      - resize_top($item) ?> - movie_img(array("class" => "g-movie", "id" => "g-movie-id-{$item->id}")); ?> - context_menu($item, "#g-movie-id-{$item->id}") ?> - resize_bottom($item) ?> -
      - - add_paginator("bottom"); ?> - - photo_bottom() ?> -
      diff --git a/3.0/themes/greydragon/views/no_sidebar.html.php b/3.0/themes/greydragon/views/no_sidebar.html.php deleted file mode 100644 index dd61bb77..00000000 --- a/3.0/themes/greydragon/views/no_sidebar.html.php +++ /dev/null @@ -1,24 +0,0 @@ - - 
    ?> - diff --git a/3.0/themes/greydragon/views/page.html.php b/3.0/themes/greydragon/views/page.html.php deleted file mode 100644 index 13664d65..00000000 --- a/3.0/themes/greydragon/views/page.html.php +++ /dev/null @@ -1,147 +0,0 @@ - - -load_sessioninfo(); ?> - - -enable_pagecache) and ($theme->item())): - // Page will expire in 60 seconds - header('Expires: ' . gmdate('D, d M Y H:i:s', time() + 60).'GMT'); - header("Cache-Control: public"); - header("Cache-Control: post-check=3600, pre-check=43200", false); - header("Content-Type: text/html; charset=UTF-8"); - header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT"); - endif; -?> - - -"; ?> - - - -item()): ?> -item()->is_album()): ?> - $theme->bb2html($theme->item()->title, 2))) ?> -item()->is_photo()): ?> - $theme->bb2html($theme->item()->title, 2))) ?> - - $theme->bb2html($theme->item()->title, 2))) ?> - -tag()): ?> - $theme->bb2html($theme->tag()->name, 2))) ?> - - - - -disable_seosupport): ?> - ' . "\n"; ?> - ' . "\n"; ?> - ' . "\n"; ?> - ' . "\n"; ?> - ' . "\n"; ?> - -" type="image/x-icon" /> -script("jquery.js") ?> -script("jquery.form.js") ?> -script("jquery-ui.js") ?> -page_subtype == "movie"): ?> -script("flowplayer.js") ?> - -script("gallery.ajax.js") ?> -head() ?> -" type="text/css" media="screen,print,projection" /> -color_pack . "/colors.css") ?>" type="text/css" media="screen,print,projection" /> - - - - - - - -page_top() ?> -
    - header_top() ?> - - - - - - -guest) or ($theme->show_guest_menu)): ?> -
    "> - site_menu() ?> -
    - - messages() ?> -header_bottom() ?> - -loginmenu_position == "header"): ?> - user_menu() ?> - - -show_breadcrumbs): ?> - breadcrumb_menu($theme, $parents); ?> - -
    -
    -
    - sidebar_menu($url) ?> -
    "> - - album_menu() ?> - - photo_menu() ?> - - movie_menu() ?> - - tag_menu() ?> - -
    - - sidebarvisible=="left"): ?> - ' ?> - sidebarvisible=="none"): ?> - - ' ?> - - - page_subtype != "login") and ($theme->page_subtype != "reauthenticate") and ($theme->sidebarvisible != "none")): ?> - - - sidebarvisible != "none")? "
    " : null ?> - - sidebarvisible == "left"): ?> - ' ?> - sidebarvisible == "none"): ?> - ' ?> - - ' ?> - - -
    -
    -
  • - -page_bottom() ?> - - diff --git a/3.0/themes/greydragon/views/photo.html.php b/3.0/themes/greydragon/views/photo.html.php deleted file mode 100644 index 884e30a5..00000000 --- a/3.0/themes/greydragon/views/photo.html.php +++ /dev/null @@ -1,79 +0,0 @@ - -desc_allowbbcode): ?> - bb2html($item->description, 1); ?> - - description)); ?> - - -is_photometa_visible): ?> -' . $theme->thumb_info($item) . ''; ?> - - -
    - bb2html(html::purify($item->title), 1); ?> -
    -

    -
    - add_paginator("top"); ?> - photo_top() ?> - photo_descmode == "top") and ($_description)): ?> -
    - -
    - resize_top($item) ?> - - file_url() . '" class="g-sb-preview" '; ?> - - - - resize_width; ?> - parent()->children(); ?> - -
    - rand_key != $item->rand_key)); $i++): - ?> - "> - resize_img(array("id" => "g-photo-id-{$item->id}", "class" => "g-resize", "alt" => $_title)) ?> - - - photo_descmode == "overlay") and ($_description)): ?> - More - - - - - -
    - resize_bottom($item) ?> -
    - photo_descmode == "bottom") and ($_description)): ?> -
    - - add_paginator("bottom"); ?> - photo_bottom() ?> -
    diff --git a/3.0/themes/greydragon/views/rss_block.html.php b/3.0/themes/greydragon/views/rss_block.html.php deleted file mode 100644 index 4d30ce59..00000000 --- a/3.0/themes/greydragon/views/rss_block.html.php +++ /dev/null @@ -1,13 +0,0 @@ - - diff --git a/3.0/themes/greydragon/views/search.html.php b/3.0/themes/greydragon/views/search.html.php deleted file mode 100644 index 94fc170c..00000000 --- a/3.0/themes/greydragon/views/search.html.php +++ /dev/null @@ -1,43 +0,0 @@ - -
    -

    $q)) ?>

    - - - - add_paginator("top"); ?> -
      - - is_album() ? "g-album" : "g-photo" ?> - "> ?> - get_thumb_element($item) ?> - ?> - -
    - add_paginator("bottom"); ?> - -

     

    -

    %term", array("term" => $q)) ?>

    - - -
    \ No newline at end of file diff --git a/3.0/themes/greydragon/views/sidebar.html.php b/3.0/themes/greydragon/views/sidebar.html.php deleted file mode 100644 index 0cad333d..00000000 --- a/3.0/themes/greydragon/views/sidebar.html.php +++ /dev/null @@ -1,8 +0,0 @@ - - -sidebar_top() ?> -
     
    -page_subtype == "album") or ($theme->page_subtype == "photo") or ($theme->page_subtype == "movie") or ($theme->item())): ?> -sidebar_blocks() ?> - -sidebar_bottom() ?> diff --git a/3.0/themes/greydragon/views/tag_block.html.php b/3.0/themes/greydragon/views/tag_block.html.php deleted file mode 100644 index f9bc5886..00000000 --- a/3.0/themes/greydragon/views/tag_block.html.php +++ /dev/null @@ -1,27 +0,0 @@ - - -
    "> - -
    - \ No newline at end of file diff --git a/3.0/themes/greydragon/views/user_profile.html.php b/3.0/themes/greydragon/views/user_profile.html.php deleted file mode 100644 index b7d92f40..00000000 --- a/3.0/themes/greydragon/views/user_profile.html.php +++ /dev/null @@ -1,50 +0,0 @@ - - - -
    -

    $user->display_name())) ?>

    - - - - " - alt="display_name()) ?>" - class="g-avatar g-left" width="40" height="40" /> - - - -
    -

    title) ?>

    -
    - view ?> -
    -
    - -
    diff --git a/3.0/themes/pear4gallery3/.gitignore b/3.0/themes/pear4gallery3/.gitignore new file mode 100644 index 00000000..5b4346fd --- /dev/null +++ b/3.0/themes/pear4gallery3/.gitignore @@ -0,0 +1,2 @@ +icons/depricated +temp/ diff --git a/3.0/themes/pear4gallery3/admin/controllers/admin_theme_options.php b/3.0/themes/pear4gallery3/admin/controllers/admin_theme_options.php new file mode 100644 index 00000000..999334f1 --- /dev/null +++ b/3.0/themes/pear4gallery3/admin/controllers/admin_theme_options.php @@ -0,0 +1,327 @@ + +load_theme_info(); + return ($theme_info->version); + } + + private function get_theme_name() { + $theme_info = $this->load_theme_info(); + return ($theme_info->name); + } + + private function prerequisite_check($group, $id, $is_ok, $caption, $caption_ok, $caption_failed, $iswarning, $msg_error) { + $confirmation_caption = ($is_ok)? $caption_ok : $caption_failed; + $checkbox = $group->checkbox($id) + ->label($caption . " " . $confirmation_caption) + ->checked($is_ok) + ->disabled(true); + if ($is_ok): + $checkbox->class("g-success"); + elseif ($iswarning): + $checkbox->class("g-prerequisite g-warning")->error_messages("failed", $msg_error)->add_error("failed", 1); + else: + $checkbox->class("g-error")->error_messages("failed", $msg_error)->add_error("failed", 1); + endif; + } + + /* Convert old values ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ + protected function upgrade_settings() { + if (module::get_var("th_pear4gallery3", "show_logo")): + module::clear_var("th_pear4gallery3", "show_logo"); + module::set_var("th_pear4gallery3", "hide_logo", FALSE); + endif; + } + + protected function get_edit_form_admin() { + $this->upgrade_settings(); + + $form = new Forge("admin/theme_options/save/", "", null, array("id" =>"g-theme-options-form")); + +// Just commenting out, we might want rssmodule in future versions. +// $rssmodulecheck = (module::is_active("rss") && module::info("rss")); + + /* Prerequisites ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ + + $group = $form->group("requirements")->label(t("Prerequisites")); + $gallery_ver = module::get_version("gallery"); + $this->prerequisite_check($group, "vercheck", $gallery_ver >= $this->min_gallery_ver, + t("Gallery 3 Core v.") . $this->min_gallery_ver . "+", t("Installed"), t("Required"), FALSE, sprintf(t("Check Failed. Minimum Required Version is %s. Found %s."), $this->min_gallery_ver, $gallery_ver)); + $this->prerequisite_check($group, "square_thumbs", (module::is_active("square_thumbs") and module::info("square_thumbs")), + t("Square Thumbnails"), t("Found"), t("Required"), FALSE, t("Install Square Thumbnails to display Thumbs correctly.")); + if (!module::get_var("th_pear4gallery3", "hide_thumbmeta")): + $this->prerequisite_check($group, "info", (module::is_active("info") and module::info("info")), + t("Info Module"), t("Found"), t("Required"), FALSE, t("Check Failed. Module is required to display Thumb metadata.")); + endif; + + /* General Settings ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ + + $group = $form->group("edit_theme")->label(t("General Settings")); + $group->input("favicon") + ->label(t("URL (or relative path) to your favicon.ico")) + ->value(module::get_var("gallery", "favicon_url")); + $group->input("appletouchicon") + ->label(t("URL (or relative path) to your apple-touch-icon.png")) + ->value(module::get_var("gallery", "appletouchicon_url")); + + /* Advanced Options - General ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ + + $group = $form->group("edit_theme_adv_main")->label(t("Advanced Options - General")); + $group->checkbox("hide_logo") + ->label(t("Hide Bottom Pear Logo")) + ->checked(module::get_var("th_pear4gallery3", "hide_logo")); + $group->dropdown("mainmenu_view") + ->label(t("Main page View")) + ->options(array("grid" => t("Grid (Default)"), "mosaic" => t("Mosaic"))) + ->selected(module::get_var("th_pear4gallery3", "mainmenu_view")); + $group->checkbox("show_guest_menu") + ->label(t("Show Main Menu for Guest Users")) + ->checked(module::get_var("th_pear4gallery3", "show_guest_menu")); + $group->dropdown("background") + ->label(t("Background color")) + ->options(array("black" => t("Black (Default)"), "dkgrey" => t("Dark-Grey"), "ltgrey" => t("Light-Grey"), "white" => t("White"))) + ->selected(module::get_var("th_pear4gallery3", "background")); + $group->input("ga_code") + ->label(t("Google analytics code.")) + ->value(module::get_var("th_pear4gallery3", "ga_code")); + + /* Advanced Options - Photo page ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ +/* + $group = $form->group("edit_theme_adv_photo")->label(t("Advanced Options - Photo Page")); + $group->dropdown("photo_popupbox") + ->label(t($sb_fb_caption) . " " . t("Mode")) + ->options(array("default" => t("Default (Slideshow/Preview)"), "preview" => t("Preview Only"), "none" => t("Disable"))) + ->selected(module::get_var("th_pear4gallery3", "photo_popupbox")); + $group->dropdown("photo_descmode") + ->label(t("Description Display Mode")) + ->options(array("overlay_top" => t("Overlay Top"), "overlay_bottom" => t("Overlay Bottom"), "bottom" => t("Bottom"), "top" => t("Top"), "hide" => t("Hide"))) + ->selected(module::get_var("th_pear4gallery3", "photo_descmode")); + $group->checkbox("thumb_inpage") + ->label(t("Keep Thumb Nav Block on the side")) + ->checked(module::get_var("th_pear4gallery3", "thumb_inpage")); + if (!$thumbnavcheck): + $group->thumb_inpage->disabled(true); + endif; + $group->checkbox("hide_photometa") + ->label(t("Hide Item Meta Data")) + ->checked(module::get_var("th_pear4gallery3", "hide_photometa", TRUE)); + $group->checkbox("desc_allowbbcode") + ->label(t("Allow BBCode/HTML in Descriptions")) + ->checked(module::get_var("th_pear4gallery3", "desc_allowbbcode")); +*/ + /* Maintenance ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ + + $group = $form->group("maintenance")->label(t("Maintenance")); + $group->checkbox("build_resize")->label(t("Mark all Image Resizes for Rebuild"))->checked(false); + $group->checkbox("build_thumbs")->label(t("Mark all Thumbnails for Rebuild"))->checked(false); + $group->checkbox("build_exif")->label(t("Mark Exif Info data for reload"))->checked(false); + if ($iptccheck): + $group->checkbox("build_iptc")->label(t("Mark IPTC Info data for reload"))->checked(false); + endif; + $group->checkbox("purge_cache")->label(t("Purge cache data"))->checked(false); + $group->checkbox("reset_theme")->label(t("Reset Theme to a Default State"))->checked(false); + + module::event("theme_edit_form", $form); + + $form->submit("g-theme-options-save")->value(t("Save Changes")); + + return $form; + } + + protected function get_edit_form_help() { + $help = '
    '; + $help .= 'Help
      '; + $help .= '
    • Prerequisites

      +

      Requirements need to be met for theme to function properly. +

    • '; + + $help .= '
    • General Settings

      +
    • '; + + $help .= '
    • Advanced Options - General

      +
    • '; + $help .= '
    • Advanced Options - Photo Page

      +
    • '; + $help .= '
    • Maintenance

      +

      Without changing image size, you can Mark all Resizes for Rebuild. + Then you need to visit Admin\Maintenance to initiate the process. +

      Same can be done for image thumbs with Mark all Thumbnails for Rebuild. +

      Mark Exif/IPTC Info for reload would mark all Exif or IPTC records as "Dirty" allowing it to be repopulated. +

      And just in case you think that something is not right, you can always Reset Theme to a Default State. +

    • '; + $help .= '
    '; + return t($help); + } + + private function save_item_state($statename, $state, $value) { + if ($state): + module::set_var("th_pear4gallery3", $statename, $value); + else: + module::clear_var("th_pear4gallery3", $statename); + endif; + } + + protected function legacy() { + module::clear_var("th_pear4gallery3", "hide_logo"); + module::clear_var("th_pear4gallery3", "mainmenu_view"); + module::clear_var("th_pear4gallery3", "show_guest_menu"); + module::clear_var("th_pear4gallery3", "background"); + module::clear_var("th_pear4gallery3", "ga_code"); + } + + protected function reset_theme() { + // Default core theme settings + module::set_var("gallery", "page_size", 9); + module::set_var("gallery", "resize_size", 640); + module::set_var("gallery", "thumb_size", 200); + module::set_var("gallery", "header_text", ""); + module::set_var("gallery", "footer_text", ""); + module::set_var("gallery", "show_credits", FALSE); + module::clear_all_vars("th_pear4gallery3"); + module::clear_var("th_pear4gallery3", "hide_logo"); + } + + public function save() { + site_status::clear("gd_init_configuration"); + access::verify_csrf(); + + $form = self::get_edit_form_admin(); + + if ($form->validate()): + $this->legacy(); + + if ($form->maintenance->reset_theme->value): + $this->reset_theme(); + module::event("theme_edit_form_completed", $form); + message::success(t("Theme details are reset")); + else: + // * General Settings **************************************************** + + $resize_size = 800; + + $build_resize = $form->maintenance->build_resize->value; + $build_thumbs = $form->maintenance->build_thumbs->value; + $build_exif = $form->maintenance->build_exif->value; + if (module::is_active("iptc") and module::info("iptc")): + $build_iptc = $form->maintenance->build_iptc->value; + else: + $build_iptc = FALSE; + endif; + $purge_cache = $form->maintenance->purge_cache->value; + + $thumb_descmode_a = $form->edit_theme_adv_thumb->thumb_descmode_a->value; + $thumb_descmode = $form->edit_theme_adv_thumb->thumb_descmode->value; + $thumb_metamode = $form->edit_theme_adv_thumb->thumb_metamode->value; + $photo_descmode = $form->edit_theme_adv_photo->photo_descmode->value; + $photo_popupbox = $form->edit_theme_adv_photo->photo_popupbox->value; + + if ($build_resize): + graphics::remove_rule("gallery", "resize", "gallery_graphics::resize"); + graphics::add_rule("gallery", "resize", "gallery_graphics::resize", + array("width" => $resize_size, "height" => $resize_size, "master" => Image::AUTO), 100); + endif; + + if (module::get_var("gallery", "resize_size") != $resize_size): + module::set_var("gallery", "resize_size", $resize_size); + endif; + + $thumb_size = 200; + $rule = Image::AUTO; + + if ($build_thumbs): + graphics::remove_rule("gallery", "thumb", "gallery_graphics::resize"); + graphics::add_rule("gallery", "thumb", "gallery_graphics::resize", + array("width" => $thumb_size, "height" => $thumb_size, "master" => $rule), 100); + endif; + + if (module::get_var("gallery", "thumb_size") != $thumb_size): + module::set_var("gallery", "thumb_size", $thumb_size); + endif; + + module::set_var("gallery", "page_size", 50); + module::set_var("gallery", "favicon_url", $form->edit_theme->favicon->value); + module::set_var("gallery", "appletouchicon_url", $form->edit_theme->appletouchicon->value); + + $this->save_item_state("logo_path", $form->edit_theme->logo_path->value, $form->edit_theme->logo_path->value); + + // * Advanced Options - General ****************************************** + + $this->save_item_state("hide_logo", $form->edit_theme_adv_main->hide_logo->value, TRUE); + $this->save_item_state("mainmenu_view", $form->edit_theme_adv_main->mainmenu_view->value != "grid", $form->edit_theme_adv_main->mainmenu_view->value); + $this->save_item_state("show_guest_menu",$form->edit_theme_adv_main->show_guest_menu->value, TRUE); + $this->save_item_state("background", $form->edit_theme_adv_main->background->value != "black", $form->edit_theme_adv_main->background->value); + $this->save_item_state("ga_code", $form->edit_theme_adv_main->ga_code->value, $form->edit_theme_adv_main->ga_code->value); + + // * Advanced Options - Photo page *************************************** + /* + $this->save_item_state("photo_descmode", $photo_descmode != "overlay_top", $photo_descmode); + $this->save_item_state("photo_popupbox", $photo_popupbox != "default", $photo_popupbox); + $this->save_item_state("thumb_inpage", $form->edit_theme_adv_photo->thumb_inpage->value, TRUE); + $this->save_item_state("hide_photometa", !$form->edit_theme_adv_photo->hide_photometa->value, FALSE); + $this->save_item_state("desc_allowbbcode", $form->edit_theme_adv_photo->desc_allowbbcode->value, TRUE); +*/ + + module::event("theme_edit_form_completed", $form); + + if ($_priorratio != $thumb_ratio): + message::warning(t("Thumb aspect ratio has been changed. Consider rebuilding thumbs if needed.")); + endif; + + message::success(t("Updated theme details")); + + if ($build_exif): + db::update('exif_records') + ->set(array('dirty'=>'1')) + ->execute(); + endif; + + if ($build_iptc): + db::update('iptc_records') + ->set(array('dirty'=>'1')) + ->execute(); + endif; + + if ($purge_cache): + db::build() + ->delete("caches") + ->execute(); + endif; + endif; + url::redirect("admin/theme_options"); + else: + print $this->get_admin_view(); + endif; + } + + protected function get_admin_view() { + $view = new Admin_View("admin.html"); + $view->page_title = t(".Pear Theme"); + $view->content = new View("admin_theme_options.html"); + $view->content->name = self::get_theme_name(); + $view->content->version = self::get_theme_version(); + $view->content->form = self::get_edit_form_admin(); + $view->content->help = self::get_edit_form_help(); + return $view; + } + + public function index() { + site_status::clear("gd_init_configuration"); + print $this->get_admin_view(); + } +} +?> diff --git a/3.0/themes/pear4gallery3/admin/views/admin_include.html.php b/3.0/themes/pear4gallery3/admin/views/admin_include.html.php new file mode 100644 index 00000000..8d818bb7 --- /dev/null +++ b/3.0/themes/pear4gallery3/admin/views/admin_include.html.php @@ -0,0 +1,90 @@ + + + + + +version / 10, 1, '.', ''); + else: + $admin_info = new ArrayObject(parse_ini_file(THEMEPATH . $name . "/theme.info"), ArrayObject::ARRAY_AS_PROPS); + $version = $admin_info->version; + endif; +?> + +
    +
    +
    name) ?> -
    + +
    +
    + +
    +
    + +
    +
    diff --git a/3.0/themes/pear4gallery3/admin/views/admin_theme_options.html.php b/3.0/themes/pear4gallery3/admin/views/admin_theme_options.html.php new file mode 100644 index 00000000..a0894dc2 --- /dev/null +++ b/3.0/themes/pear4gallery3/admin/views/admin_theme_options.html.php @@ -0,0 +1,14 @@ + +is_module = FALSE; + $view->name = module::get_var("gallery", "active_site_theme"); + $view->form = $form; + $view->help = $help; + print $view; +?> + diff --git a/3.0/themes/pear4gallery3/css/fix-ie.css b/3.0/themes/pear4gallery3/css/fix-ie.css new file mode 100644 index 00000000..0633ff07 --- /dev/null +++ b/3.0/themes/pear4gallery3/css/fix-ie.css @@ -0,0 +1,59 @@ +/** + * Fix display in IE 6, 7, and 8 + */ + +#g-banner { + z-index: 2; + zoom: 1; +} + +#g-sidebar { + overflow: hidden; +} + +#g-photo, +#g-movie { + zoom: 1; +} + +#g-photo .g-context-menu, +#g-movie .g-context-menu { + width: 240px; +} + +input.submit { + clear: none !important; + display: inline !important; +} + +.g-short-form input.text, +.g-short-form input.submit { + font-size: 1em; + line-height: 1em; + padding: .38em .3em; +} + +#g-search-form input#q { + width: 300px; +} + +#g-add-tag-form input.textbox { + width: 110px !important; +} + +#g-add-tag-form input[type='submit'] { + padding: .3em 0 !important; +} + +#g-dialog .g-cancel { + display: inline-block !important; + float: none !important; +} + +.g-paginator .g-text-right { + width: 29%; +} + +.g-paginator .ui-icon-right { + width: 60px; +} diff --git a/3.0/themes/pear4gallery3/css/imageflow.packed.css b/3.0/themes/pear4gallery3/css/imageflow.packed.css new file mode 100644 index 00000000..b0c52141 --- /dev/null +++ b/3.0/themes/pear4gallery3/css/imageflow.packed.css @@ -0,0 +1 @@ +@charset "utf-8"; @media screen, projection{.imageflow{overflow:hidden; position:relative; text-align:left; visibility:hidden; width:100%}.imageflow img{border:none; position:absolute; top:0px; visibility:hidden; -ms-interpolation-mode:bicubic}.imageflow p{margin:0 auto; text-align:center}.imageflow .loading{border:1px solid white; height:15px; left:50%; margin-left:-106px; padding:5px; position:relative; visibility:visible; width:200px}.imageflow .loading_bar{background:#fff; height:15px; visibility:visible; width:1%}.imageflow .navigation{z-index:10000}.imageflow .caption{font-weight:bold; position:relative; text-align:center; z-index:10001}.imageflow .scrollbar{border-bottom:1px solid #b3b3b3; position:relative; visibility:hidden; z-index:10002; height:1px}.imageflow .slider{background:url(../icons/slider.png) no-repeat; height:14px; margin:-6px 0 0 -7px; position:absolute; width:14px; z-index:10003}.imageflow .slideshow{cursor:pointer; height:14px; margin:20px 0 0 20px; position:absolute; width:14px; z-index:10003}.imageflow .slideshow.pause{background:url(../icons/button_pause.png) no-repeat}.imageflow .slideshow.play{background:url(../icons/button_play.png) no-repeat}.imageflow .images{overflow:hidden; white-space:nowrap}.imageflow .button{cursor:pointer; height:17px; position:relative; width:17px}.imageflow .previous{background:url(../icons/button_left.png) top left no-repeat; float:left; margin:-7px 0 0 -30px}.imageflow .next{background:url(../icons/button_right.png) top left no-repeat; float:right; margin:-7px -30px 0 30px}} diff --git a/3.0/themes/pear4gallery3/css/pear.css b/3.0/themes/pear4gallery3/css/pear.css new file mode 100644 index 00000000..475a0757 --- /dev/null +++ b/3.0/themes/pear4gallery3/css/pear.css @@ -0,0 +1,145 @@ +.gallery-thumb { + float: left; + margin-bottom: 5px; + margin-left: 5px; + margin-right: 5px; + position: relative; + text-align: center; + cursor: pointer; +} + +.gallery-album { + display: block; + height: 400px; + overflow: auto; + padding-bottom: 10px; + padding-top: 10px; +} + +th, td { + padding: 0; + border-width: 0; +} + +.giInfo { + color: #888888; + font-family: Verdana, Arial, Helvetica, sans-serif; + font-size: 9px; + height: 11px; + margin-bottom: 0px; + margin-left: 12px; + margin-right: 0px; + text-align: left; +} +.pear { + font-family: Verdana, Arial, Helvetica, sans-serif; + font-size: 10px; + color: #999 !important; + background-color: #000; +} +.giTitle { + font-size: 1.1em; + font-weight: bold; + margin: 3px 10px !important; + padding: 0 0; + text-align: left; +} + +#gsNavBar div { +font-weight: bold; +} + +h2 { + font-size: 1.1em; + font-weight: bold; +} + +.center { + text-align: center !important; +} + +#g-header { + margin-top: -2px; + position: fixed; + top: 44px; + width: 100%; + z-index: 50; +} +/*Menu*/ +.sf-menu li:hover, .sf-menu li.sfHover, .sf-menu a:focus, .sf-menu a:hover, .sf-menu a:active { + background: none repeat scroll 0 0 #333333; + outline: 0 none; +} +.sf-menu li { + background: none repeat scroll 0 0 #000000; + float: left; + position: relative; +} +.sf-menu li li, .sf-menu li li ul li { + background-color: #000; +} +.sf-menu ul { + background: none repeat scroll 0 0 #000000; +} +.sf-menu, .sf-menu * { + list-style: none outside none; + margin: 0; + padding: 0; +} +a, .g-menu a, #g-dialog a, .g-button, .g-button:hover, .g-button:active, a.ui-state-hover, input.ui-state-hover, button.ui-state-hover { + color: #777777 !important; + cursor: pointer !important; + text-decoration: none; +} +.sf-menu a, .sf-menu a:visited { + color: #555555; +} +.sf-menu a { + border-left: 1px solid #333; + border-top: 1px solid #222; + padding: 0.75em 1em; + text-decoration: none; + display: block; + position: relative; +} +.ui-state-default, .ui-widget-content .ui-state-default { + background: #ccc; + border: 1px solid #C5DBEC; + color: #555 + font-weight: bold; + outline: medium none; +} +#g-banner { + background-color: #555; + border-bottom: 1px solid #333333; + min-height: 5em; + padding: 1em 20px; + position: relative; +} + +.g-paginator { + margin-bottom: 5px; + margin-left: 15px; + margin-right: 15px; + padding-top: 6px; +} + +a.buttonFirst { background-position: 0px 0px !important; } +a.buttonFirst:hover { background-position: -15px 0px !important; } +a.buttonPrev { background-position: 0px -15px !important; } +a.buttonPrev:hover { background-position: -15px -15px !important; } +a.buttonNext { background-position: 0px -30px !important;} +a.buttonNext:hover { background-position: -15px -30px !important;} +a.buttonLast { background-position: 0px -45px !important; } +a.buttonLast:hover { background-position: -15px -45px !important; } + +a.buttonNext, a.buttonLast { float: right; } +a.buttonFirst, a.buttonPrev { float: left; } + +.g-paginator .buttonAction { + background: url("../icons/paginator.gif") no-repeat 0 0; + height: 15px; + width: 15px; + margin-left: 0; + display: block; +} diff --git a/3.0/themes/pear4gallery3/css/screen.css b/3.0/themes/pear4gallery3/css/screen.css new file mode 100644 index 00000000..6bac8319 --- /dev/null +++ b/3.0/themes/pear4gallery3/css/screen.css @@ -0,0 +1,1358 @@ +/** + * Gallery 3 Wind Theme Screen Styles + * + * @requires YUI reset, font, grids CSS + * + * Sheet organization: + * 1) Font sizes, base HTML elements + * 2) Reusable content blocks + * 3) Page layout containers + * 4) Content blocks in specific layout containers + * 5) States and interactions + * 6) Positioning and order + * 7) Navigation and menus + * 8) jQuery and jQuery UI + * 9) Right-to-left language styles + */ + +/** ******************************************************************* + * 1) Font sizes, base HTML elements + **********************************************************************/ + +body, html { + background-color: #ccc; + font-family: 'Lucida Grande', 'Lucida Sans', Arial, sans-serif; +} + +p { + margin-bottom: 1em; +} + +em { + font-style: oblique; +} + +h1, h2, h3, h4, h5, strong, th { + font-weight: bold; +} + +h1 { + font-size: 1.7em; +} + +#g-dialog h1 { + font-size: 1.1em; +} + +h2 { + font-size: 1.4em; +} + +#g-sidebar .g-block h2 { + font-size: 1.2em; +} + +#g-sidebar .g-block li { + margin-bottom: .6em; +} + +#g-content, +#g-site-menu, +h3 { + font-size: 1.2em; +} + +#g-sidebar, +.g-breadcrumbs { + font-size: .9em; +} + +#g-banner, +#g-footer, +.g-message { + font-size: .8em; +} + +#g-album-grid .g-item, +#g-item #g-photo, +#g-item #g-movie { + font-size: .7em; +} + +/* Links ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ + +a, +.g-menu a, +#g-dialog a, +.g-button, +.g-button:hover, +.g-button:active, +a.ui-state-hover, +input.ui-state-hover, +button.ui-state-hover { + color: #5382bf !important; + cursor: pointer !important; + text-decoration: none; + -moz-outline-style: none; +} + +a:hover, +#g-dialog a:hover { + text-decoration: underline; +} + +.g-menu a:hover { + text-decoration: none; +} + +#g-dialog #g-action-status li { + width: 400px; + white-space: normal; + padding-left: 32px; +} + +/* Forms ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ +form { + margin: 0; +} + +fieldset { + border: 1px solid #ccc; + padding: 0 1em .8em 1em; +} + +#g-banner fieldset, +#g-sidebar fieldset { + border: none; + padding: 0; +} + +legend { + font-weight: bold; + margin: 0; + padding: 0 .2em; +} + +#g-banner legend, +#g-sidebar legend, +input[type="hidden"] { + display: none; +} + +input.textbox, +input[type="text"], +input[type="password"], +textarea { + border: 1px solid #e8e8e8; + border-top-color: #ccc; + border-left-color: #ccc; + clear: both; + color: #333; + width: 50%; +} + +textarea { + height: 12em; + width: 97%; +} + +input:focus, +input.textbox:focus, +input[type=text]:focus, +textarea:focus, +option:focus { + background-color: #ffc; + color: #000; +} + +input.checkbox, +input[type=checkbox], +input.radio, +input[type=radio] { + float: left; + margin-right: .4em; +} + +/* Form layout ~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ + +form li { + margin: 0; + padding: 0 0 .2em 0; +} + +form ul { + margin-top: 0; +} + +form ul ul { + clear: both; +} + +form ul ul li { + float: left; +} + +input, +select, +textarea { + display: block; + clear: both; + padding: .2em; +} + +input[type="submit"], +input[type="reset"] { + display: inline; + clear: none; + float: left; +} + +/* Forms in dialogs and panels ~~~~~~~~~ */ + +#g-dialog ul li { + padding-bottom: .8em; +} + +#g-dialog fieldset, +#g-panel fieldset { + border: none; + padding: 0; +} + +#g-panel legend { + display: none; +} + +input[readonly] { + background-color: #F4F4FC; +} + +#g-dialog input.textbox, +#g-dialog input[type=text], +#g-dialog input[type=password], +#g-dialog textarea { + width: 97%; +} + +/* Short forms ~~~~~~~~~~~~~~~~~~~~~~~ */ + +.g-short-form legend, +.g-short-form label { + display: none; +} + +.g-short-form fieldset { + border: none; + padding: 0; +} + +.g-short-form li { + float: left; + margin: 0 !important; + padding: .4em 0; +} + +.g-short-form .textbox, +.g-short-form input[type=text] { + color: #666; + padding: .3em .6em; + width: 100%; +} + +.g-short-form .textbox.g-error { + border: 1px solid #f00; + color: #f00; + padding-left: 24px; +} + +.g-short-form .g-cancel { + display: block; + margin: .3em .8em; +} + +#g-sidebar .g-short-form li { + padding-left: 0; + padding-right: 0; +} + +/* Tables ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ + +table { + width: 100%; +} + +#g-content table { + margin: 1em 0; +} + +caption, +th { + text-align: left; +} + +th, +td { + border: none; + border-bottom: 1px solid #ccc; + padding: .5em; +} + +td { + vertical-align: top; +} + +/* Text ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ +.g-text-small { + font-size: .8em; +} + +.g-text-big { + font-size: 1.2em; +} + +.g-text-right { + text-align: right; +} + +/** ******************************************************************* + * 2) Reusable content blocks + *********************************************************************/ + +.g-block h2 { + background-color: #e8e8e8; + padding: .3em .8em; +} + +.g-block-content { + margin-top: 1em; +} + +/** ******************************************************************* + * 3) Page layout containers + *********************************************************************/ + +/* Dimension and scale ~~~~~~~~~~~~~~~~~~~ */ +.g-one-quarter { + width: 25%; +} + +.g-one-third { + width: 33%; +} + +.g-one-half { + width: 50%; +} + +.g-two-thirds { + width: 66%; +} + +.g-three-quarters { + width: 75%; +} + +.g-whole { + width: 100%; +} + +/* View container ~~~~~~~~~~~~~~~~~~~~~~~~ */ + +.g-view { + background-color: #fff; + border: 1px solid #ccc; + border-bottom: none; +} + +/* Layout containers ~~~~~~~~~~~~~~~~~~~~~ */ + +#g-header { + margin-bottom: 1em; +} + +#g-banner { + background-color: #e8e8e8; + border-bottom: 1px solid #ccc; + min-height: 5em; + padding: 1em 20px; + position: relative; +} + +#g-content { + padding-left: 20px; + position: relative; + width: 696px; +} + +#g-sidebar { + padding: 0 20px; + width: 220px; +} + +#g-footer { + background-color: #e8e8e8; + border-top: 1px solid #ccc; + margin-top: 20px; + padding: 10px 20px; +} + +/** ******************************************************************* + * 4) Content blocks in specific layout containers + *********************************************************************/ + +/* Header ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ + +#g-banner #g-quick-search-form { + clear: right; + float: right; + margin-top: 1em; +} + +#g-banner #g-quick-search-form input[type='text'] { + width: 17em; +} + +#g-content .g-block h2 { + background-color: transparent; + padding-left: 0; +} + +/* Sidebar ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ + +#g-sidebar .g-block-content { + padding-left: 1em; +} + +#g-sidebar #g-image-block { + overflow: hidden; +} + +/* Album content ~~~~~~~~~~~~~~~~~~~~~~~~~ */ + +#g-content #g-album-grid { + margin: 1em 0; + position: relative; + z-index: 1; +} + +#g-content #g-album-grid .g-item { + background-color: #fff; + border: 1px solid #fff; + float: left; + padding: .6em 8px; + position: relative; + text-align: center; + width: 213px; + z-index: 1; +} + +#g-content #g-album-grid .g-item h2 { + margin: 5px 0; +} + +#g-content .g-photo h2, +#g-content .g-item .g-metadata { + display: none; + margin-bottom: .6em; +} + +#g-content #g-album-grid .g-album { + background-color: #e8e8e8; +} + +#g-content #g-album-grid .g-album h2 span.g-album { + background: transparent url('../images/ico-album.png') no-repeat top left; + display: inline-block; + height: 16px; + margin-right: 5px; + width: 16px; +} + +#g-content #g-album-grid .g-hover-item { + border: 1px solid #000; + position: absolute !important; + z-index: 1000 !important; +} + +#g-content .g-hover-item h2, +#g-content .g-hover-item .g-metadata { + display: block; +} + +#g-content #g-album-grid #g-place-holder { + position: relative; + visibility: hidden; + z-index: 1; +} + +/* Search results ~~~~~~~~~~~~~~~~~~~~~~~~ */ + +#g-content #g-search-results { + margin-top: 1em; + padding-top: 1em; +} + +/* Individual photo content ~~~~~~~~~~~~~~ */ + +#g-item { + position: relative; + width: 100%; +} + +#g-item #g-photo, +#g-item #g-movie { + padding: 2.2em 0; + position: relative; +} + +#g-item img.g-resize, +#g-item a.g-movie { + display: block; + margin: 0 auto; +} + +/* Footer content ~~~~~~~~~~~~~~~~~~~~~~~~ */ + +#g-footer #g-credits li { + padding-right: 1.2em; +} + +/* In-line editing ~~~~~~~~~~~~~~~~~~~~~~ */ + +#g-in-place-edit-message { + background-color: #fff; +} + +/* Permissions ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ +#g-edit-permissions-form td { + background-image: none; +} + +#g-edit-permissions-form fieldset { + border: 1px solid #ccc; +} + +#g-permissions .g-denied { + background-color: #fcc; +} + +#g-permissions .g-allowed { + background-color: #cfc; +} + +#g-permissions .g-breadcrumbs a { + border: 1px solid #fff; +} + +#g-permissions .g-active a { + border: 1px solid #ddd; + background: #eee; +} + +/** ******************************************************************* + * 5) States and interactions + **********************************************************************/ + +.g-active, +.g-enabled, +.g-available, +.g-selected, +.g-highlight { + font-weight: bold; +} + +.g-inactive, +.g-disabled, +.g-unavailable, +.g-uneditable, +.g-locked, +.g-deselected, +.g-understate { + color: #ccc; + font-weight: normal; +} + +.g-editable { + padding: .2em .3em; +} + +.g-editable:hover { + background-color: #ffc; + cursor: text; +} + +.g-error, +.g-info, +.g-success, +.g-warning { + padding-left: 30px; +} + +form li.g-error, +form li.g-info, +form li.g-success, +form li.g-warning { + background-image: none; + padding: .3em .8em .3em 0; +} + +.g-short-form li.g-error { + padding: .3em 0; +} + +form.g-error input[type="text"], +li.g-error input[type="text"], +form.g-error input[type="password"], +li.g-error input[type="password"], +form.g-error input[type="checkbox"], +li.g-error input[type="checkbox"], +form.g-error input[type="radio"], +li.g-error input[type="radio"], +form.g-error textarea, +li.g-error textarea, +form.g-error select, +li.g-error select { + border: 2px solid #f00; + margin-bottom: .2em; +} + +.g-error, +.g-denied, +tr.g-error td.g-error, +#g-add-photos-status .g-error { + background: #f6cbca url('../images/ico-error.png') no-repeat .4em 50%; + color: #f00; +} + +.g-info { + background: #e8e8e8 url('../images/ico-info.png') no-repeat .4em 50%; +} + +.g-success, +.g-allowed, +#g-add-photos-status .g-success { + background: #d9efc2 url('../images/ico-success.png') no-repeat .4em 50%; +} + +tr.g-success { + background-image: none; +} + +tr.g-success td.g-success { + background-image: url('../images/ico-success.png'); +} + +.g-warning, +tr.g-warning td.g-warning { + background: #fcf9ce url('../images/ico-warning.png') no-repeat .4em 50%; +} + +form .g-error { + background-color: #fff; + padding-left: 20px; +} + +.g-open { +} + +.g-closed { +} + +.g-installed { + background-color: #eeeeee; +} + +.g-default { + background-color: #c5dbec; + font-weight: bold; +} + +.g-draggable { + cursor: move; +} + +.g-draggable:hover { + border: 1px dashed #000; +} + +.ui-sortable .g-target, +.ui-state-highlight { + background-color: #fcf9ce; + border: 2px dotted #999; + height: 2em; + margin: 1em 0; +} + +/* Ajax loading indicator ~~~~~~~~~~~~~~~~ */ + +.g-loading-large, +.g-dialog-loading-large { + background: #e8e8e8 url('../images/loading-large.gif') no-repeat center center !important; +} + +.g-loading-small { + background: #e8e8e8 url('../images/loading-small.gif') no-repeat center center !important; +} + +/** ******************************************************************* + * 6) Positioning and order + **********************************************************************/ + +.g-left { + clear: none; + float: left; +} + +.g-right { + clear: none; + float: right; +} + +.g-first { +} + +.g-last { +} + +.g-even { + background-color: #fff; +} + +.g-odd { + background-color: #eee; +} + +/** ******************************************************************* + * 7) Navigation and menus + *********************************************************************/ + +/* Login menu ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ + +#g-banner #g-login-menu { + color: #999; + float: right; +} + +#g-banner #g-login-menu li { + padding-left: 1.2em; +} + +/* Site Menu ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ + +#g-site-menu { + bottom: 0; + left: 140px; + position: absolute; +} + +#g-site-menu ul { + margin-bottom: 0 !important; +} + +/* Context Menu ~~~~~~~~~~~~~~~~~~~~~~~~~ */ + +.g-context-menu { + background-color: #fff; + bottom: 0; + left: 0; + position: absolute; +} + +.g-item .g-context-menu { + display: none; + margin-top: 2em; + width: 100%; +} + +#g-item .g-context-menu ul { + display: none; +} + +.g-context-menu li { + border-left: none; + border-right: none; + border-bottom: none; +} + +.g-context-menu li a { + display: block; + line-height: 1.6em; +} + +.g-hover-item .g-context-menu { + display: block; +} + +.g-hover-item .g-context-menu li { + text-align: left; +} + +.g-hover-item .g-context-menu a:hover { + text-decoration: none; +} + +/* View Menu ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ + +#g-view-menu { + margin-bottom: 1em; +} + +#g-view-menu a { + background-repeat: no-repeat; + background-position: 50% 50%; + height: 28px !important; + width: 43px !important; +} + +#g-view-menu #g-slideshow-link { + background-image: url('../images/ico-view-slideshow.png'); +} + +#g-view-menu .g-fullsize-link { + background-image: url('../images/ico-view-fullsize.png'); +} + +#g-view-menu #g-comments-link { + background-image: url('../images/ico-view-comments.png'); +} + +#g-view-menu #g-print-digibug-link { + background-image: url('../images/ico-print.png'); +} + +/** ******************************************************************* + * 8) jQuery and jQuery UI + *********************************************************************/ +/* Generic block container ~~~~~~~~~~~~~~~ */ + +.g-block { + clear: both; + margin-bottom: 2.5em; +} + +.g-block-content { +} + +/* Superfish menu overrides ~~~~~~~~~~~~~~ */ +.sf-menu ul { + width: 12em; +} + +ul.sf-menu li li:hover ul, +ul.sf-menu li li.sfHover ul { + left: 12em; +} + +ul.sf-menu li li li:hover ul, +ul.sf-menu li li li.sfHover ul { + left: 12em; +} + +.sf-menu li li, +.sf-menu li li ul li { + background-color: #bdd2ff; +} + +.sf-menu li:hover { + background-color: #dfe9ff; +} + +/* jQuery UI Dialog ~~~~~~~~~~~~~~~~~~~~~~ */ + +.ui-widget-overlay { + background: #000; + opacity: .7; +} + +/* Buttons ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ + +.g-button { + display: inline-block; + margin: 0 4px 0 0; + padding: .2em .4em; +} + +.g-button, +.g-button:hover, +.g-button:active { + cursor: pointer !important; + outline: 0; + text-decoration: none; + -moz-outline-style: none; +} + +button { + padding: 2px 4px 2px 4px; +} + +/* jQuery UI ThemeRoller buttons ~~~~~~~~~ */ + +.g-buttonset { + padding-left: 1px; +} + +.g-buttonset li { + float: left; +} + +.g-buttonset .g-button { + margin: 0; +} + +.ui-icon-left .ui-icon { + float: left; + margin-right: .2em; +} + +.ui-icon-right .ui-icon { + float: right; + margin-left: .2em; +} + +/* Rotate icon, ThemeRoller only provides one of these */ + +.ui-icon-rotate-ccw { + background-position: -192px -64px; +} + +.ui-icon-rotate-cw { + background-position: -208px -64px; +} + +.g-progress-bar { + height: 1em; + width: 100%; + margin-top: .5em; + display: inline-block; +} + +/* Status and validation messages ~~~~ */ + +.g-message-block { + background-position: .4em .3em; + border: 1px solid #ccc; + padding: 0; +} + +#g-action-status { + margin-bottom: 1em; +} + +#g-action-status li, +p#g-action-status, +div#g-action-status { + padding: .3em .3em .3em 30px; +} + +#g-site-status li { + border-bottom: 1px solid #ccc; + padding: .3em .3em .3em 30px; +} + +.g-module-status { + clear: both; + margin-bottom: 1em; +} + +.g-message { + background-position: 0 50%; +} + +/* Breadcrumbs ~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ + +.g-breadcrumbs { + clear: both; + padding: 0 20px; +} + +.g-breadcrumbs li { + background: transparent url('../images/ico-separator.gif') no-repeat scroll left center; + float: left; + padding: 1em 8px 1em 18px; +} + +.g-breadcrumbs .g-first { + background: none; + padding-left: 0; +} + +.g-breadcrumbs li a, +.g-breadcrumbs li span { + display: block; +} + +#g-dialog ul.g-breadcrumbs { + margin-left: 0; + padding-left: 0; +} + +/* Pagination ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ + + +.g-paginator li { + float: left; + width: 30%; +} + +.g-paginator .g-info { + background: none; + padding: .2em 0; + text-align: center; + width: 40%; +} + +/* Dialogs and panels ~~~~~~~~~~~~~~~~~~ */ + +#g-dialog { + text-align: left; +} + +#g-dialog legend { + display: none; +} + +#g-dialog .g-cancel { + margin: .4em 1em; +} + +#g-panel { + display: none; + padding: 1em; +} + +/* Inline layout ~~~~~~~~~~ */ + +.g-inline li { + float: left; + margin-left: 1.8em; + padding-left: 0 !important; +} + +.g-inline li.g-first { + margin-left: 0; +} + +/* Autocomplete ~~~~~~~~~~ */ +.ac_loading { + background: white url('../images/loading-small.gif') right center no-repeat !important; +} + +/** ******************************************************************* + * 9) Right to left language styles + *********************************************************************/ + +.rtl { + direction: rtl; +} + +.rtl #g-header, +.rtl #g-content, +.rtl #g-sidebar, +.rtl #g-footer, +.rtl caption, +.rtl th, +.rtl #g-dialog, +.rtl .g-context-menu li a, +.rtl .g-message-box li, +.rtl #g-site-status li { + text-align: right; +} + +.rtl .g-text-right { + text-align: left; +} + +.rtl .g-error, +.rtl .g-info, +.rtl .g-success, +.rtl .g-warning, +.rtl #g-add-photos-status .g-success, +.rtl #g-add-photos-status .g-error { + background-position: center right; + padding-right: 30px !important; +} + +.rtl form li.g-error, +.rtl form li.g-info, +.rtl form li.g-success, +.rtl form li.g-warning { + padding-right: 0 !important; +} + +.rtl .g-left, +.rtl .g-inline li, +.rtl #g-content #g-album-grid .g-item, +.rtl .sf-menu li, +.rtl .g-breadcrumbs li, +.rtl .g-paginator li, +.rtl .g-buttonset li, +.rtl .ui-icon-left .ui-icon, +.rtl .g-short-form li, +.rtl form ul ul li, +.rtl input[type="submit"], +.rtl input[type="reset"], +.rtl input.checkbox, +.rtl input[type=checkbox], +.rtl input.radio, +.rtl input[type=radio] { + float: right; +} + +.rtl .g-right, +.rtl .ui-icon-right .ui-icon { + float: left; +} + +.rtl .g-inline li { + margin-right: 1em; +} + +.rtl .g-inline li.g-first { + margin-right: 0; +} + +.rtl .g-breadcrumbs li { + background: transparent url('../images/ico-separator-rtl.gif') no-repeat scroll right center; + padding: 1em 18px 1em 8px; +} + +.rtl .g-breadcrumbs .g-first { + background: none; + padding-right: 0; +} + +.rtl input.checkbox { + margin-left: .4em; +} + +.rtl #g-add-comment { + right: inherit; + left: 0; +} + +.rtl .ui-icon-left .ui-icon { + margin-left: .2em; +} + +.rtl .ui-icon-right .ui-icon { + margin-right: .2em; +} + +/* RTL Corner radius ~~~~~~~~~~~~~~~~~~~~~~ */ +.rtl .g-buttonset .ui-corner-tl { + -moz-border-radius-topleft: 0; + -webkit-border-top-left-radius: 0; + border-top-left-radius: 0; + -moz-border-radius-topright: 5px !important; + -webkit-border-top-right-radius: 5px !important; + border-top-right-radius: 5px !important; +} + +.rtl .g-buttonset .ui-corner-tr { + -moz-border-radius-topright: 0; + -webkit-border-top-right-radius: 0; + border-top-right-radius: 0; + -moz-border-radius-topleft: 5px !important; + -webkit-border-top-left-radius: 5px !important; + border-top-left-radius: 5px !important; +} + +.rtl .g-buttonset .ui-corner-bl { + -moz-border-radius-bottomleft: 0; + -webkit-border-bottom-left-radius: 0; + border-bottom-left-radius: 0; + -moz-border-radius-bottomright: 5px !important; + -webkit-border-bottom-right-radius: 5px !important; + border-bottom-right-radius: 5px !important; +} + +.rtl .g-buttonset .ui-corner-br { + -moz-border-radius-bottomright: 0; + -webkit-border-bottom-right-radius: 0; + border-bottom-right-radius: 0; + -moz-border-radius-bottomleft: 5px !important; + -webkit-border-bottom-left-radius: 5px !important; + border-bottom-left-radius: 5px !important; +} + +.rtl .g-buttonset .ui-corner-right, +.rtl .ui-progressbar .ui-corner-right { + -moz-border-radius-topright: 0; + -webkit-border-top-right-radius: 0; + border-top-right-radius: 0; + -moz-border-radius-topleft: 5px !important; + -webkit-border-top-left-radius: 5px !important; + border-top-left-radius: 5px !important; + -moz-border-radius-bottomright: 0; + -webkit-border-bottom-right-radius: 0; + border-bottom-right-radius: 0; + -moz-border-radius-bottomleft: 5px !important; + -webkit-border-bottom-left-radius: 5px !important; + border-bottom-left-radius: 5px !important; +} + +.rtl .g-buttonset .ui-corner-left, +.rtl .ui-progressbar .ui-corner-left { + -moz-border-radius-topleft: 0; + -webkit-border-top-left-radius: 0; + border-top-left-radius: 0; + -moz-border-radius-topright: 5px !important; + -webkit-border-top-right-radius: 5px !important; + border-top-right-radius: 5px !important; + -moz-border-radius-bottomleft: 0; + -webkit-border-bottom-left-radius: 0; + border-bottom-left-radius: 0; + -moz-border-radius-bottomright: 5px !important; + -webkit-border-bottom-right-radius: 5px !important; + border-bottom-right-radius: 5px !important; +} + +/* RTL Superfish ~~~~~~~~~~~~~~~~~~~~~~~~~ */ + +.rtl .sf-menu a { + border-left: none; + border-right:1px solid #fff; +} + +.rtl .sf-menu a.sf-with-ul { + padding-left: 2.25em; + padding-right: 1em; +} + +.rtl .sf-sub-indicator { + left: .75em !important; + right: auto; + background: url('../../../lib/superfish/images/arrows-ffffff-rtl.png') no-repeat -10px -100px; /* 8-bit indexed alpha png. IE6 gets solid image only */ +} +.rtl a > .sf-sub-indicator { /* give all except IE6 the correct values */ + top: .8em; + background-position: -10px -100px; /* use translucent arrow for modern browsers*/ +} +/* apply hovers to modern browsers */ +.rtl a:focus > .sf-sub-indicator, +.rtl a:hover > .sf-sub-indicator, +.rtl a:active > .sf-sub-indicator, +.rtl li:hover > a > .sf-sub-indicator, +.rtl li.sfHover > a > .sf-sub-indicator { + background-position: 0 -100px; /* arrow hovers for modern browsers*/ +} + +/* point right for anchors in subs */ +.rtl .sf-menu ul .sf-sub-indicator { background-position: 0 0; } +.rtl .sf-menu ul a > .sf-sub-indicator { background-position: -10px 0; } +/* apply hovers to modern browsers */ +.rtl .sf-menu ul a:focus > .sf-sub-indicator, +.rtl .sf-menu ul a:hover > .sf-sub-indicator, +.rtl .sf-menu ul a:active > .sf-sub-indicator, +.rtl .sf-menu ul li:hover > a > .sf-sub-indicator, +.rtl .sf-menu ul li.sfHover > a > .sf-sub-indicator { + background-position: 0 0; /* arrow hovers for modern browsers*/ +} + +.rtl .sf-menu li:hover ul, +.rtl .sf-menu li.sfHover ul { + right: 0; + left: auto; +} + +.rtl ul.sf-menu li li:hover ul, +.rtl ul.sf-menu li li.sfHover ul { + right: 12em; /* match ul width */ + left: auto; +} +.rtl ul.sf-menu li li li:hover ul, +.rtl ul.sf-menu li li li.sfHover ul { + right: 12em; /* match ul width */ + left: auto; +} + +/*** shadows for all but IE6 ***/ +.rtl .sf-shadow ul { + background: url('../../../lib/superfish/images/shadow.png') no-repeat bottom left; + padding: 0 0 9px 8px; + border-top-right-radius: 0; + border-bottom-left-radius: 0; + -moz-border-radius-topright: 0; + -moz-border-radius-bottomleft: 0; + -webkit-border-top-right-radius: 0; + -webkit-border-bottom-left-radius: 0; + -moz-border-radius-topleft: 17px; + -moz-border-radius-bottomright: 17px; + -webkit-border-top-left-radius: 17px; + -webkit-border-bottom-right-radius: 17px; + border-top-left-radius: 17px; + border-bottom-right-radius: 17px; +} + +/* RTL ThemeRoller ~~~~~~~~~~~~~~~~~~~~~~~~ */ + +.rtl .ui-dialog .ui-dialog-titlebar { + padding: 0.5em 1em 0.3em 0.3em; +} + +.rtl .ui-dialog .ui-dialog-title { + float: right; +} + +.rtl .ui-dialog .ui-dialog-titlebar-close { + left: 0.3em; + right: auto; +} + + +/* RTL paginator ~~~~~~~~~~~~~~~~~~~~~~~~~~ */ + +.rtl .g-paginator .g-info { + width: 35%; +} + +.rtl .g-paginator .g-text-right { + margin-left: 0; +} + +.rtl .g-paginator .ui-icon-seek-end { + background-position: -80px -160px; +} + +.rtl .g-paginator .ui-icon-seek-next { + background-position: -48px -160px; +} + +.rtl .g-paginator .ui-icon-seek-prev { + background-position: -32px -160px; +} + +.rtl .g-paginator .ui-icon-seek-first { + background-position: -64px -160px; +} + +.rtl #g-header #g-login-menu, +.rtl #g-header #g-quick-search-form { + clear: left; + float: left; +} + +.rtl #g-header #g-login-menu li { + margin-left: 0; + padding-left: 0; + padding-right: 1.2em; +} + +.rtl #g-site-menu { + left: auto; + right: 150px; +} + +.rtl #g-view-menu #g-slideshow-link { + background-image: url('../images/ico-view-slideshow-rtl.png'); +} + +.rtl #g-sidebar .g-block-content { + padding-right: 1em; + padding-left: 0; +} + +.rtl #g-footer #g-credits li { + padding-left: 1.2em !important; + padding-right: 0; +} diff --git a/3.0/themes/pear4gallery3/css/themeroller/images/ui-bg_flat_0_aaaaaa_40x100.png b/3.0/themes/pear4gallery3/css/themeroller/images/ui-bg_flat_0_aaaaaa_40x100.png new file mode 100644 index 00000000..5b5dab2a Binary files /dev/null and b/3.0/themes/pear4gallery3/css/themeroller/images/ui-bg_flat_0_aaaaaa_40x100.png differ diff --git a/3.0/themes/pear4gallery3/css/themeroller/images/ui-bg_flat_55_fbec88_40x100.png b/3.0/themes/pear4gallery3/css/themeroller/images/ui-bg_flat_55_fbec88_40x100.png new file mode 100644 index 00000000..47acaadd Binary files /dev/null and b/3.0/themes/pear4gallery3/css/themeroller/images/ui-bg_flat_55_fbec88_40x100.png differ diff --git a/3.0/themes/pear4gallery3/css/themeroller/images/ui-bg_glass_75_d0e5f5_1x400.png b/3.0/themes/pear4gallery3/css/themeroller/images/ui-bg_glass_75_d0e5f5_1x400.png new file mode 100644 index 00000000..9fb564f8 Binary files /dev/null and b/3.0/themes/pear4gallery3/css/themeroller/images/ui-bg_glass_75_d0e5f5_1x400.png differ diff --git a/3.0/themes/pear4gallery3/css/themeroller/images/ui-bg_glass_85_dfeffc_1x400.png b/3.0/themes/pear4gallery3/css/themeroller/images/ui-bg_glass_85_dfeffc_1x400.png new file mode 100644 index 00000000..01495152 Binary files /dev/null and b/3.0/themes/pear4gallery3/css/themeroller/images/ui-bg_glass_85_dfeffc_1x400.png differ diff --git a/3.0/themes/pear4gallery3/css/themeroller/images/ui-bg_glass_95_fef1ec_1x400.png b/3.0/themes/pear4gallery3/css/themeroller/images/ui-bg_glass_95_fef1ec_1x400.png new file mode 100644 index 00000000..4443fdc1 Binary files /dev/null and b/3.0/themes/pear4gallery3/css/themeroller/images/ui-bg_glass_95_fef1ec_1x400.png differ diff --git a/3.0/themes/pear4gallery3/css/themeroller/images/ui-bg_gloss-wave_55_5c9ccc_500x100.png b/3.0/themes/pear4gallery3/css/themeroller/images/ui-bg_gloss-wave_55_5c9ccc_500x100.png new file mode 100644 index 00000000..0cdbda36 Binary files /dev/null and b/3.0/themes/pear4gallery3/css/themeroller/images/ui-bg_gloss-wave_55_5c9ccc_500x100.png differ diff --git a/3.0/themes/pear4gallery3/css/themeroller/images/ui-bg_inset-hard_100_f5f8f9_1x100.png b/3.0/themes/pear4gallery3/css/themeroller/images/ui-bg_inset-hard_100_f5f8f9_1x100.png new file mode 100644 index 00000000..4f3faf8a Binary files /dev/null and b/3.0/themes/pear4gallery3/css/themeroller/images/ui-bg_inset-hard_100_f5f8f9_1x100.png differ diff --git a/3.0/themes/pear4gallery3/css/themeroller/images/ui-bg_inset-hard_100_fcfdfd_1x100.png b/3.0/themes/pear4gallery3/css/themeroller/images/ui-bg_inset-hard_100_fcfdfd_1x100.png new file mode 100644 index 00000000..38c38335 Binary files /dev/null and b/3.0/themes/pear4gallery3/css/themeroller/images/ui-bg_inset-hard_100_fcfdfd_1x100.png differ diff --git a/3.0/themes/pear4gallery3/css/themeroller/images/ui-icons_217bc0_256x240.png b/3.0/themes/pear4gallery3/css/themeroller/images/ui-icons_217bc0_256x240.png new file mode 100644 index 00000000..7719d487 Binary files /dev/null and b/3.0/themes/pear4gallery3/css/themeroller/images/ui-icons_217bc0_256x240.png differ diff --git a/3.0/themes/pear4gallery3/css/themeroller/images/ui-icons_2e83ff_256x240.png b/3.0/themes/pear4gallery3/css/themeroller/images/ui-icons_2e83ff_256x240.png new file mode 100644 index 00000000..d9897d25 Binary files /dev/null and b/3.0/themes/pear4gallery3/css/themeroller/images/ui-icons_2e83ff_256x240.png differ diff --git a/3.0/themes/pear4gallery3/css/themeroller/images/ui-icons_469bdd_256x240.png b/3.0/themes/pear4gallery3/css/themeroller/images/ui-icons_469bdd_256x240.png new file mode 100644 index 00000000..d8161854 Binary files /dev/null and b/3.0/themes/pear4gallery3/css/themeroller/images/ui-icons_469bdd_256x240.png differ diff --git a/3.0/themes/pear4gallery3/css/themeroller/images/ui-icons_6da8d5_256x240.png b/3.0/themes/pear4gallery3/css/themeroller/images/ui-icons_6da8d5_256x240.png new file mode 100644 index 00000000..b3c7d662 Binary files /dev/null and b/3.0/themes/pear4gallery3/css/themeroller/images/ui-icons_6da8d5_256x240.png differ diff --git a/3.0/themes/pear4gallery3/css/themeroller/images/ui-icons_cd0a0a_256x240.png b/3.0/themes/pear4gallery3/css/themeroller/images/ui-icons_cd0a0a_256x240.png new file mode 100644 index 00000000..2db88b79 Binary files /dev/null and b/3.0/themes/pear4gallery3/css/themeroller/images/ui-icons_cd0a0a_256x240.png differ diff --git a/3.0/themes/pear4gallery3/css/themeroller/images/ui-icons_d8e7f3_256x240.png b/3.0/themes/pear4gallery3/css/themeroller/images/ui-icons_d8e7f3_256x240.png new file mode 100644 index 00000000..2c8aac46 Binary files /dev/null and b/3.0/themes/pear4gallery3/css/themeroller/images/ui-icons_d8e7f3_256x240.png differ diff --git a/3.0/themes/pear4gallery3/css/themeroller/images/ui-icons_f9bd01_256x240.png b/3.0/themes/pear4gallery3/css/themeroller/images/ui-icons_f9bd01_256x240.png new file mode 100644 index 00000000..e81603f5 Binary files /dev/null and b/3.0/themes/pear4gallery3/css/themeroller/images/ui-icons_f9bd01_256x240.png differ diff --git a/3.0/themes/pear4gallery3/css/themeroller/ui.base.css b/3.0/themes/pear4gallery3/css/themeroller/ui.base.css new file mode 100644 index 00000000..1a1810c8 --- /dev/null +++ b/3.0/themes/pear4gallery3/css/themeroller/ui.base.css @@ -0,0 +1,7 @@ +@import "ui.core.css"; +@import "ui.theme.css"; +@import "ui.datepicker.css"; +@import "ui.dialog.css"; +@import "ui.progressbar.css"; +@import "ui.resizable.css"; +@import "ui.tabs.css"; diff --git a/3.0/themes/pear4gallery3/css/themeroller/ui.core.css b/3.0/themes/pear4gallery3/css/themeroller/ui.core.css new file mode 100644 index 00000000..d832ad7d --- /dev/null +++ b/3.0/themes/pear4gallery3/css/themeroller/ui.core.css @@ -0,0 +1,37 @@ +/* +* jQuery UI CSS Framework +* Copyright (c) 2009 AUTHORS.txt (http://ui.jquery.com/about) +* Dual licensed under the MIT (MIT-LICENSE.txt) and GPL (GPL-LICENSE.txt) licenses. +*/ + +/* Layout helpers +----------------------------------*/ +.ui-helper-hidden { display: none; } +.ui-helper-hidden-accessible { position: absolute; left: -99999999px; } +.ui-helper-reset { margin: 0; padding: 0; border: 0; outline: 0; line-height: 1.3; text-decoration: none; font-size: 100%; list-style: none; } +.ui-helper-clearfix:after { content: "."; display: block; height: 0; clear: both; visibility: hidden; } +.ui-helper-clearfix { display: inline-block; } +/* required comment for clearfix to work in Opera \*/ +* html .ui-helper-clearfix { height:1%; } +.ui-helper-clearfix { display:block; } +/* end clearfix */ +.ui-helper-zfix { width: 100%; height: 100%; top: 0; left: 0; position: absolute; opacity: 0; filter:Alpha(Opacity=0); } + + +/* Interaction Cues +----------------------------------*/ +.ui-state-disabled { cursor: default !important; } + + +/* Icons +----------------------------------*/ + +/* states and images */ +.ui-icon { display: block; text-indent: -99999px; overflow: hidden; background-repeat: no-repeat; } + + +/* Misc visuals +----------------------------------*/ + +/* Overlays */ +.ui-widget-overlay { position: absolute; top: 0; left: 0; width: 100%; height: 100%; } \ No newline at end of file diff --git a/3.0/themes/pear4gallery3/css/themeroller/ui.datepicker.css b/3.0/themes/pear4gallery3/css/themeroller/ui.datepicker.css new file mode 100644 index 00000000..92986c9e --- /dev/null +++ b/3.0/themes/pear4gallery3/css/themeroller/ui.datepicker.css @@ -0,0 +1,62 @@ +/* Datepicker +----------------------------------*/ +.ui-datepicker { width: 17em; padding: .2em .2em 0; } +.ui-datepicker .ui-datepicker-header { position:relative; padding:.2em 0; } +.ui-datepicker .ui-datepicker-prev, .ui-datepicker .ui-datepicker-next { position:absolute; top: 2px; width: 1.8em; height: 1.8em; } +.ui-datepicker .ui-datepicker-prev-hover, .ui-datepicker .ui-datepicker-next-hover { top: 1px; } +.ui-datepicker .ui-datepicker-prev { left:2px; } +.ui-datepicker .ui-datepicker-next { right:2px; } +.ui-datepicker .ui-datepicker-prev-hover { left:1px; } +.ui-datepicker .ui-datepicker-next-hover { right:1px; } +.ui-datepicker .ui-datepicker-prev span, .ui-datepicker .ui-datepicker-next span { display: block; position: absolute; left: 50%; margin-left: -8px; top: 50%; margin-top: -8px; } +.ui-datepicker .ui-datepicker-title { margin: 0 2.3em; line-height: 1.8em; text-align: center; } +.ui-datepicker .ui-datepicker-title select { float:left; font-size:1em; margin:1px 0; } +.ui-datepicker select.ui-datepicker-month-year {width: 100%;} +.ui-datepicker select.ui-datepicker-month, +.ui-datepicker select.ui-datepicker-year { width: 49%;} +.ui-datepicker .ui-datepicker-title select.ui-datepicker-year { float: right; } +.ui-datepicker table {width: 100%; font-size: .9em; border-collapse: collapse; margin:0 0 .4em; } +.ui-datepicker th { padding: .7em .3em; text-align: center; font-weight: bold; border: 0; } +.ui-datepicker td { border: 0; padding: 1px; } +.ui-datepicker td span, .ui-datepicker td a { display: block; padding: .2em; text-align: right; text-decoration: none; } +.ui-datepicker .ui-datepicker-buttonpane { background-image: none; margin: .7em 0 0 0; padding:0 .2em; border-left: 0; border-right: 0; border-bottom: 0; } +.ui-datepicker .ui-datepicker-buttonpane button { float: right; margin: .5em .2em .4em; cursor: pointer; padding: .2em .6em .3em .6em; width:auto; overflow:visible; } +.ui-datepicker .ui-datepicker-buttonpane button.ui-datepicker-current { float:left; } + +/* with multiple calendars */ +.ui-datepicker.ui-datepicker-multi { width:auto; } +.ui-datepicker-multi .ui-datepicker-group { float:left; } +.ui-datepicker-multi .ui-datepicker-group table { width:95%; margin:0 auto .4em; } +.ui-datepicker-multi-2 .ui-datepicker-group { width:50%; } +.ui-datepicker-multi-3 .ui-datepicker-group { width:33.3%; } +.ui-datepicker-multi-4 .ui-datepicker-group { width:25%; } +.ui-datepicker-multi .ui-datepicker-group-last .ui-datepicker-header { border-left-width:0; } +.ui-datepicker-multi .ui-datepicker-group-middle .ui-datepicker-header { border-left-width:0; } +.ui-datepicker-multi .ui-datepicker-buttonpane { clear:left; } +.ui-datepicker-row-break { clear:left; width:100%; } + +/* RTL support */ +.ui-datepicker-rtl { direction: rtl; } +.ui-datepicker-rtl .ui-datepicker-prev { right: 2px; left: auto; } +.ui-datepicker-rtl .ui-datepicker-next { left: 2px; right: auto; } +.ui-datepicker-rtl .ui-datepicker-prev:hover { right: 1px; left: auto; } +.ui-datepicker-rtl .ui-datepicker-next:hover { left: 1px; right: auto; } +.ui-datepicker-rtl .ui-datepicker-buttonpane { clear:right; } +.ui-datepicker-rtl .ui-datepicker-buttonpane button { float: left; } +.ui-datepicker-rtl .ui-datepicker-buttonpane button.ui-datepicker-current { float:right; } +.ui-datepicker-rtl .ui-datepicker-group { float:right; } +.ui-datepicker-rtl .ui-datepicker-group-last .ui-datepicker-header { border-right-width:0; border-left-width:1px; } +.ui-datepicker-rtl .ui-datepicker-group-middle .ui-datepicker-header { border-right-width:0; border-left-width:1px; } + +/* IE6 IFRAME FIX (taken from datepicker 1.5.3 */ +.ui-datepicker-cover { + display: none; /*sorry for IE5*/ + display/**/: block; /*sorry for IE5*/ + position: absolute; /*must have*/ + z-index: -1; /*must have*/ + filter: mask(); /*must have*/ + top: -4px; /*must have*/ + left: -4px; /*must have*/ + width: 200px; /*must have*/ + height: 200px; /*must have*/ +} \ No newline at end of file diff --git a/3.0/themes/pear4gallery3/css/themeroller/ui.dialog.css b/3.0/themes/pear4gallery3/css/themeroller/ui.dialog.css new file mode 100644 index 00000000..f10f4090 --- /dev/null +++ b/3.0/themes/pear4gallery3/css/themeroller/ui.dialog.css @@ -0,0 +1,13 @@ +/* Dialog +----------------------------------*/ +.ui-dialog { position: relative; padding: .2em; width: 300px; } +.ui-dialog .ui-dialog-titlebar { padding: .5em .3em .3em 1em; position: relative; } +.ui-dialog .ui-dialog-title { float: left; margin: .1em 0 .2em; } +.ui-dialog .ui-dialog-titlebar-close { position: absolute; right: .3em; top: 50%; width: 19px; margin: -10px 0 0 0; padding: 1px; height: 18px; } +.ui-dialog .ui-dialog-titlebar-close span { display: block; margin: 1px; } +.ui-dialog .ui-dialog-titlebar-close:hover, .ui-dialog .ui-dialog-titlebar-close:focus { padding: 0; } +.ui-dialog .ui-dialog-content { border: 0; padding: .5em 1em; background: none; overflow: auto; } +.ui-dialog .ui-dialog-buttonpane { text-align: left; border-width: 1px 0 0 0; background-image: none; margin: .5em 0 0 0; padding: .3em 1em .5em .4em; } +.ui-dialog .ui-dialog-buttonpane button { float: right; margin: .5em .4em .5em 0; cursor: pointer; padding: .2em .6em .3em .6em; line-height: 1.4em; width:auto; overflow:visible; } +.ui-dialog .ui-resizable-se { width: 14px; height: 14px; right: 3px; bottom: 3px; } +.ui-draggable .ui-dialog-titlebar { cursor: move; } \ No newline at end of file diff --git a/3.0/themes/pear4gallery3/css/themeroller/ui.progressbar.css b/3.0/themes/pear4gallery3/css/themeroller/ui.progressbar.css new file mode 100644 index 00000000..bc0939ec --- /dev/null +++ b/3.0/themes/pear4gallery3/css/themeroller/ui.progressbar.css @@ -0,0 +1,4 @@ +/* Progressbar +----------------------------------*/ +.ui-progressbar { height:2em; text-align: left; } +.ui-progressbar .ui-progressbar-value {margin: -1px; height:100%; } \ No newline at end of file diff --git a/3.0/themes/pear4gallery3/css/themeroller/ui.resizable.css b/3.0/themes/pear4gallery3/css/themeroller/ui.resizable.css new file mode 100644 index 00000000..44efeb2e --- /dev/null +++ b/3.0/themes/pear4gallery3/css/themeroller/ui.resizable.css @@ -0,0 +1,13 @@ +/* Resizable +----------------------------------*/ +.ui-resizable { position: relative;} +.ui-resizable-handle { position: absolute;font-size: 0.1px;z-index: 99999; display: block;} +.ui-resizable-disabled .ui-resizable-handle, .ui-resizable-autohide .ui-resizable-handle { display: none; } +.ui-resizable-n { cursor: n-resize; height: 7px; width: 100%; top: -5px; left: 0px; } +.ui-resizable-s { cursor: s-resize; height: 7px; width: 100%; bottom: -5px; left: 0px; } +.ui-resizable-e { cursor: e-resize; width: 7px; right: -5px; top: 0px; height: 100%; } +.ui-resizable-w { cursor: w-resize; width: 7px; left: -5px; top: 0px; height: 100%; } +.ui-resizable-se { cursor: se-resize; width: 12px; height: 12px; right: 1px; bottom: 1px; } +.ui-resizable-sw { cursor: sw-resize; width: 9px; height: 9px; left: -5px; bottom: -5px; } +.ui-resizable-nw { cursor: nw-resize; width: 9px; height: 9px; left: -5px; top: -5px; } +.ui-resizable-ne { cursor: ne-resize; width: 9px; height: 9px; right: -5px; top: -5px;} \ No newline at end of file diff --git a/3.0/themes/pear4gallery3/css/themeroller/ui.tabs.css b/3.0/themes/pear4gallery3/css/themeroller/ui.tabs.css new file mode 100644 index 00000000..70ed3ef4 --- /dev/null +++ b/3.0/themes/pear4gallery3/css/themeroller/ui.tabs.css @@ -0,0 +1,9 @@ +/* Tabs +----------------------------------*/ +.ui-tabs {padding: .2em;} +.ui-tabs .ui-tabs-nav { padding: .2em .2em 0 .2em; position: relative; } +.ui-tabs .ui-tabs-nav li { float: left; border-bottom: 0 !important; margin: 0 .2em -1px 0; padding: 0; list-style: none; } +.ui-tabs .ui-tabs-nav li a { display:block; text-decoration: none; padding: .5em 1em; } +.ui-tabs .ui-tabs-nav li.ui-tabs-selected { padding-bottom: .1em; border-bottom: 0; } +.ui-tabs .ui-tabs-panel { padding: 1em 1.4em; display: block; border: 0; background: none; } +.ui-tabs .ui-tabs-hide { display: none !important; } \ No newline at end of file diff --git a/3.0/themes/pear4gallery3/css/themeroller/ui.theme.css b/3.0/themes/pear4gallery3/css/themeroller/ui.theme.css new file mode 100644 index 00000000..477252e5 --- /dev/null +++ b/3.0/themes/pear4gallery3/css/themeroller/ui.theme.css @@ -0,0 +1,243 @@ + + +/* +* jQuery UI CSS Framework +* Copyright (c) 2009 AUTHORS.txt (http://ui.jquery.com/about) +* Dual licensed under the MIT (MIT-LICENSE.txt) and GPL (GPL-LICENSE.txt) licenses. +* To view and modify this theme, visit http://ui.jquery.com/themeroller/?tr=&ffDefault=Lucida%20Grande,%20Lucida%20Sans,%20Arial,%20sans-serif&fwDefault=bold&fsDefault=1.1em&cornerRadius=5px&bgColorHeader=5c9ccc&bgTextureHeader=12_gloss_wave.png&bgImgOpacityHeader=55&borderColorHeader=4297d7&fcHeader=ffffff&iconColorHeader=d8e7f3&bgColorContent=fcfdfd&bgTextureContent=06_inset_hard.png&bgImgOpacityContent=100&borderColorContent=a6c9e2&fcContent=222222&iconColorContent=469bdd&bgColorDefault=dfeffc&bgTextureDefault=02_glass.png&bgImgOpacityDefault=85&borderColorDefault=c5dbec&fcDefault=2e6e9e&iconColorDefault=6da8d5&bgColorHover=d0e5f5&bgTextureHover=02_glass.png&bgImgOpacityHover=75&borderColorHover=79b7e7&fcHover=1d5987&iconColorHover=217bc0&bgColorActive=f5f8f9&bgTextureActive=06_inset_hard.png&bgImgOpacityActive=100&borderColorActive=79b7e7&fcActive=e17009&iconColorActive=f9bd01&bgColorHighlight=fbec88&bgTextureHighlight=01_flat.png&bgImgOpacityHighlight=55&borderColorHighlight=fad42e&fcHighlight=363636&iconColorHighlight=2e83ff&bgColorError=fef1ec&bgTextureError=02_glass.png&bgImgOpacityError=95&borderColorError=cd0a0a&fcError=cd0a0a&iconColorError=cd0a0a&bgColorOverlay=aaaaaa&bgTextureOverlay=01_flat.png&bgImgOpacityOverlay=0&opacityOverlay=30&bgColorShadow=aaaaaa&bgTextureShadow=01_flat.png&bgImgOpacityShadow=0&opacityShadow=30&thicknessShadow=8px&offsetTopShadow=-8px&offsetLeftShadow=-8px&cornerRadiusShadow=8px +*/ + + +/* Component containers +----------------------------------*/ +.ui-widget { font-family: Lucida Grande, Lucida Sans, Arial, sans-serif; font-size: 1.1em; } +.ui-widget input, .ui-widget select, .ui-widget textarea, .ui-widget button { font-family: Lucida Grande, Lucida Sans, Arial, sans-serif; font-size: 1em; } +.ui-widget-header { border: 1px solid #4297d7; background: #5c9ccc url(images/ui-bg_gloss-wave_55_5c9ccc_500x100.png) 50% 50% repeat-x; color: #ffffff; font-weight: bold; } +.ui-widget-header a { color: #ffffff; } +.ui-widget-content { border: 1px solid #a6c9e2; background: #fcfdfd url(images/ui-bg_inset-hard_100_fcfdfd_1x100.png) 50% bottom repeat-x; color: #222222; } +.ui-widget-content a { color: #222222; } + +/* Interaction states +----------------------------------*/ +.ui-state-default, .ui-widget-content .ui-state-default { border: 1px solid #c5dbec; background: #dfeffc url(images/ui-bg_glass_85_dfeffc_1x400.png) 50% 50% repeat-x; font-weight: bold; color: #2e6e9e; outline: none; } +.ui-state-default a { color: #2e6e9e; text-decoration: none; outline: none; } +.ui-state-hover, .ui-widget-content .ui-state-hover, .ui-state-focus, .ui-widget-content .ui-state-focus { border: 1px solid #79b7e7; background: #d0e5f5 url(images/ui-bg_glass_75_d0e5f5_1x400.png) 50% 50% repeat-x; font-weight: bold; color: #1d5987; outline: none; } +.ui-state-hover a { color: #1d5987; text-decoration: none; outline: none; } +.ui-state-active, .ui-widget-content .ui-state-active { border: 1px solid #79b7e7; background: #f5f8f9 url(images/ui-bg_inset-hard_100_f5f8f9_1x100.png) 50% 50% repeat-x; font-weight: bold; color: #e17009; outline: none; } +.ui-state-active a { color: #e17009; outline: none; text-decoration: none; } + +/* Interaction Cues +----------------------------------*/ +.ui-state-highlight, .ui-widget-content .ui-state-highlight {border: 1px solid #fad42e; background: #fbec88 url(images/ui-bg_flat_55_fbec88_40x100.png) 50% 50% repeat-x; color: #363636; } +.ui-state-error, .ui-widget-content .ui-state-error {border: 1px solid #cd0a0a; background: #fef1ec url(images/ui-bg_glass_95_fef1ec_1x400.png) 50% 50% repeat-x; color: #cd0a0a; } +.ui-state-error-text, .ui-widget-content .ui-state-error-text { color: #cd0a0a; } +.ui-state-disabled, .ui-widget-content .ui-state-disabled { opacity: .35; filter:Alpha(Opacity=35); background-image: none; } +.ui-priority-primary, .ui-widget-content .ui-priority-primary { font-weight: bold; } +.ui-priority-secondary, .ui-widget-content .ui-priority-secondary { opacity: .7; filter:Alpha(Opacity=70); font-weight: normal; } + +/* Icons +----------------------------------*/ + +/* states and images */ +.ui-icon { width: 16px; height: 16px; background-image: url(images/ui-icons_469bdd_256x240.png); } +.ui-widget-content .ui-icon {background-image: url(images/ui-icons_469bdd_256x240.png); } +.ui-widget-header .ui-icon {background-image: url(images/ui-icons_d8e7f3_256x240.png); } +.ui-state-default .ui-icon { background-image: url(images/ui-icons_6da8d5_256x240.png); } +.ui-state-hover .ui-icon, .ui-state-focus .ui-icon {background-image: url(images/ui-icons_217bc0_256x240.png); } +.ui-state-active .ui-icon {background-image: url(images/ui-icons_f9bd01_256x240.png); } +.ui-state-highlight .ui-icon {background-image: url(images/ui-icons_2e83ff_256x240.png); } +.ui-state-error .ui-icon, .ui-state-error-text .ui-icon {background-image: url(images/ui-icons_cd0a0a_256x240.png); } + +/* positioning */ +.ui-icon-carat-1-n { background-position: 0 0; } +.ui-icon-carat-1-ne { background-position: -16px 0; } +.ui-icon-carat-1-e { background-position: -32px 0; } +.ui-icon-carat-1-se { background-position: -48px 0; } +.ui-icon-carat-1-s { background-position: -64px 0; } +.ui-icon-carat-1-sw { background-position: -80px 0; } +.ui-icon-carat-1-w { background-position: -96px 0; } +.ui-icon-carat-1-nw { background-position: -112px 0; } +.ui-icon-carat-2-n-s { background-position: -128px 0; } +.ui-icon-carat-2-e-w { background-position: -144px 0; } +.ui-icon-triangle-1-n { background-position: 0 -16px; } +.ui-icon-triangle-1-ne { background-position: -16px -16px; } +.ui-icon-triangle-1-e { background-position: -32px -16px; } +.ui-icon-triangle-1-se { background-position: -48px -16px; } +.ui-icon-triangle-1-s { background-position: -64px -16px; } +.ui-icon-triangle-1-sw { background-position: -80px -16px; } +.ui-icon-triangle-1-w { background-position: -96px -16px; } +.ui-icon-triangle-1-nw { background-position: -112px -16px; } +.ui-icon-triangle-2-n-s { background-position: -128px -16px; } +.ui-icon-triangle-2-e-w { background-position: -144px -16px; } +.ui-icon-arrow-1-n { background-position: 0 -32px; } +.ui-icon-arrow-1-ne { background-position: -16px -32px; } +.ui-icon-arrow-1-e { background-position: -32px -32px; } +.ui-icon-arrow-1-se { background-position: -48px -32px; } +.ui-icon-arrow-1-s { background-position: -64px -32px; } +.ui-icon-arrow-1-sw { background-position: -80px -32px; } +.ui-icon-arrow-1-w { background-position: -96px -32px; } +.ui-icon-arrow-1-nw { background-position: -112px -32px; } +.ui-icon-arrow-2-n-s { background-position: -128px -32px; } +.ui-icon-arrow-2-ne-sw { background-position: -144px -32px; } +.ui-icon-arrow-2-e-w { background-position: -160px -32px; } +.ui-icon-arrow-2-se-nw { background-position: -176px -32px; } +.ui-icon-arrowstop-1-n { background-position: -192px -32px; } +.ui-icon-arrowstop-1-e { background-position: -208px -32px; } +.ui-icon-arrowstop-1-s { background-position: -224px -32px; } +.ui-icon-arrowstop-1-w { background-position: -240px -32px; } +.ui-icon-arrowthick-1-n { background-position: 0 -48px; } +.ui-icon-arrowthick-1-ne { background-position: -16px -48px; } +.ui-icon-arrowthick-1-e { background-position: -32px -48px; } +.ui-icon-arrowthick-1-se { background-position: -48px -48px; } +.ui-icon-arrowthick-1-s { background-position: -64px -48px; } +.ui-icon-arrowthick-1-sw { background-position: -80px -48px; } +.ui-icon-arrowthick-1-w { background-position: -96px -48px; } +.ui-icon-arrowthick-1-nw { background-position: -112px -48px; } +.ui-icon-arrowthick-2-n-s { background-position: -128px -48px; } +.ui-icon-arrowthick-2-ne-sw { background-position: -144px -48px; } +.ui-icon-arrowthick-2-e-w { background-position: -160px -48px; } +.ui-icon-arrowthick-2-se-nw { background-position: -176px -48px; } +.ui-icon-arrowthickstop-1-n { background-position: -192px -48px; } +.ui-icon-arrowthickstop-1-e { background-position: -208px -48px; } +.ui-icon-arrowthickstop-1-s { background-position: -224px -48px; } +.ui-icon-arrowthickstop-1-w { background-position: -240px -48px; } +.ui-icon-arrowreturnthick-1-w { background-position: 0 -64px; } +.ui-icon-arrowreturnthick-1-n { background-position: -16px -64px; } +.ui-icon-arrowreturnthick-1-e { background-position: -32px -64px; } +.ui-icon-arrowreturnthick-1-s { background-position: -48px -64px; } +.ui-icon-arrowreturn-1-w { background-position: -64px -64px; } +.ui-icon-arrowreturn-1-n { background-position: -80px -64px; } +.ui-icon-arrowreturn-1-e { background-position: -96px -64px; } +.ui-icon-arrowreturn-1-s { background-position: -112px -64px; } +.ui-icon-arrowrefresh-1-w { background-position: -128px -64px; } +.ui-icon-arrowrefresh-1-n { background-position: -144px -64px; } +.ui-icon-arrowrefresh-1-e { background-position: -160px -64px; } +.ui-icon-arrowrefresh-1-s { background-position: -176px -64px; } +.ui-icon-arrow-4 { background-position: 0 -80px; } +.ui-icon-arrow-4-diag { background-position: -16px -80px; } +.ui-icon-extlink { background-position: -32px -80px; } +.ui-icon-newwin { background-position: -48px -80px; } +.ui-icon-refresh { background-position: -64px -80px; } +.ui-icon-shuffle { background-position: -80px -80px; } +.ui-icon-transfer-e-w { background-position: -96px -80px; } +.ui-icon-transferthick-e-w { background-position: -112px -80px; } +.ui-icon-folder-collapsed { background-position: 0 -96px; } +.ui-icon-folder-open { background-position: -16px -96px; } +.ui-icon-document { background-position: -32px -96px; } +.ui-icon-document-b { background-position: -48px -96px; } +.ui-icon-note { background-position: -64px -96px; } +.ui-icon-mail-closed { background-position: -80px -96px; } +.ui-icon-mail-open { background-position: -96px -96px; } +.ui-icon-suitcase { background-position: -112px -96px; } +.ui-icon-comment { background-position: -128px -96px; } +.ui-icon-person { background-position: -144px -96px; } +.ui-icon-print { background-position: -160px -96px; } +.ui-icon-trash { background-position: -176px -96px; } +.ui-icon-locked { background-position: -192px -96px; } +.ui-icon-unlocked { background-position: -208px -96px; } +.ui-icon-bookmark { background-position: -224px -96px; } +.ui-icon-tag { background-position: -240px -96px; } +.ui-icon-home { background-position: 0 -112px; } +.ui-icon-flag { background-position: -16px -112px; } +.ui-icon-calendar { background-position: -32px -112px; } +.ui-icon-cart { background-position: -48px -112px; } +.ui-icon-pencil { background-position: -64px -112px; } +.ui-icon-clock { background-position: -80px -112px; } +.ui-icon-disk { background-position: -96px -112px; } +.ui-icon-calculator { background-position: -112px -112px; } +.ui-icon-zoomin { background-position: -128px -112px; } +.ui-icon-zoomout { background-position: -144px -112px; } +.ui-icon-search { background-position: -160px -112px; } +.ui-icon-wrench { background-position: -176px -112px; } +.ui-icon-gear { background-position: -192px -112px; } +.ui-icon-heart { background-position: -208px -112px; } +.ui-icon-star { background-position: -224px -112px; } +.ui-icon-link { background-position: -240px -112px; } +.ui-icon-cancel { background-position: 0 -128px; } +.ui-icon-plus { background-position: -16px -128px; } +.ui-icon-plusthick { background-position: -32px -128px; } +.ui-icon-minus { background-position: -48px -128px; } +.ui-icon-minusthick { background-position: -64px -128px; } +.ui-icon-close { background-position: -80px -128px; } +.ui-icon-closethick { background-position: -96px -128px; } +.ui-icon-key { background-position: -112px -128px; } +.ui-icon-lightbulb { background-position: -128px -128px; } +.ui-icon-scissors { background-position: -144px -128px; } +.ui-icon-clipboard { background-position: -160px -128px; } +.ui-icon-copy { background-position: -176px -128px; } +.ui-icon-contact { background-position: -192px -128px; } +.ui-icon-image { background-position: -208px -128px; } +.ui-icon-video { background-position: -224px -128px; } +.ui-icon-script { background-position: -240px -128px; } +.ui-icon-alert { background-position: 0 -144px; } +.ui-icon-info { background-position: -16px -144px; } +.ui-icon-notice { background-position: -32px -144px; } +.ui-icon-help { background-position: -48px -144px; } +.ui-icon-check { background-position: -64px -144px; } +.ui-icon-bullet { background-position: -80px -144px; } +.ui-icon-radio-off { background-position: -96px -144px; } +.ui-icon-radio-on { background-position: -112px -144px; } +.ui-icon-pin-w { background-position: -128px -144px; } +.ui-icon-pin-s { background-position: -144px -144px; } +.ui-icon-play { background-position: 0 -160px; } +.ui-icon-pause { background-position: -16px -160px; } +.ui-icon-seek-next { background-position: -32px -160px; } +.ui-icon-seek-prev { background-position: -48px -160px; } +.ui-icon-seek-end { background-position: -64px -160px; } +.ui-icon-seek-first { background-position: -80px -160px; } +.ui-icon-stop { background-position: -96px -160px; } +.ui-icon-eject { background-position: -112px -160px; } +.ui-icon-volume-off { background-position: -128px -160px; } +.ui-icon-volume-on { background-position: -144px -160px; } +.ui-icon-power { background-position: 0 -176px; } +.ui-icon-signal-diag { background-position: -16px -176px; } +.ui-icon-signal { background-position: -32px -176px; } +.ui-icon-battery-0 { background-position: -48px -176px; } +.ui-icon-battery-1 { background-position: -64px -176px; } +.ui-icon-battery-2 { background-position: -80px -176px; } +.ui-icon-battery-3 { background-position: -96px -176px; } +.ui-icon-circle-plus { background-position: 0 -192px; } +.ui-icon-circle-minus { background-position: -16px -192px; } +.ui-icon-circle-close { background-position: -32px -192px; } +.ui-icon-circle-triangle-e { background-position: -48px -192px; } +.ui-icon-circle-triangle-s { background-position: -64px -192px; } +.ui-icon-circle-triangle-w { background-position: -80px -192px; } +.ui-icon-circle-triangle-n { background-position: -96px -192px; } +.ui-icon-circle-arrow-e { background-position: -112px -192px; } +.ui-icon-circle-arrow-s { background-position: -128px -192px; } +.ui-icon-circle-arrow-w { background-position: -144px -192px; } +.ui-icon-circle-arrow-n { background-position: -160px -192px; } +.ui-icon-circle-zoomin { background-position: -176px -192px; } +.ui-icon-circle-zoomout { background-position: -192px -192px; } +.ui-icon-circle-check { background-position: -208px -192px; } +.ui-icon-circlesmall-plus { background-position: 0 -208px; } +.ui-icon-circlesmall-minus { background-position: -16px -208px; } +.ui-icon-circlesmall-close { background-position: -32px -208px; } +.ui-icon-squaresmall-plus { background-position: -48px -208px; } +.ui-icon-squaresmall-minus { background-position: -64px -208px; } +.ui-icon-squaresmall-close { background-position: -80px -208px; } +.ui-icon-grip-dotted-vertical { background-position: 0 -224px; } +.ui-icon-grip-dotted-horizontal { background-position: -16px -224px; } +.ui-icon-grip-solid-vertical { background-position: -32px -224px; } +.ui-icon-grip-solid-horizontal { background-position: -48px -224px; } +.ui-icon-gripsmall-diagonal-se { background-position: -64px -224px; } +.ui-icon-grip-diagonal-se { background-position: -80px -224px; } + + +/* Misc visuals +----------------------------------*/ + +/* Corner radius */ +.ui-corner-tl { -moz-border-radius-topleft: 5px; -webkit-border-top-left-radius: 5px; border-top-left-radius: 5px; } +.ui-corner-tr { -moz-border-radius-topright: 5px; -webkit-border-top-right-radius: 5px; border-top-right-radius: 5px; } +.ui-corner-bl { -moz-border-radius-bottomleft: 5px; -webkit-border-bottom-left-radius: 5px; border-bottom-left-radius: 5px; } +.ui-corner-br { -moz-border-radius-bottomright: 5px; -webkit-border-bottom-right-radius: 5px; border-bottom-right-radius: 5px; } +.ui-corner-top { -moz-border-radius-topleft: 5px; -webkit-border-top-left-radius: 5px; border-top-left-radius: 5px; -moz-border-radius-topright: 5px; -webkit-border-top-right-radius: 5px; border-top-right-radius: 5px; } +.ui-corner-bottom { -moz-border-radius-bottomleft: 5px; -webkit-border-bottom-left-radius: 5px; border-bottom-left-radius: 5px; -moz-border-radius-bottomright: 5px; -webkit-border-bottom-right-radius: 5px; border-bottom-right-radius: 5px; } +.ui-corner-right { -moz-border-radius-topright: 5px; -webkit-border-top-right-radius: 5px; border-top-right-radius: 5px; -moz-border-radius-bottomright: 5px; -webkit-border-bottom-right-radius: 5px; border-bottom-right-radius: 5px; } +.ui-corner-left { -moz-border-radius-topleft: 5px; -webkit-border-top-left-radius: 5px; border-top-left-radius: 5px; -moz-border-radius-bottomleft: 5px; -webkit-border-bottom-left-radius: 5px; border-bottom-left-radius: 5px; } +.ui-corner-all { -moz-border-radius: 5px; -webkit-border-radius: 5px; border-radius: 5px; } + +/* Overlays */ +.ui-widget-overlay { background: #aaaaaa url(images/ui-bg_flat_0_aaaaaa_40x100.png) 50% 50% repeat-x; opacity: .30;filter:Alpha(Opacity=30); } +.ui-widget-shadow { margin: -8px 0 0 -8px; padding: 8px; background: #aaaaaa url(images/ui-bg_flat_0_aaaaaa_40x100.png) 50% 50% repeat-x; opacity: .30;filter:Alpha(Opacity=30); -moz-border-radius: 8px; -webkit-border-radius: 8px; } \ No newline at end of file diff --git a/3.0/themes/pear4gallery3/helpers/pear4gallery3_installer.php b/3.0/themes/pear4gallery3/helpers/pear4gallery3_installer.php new file mode 100644 index 00000000..58318e1b --- /dev/null +++ b/3.0/themes/pear4gallery3/helpers/pear4gallery3_installer.php @@ -0,0 +1,27 @@ + + diff --git a/3.0/themes/pear4gallery3/icons/addcomment.gif b/3.0/themes/pear4gallery3/icons/addcomment.gif new file mode 100644 index 00000000..35cd6f81 Binary files /dev/null and b/3.0/themes/pear4gallery3/icons/addcomment.gif differ diff --git a/3.0/themes/pear4gallery3/icons/album.gif b/3.0/themes/pear4gallery3/icons/album.gif new file mode 100644 index 00000000..9c59d447 Binary files /dev/null and b/3.0/themes/pear4gallery3/icons/album.gif differ diff --git a/3.0/themes/pear4gallery3/icons/button_left.png b/3.0/themes/pear4gallery3/icons/button_left.png new file mode 100644 index 00000000..1567289c Binary files /dev/null and b/3.0/themes/pear4gallery3/icons/button_left.png differ diff --git a/3.0/themes/pear4gallery3/icons/button_pause.png b/3.0/themes/pear4gallery3/icons/button_pause.png new file mode 100644 index 00000000..aefcd29f Binary files /dev/null and b/3.0/themes/pear4gallery3/icons/button_pause.png differ diff --git a/3.0/themes/pear4gallery3/icons/button_play.png b/3.0/themes/pear4gallery3/icons/button_play.png new file mode 100644 index 00000000..c9deeb07 Binary files /dev/null and b/3.0/themes/pear4gallery3/icons/button_play.png differ diff --git a/3.0/themes/pear4gallery3/icons/button_right.png b/3.0/themes/pear4gallery3/icons/button_right.png new file mode 100644 index 00000000..6a62078b Binary files /dev/null and b/3.0/themes/pear4gallery3/icons/button_right.png differ diff --git a/3.0/themes/pear4gallery3/icons/carousel.png b/3.0/themes/pear4gallery3/icons/carousel.png new file mode 100644 index 00000000..17dab5b3 Binary files /dev/null and b/3.0/themes/pear4gallery3/icons/carousel.png differ diff --git a/3.0/themes/pear4gallery3/icons/carousel_active.png b/3.0/themes/pear4gallery3/icons/carousel_active.png new file mode 100644 index 00000000..52be650e Binary files /dev/null and b/3.0/themes/pear4gallery3/icons/carousel_active.png differ diff --git a/3.0/themes/pear4gallery3/icons/cart.gif b/3.0/themes/pear4gallery3/icons/cart.gif new file mode 100644 index 00000000..27e7be94 Binary files /dev/null and b/3.0/themes/pear4gallery3/icons/cart.gif differ diff --git a/3.0/themes/pear4gallery3/icons/close.gif b/3.0/themes/pear4gallery3/icons/close.gif new file mode 100644 index 00000000..3019ba47 Binary files /dev/null and b/3.0/themes/pear4gallery3/icons/close.gif differ diff --git a/3.0/themes/pear4gallery3/icons/color.css b/3.0/themes/pear4gallery3/icons/color.css new file mode 100644 index 00000000..890e5112 --- /dev/null +++ b/3.0/themes/pear4gallery3/icons/color.css @@ -0,0 +1,278 @@ +/* i18n('Ice Carbon Icons'); ?> + * $Revision: 16034 $ + */ + +#gallery { + color: #999 !important; + background-color: #333 !important; +} +body.gallery { background-color: #333 !important; } + +.gbBlock { + border-color: #666 !important; +} + +.gcBorder1 { border-color: #6f6f6f !important; } +.gcBorder2 { border-color: #666 !important; } + +#gallery a { color: #999 !important; } +#gallery a:hover { color: #ccc !important; } +#gallery a:active { color: #ccc !important; } + +.giError { color: #f00 !important; } +.giInfo { color: #888 !important; } +.block-core-PeerList .current { color: #ccc !important; } + +table.gbDataTable th { background-color: #4f4f4f !important; } +.gbEven { background-color: #3f3f3f !important; } +.gbOdd { background-color: #393939 !important; } + +#gallery select { + background-color: #bbb !important; + -moz-border-top-colors: #AAA #EEE !important; + -moz-border-left-colors: #AAA #EEE !important; + -moz-border-bottom-colors: #AAA #EEE !important; + -moz-border-right-colors: #AAA #EEE !important; +} + +#gallery input { + background-color: #bbb !important; + -moz-border-top-colors: #AAA #EEE !important; + -moz-border-left-colors: #AAA #EEE !important; + -moz-border-bottom-colors: #AAA #EEE !important; + -moz-border-right-colors: #AAA #EEE !important; +} + +#gallery textarea { + background-color: #bbb !important; + -moz-border-top-colors: #AAA #EEE !important; + -moz-border-left-colors: #AAA #EEE !important; + -moz-border-bottom-colors: #AAA #EEE !important; + -moz-border-right-colors: #AAA #EEE !important; +} + +#gallery input:focus, #gallery textarea:focus { + background-color: #ddd !important; + -moz-border-top-colors: #AAA #EEE !important; + -moz-border-left-colors: #AAA #EEE !important; + -moz-border-bottom-colors: #AAA #EEE !important; + -moz-border-right-colors: #AAA #EEE !important; +} + +#gallery input.inputTypeSubmit, #gallery input.inputTypeButton { /* No input[type=submit] in IE */ + color: #333 !important; + background-color: #eee !important; +} +#gallery input.inputTypeSubmit:hover, #gallery input.inputTypeButton:hover { /* No input[type=submit] in IE */ + background-color: #ccc !important; +} + +#gallery select:hover { + background-color: #ddd !important; + -moz-border-top-colors: #AAA #EEE !important; + -moz-border-left-colors: #AAA #EEE !important; + -moz-border-bottom-colors: #AAA #EEE !important; + -moz-border-right-colors: #AAA #EEE !important; +} + +#gallery div.gbTabBar a { + color: #00a0ff !important; +} + +#gsSidebarCol { + border: #666 1px solid !important; + background-color: #333 !important; +} + +#gallery img.giThumbnail:hover { + border-color: #333 !important; + background-color: #555 !important; +} + +#gallery img.giThumbnailIce { + background-color: #444 !important; + border: 1px solid #666 !important; +} +#gallery img.giThumbnailIce:hover { + background-color: #555 !important; +} + +#microThumb img.giThumbnailIce { + border-color: #333 !important; +} + +#microThumb img.giThumbnailIce:hover { + border-color: #666 !important; +} + +#microThumbCurrent img.giThumbnailIce { + border-color: #333 !important; +} + +#microThumbCurrent img.giThumbnailIce:hover { + border-color: #666 !important; +} + +#gsNavBar div.gbBreadCrumb { + background-image: none !important; +} + +#photoframe { + background-color: #333 !important; + border: 0px solid #ddd !important; + padding: 0px !important; + -moz-border-radius: 0px !important; +} + +div.gbTabBar span.o { + padding: 6px 0 5px 16px !important; + background: url('table_left.gif') no-repeat left top !important; +} + +#gallery div.gbTabBar span span { + padding: 6px 16px 5px 4px !important; + background: url('table_right.gif') no-repeat right top !important; +} + +#gallery div.gbTabBar a { + color: #666 !important; + text-decoration: none !important; +} + +#gallery div.gbTabBar a:hover { color: #333 !important; } + +#gallery div.gbTabBar span.giSelected { + background-image: url('table_left_on.gif') !important; +} + +#gallery div.gbTabBar span.giSelected span { + color: #333; + background-image: url('table_right_on.gif') !important; +} + +span.bsw_ButtonEnabled { + color: #ddd !important; +} +.autoCompleteContainer li { + background-color: #333 !important; +} + +.buttonAction a { + display: block !important; + width: 20px !important; + height: 20px !important; + margin-left: 7px !important; +} + +.buttonAction a { + opacity: 1.0 !important; + filter: alpha(opacity=100) !important; /* IE's opacity*/ +} + +.buttonAction a:hover { + opacity: 1.0 !important; + filter: alpha(opacity=100)!important; /* IE's opacity*/ + } + + .iconAlbum { + background: url('album.gif') no-repeat !important; + background-position: center center !important; +} + +.buttonClose a { + padding: 0px !important; + width: 15px !important; + height: 15px !important; + background: url('close.gif') no-repeat !important; + margin: 1px !important; +} +.buttonClose a:hover { background-position: -15px 0 !important; } + +.buttonFirst a { + width: 15px !important; + height: 15px !important; + margin-left: 0px !important; + background: url('first.gif') no-repeat !important; +} +.buttonFirst a:hover { background-position: -15px 0 !important; } + +.buttonLast a { + width: 15px !important; + height: 15px !important; + margin-left: 0px !important; + background: url('last.gif') no-repeat !important; +} +.buttonLast a:hover { background-position: -15px 0 !important; } + +.buttonPrev a { + width: 15px !important; + height: 15px !important; + margin-left: 0px !important; + background: url('prev.gif') no-repeat !important; +} +.buttonPrev a:hover { background-position: -15px 0 !important; } + +.buttonNext a { + width: 15px !important; + height: 15px !important; + margin-left: 0px !important; + background: url('next.gif') no-repeat !important; +} +.buttonNext a:hover { background-position: -15px 0 !important; } + +.buttonExif a { + width: 18px !important; + height: 15px !important; + padding: 0px !important; + background: url('exif.gif') no-repeat !important; +} +.buttonExif a:hover { background-position: -18px 0 !important; } + +.buttonPopup a { + width: 17px !important; + height: 15px !important; + padding: 0px !important; + background: url('popup.gif') no-repeat !important; +} +.buttonPopup a:hover { background-position: -17px 0 !important; } + +.buttonAddComment a { + width: 15px !important; + height: 15px !important; + padding: 0px !important; + background: url('addcomment.gif') no-repeat !important; +} +.buttonAddComment a:hover { background-position: -15px 0 !important; } + +.buttonViewComments a { + width: 15px !important; + height: 15px !important; + padding: 0px !important; + background: url('viewcomments.gif') no-repeat !important; +} +.buttonViewComments a:hover { background-position: -15px 0 !important; } + +.buttonViewSlideshow a { + width: 15px !important; + height: 15px !important; + padding: 0px !important; + background: url('slideshow.gif') no-repeat !important; +} +.buttonViewSlideshow a:hover { background-position: -15px 0 !important; } + +.buttonCart a { + width: 16px !important; + height: 15px !important; + padding: 0px !important; + background: url('cart.gif') no-repeat !important; +} +.buttonCart a:hover { background-position: -16px 0 !important; } + +.buttonShowSidebar a { + width: 15px !important; + height: 15px !important; + padding: 0px !important; + background: url('showsidebar.gif') no-repeat !important; +} +.buttonShowSidebar a:hover { background-position: -15px 0 !important; } + diff --git a/3.0/themes/pear4gallery3/icons/color_picker.png b/3.0/themes/pear4gallery3/icons/color_picker.png new file mode 100644 index 00000000..d2e89ab4 Binary files /dev/null and b/3.0/themes/pear4gallery3/icons/color_picker.png differ diff --git a/3.0/themes/pear4gallery3/icons/color_picker_sprite.png b/3.0/themes/pear4gallery3/icons/color_picker_sprite.png new file mode 100644 index 00000000..977797b0 Binary files /dev/null and b/3.0/themes/pear4gallery3/icons/color_picker_sprite.png differ diff --git a/3.0/themes/pear4gallery3/icons/download.png b/3.0/themes/pear4gallery3/icons/download.png new file mode 100644 index 00000000..998b3959 Binary files /dev/null and b/3.0/themes/pear4gallery3/icons/download.png differ diff --git a/3.0/themes/pear4gallery3/icons/email.png b/3.0/themes/pear4gallery3/icons/email.png new file mode 100644 index 00000000..0110d0d1 Binary files /dev/null and b/3.0/themes/pear4gallery3/icons/email.png differ diff --git a/3.0/themes/pear4gallery3/icons/exif.gif b/3.0/themes/pear4gallery3/icons/exif.gif new file mode 100644 index 00000000..281214be Binary files /dev/null and b/3.0/themes/pear4gallery3/icons/exif.gif differ diff --git a/3.0/themes/pear4gallery3/icons/footer_bg.png b/3.0/themes/pear4gallery3/icons/footer_bg.png new file mode 100644 index 00000000..88b30955 Binary files /dev/null and b/3.0/themes/pear4gallery3/icons/footer_bg.png differ diff --git a/3.0/themes/pear4gallery3/icons/grid.png b/3.0/themes/pear4gallery3/icons/grid.png new file mode 100644 index 00000000..11238964 Binary files /dev/null and b/3.0/themes/pear4gallery3/icons/grid.png differ diff --git a/3.0/themes/pear4gallery3/icons/grid_active.png b/3.0/themes/pear4gallery3/icons/grid_active.png new file mode 100644 index 00000000..2602a795 Binary files /dev/null and b/3.0/themes/pear4gallery3/icons/grid_active.png differ diff --git a/3.0/themes/pear4gallery3/icons/hud_control/close.png b/3.0/themes/pear4gallery3/icons/hud_control/close.png new file mode 100644 index 00000000..30ceceae Binary files /dev/null and b/3.0/themes/pear4gallery3/icons/hud_control/close.png differ diff --git a/3.0/themes/pear4gallery3/icons/hud_control/close_over.png b/3.0/themes/pear4gallery3/icons/hud_control/close_over.png new file mode 100644 index 00000000..df94e509 Binary files /dev/null and b/3.0/themes/pear4gallery3/icons/hud_control/close_over.png differ diff --git a/3.0/themes/pear4gallery3/icons/hud_control/comment.png b/3.0/themes/pear4gallery3/icons/hud_control/comment.png new file mode 100644 index 00000000..68d21088 Binary files /dev/null and b/3.0/themes/pear4gallery3/icons/hud_control/comment.png differ diff --git a/3.0/themes/pear4gallery3/icons/hud_control/comment_over.png b/3.0/themes/pear4gallery3/icons/hud_control/comment_over.png new file mode 100644 index 00000000..1d520d7f Binary files /dev/null and b/3.0/themes/pear4gallery3/icons/hud_control/comment_over.png differ diff --git a/3.0/themes/pear4gallery3/icons/hud_control/controlsbg.png b/3.0/themes/pear4gallery3/icons/hud_control/controlsbg.png new file mode 100644 index 00000000..8df96ad8 Binary files /dev/null and b/3.0/themes/pear4gallery3/icons/hud_control/controlsbg.png differ diff --git a/3.0/themes/pear4gallery3/icons/hud_control/download.png b/3.0/themes/pear4gallery3/icons/hud_control/download.png new file mode 100644 index 00000000..dc66d16d Binary files /dev/null and b/3.0/themes/pear4gallery3/icons/hud_control/download.png differ diff --git a/3.0/themes/pear4gallery3/icons/hud_control/download_disabled.png b/3.0/themes/pear4gallery3/icons/hud_control/download_disabled.png new file mode 100644 index 00000000..5f424c6d Binary files /dev/null and b/3.0/themes/pear4gallery3/icons/hud_control/download_disabled.png differ diff --git a/3.0/themes/pear4gallery3/icons/hud_control/download_over.png b/3.0/themes/pear4gallery3/icons/hud_control/download_over.png new file mode 100644 index 00000000..a1723e7d Binary files /dev/null and b/3.0/themes/pear4gallery3/icons/hud_control/download_over.png differ diff --git a/3.0/themes/pear4gallery3/icons/hud_control/info.png b/3.0/themes/pear4gallery3/icons/hud_control/info.png new file mode 100644 index 00000000..ffb7f7a4 Binary files /dev/null and b/3.0/themes/pear4gallery3/icons/hud_control/info.png differ diff --git a/3.0/themes/pear4gallery3/icons/hud_control/info_over.png b/3.0/themes/pear4gallery3/icons/hud_control/info_over.png new file mode 100644 index 00000000..42ec4475 Binary files /dev/null and b/3.0/themes/pear4gallery3/icons/hud_control/info_over.png differ diff --git a/3.0/themes/pear4gallery3/icons/hud_control/next.png b/3.0/themes/pear4gallery3/icons/hud_control/next.png new file mode 100644 index 00000000..59dc8a39 Binary files /dev/null and b/3.0/themes/pear4gallery3/icons/hud_control/next.png differ diff --git a/3.0/themes/pear4gallery3/icons/hud_control/next_disabled.png b/3.0/themes/pear4gallery3/icons/hud_control/next_disabled.png new file mode 100644 index 00000000..2d53548a Binary files /dev/null and b/3.0/themes/pear4gallery3/icons/hud_control/next_disabled.png differ diff --git a/3.0/themes/pear4gallery3/icons/hud_control/next_over.png b/3.0/themes/pear4gallery3/icons/hud_control/next_over.png new file mode 100644 index 00000000..0a14880e Binary files /dev/null and b/3.0/themes/pear4gallery3/icons/hud_control/next_over.png differ diff --git a/3.0/themes/pear4gallery3/icons/hud_control/pause.png b/3.0/themes/pear4gallery3/icons/hud_control/pause.png new file mode 100644 index 00000000..cb6ccc06 Binary files /dev/null and b/3.0/themes/pear4gallery3/icons/hud_control/pause.png differ diff --git a/3.0/themes/pear4gallery3/icons/hud_control/pause_over.png b/3.0/themes/pear4gallery3/icons/hud_control/pause_over.png new file mode 100644 index 00000000..104edf7d Binary files /dev/null and b/3.0/themes/pear4gallery3/icons/hud_control/pause_over.png differ diff --git a/3.0/themes/pear4gallery3/icons/hud_control/play.png b/3.0/themes/pear4gallery3/icons/hud_control/play.png new file mode 100644 index 00000000..babcf734 Binary files /dev/null and b/3.0/themes/pear4gallery3/icons/hud_control/play.png differ diff --git a/3.0/themes/pear4gallery3/icons/hud_control/play_over.png b/3.0/themes/pear4gallery3/icons/hud_control/play_over.png new file mode 100644 index 00000000..873e9d0f Binary files /dev/null and b/3.0/themes/pear4gallery3/icons/hud_control/play_over.png differ diff --git a/3.0/themes/pear4gallery3/icons/hud_control/prev.png b/3.0/themes/pear4gallery3/icons/hud_control/prev.png new file mode 100644 index 00000000..d141070a Binary files /dev/null and b/3.0/themes/pear4gallery3/icons/hud_control/prev.png differ diff --git a/3.0/themes/pear4gallery3/icons/hud_control/prev_disabled.png b/3.0/themes/pear4gallery3/icons/hud_control/prev_disabled.png new file mode 100644 index 00000000..d66f83ff Binary files /dev/null and b/3.0/themes/pear4gallery3/icons/hud_control/prev_disabled.png differ diff --git a/3.0/themes/pear4gallery3/icons/hud_control/prev_over.png b/3.0/themes/pear4gallery3/icons/hud_control/prev_over.png new file mode 100644 index 00000000..fd43d3f5 Binary files /dev/null and b/3.0/themes/pear4gallery3/icons/hud_control/prev_over.png differ diff --git a/3.0/themes/pear4gallery3/icons/knob.png b/3.0/themes/pear4gallery3/icons/knob.png new file mode 100644 index 00000000..66f7d562 Binary files /dev/null and b/3.0/themes/pear4gallery3/icons/knob.png differ diff --git a/3.0/themes/pear4gallery3/icons/larger.png b/3.0/themes/pear4gallery3/icons/larger.png new file mode 100644 index 00000000..c148bdf1 Binary files /dev/null and b/3.0/themes/pear4gallery3/icons/larger.png differ diff --git a/3.0/themes/pear4gallery3/icons/mosaic.png b/3.0/themes/pear4gallery3/icons/mosaic.png new file mode 100644 index 00000000..484fa7bd Binary files /dev/null and b/3.0/themes/pear4gallery3/icons/mosaic.png differ diff --git a/3.0/themes/pear4gallery3/icons/mosaic_active.png b/3.0/themes/pear4gallery3/icons/mosaic_active.png new file mode 100644 index 00000000..aedf8d48 Binary files /dev/null and b/3.0/themes/pear4gallery3/icons/mosaic_active.png differ diff --git a/3.0/themes/pear4gallery3/icons/options_bar_bg.png b/3.0/themes/pear4gallery3/icons/options_bar_bg.png new file mode 100644 index 00000000..6184e30f Binary files /dev/null and b/3.0/themes/pear4gallery3/icons/options_bar_bg.png differ diff --git a/3.0/themes/pear4gallery3/icons/paginator.gif b/3.0/themes/pear4gallery3/icons/paginator.gif new file mode 100644 index 00000000..fb884748 Binary files /dev/null and b/3.0/themes/pear4gallery3/icons/paginator.gif differ diff --git a/3.0/themes/pear4gallery3/icons/pear.css b/3.0/themes/pear4gallery3/icons/pear.css new file mode 100644 index 00000000..03988e76 --- /dev/null +++ b/3.0/themes/pear4gallery3/icons/pear.css @@ -0,0 +1,793 @@ +.gallery-thumb-round { + background: url('rounded.png') no-repeat scroll left top; + position: absolute; +} + +.skimm_div { + position: absolute; +} + +.skimm_small { + position: absolute; +} + +.rNavBar{ + position: relative; + float: right; + top: -22px; +} + +.lNavBar{ + position: relative; + float: left; +} + +.pearTitle { +color: #ddd; +margin: auto; +position: relative; +text-align: center; +width: 50%; +font-variant: small-caps; +font-size: 1.7em !important; +} + +.count { +color: #666; +font-size: 0.7em !important; +} + +#gsNavBar { +background:transparent url('top_bar_bg.png') repeat-x 100% -12px; +position: static; +height: 37px; +padding-top: 10px; +overflow: hidden; +text-shadow: 0 -1px 2px #111111; +font-weight: bold; +} + +#footerWrapper { + min-width: 800px; +width: 100%; +background:transparent url('footer_bg.png') top center; +height:40px; + clear:both; +} + +#logoButton { + display: block; + z-index: 100; +background: transparent url('pear_logo_sml.png') no-repeat center left; +width: 83px; +height: 40px; +border: 0px; +padding: 0px; +margin: auto; +position: relative; +cursor: pointer; /* hand-shaped cursor */ +cursor: hand; /* for IE 5.x */ +} + +#logoButton:hover, #logoButton.hover { +border: 0px; +background: transparent url('pear_logo_sml.png') no-repeat center left; +} + +/************************ COLOR PICKER **************************/ + + +#colorPicker { + position: relative; + color: #FFFFFF; + height: 17px; + padding: 0px 0px; + width: auto; + float: right; + z-index: 100; + font-size: 12px; + top: 11px; +} + + + + +#colorPicker div.label { + margin-top: 2px; + margin-right: 6px; + float: left; + background-color: transparent ! important; + width: auto ! important; + height: 20px; + color: #666666; + display: block; + font-size: 12px; + text-shadow: #111111 0px -1px 1px; +} + +#colorPicker.disabled div.label{ + text-shadow: #242424 0px -1px 1px; + color: #3f3f3f; +} + +#colorPicker .swatch { + float: left; + background-color: #ffffff; + height: 15px; + width: 14px; + display: block; + margin-right: 6px; + margin-top: 2px; + cursor: pointer; +/* background-position: 0px -58px; +*/ background-color: transparent; + background-repeat: no-repeat; +} +/* +#colorPicker .hover-with-swatch, #colorPicker .swatch:hover { + background-position: -1px -37px !important; +} +*/ + + +#colorPicker .sel-with-swatch, #colorPicker .hover-with-sel-with-swatch { + cursor: default ! important; +} + +#colorPicker .disabled-with-swatch, #colorPicker.disabled-with-sel-with-swatch, #colorPicker .disabled-with-hover-with-swatch +{ +/* background-position: 0px 0px ! important; */ + cursor: default ! important; +} + +#colorPicker #black { + background-image: url('color_picker.png') ; + background-position: -1px 0px; +} + +#colorPicker #black:hover { + background-position: -1px -40px; +} + +.black-with-sel-with-swatch{ + background-position: -1px -20px ! important; +} + +#colorPicker #dkgrey { + background-image: url('color_picker.png') ; + background-position: -23px 0px; +} + +#colorPicker #dkgrey:hover { + background-position: -23px -40px; +} + +.dkgrey-with-sel-with-swatch{ + background-position: -23px -20px ! important; +} + +#colorPicker #ltgrey { + background-image: url('color_picker.png'); + background-position: -43px 0px; +} + +#colorPicker #ltgrey:hover { + background-position: -43px -40px; +} + +.ltgrey-with-sel-with-swatch{ + background-position: -43px -20px ! important; +} + +#colorPicker #white { + background-image: url('color_picker.png'); + background-position: -63px 0px; + margin-right: 16px; +} + +#colorPicker #white:hover { + background-position: -63px -40px; +} + +.white-with-sel-with-swatch{ + background-position: -63px -20px ! important; +} + +/************************ SLIDER VIEW **************************/ + +.sliderView { +padding: 7px 37px 7px 3%; +position: relative; +color: #FFFFFF; +top: 10px; +height: 3px; +width: 154px; +float: right; +z-index: 100; +} + +.sliderView .smaller { +height: 14px; +width: 14px; +float: left; +position: relative; +left: -24px; +top: -4px; +cursor: pointer; /* hand-shaped cursor */ +cursor: hand; /* for IE 5.x */ +background: url(smaller.png) top center no-repeat; +} + +.sliderView .larger { +height: 16px; +width: 16px; +float: left; +position: relative; +top: -4px; +left: 133px; +cursor: pointer; /* hand-shaped cursor */ +cursor: hand; /* for IE 5.x */ +background: url(larger.png) top center no-repeat; +} + +/*.sliderView .sliderLeftCap { +height: 15px; +width: 5px; +float: left; +position: relative; +left: 0px; +background: url(view_control/track_left.png) top center repeat-x; +}*/ + +.sliderView .sliderRightCap { +height: 15px; +width: 3px; +float: left; +position: relative; +left: 137px; +background: transparent url(track_fill_right.png) scroll top right no-repeat; +} + +.sliderView .track { +width: 137px; +height: 15px; +background: transparent url(track_fill_left.png) scroll top left no-repeat; +position: relative; +border: 0px; +} + +.sliderView .ui-slider-handle { +background: transparent url('knob.png') top left no-repeat; +position: absolute; +top: -5px; +width: 16px; +height: 16px; +cursor: pointer; /* hand-shaped cursor */ +cursor: hand; /* for IE 5.x */ +margin-left: -7px; +border: 0px; +} + +.disabled-with-sliderView { + +} + +.disabled-with-sliderView .smaller, .disabled-with-sliderView .larger, .disabled-with-sliderView .handle{ +cursor: default; +} + +.disabled-with-sliderView .smaller { + background-image: url('view_control/smaller_dim.png'); +} + +.disabled-with-sliderView .larger { + background-image: url('view_control/larger_dim.png'); +} + +.disabled-with-sliderView .handle { + background-image: url('view_control/knob_dim.png'); +} + +.disabled-with-sliderView .sliderRightCap { + background-image: url('view_control/track_right_dim.png') +} + +.disabled-with-sliderView .track { + background-image: url('view_control/track_fill_left_dim.png') +} + + +/************************ VIEW CONTROLS **************************/ +#viewControls { +position: relative; +color: #616161; +width: 381px; +float: left; + margin-left: 30px; + margin-top: 13px; + z-index: 800; + font-size: 12px; + text-shadow: #111111 0px -1px 1px; +} + +.japanese #viewControls { + font-size: 11px; +} + +#viewControls .separator { +width: 55px; +height: 18px; + padding-left: 5px; +} +#viewControls .label { + margin-top:-1px; +} + +#viewControls .viewSwitcher { +height: 14px; + + margin-right: 17px; +float: left; +cursor: pointer; /* hand-shaped cursor */ +cursor: hand; /* for IE 5.x */ + font-weight: bold; +} + +#viewControls .viewSwitcher:hover, #viewControls .sel-with-viewSwitcher, #viewControls .hover-with-viewSwitcher { +color: #ffffff; +} +#viewControls .sel-with-viewSwitcher { + cursor: default; +} +#viewControls #grid { +background: url('grid.png') center left no-repeat; + text-indent: 20px; + +} + +#viewControls #grid:hover, +#viewControls #grid.sel { +color: #ffffff; +background: url('grid_active.png') center left no-repeat; + +} + +#viewControls #carousel { + text-indent: 22px; +background: url('carousel.png') center left no-repeat; + +} + +#viewControls #carousel:hover, +#viewControls #carousel.sel { +background: url('carousel_active.png') center left no-repeat; + +} + + + +#viewControls #mosaic { + +background: url('mosaic.png') center left no-repeat; + text-indent: 20px; +} + +#viewControls #mosaic:hover, +#viewControls #mosaic.sel { +background: url('mosaic_active.png') center left no-repeat; + +} + +#viewControls #slideshow { + text-indent: 16px; +background: url('slideshow.png') center left no-repeat; +float: left; + margin-right: 0px; +} + +#viewControls #slideshow:hover, +#viewControls #slideshow.sel { +color: #ffffff; +background: url('slideshow_active.png') center left no-repeat; + +} +/************************ DETAIL VIEW **************************/ + +#detailView { + margin: 0 auto; + position: fixed; + left: 0; + top: 0; + width: 100%; + height: 100%; + z-index: 999; + background-color: #000000; + display: none; +} + +#detailView .iMovieVideo { + background-color: #000000 ! important; +} + +.titleLabel { + color:#AAAAAA; + font-size:13px; + font-weight:bold; +/* overflow:hidden; +*/ position:relative; + margin:0px auto; + margin-top:16px; + text-align:center; + text-shadow:black 0px 0px 1px; + white-space:nowrap; + height:21px; + text-overflow: ellipsis; +} + +.japanese .titleLabel { + font-size:12px; +} + +.titleLabel:hover { +/* color: #fff;*/ +} + +#detailView .overlay { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; +; + +/* filter + +: alpha(opacity=95); + opacity: 0.95; + -moz-opacity:0.95; */ +} + +#detailView .content { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + overflow: hidden; +} + +#detailView .iMovieVideo +{ + overflow-y: auto; + overflow-x: hidden; +} + +.under-panel #detailView .content { + overflow: hidden; +} + +#detailView .imageContainer { + text-align: center; +/* margin: 69px 69px 0px 69px;*/ + margin-top: 32px; + cursor: pointer; +} + + +#slideshowView .imageContainer { + margin: 0px 0px 0px 0px; + padding: 0px 0px; + overflow: hidden; +} + +#slideshowView .reflectionContainer { + position: absolute; + max-height:50px; + overflow: hidden; +} + +#slideshowView .reflection { + vertical-align: top; +/* height: 20%;*/ + width: 100%; + left:0px; + position: absolute; + +} + +#slideshowView .reflectionMask { + background: transparent url('reflection-black.png') repeat-x 0px bottom; + width: 100%; + height: 100%; + overflow: hidden; + display: block; + z-index: 100; + position: absolute; + vertical-align: top; + left:0px; + padding-bottom: 2px ; +} + + +.bg_white #slideshowView .reflectionMask { + background-image: url('reflection-white.png'); +} + +.bg_ltgrey #slideshowView .reflectionMask { + background-image: url('reflection-lightgrey.png'); +} + + +.bg_dkgrey #slideshowView .reflectionMask { + background-image: url('reflections-darkgrey.png'); +} + + +#slideshowView #slideshowHoverView { + height:58px; +} + + +/************************ HOVER VIEW **************************/ + +#hoverView { + height: 58px; + position: absolute; + bottom: 30px; + width: 99%; + text-align: center; + z-index: 999; +} + +#hoverView #hoverViewMenu { + margin: 0 auto; + position: relative; + width: 262px; + height: 58px; + width: 300px; + height: 60px; + background: url('hud_control/controlsbg.png') top left no-repeat; +} + +#hoverView .download_detail_disabled { + position: absolute; + top: 0px; + top: 10px; + left: 9px; + height: 58px; + width: 43px; + background: url('hud_control/download_disabled.png') top left no-repeat; +} + +#hoverView .download_detail { + cursor: pointer; /* hand-shaped cursor */ + cursor: hand; /* for IE 5.x */ + position: absolute; + top: 0px; + top: 10px; + left: 9px; + height: 58px; + width: 43px; + background: url('hud_control/download.png') top left no-repeat; +} + +#hoverView .download_detail:hover { + background: url('hud_control/download_over.png') top left no-repeat; +} + +#hoverView .prev_detail_disabled { + position: absolute; + top: 0px; + top: 18px; + left: 82px; + height: 58px; + width: 43px; + background: url('hud_control/prev_disabled.png') top left no-repeat; +} + +#hoverView .prev_detail { + cursor: pointer; /* hand-shaped cursor */ + cursor: hand; /* for IE 5.x */ + position: absolute; + top: 0px; + top: 18px; + left: 82px; + height: 58px; + width: 43px; + background: url('hud_control/prev.png') top left no-repeat; +} + +#hoverView .prev_detail:hover { + background: url('hud_control/prev_over.png') top left no-repeat; +} + +#hoverView .play_detail { + cursor: pointer; /* hand-shaped cursor */ + cursor: hand; /* for IE 5.x */ + position: absolute; + top: 0px; + top: 10px; + left: 134px; + height: 58px; + width: 43px; + background: url('hud_control/play.png') top left no-repeat; +} + +#hoverView .play_detail:hover { + background: url('hud_control/play_over.png') top left no-repeat; +} + +#hoverView .pause_detail { + cursor: pointer; /* hand-shaped cursor */ + cursor: hand; /* for IE 5.x */ + position: absolute; + top: 0px; + top: 10px; + left: 134px; + height: 58px; + width: 43px; + background: url('hud_control/pause.png') top left no-repeat; +} + +#hoverView .pause_detail:hover { + background: url('hud_control/pause_over.png') top left no-repeat; +} + +#hoverView .next_detail_disabled { + position: absolute; + top: 0px; + top: 18px; + left: 177px; + height: 58px; + width: 43px; + background: url('hud_control/next_disabled.png') top left no-repeat; +} + +#hoverView .next_detail { + cursor: pointer; /* hand-shaped cursor */ + cursor: hand; /* for IE 5.x */ + position: absolute; + top: 0px; + top: 18px; + left: 177px; + height: 58px; + width: 43px; + background: url('hud_control/next.png') top left no-repeat; +} + +#hoverView .next_detail:hover { + background: url('hud_control/next_over.png') top left no-repeat; +} + + +#hoverView #comment_detail { + cursor: pointer; /* hand-shaped cursor */ + cursor: hand; /* for IE 5.x */ + position: absolute; + top: 0px; + left: 209px; + height: 58px; + width: 43px; + background: url('hud_control/comment.png') top left no-repeat; + padding-top: 18px; + text-align: center; + font-size: 12px; + font-weight: bold; +} + +.japanese #hoverView #comment_detail { + font-size: 11px; +} + +#hoverView #comment_detail:hover { + background: url('hud_control/comment_over.png') top left no-repeat; +} + +#hoverView .info_detail_selected { + cursor: pointer; /* hand-shaped cursor */ + cursor: hand; /* for IE 5.x */ + position: absolute; + top: 0px; + top: 10px; + left: 240px; + height: 58px; + width: 43px; + background: url('hud_control/info_over.png') top left no-repeat; +} + +#hoverView .info_detail { + cursor: pointer; /* hand-shaped cursor */ + cursor: hand; /* for IE 5.x */ + position: absolute; + top: 0px; + top: 10px; + left: 240px; + height: 58px; + width: 43px; + background: url('hud_control/info.png') top left no-repeat; +} + +#hoverView .info_detail:hover { + background: url('hud_control/info_over.png') top left no-repeat; +} + + +/* ******************** Button Alts *************** */ +#backToAlbumLink { + left: 24px; + float: left; + position: absolute; + top: 13px; + white-space: nowrap; +} + +#backToAlbumButton .outer{ + min-width: 108px !important; +} + +button.push { + background: transparent none repeat scroll 0%; + margin: 0px; + padding-right: 0px; + border: medium none; + height: 34px; + min-width: 80px; + outline-color: invert; + outline-style: none; + outline-width: medium; + padding-left: 20px; + vertical-align: baseline; +} + +button.push .outer { + display: block; + padding: 0px 4px 0px 2px; + position: relative: + width: 100%; +} + +button.large-with-push { + cursor: pointer ; + position: relative ; +} + +button.large-with-push .label { + font-weight: bold; + line-height: 13px ; + height: 18px; + padding: 7px 25px 10px 20px; + margin-left: 6px; + text-indent: -14px; + background: transparent url('button_right.png') no-repeat scroll right -71px; + right: -6px; + color: #E0E0E0; + text-shadow: #1E1E1E 0px 0px 2px; +} + +button.large-with-push .outer { + height: 34px; + padding-left: 2px; + margin-left: -3px; + background: transparent url('button_left.png') no-repeat scroll 0px -71px; + +} + +button.large-with-push:active .label, +button.active-with-large-with-push .label{ + + color: #939393; + text-shadow: black 0px 0px 0px; + background: transparent url('button_right.png') no-repeat scroll right -106px ; +} + +button.large-with-push:active img, +button.active-with-large-with-push img { + opacity: .5; + filter: alpha(opacity=50); +} + + +button.large-with-push:active .outer, +button.active-with-large-with-push .outer { + background: transparent url('button_left.png') no-repeat scroll left -106px; +} diff --git a/3.0/themes/pear4gallery3/icons/pear_logo_lrg.png b/3.0/themes/pear4gallery3/icons/pear_logo_lrg.png new file mode 100644 index 00000000..9041a714 Binary files /dev/null and b/3.0/themes/pear4gallery3/icons/pear_logo_lrg.png differ diff --git a/3.0/themes/pear4gallery3/icons/pear_logo_sml.png b/3.0/themes/pear4gallery3/icons/pear_logo_sml.png new file mode 100644 index 00000000..d69401f9 Binary files /dev/null and b/3.0/themes/pear4gallery3/icons/pear_logo_sml.png differ diff --git a/3.0/themes/pear4gallery3/icons/popup.gif b/3.0/themes/pear4gallery3/icons/popup.gif new file mode 100644 index 00000000..fbb09ea0 Binary files /dev/null and b/3.0/themes/pear4gallery3/icons/popup.gif differ diff --git a/3.0/themes/pear4gallery3/icons/reflection-black.png b/3.0/themes/pear4gallery3/icons/reflection-black.png new file mode 100644 index 00000000..5f9a7ccb Binary files /dev/null and b/3.0/themes/pear4gallery3/icons/reflection-black.png differ diff --git a/3.0/themes/pear4gallery3/icons/reflection-darkgrey.png b/3.0/themes/pear4gallery3/icons/reflection-darkgrey.png new file mode 100644 index 00000000..662cb232 Binary files /dev/null and b/3.0/themes/pear4gallery3/icons/reflection-darkgrey.png differ diff --git a/3.0/themes/pear4gallery3/icons/reflection-lightgrey.png b/3.0/themes/pear4gallery3/icons/reflection-lightgrey.png new file mode 100644 index 00000000..89848422 Binary files /dev/null and b/3.0/themes/pear4gallery3/icons/reflection-lightgrey.png differ diff --git a/3.0/themes/pear4gallery3/icons/reflection-white.png b/3.0/themes/pear4gallery3/icons/reflection-white.png new file mode 100644 index 00000000..27e02aaf Binary files /dev/null and b/3.0/themes/pear4gallery3/icons/reflection-white.png differ diff --git a/3.0/themes/pear4gallery3/icons/rounded.png b/3.0/themes/pear4gallery3/icons/rounded.png new file mode 100644 index 00000000..ce8e31d3 Binary files /dev/null and b/3.0/themes/pear4gallery3/icons/rounded.png differ diff --git a/3.0/themes/pear4gallery3/icons/showsidebar.gif b/3.0/themes/pear4gallery3/icons/showsidebar.gif new file mode 100644 index 00000000..b5fcd868 Binary files /dev/null and b/3.0/themes/pear4gallery3/icons/showsidebar.gif differ diff --git a/3.0/themes/pear4gallery3/icons/slider.png b/3.0/themes/pear4gallery3/icons/slider.png new file mode 100644 index 00000000..ddb4995c Binary files /dev/null and b/3.0/themes/pear4gallery3/icons/slider.png differ diff --git a/3.0/themes/pear4gallery3/icons/slideshow.gif b/3.0/themes/pear4gallery3/icons/slideshow.gif new file mode 100644 index 00000000..2738b9c8 Binary files /dev/null and b/3.0/themes/pear4gallery3/icons/slideshow.gif differ diff --git a/3.0/themes/pear4gallery3/icons/slideshow.png b/3.0/themes/pear4gallery3/icons/slideshow.png new file mode 100644 index 00000000..54b04497 Binary files /dev/null and b/3.0/themes/pear4gallery3/icons/slideshow.png differ diff --git a/3.0/themes/pear4gallery3/icons/slideshow_active.png b/3.0/themes/pear4gallery3/icons/slideshow_active.png new file mode 100644 index 00000000..4aa7386c Binary files /dev/null and b/3.0/themes/pear4gallery3/icons/slideshow_active.png differ diff --git a/3.0/themes/pear4gallery3/icons/smaller.png b/3.0/themes/pear4gallery3/icons/smaller.png new file mode 100644 index 00000000..c57cd27f Binary files /dev/null and b/3.0/themes/pear4gallery3/icons/smaller.png differ diff --git a/3.0/themes/pear4gallery3/icons/subscribe.png b/3.0/themes/pear4gallery3/icons/subscribe.png new file mode 100644 index 00000000..470cca6e Binary files /dev/null and b/3.0/themes/pear4gallery3/icons/subscribe.png differ diff --git a/3.0/themes/pear4gallery3/icons/table_left.gif b/3.0/themes/pear4gallery3/icons/table_left.gif new file mode 100644 index 00000000..fa3981cf Binary files /dev/null and b/3.0/themes/pear4gallery3/icons/table_left.gif differ diff --git a/3.0/themes/pear4gallery3/icons/table_left_on.gif b/3.0/themes/pear4gallery3/icons/table_left_on.gif new file mode 100644 index 00000000..9cd7c879 Binary files /dev/null and b/3.0/themes/pear4gallery3/icons/table_left_on.gif differ diff --git a/3.0/themes/pear4gallery3/icons/table_right.gif b/3.0/themes/pear4gallery3/icons/table_right.gif new file mode 100644 index 00000000..cf4b804d Binary files /dev/null and b/3.0/themes/pear4gallery3/icons/table_right.gif differ diff --git a/3.0/themes/pear4gallery3/icons/table_right_on.gif b/3.0/themes/pear4gallery3/icons/table_right_on.gif new file mode 100644 index 00000000..f508859e Binary files /dev/null and b/3.0/themes/pear4gallery3/icons/table_right_on.gif differ diff --git a/3.0/themes/pear4gallery3/icons/top_bar_bg.png b/3.0/themes/pear4gallery3/icons/top_bar_bg.png new file mode 100644 index 00000000..a6bb0759 Binary files /dev/null and b/3.0/themes/pear4gallery3/icons/top_bar_bg.png differ diff --git a/3.0/themes/pear4gallery3/icons/track_fill_left.png b/3.0/themes/pear4gallery3/icons/track_fill_left.png new file mode 100644 index 00000000..2866db5c Binary files /dev/null and b/3.0/themes/pear4gallery3/icons/track_fill_left.png differ diff --git a/3.0/themes/pear4gallery3/icons/track_fill_right.png b/3.0/themes/pear4gallery3/icons/track_fill_right.png new file mode 100644 index 00000000..c70af587 Binary files /dev/null and b/3.0/themes/pear4gallery3/icons/track_fill_right.png differ diff --git a/3.0/themes/pear4gallery3/icons/upload.png b/3.0/themes/pear4gallery3/icons/upload.png new file mode 100644 index 00000000..6331c692 Binary files /dev/null and b/3.0/themes/pear4gallery3/icons/upload.png differ diff --git a/3.0/themes/pear4gallery3/icons/viewcomments.gif b/3.0/themes/pear4gallery3/icons/viewcomments.gif new file mode 100644 index 00000000..fd3ca07d Binary files /dev/null and b/3.0/themes/pear4gallery3/icons/viewcomments.gif differ diff --git a/3.0/themes/pear4gallery3/images/avatar.jpg b/3.0/themes/pear4gallery3/images/avatar.jpg new file mode 100644 index 00000000..acad9314 Binary files /dev/null and b/3.0/themes/pear4gallery3/images/avatar.jpg differ diff --git a/3.0/themes/pear4gallery3/images/ico-album.png b/3.0/themes/pear4gallery3/images/ico-album.png new file mode 100644 index 00000000..affa1b84 Binary files /dev/null and b/3.0/themes/pear4gallery3/images/ico-album.png differ diff --git a/3.0/themes/pear4gallery3/images/ico-denied-inactive.png b/3.0/themes/pear4gallery3/images/ico-denied-inactive.png new file mode 100644 index 00000000..56db3ff5 Binary files /dev/null and b/3.0/themes/pear4gallery3/images/ico-denied-inactive.png differ diff --git a/3.0/themes/pear4gallery3/images/ico-denied-passive.png b/3.0/themes/pear4gallery3/images/ico-denied-passive.png new file mode 100644 index 00000000..1e992230 Binary files /dev/null and b/3.0/themes/pear4gallery3/images/ico-denied-passive.png differ diff --git a/3.0/themes/pear4gallery3/images/ico-denied.png b/3.0/themes/pear4gallery3/images/ico-denied.png new file mode 100644 index 00000000..08f24936 Binary files /dev/null and b/3.0/themes/pear4gallery3/images/ico-denied.png differ diff --git a/3.0/themes/greydragon/css/colorpacks/carbon/images/ico-error.png b/3.0/themes/pear4gallery3/images/ico-error.png similarity index 100% rename from 3.0/themes/greydragon/css/colorpacks/carbon/images/ico-error.png rename to 3.0/themes/pear4gallery3/images/ico-error.png diff --git a/3.0/themes/pear4gallery3/images/ico-help.png b/3.0/themes/pear4gallery3/images/ico-help.png new file mode 100644 index 00000000..5c870176 Binary files /dev/null and b/3.0/themes/pear4gallery3/images/ico-help.png differ diff --git a/3.0/themes/pear4gallery3/images/ico-info.png b/3.0/themes/pear4gallery3/images/ico-info.png new file mode 100644 index 00000000..12cd1aef Binary files /dev/null and b/3.0/themes/pear4gallery3/images/ico-info.png differ diff --git a/3.0/themes/pear4gallery3/images/ico-lock.png b/3.0/themes/pear4gallery3/images/ico-lock.png new file mode 100644 index 00000000..2ebc4f6f Binary files /dev/null and b/3.0/themes/pear4gallery3/images/ico-lock.png differ diff --git a/3.0/themes/pear4gallery3/images/ico-print.png b/3.0/themes/pear4gallery3/images/ico-print.png new file mode 100644 index 00000000..b82a8e1e Binary files /dev/null and b/3.0/themes/pear4gallery3/images/ico-print.png differ diff --git a/3.0/themes/pear4gallery3/images/ico-separator-rtl.gif b/3.0/themes/pear4gallery3/images/ico-separator-rtl.gif new file mode 100644 index 00000000..d9061a46 Binary files /dev/null and b/3.0/themes/pear4gallery3/images/ico-separator-rtl.gif differ diff --git a/3.0/themes/pear4gallery3/images/ico-separator.gif b/3.0/themes/pear4gallery3/images/ico-separator.gif new file mode 100644 index 00000000..3de2d0d3 Binary files /dev/null and b/3.0/themes/pear4gallery3/images/ico-separator.gif differ diff --git a/3.0/themes/pear4gallery3/images/ico-success-inactive.png b/3.0/themes/pear4gallery3/images/ico-success-inactive.png new file mode 100644 index 00000000..74b2032f Binary files /dev/null and b/3.0/themes/pear4gallery3/images/ico-success-inactive.png differ diff --git a/3.0/themes/pear4gallery3/images/ico-success-passive.png b/3.0/themes/pear4gallery3/images/ico-success-passive.png new file mode 100644 index 00000000..dc8d1ded Binary files /dev/null and b/3.0/themes/pear4gallery3/images/ico-success-passive.png differ diff --git a/3.0/themes/greydragon/css/colorpacks/carbon/images/ico-success.png b/3.0/themes/pear4gallery3/images/ico-success.png similarity index 100% rename from 3.0/themes/greydragon/css/colorpacks/carbon/images/ico-success.png rename to 3.0/themes/pear4gallery3/images/ico-success.png diff --git a/3.0/themes/pear4gallery3/images/ico-view-comments.png b/3.0/themes/pear4gallery3/images/ico-view-comments.png new file mode 100644 index 00000000..e5d3630f Binary files /dev/null and b/3.0/themes/pear4gallery3/images/ico-view-comments.png differ diff --git a/3.0/themes/pear4gallery3/images/ico-view-fullsize.png b/3.0/themes/pear4gallery3/images/ico-view-fullsize.png new file mode 100644 index 00000000..0be23e9b Binary files /dev/null and b/3.0/themes/pear4gallery3/images/ico-view-fullsize.png differ diff --git a/3.0/themes/pear4gallery3/images/ico-view-slideshow-rtl.png b/3.0/themes/pear4gallery3/images/ico-view-slideshow-rtl.png new file mode 100644 index 00000000..5788b3c3 Binary files /dev/null and b/3.0/themes/pear4gallery3/images/ico-view-slideshow-rtl.png differ diff --git a/3.0/themes/pear4gallery3/images/ico-view-slideshow.png b/3.0/themes/pear4gallery3/images/ico-view-slideshow.png new file mode 100644 index 00000000..82f61f63 Binary files /dev/null and b/3.0/themes/pear4gallery3/images/ico-view-slideshow.png differ diff --git a/3.0/themes/pear4gallery3/images/ico-warning.png b/3.0/themes/pear4gallery3/images/ico-warning.png new file mode 100644 index 00000000..628cf2da Binary files /dev/null and b/3.0/themes/pear4gallery3/images/ico-warning.png differ diff --git a/3.0/themes/pear4gallery3/images/loading-large.gif b/3.0/themes/pear4gallery3/images/loading-large.gif new file mode 100644 index 00000000..cc70a7a8 Binary files /dev/null and b/3.0/themes/pear4gallery3/images/loading-large.gif differ diff --git a/3.0/themes/pear4gallery3/images/loading-small.gif b/3.0/themes/pear4gallery3/images/loading-small.gif new file mode 100644 index 00000000..d0bce154 Binary files /dev/null and b/3.0/themes/pear4gallery3/images/loading-small.gif differ diff --git a/3.0/themes/pear4gallery3/images/select-photos-backg.png b/3.0/themes/pear4gallery3/images/select-photos-backg.png new file mode 100644 index 00000000..81c2d616 Binary files /dev/null and b/3.0/themes/pear4gallery3/images/select-photos-backg.png differ diff --git a/3.0/themes/pear4gallery3/js/imageflow.packed.js b/3.0/themes/pear4gallery3/js/imageflow.packed.js new file mode 100644 index 00000000..dc3f1017 --- /dev/null +++ b/3.0/themes/pear4gallery3/js/imageflow.packed.js @@ -0,0 +1,38 @@ +/* +Name: ImageFlow +Version: 1.3.0 (March 9 2010) +Author: Finn Rudolph +Support: http://finnrudolph.de/ImageFlow + +License: ImageFlow is licensed under a Creative Commons + Attribution-Noncommercial 3.0 Unported License + (http://creativecommons.org/licenses/by-nc/3.0/). + + You are free: + + to Share - to copy, distribute and transmit the work + + to Remix - to adapt the work + + Under the following conditions: + + Attribution. You must attribute the work in the manner specified by the author or licensor + (but not in any way that suggests that they endorse you or your use of the work). + + Noncommercial. You may not use this work for commercial purposes. + + + For any reuse or distribution, you must make clear to others the license terms of this work. + + Any of the above conditions can be waived if you get permission from the copyright holder. + + Nothing in this license impairs or restricts the author's moral rights. + +Credits: This script is based on Michael L. Perrys Cover flow in Javascript [1]. + The reflections are generated server-sided by a slightly hacked version + of Richard Daveys easyreflections [2] written in PHP. The mouse wheel + support is an implementation of Adomas Paltanavicius JavaScript mouse + wheel code [3]. It also uses the domReadyEvent from Tanny O'Haley [4]. + + [1] http://www.adventuresinsoftware.com/blog/?p=104#comment-1981 + [2] http://reflection.corephp.co.uk/v2.php + [3] http://adomas.org/javascript-mouse-wheel/ + [4] http://tanny.ica.com/ICA/TKO/tkoblog.nsf/dx/domcontentloaded-for-browsers-part-v +*/ + +/* ImageFlow - compressed with http://dean.edwards.name/packer/ */ +eval(function(p,a,c,k,e,r){e=function(c){return(c35?String.fromCharCode(c+29):c.toString(36))};if(!''.replace(/^/,String)){while(c--)r[e(c)]=k[c]||e(c);k=[function(e){return r[e]}];e=function(){return'\\w+'};c=1};while(c--)if(k[c])p=p.replace(new RegExp('\\b'+e(c)+'\\b','g'),k[c]);return p}('v 4Z(){u.2v={3Q:50,2N:1.5a,2J:y,30:C,1a:y,3j:\'1E\',S:\'5u\',2h:1.0,J:4,33:\'\',2f:C,3a:0.49,36:1.0,2z:v(){B.3V=u.2i},1Y:y,1T:[10,8,6,4,2],2x:5t,2y:1d,3e:C,2M:C,3G:\'\',1N:0.5,31:y,3L:\'\',3u:0.6,2G:C,2X:\'e-5m\',1q:14,1y:y,34:5n,3k:y,3r:1,3D:C,3H:y,1g:4w};9 t=u;u.X=v(a){17(9 b 3T t.2v){u[b]=(a!==1t&&a[b]!==1t)?a[b]:t.2v[b]}9 c=B.R(t.S);7(c){c.A.1H=\'2g\';u.N=c;7(u.3N()){u.H=B.R(t.S+\'5j\');u.2j=B.R(t.S+\'4z\');u.1V=B.R(t.S+\'3X\');u.1B=B.R(t.S+\'4c\');u.1R=B.R(t.S+\'4f\');u.3x=B.R(t.S+\'4j\');u.3l=B.R(t.S+\'4s\');u.1L=B.R(t.S+\'5e\');u.1M=[];u.1w=0;u.E=0;u.1C=0;u.1D=0;u.2q=C;u.2s=C;u.T=y;9 d=u.N.3F;9 e=W.11(d/t.2N);B.R(t.S+\'2A\').A.3b=((e*0.5)-22)+\'M\';c.A.1c=e+\'M\';u.21()}}};u.3N=v(){9 a=t.D.U(\'12\',\'23\');9 b,2S,1l,15;9 c=t.N.F.1r;17(9 d=0;d1){9 i;17(i=0;i1){t.1e.X();t.I.X();t.K.X();t.2o.X();7(t.1y){t.P.X()}7(t.2G){t.1B.A.1H=\'2g\'}}}};u.2Y=v(){9 a=t.H.F.1r;9 i=0,20=0;9 b=Z;17(9 c=0;c(c.h/(t.1N+1))){c.1j=t.2x;c.26=t.2x}G{c.1j=t.2y;c.26=t.2y}7(t.2f===y){c.A.4O=\'4S\';c.A.1Z=\'4U\'}c.A.3s=t.3j;i++}}u.O=t.1M.1r;7(t.2f===y){c=t.H.F[t.1M[0]];u.3J=c.w*t.O;c.A.55=(t.Y/2)+(c.w/2)+\'M\';t.H.A.1c=c.h+\'M\';t.1V.A.1c=(t.1A-c.h)+\'M\'}7(t.2q){t.2q=y;t.E=t.3r-1;7(t.E<0){t.E=0}7(t.1a){t.E=t.E+t.J}2U=(t.1a)?(t.O-(t.J))-1:t.O-1;7(t.E>2U){t.E=2U}7(t.3D===y){t.1K(-t.E*t.1g)}7(t.3H){t.1K(5v)}}7(t.O>1){t.1J(t.E)}t.1K(t.1w)};u.1K=v(x){u.1w=x;u.1o=t.O;17(9 a=0;at.1D){b.A.1H=\'3S\';b.A.1Z=\'2H\'}G{9 z=(W.4I(4p+x*x)+1d)*t.36;9 d=x/z*t.1I+t.1I;b.A.1Z=\'4r\';9 e=(b.h/b.w*b.1j)/z*t.1I;9 f=0;1G(e>t.1A){1x y:f=b.1j/z*t.1I;13;1E:e=t.1A;f=b.w*e/b.h;13}9 g=(t.2u-e)+((e/(t.1N+1))*t.1N);b.A.2Z=d-(b.1j/2)/z*t.1I+\'M\';7(f&&e){b.A.1c=e+\'M\';b.A.1u=f+\'M\';b.A.5s=g+\'M\'}b.A.1H=\'2g\';1G(x<0){1x C:u.1o++;13;1E:u.1o=t.1o-1;13}1G(b.i==t.E){1x y:b.1k=v(){t.1J(u.i)};13;1E:u.1o=t.1o+1;7(b.2i!==\'\'){b.1k=t.2z}13}b.A.1o=t.1o}}G{7((c+t.1U)t.1D){b.A.1H=\'3S\'}G{b.A.1H=\'2g\';1G(b.i==t.E){1x y:b.1k=v(){t.1J(u.i)};13;1E:7(b.2i!==\'\'){b.1k=t.2z}13}}t.H.A.2R=(x-t.3J)+\'M\'}x+=t.1g}};u.1J=v(a){9 b,1v;7(t.1a){7(a+1===t.J){1v=t.O-t.J;b=-1v*t.1g;a=1v-1}7(a===(t.O-t.J)){1v=t.J-1;b=-1v*t.1g;a=1v+1}}9 x=-a*t.1g;u.1C=x;u.1D=x;u.E=a;9 c=t.H.F[a].1z(\'4v\');7(c===\'\'||t.30===y){c=\'&56;\'}t.2j.4e=c;7(t.I.T===y){7(t.1a){u.1b=((a-t.J)*t.1f)/(t.O-(t.J*2)-1)-t.I.2k}G{u.1b=(a*t.1f)/(t.O-1)-t.I.2k}t.1R.A.2R=(t.1b-t.1q)+\'M\'}7(t.1Y===C||t.2h!==t.2v.2h){t.D.27(t.H.F[a],t.1T[0]);t.H.F[a].1j=t.H.F[a].1j*t.2h;9 d=0;9 e=0;9 f=0;9 g=t.1T.1r;17(9 i=1;i<(t.J+1);i++){7((i+1)>g){d=t.1T[g-1]}G{d=t.1T[i]}e=a+i;f=a-i;7(e=0){t.D.27(t.H.F[f],d);t.H.F[f].1j=t.H.F[f].26}}}7(b){t.1K(b)}7(t.T===y){t.T=C;t.2E()}};u.2E=v(){1G(t.1Ct.1w+1){1x C:t.1K(t.1w+(t.1C-t.1w)/3);L.1n(t.2E,t.3Q);t.T=C;13;1E:t.T=y;13}};u.2l=v(a){7(t.1y){t.P.2c()}t.1J(a)};u.P={2n:1,X:v(){(t.3k)?t.P.1p():t.P.1h()},2c:v(){t.D.2L(t.N,\'3m\',t.P.2c);t.P.1h()},3o:v(){t.D.16(t.N,\'3m\',t.P.2c)},1p:v(){t.D.25(t.1L,\'1y 43\');t.1L.1k=v(){t.P.1h()};t.P.3t=L.47(t.P.2P,t.34);L.1n(t.P.3o,1d)},1h:v(){t.D.25(t.1L,\'1y 4b\');t.1L.1k=v(){t.P.1p()};L.4d(t.P.3t)},2P:v(){9 a=t.E+t.P.2n;9 b=y;7(a===t.O){t.P.2n=-1;b=C}7(a<0){t.P.2n=1;b=C}(b)?t.P.2P():t.1J(a)}};u.1e={X:v(){7(L.1m){t.N.1m(\'4h\',t.1e.1W,y)}t.D.16(t.N,\'4k\',t.1e.1W)},1W:v(a){9 b=0;7(!a){a=L.1F}7(a.3z){b=a.3z/4q}G 7(a.3B){b=-a.3B/3}7(b){t.1e.19(b)}t.D.2p(a)},19:v(a){9 b=y;9 c=0;7(a>0){7(t.E>=1){c=t.E-1;b=C}}G{7(t.E<(t.O-1)){c=t.E+1;b=C}}7(b){t.2l(c)}}};u.I={1P:Z,2T:0,2e:0,2k:0,T:y,X:v(){t.D.16(t.N,\'4B\',t.I.3K);t.D.16(t.N,\'3M\',t.I.1h);t.D.16(B,\'3M\',t.I.1h);t.N.4H=v(){9 a=C;7(t.I.T){a=y}V a}},1p:v(o){t.I.1P=o;t.I.2T=t.I.2e-o.3I+t.1b},1h:v(){t.I.1P=Z;t.I.T=y},3K:v(e){9 a=0;7(!e){e=L.1F}7(e.2D){a=e.2D}G 7(e.3P){a=e.3P+B.2K.3d+B.4Q.3d}t.I.2e=a;7(t.I.1P!==Z){9 b=(t.I.2e-t.I.2T)+t.1q;7(b<(-t.1b)){b=-t.1b}7(b>(t.1f-t.1b)){b=t.1f-t.1b}9 c,E;7(t.1a){c=(b+t.1b)/(t.1f/(t.O-(t.J*2)-1));E=W.11(c)+t.J}G{c=(b+t.1b)/(t.1f/(t.O-1));E=W.11(c)}t.I.2k=b;t.I.1P.A.2Z=b+\'M\';7(t.E!==E){t.2l(E)}t.I.T=C}}};u.K={x:0,2B:0,2r:0,T:y,2F:C,X:v(){t.D.16(t.1V,\'4Y\',t.K.1p);t.D.16(B,\'51\',t.K.19);t.D.16(B,\'53\',t.K.1h)},3f:v(e){9 a=y;7(e.28){9 b=e.28[0].1C;7(b===t.1V||b===t.1R||b===t.1B){a=C}}V a},2C:v(e){9 x=0;7(e.28){x=e.28[0].2D}V x},1p:v(e){t.K.2B=t.K.2C(e);t.K.T=C;t.D.2p(e)},3w:v(){9 a=y;7(t.K.T){a=C}V a},19:v(e){7(t.K.3w&&t.K.3f(e)){9 a=(t.1a)?(t.O-(t.J*2)-1):(t.O-1);7(t.K.2F){t.K.2r=(a-t.E)*(t.Y/a);t.K.2F=y}9 b=-(t.K.2C(e)-t.K.2B-t.K.2r);7(b<0){b=0}7(b>t.Y){b=t.Y}t.K.x=b;9 c=W.11(b/(t.Y/a));c=a-c;7(t.E!==c){7(t.1a){c=c+t.J}t.2l(c)}t.D.2p(e)}},1h:v(){t.K.2r=t.K.x;t.K.T=y}};u.2o={X:v(){B.5d=v(a){t.2o.19(a)}},19:v(a){9 b=t.2o.1W(a);1G(b){1x 39:t.1e.19(-1);13;1x 37:t.1e.19(1);13}},1W:v(a){a=a||L.1F;V a.5h}};u.D={16:v(a,b,c){7(a.1m){a.1m(b,c,y)}G 7(a.3g){a["e"+b+c]=c;a[b+c]=v(){a["e"+b+c](L.1F)};a.3g("3y"+b,a[b+c])}},2L:v(a,b,c){7(a.32){a.32(b,c,y)}G 7(a.3A){7(a[b+c]===1t){5r(\'D.2L » 4G 3i 3C 1F 48 1t - 4K 4l 4M 42 3i 3C 4N 4n 1F?\')}a.3A(\'3y\'+b,a[b+c]);a[b+c]=Z;a[\'e\'+b+c]=Z}},27:v(a,b){7(t.1Y===C){a.A.1Y=b/10;a.A.4P=\'4a(1Y=\'+b*10+\')\'}},U:v(a,b,c){9 d=B.4R(a);d.2d(\'38\',t.S+\'4T\'+b);7(c!==1t){b+=\' \'+c}t.D.25(d,b);V d},25:v(a,b){7(a){a.2d(\'3Z\',b);a.2d(\'4V\',b)}},2p:v(e){7(e.3E){e.3E()}G{e.4X=y}V y},3c:v(){9 a=L.2t;7(1X L.2t!=\'v\'){L.2t=v(){t.2m()}}G{L.2t=v(){7(a){a()}t.2m()}}}}}9 1i={2Q:"1i",1S:{},1s:1,1Q:y,2O:Z,3n:v(a){7(!a.$$1s){a.$$1s=u.1s++;7(u.1Q){a()}u.1S[a.$$1s]=a}},58:v(a){7(a.$$1s){4x u.1S[a.$$1s]}},18:v(){7(u.1Q){V}u.1Q=C;17(9 i 3T u.1S){u.1S[i]()}},2w:v(){7(u.1Q){V}7(/5c|4y/i.3O(4g.5f)){7(/4A|2I/.3O(B.3p)){u.18()}G{1n(u.2Q+".2w()",1d)}}G 7(B.R("2V")){V C}7(1X u.2O==="v"){7(1X B.2W!==\'1t\'&&(B.2W(\'2K\')[0]!==Z||B.2K!==Z)){7(u.2O()){u.18()}G{1n(u.2Q+".2w()",4C)}}}V C},X:v(){7(B.1m){B.1m("5k",v(){1i.18()},y)}1n("1i.2w()",1d);v 18(){1i.18()}7(1X 16!=="1t"){16(L,"3R",18)}G 7(B.1m){B.1m("3R",18,y)}G 7(1X L.2a==="v"){9 a=L.2a;L.2a=v(){1i.18();a()}}G{L.2a=18}/*@4E@7(@5o||@3Y)B.44("<3U 38=2V 54 1l=\\"//:\\"><\\/3U>");9 b=B.R("2V");b.59=v(){7(u.3p=="2I"){1i.18()}};@5b@*/}};9 5l=v(a){1i.3n(a)};1i.X();',62,342,'|||||||if||var|||||||||||||||||||||this|function|||false||style|document|true|Helper|imageID|childNodes|else|imagesDiv|MouseDrag|imageFocusMax|Touch|window|px|ImageFlowDiv|max|Slideshow|appendChild|getElementById|ImageFlowID|busy|createDocumentElement|return|Math|init|imagesDivWidth|null||round|div|break||imageNode|addEvent|for|run|handle|circular|newSliderX|height|100|MouseWheel|scrollbarWidth|xStep|stop|domReadyEvent|pc|onclick|src|addEventListener|setTimeout|zIndex|start|sliderWidth|length|domReadyID|undefined|width|clonedImageID|current|case|slideshow|getAttribute|maxHeight|scrollbarDiv|target|memTarget|default|event|switch|visibility|size|glideTo|moveTo|buttonSlideshow|indexArray|reflectionP|cloneNode|object|bDone|sliderDiv|events|opacityArray|maxFocus|navigationDiv|get|typeof|opacity|display|completed|loadingProgress||images|nodeType|setClassName|pcMem|setOpacity|touches|nodeName|onload|IMG|interrupt|setAttribute|mouseX|imageScaling|visible|imageFocusM|url|captionDiv|newX|glideOnEvent|refresh|direction|Key|suppressBrowserDefault|firstRefresh|stopX|firstCheck|onresize|imagesDivHeight|defaults|schedule|percentLandscape|percentOther|onClick|_loading_txt|startX|getX|pageX|animate|first|slider|none|complete|buttons|body|removeEvent|reflections|aspectRatio|DOMContentLoadedCustom|slide|name|marginLeft|version|objectX|maxId|__ie_onload|getElementsByTagName|sliderCursor|loadingStatus|left|captions|reflectionPNG|removeEventListener|imagePath|slideshowSpeed|button|imagesM||id||imagesHeight|paddingTop|addResizeEvent|scrollLeft|preloadImages|isOnNavigationDiv|attachEvent|createTextNode|to|imageCursor|slideshowAutoplay|buttonPreviousDiv|click|add|addInterruptEvent|readyState|02|startID|cursor|action|scrollbarP|loading|isBusy|buttonNextDiv|on|wheelDelta|detachEvent|detail|detach|glideToStartID|preventDefault|offsetWidth|reflectionGET|startAnimation|offsetLeft|totalImagesWidth|drag|reflectPath|mouseup|createStructure|test|clientX|animationSpeed|load|hidden|in|script|location|reflect|_navigation|_win64|class||next|trying|pause|write|php|navigation|setInterval|is|67|alpha|play|_scrollbar|clearInterval|innerHTML|_slider|navigator|DOMMouseScroll|firstChild|_next|mousewheel|you|marginTop|unattached|loading_bar|10000|120|block|_previous|previous|onmousedown|alt|150|delete|WebKit|_caption|loaded|mousemove|250|longdesc|cc_on|xPosition|Pointer|onselectstart|sqrt|caption|perhaps|_loading|are|an|position|filter|documentElement|createElement|relative|_|inline|className|1000|returnValue|touchstart|ImageFlow||touchmove|loading_txt|touchend|defer|paddingLeft|nbsp|scrollbar|remove|onreadystatechange|964|end|KHTML|onkeydown|_slideshow|userAgent|_loading_bar|keyCode|replaceChild|_images|DOMContentLoaded|domReady|resize|1500|_win32|img|removeChild|alert|top|118|imageflow|5000'.split('|'),0,{})); + diff --git a/3.0/themes/pear4gallery3/js/jquery-ui-1.7.3.custom.min.js b/3.0/themes/pear4gallery3/js/jquery-ui-1.7.3.custom.min.js new file mode 100644 index 00000000..d33ad5be --- /dev/null +++ b/3.0/themes/pear4gallery3/js/jquery-ui-1.7.3.custom.min.js @@ -0,0 +1,20 @@ +/* + * jQuery UI 1.7.3 + * + * Copyright (c) 2009 AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT (MIT-LICENSE.txt) + * and GPL (GPL-LICENSE.txt) licenses. + * + * http://docs.jquery.com/UI + */ jQuery.ui||(function(c){var i=c.fn.remove,d=c.browser.mozilla&&(parseFloat(c.browser.version)<1.9);c.ui={version:"1.7.3",plugin:{add:function(k,l,n){var m=c.ui[k].prototype;for(var j in n){m.plugins[j]=m.plugins[j]||[];m.plugins[j].push([l,n[j]])}},call:function(j,l,k){var n=j.plugins[l];if(!n||!j.element[0].parentNode){return}for(var m=0;m0){return true}m[j]=1;l=(m[j]>0);m[j]=0;return l},isOverAxis:function(k,j,l){return(k>j)&&(k<(j+l))},isOver:function(o,k,n,m,j,l){return c.ui.isOverAxis(o,n,j)&&c.ui.isOverAxis(k,m,l)},keyCode:{BACKSPACE:8,CAPS_LOCK:20,COMMA:188,CONTROL:17,DELETE:46,DOWN:40,END:35,ENTER:13,ESCAPE:27,HOME:36,INSERT:45,LEFT:37,NUMPAD_ADD:107,NUMPAD_DECIMAL:110,NUMPAD_DIVIDE:111,NUMPAD_ENTER:108,NUMPAD_MULTIPLY:106,NUMPAD_SUBTRACT:109,PAGE_DOWN:34,PAGE_UP:33,PERIOD:190,RIGHT:39,SHIFT:16,SPACE:32,TAB:9,UP:38}};if(d){var f=c.attr,e=c.fn.removeAttr,h="http://www.w3.org/2005/07/aaa",a=/^aria-/,b=/^wairole:/;c.attr=function(k,j,l){var m=l!==undefined;return(j=="role"?(m?f.call(this,k,j,"wairole:"+l):(f.apply(this,arguments)||"").replace(b,"")):(a.test(j)?(m?k.setAttributeNS(h,j.replace(a,"aaa:"),l):f.call(this,k,j.replace(a,"aaa:"))):f.apply(this,arguments)))};c.fn.removeAttr=function(j){return(a.test(j)?this.each(function(){this.removeAttributeNS(h,j.replace(a,""))}):e.call(this,j))}}c.fn.extend({remove:function(j,k){return this.each(function(){if(!k){if(!j||c.filter(j,[this]).length){c("*",this).add(this).each(function(){c(this).triggerHandler("remove")})}}return i.call(c(this),j,k)})},enableSelection:function(){return this.attr("unselectable","off").css("MozUserSelect","").unbind("selectstart.ui")},disableSelection:function(){return this.attr("unselectable","on").css("MozUserSelect","none").bind("selectstart.ui",function(){return false})},scrollParent:function(){var j;if((c.browser.msie&&(/(static|relative)/).test(this.css("position")))||(/absolute/).test(this.css("position"))){j=this.parents().filter(function(){return(/(relative|absolute|fixed)/).test(c.curCSS(this,"position",1))&&(/(auto|scroll)/).test(c.curCSS(this,"overflow",1)+c.curCSS(this,"overflow-y",1)+c.curCSS(this,"overflow-x",1))}).eq(0)}else{j=this.parents().filter(function(){return(/(auto|scroll)/).test(c.curCSS(this,"overflow",1)+c.curCSS(this,"overflow-y",1)+c.curCSS(this,"overflow-x",1))}).eq(0)}return(/fixed/).test(this.css("position"))||!j.length?c(document):j}});c.extend(c.expr[":"],{data:function(l,k,j){return !!c.data(l,j[3])},focusable:function(k){var l=k.nodeName.toLowerCase(),j=c.attr(k,"tabindex");return(/input|select|textarea|button|object/.test(l)?!k.disabled:"a"==l||"area"==l?k.href||!isNaN(j):!isNaN(j))&&!c(k)["area"==l?"parents":"closest"](":hidden").length},tabbable:function(k){var j=c.attr(k,"tabindex");return(isNaN(j)||j>=0)&&c(k).is(":focusable")}});function g(m,n,o,l){function k(q){var p=c[m][n][q]||[];return(typeof p=="string"?p.split(/,?\s+/):p)}var j=k("getter");if(l.length==1&&typeof l[0]=="string"){j=j.concat(k("getterSetter"))}return(c.inArray(o,j)!=-1)}c.widget=function(k,j){var l=k.split(".")[0];k=k.split(".")[1];c.fn[k]=function(p){var n=(typeof p=="string"),o=Array.prototype.slice.call(arguments,1);if(n&&p.substring(0,1)=="_"){return this}if(n&&g(l,k,p,o)){var m=c.data(this[0],k);return(m?m[p].apply(m,o):undefined)}return this.each(function(){var q=c.data(this,k);(!q&&!n&&c.data(this,k,new c[l][k](this,p))._init());(q&&n&&c.isFunction(q[p])&&q[p].apply(q,o))})};c[l]=c[l]||{};c[l][k]=function(o,n){var m=this;this.namespace=l;this.widgetName=k;this.widgetEventPrefix=c[l][k].eventPrefix||k;this.widgetBaseClass=l+"-"+k;this.options=c.extend({},c.widget.defaults,c[l][k].defaults,c.metadata&&c.metadata.get(o)[k],n);this.element=c(o).bind("setData."+k,function(q,p,r){if(q.target==o){return m._setData(p,r)}}).bind("getData."+k,function(q,p){if(q.target==o){return m._getData(p)}}).bind("remove",function(){return m.destroy()})};c[l][k].prototype=c.extend({},c.widget.prototype,j);c[l][k].getterSetter="option"};c.widget.prototype={_init:function(){},destroy:function(){this.element.removeData(this.widgetName).removeClass(this.widgetBaseClass+"-disabled "+this.namespace+"-state-disabled").removeAttr("aria-disabled")},option:function(l,m){var k=l,j=this;if(typeof l=="string"){if(m===undefined){return this._getData(l)}k={};k[l]=m}c.each(k,function(n,o){j._setData(n,o)})},_getData:function(j){return this.options[j]},_setData:function(j,k){this.options[j]=k;if(j=="disabled"){this.element[k?"addClass":"removeClass"](this.widgetBaseClass+"-disabled "+this.namespace+"-state-disabled").attr("aria-disabled",k)}},enable:function(){this._setData("disabled",false)},disable:function(){this._setData("disabled",true)},_trigger:function(l,m,n){var p=this.options[l],j=(l==this.widgetEventPrefix?l:this.widgetEventPrefix+l);m=c.Event(m);m.type=j;if(m.originalEvent){for(var k=c.event.props.length,o;k;){o=c.event.props[--k];m[o]=m.originalEvent[o]}}this.element.trigger(m,n);return !(c.isFunction(p)&&p.call(this.element[0],m,n)===false||m.isDefaultPrevented())}};c.widget.defaults={disabled:false};c.ui.mouse={_mouseInit:function(){var j=this;this.element.bind("mousedown."+this.widgetName,function(k){return j._mouseDown(k)}).bind("click."+this.widgetName,function(k){if(j._preventClickEvent){j._preventClickEvent=false;k.stopImmediatePropagation();return false}});if(c.browser.msie){this._mouseUnselectable=this.element.attr("unselectable");this.element.attr("unselectable","on")}this.started=false},_mouseDestroy:function(){this.element.unbind("."+this.widgetName);(c.browser.msie&&this.element.attr("unselectable",this._mouseUnselectable))},_mouseDown:function(l){l.originalEvent=l.originalEvent||{};if(l.originalEvent.mouseHandled){return}(this._mouseStarted&&this._mouseUp(l));this._mouseDownEvent=l;var k=this,m=(l.which==1),j=(typeof this.options.cancel=="string"?c(l.target).parents().add(l.target).filter(this.options.cancel).length:false);if(!m||j||!this._mouseCapture(l)){return true}this.mouseDelayMet=!this.options.delay;if(!this.mouseDelayMet){this._mouseDelayTimer=setTimeout(function(){k.mouseDelayMet=true},this.options.delay)}if(this._mouseDistanceMet(l)&&this._mouseDelayMet(l)){this._mouseStarted=(this._mouseStart(l)!==false);if(!this._mouseStarted){l.preventDefault();return true}}this._mouseMoveDelegate=function(n){return k._mouseMove(n)};this._mouseUpDelegate=function(n){return k._mouseUp(n)};c(document).bind("mousemove."+this.widgetName,this._mouseMoveDelegate).bind("mouseup."+this.widgetName,this._mouseUpDelegate);(c.browser.safari||l.preventDefault());l.originalEvent.mouseHandled=true;return true},_mouseMove:function(j){if(c.browser.msie&&!j.button){return this._mouseUp(j)}if(this._mouseStarted){this._mouseDrag(j);return j.preventDefault()}if(this._mouseDistanceMet(j)&&this._mouseDelayMet(j)){this._mouseStarted=(this._mouseStart(this._mouseDownEvent,j)!==false);(this._mouseStarted?this._mouseDrag(j):this._mouseUp(j))}return !this._mouseStarted},_mouseUp:function(j){c(document).unbind("mousemove."+this.widgetName,this._mouseMoveDelegate).unbind("mouseup."+this.widgetName,this._mouseUpDelegate);if(this._mouseStarted){this._mouseStarted=false;this._preventClickEvent=(j.target==this._mouseDownEvent.target);this._mouseStop(j)}return false},_mouseDistanceMet:function(j){return(Math.max(Math.abs(this._mouseDownEvent.pageX-j.pageX),Math.abs(this._mouseDownEvent.pageY-j.pageY))>=this.options.distance)},_mouseDelayMet:function(j){return this.mouseDelayMet},_mouseStart:function(j){},_mouseDrag:function(j){},_mouseStop:function(j){},_mouseCapture:function(j){return true}};c.ui.mouse.defaults={cancel:null,distance:1,delay:0}})(jQuery);;/* + * jQuery UI Slider 1.7.3 + * + * Copyright (c) 2009 AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT (MIT-LICENSE.txt) + * and GPL (GPL-LICENSE.txt) licenses. + * + * http://docs.jquery.com/UI/Slider + * + * Depends: + * ui.core.js + */ (function(a){a.widget("ui.slider",a.extend({},a.ui.mouse,{_init:function(){var b=this,c=this.options;this._keySliding=false;this._handleIndex=null;this._detectOrientation();this._mouseInit();this.element.addClass("ui-slider ui-slider-"+this.orientation+" ui-widget ui-widget-content ui-corner-all");this.range=a([]);if(c.range){if(c.range===true){this.range=a("
    ");if(!c.values){c.values=[this._valueMin(),this._valueMin()]}if(c.values.length&&c.values.length!=2){c.values=[c.values[0],c.values[0]]}}else{this.range=a("
    ")}this.range.appendTo(this.element).addClass("ui-slider-range");if(c.range=="min"||c.range=="max"){this.range.addClass("ui-slider-range-"+c.range)}this.range.addClass("ui-widget-header")}if(a(".ui-slider-handle",this.element).length==0){a('').appendTo(this.element).addClass("ui-slider-handle")}if(c.values&&c.values.length){while(a(".ui-slider-handle",this.element).length').appendTo(this.element).addClass("ui-slider-handle")}}this.handles=a(".ui-slider-handle",this.element).addClass("ui-state-default ui-corner-all");this.handle=this.handles.eq(0);this.handles.add(this.range).filter("a").click(function(d){d.preventDefault()}).hover(function(){if(!c.disabled){a(this).addClass("ui-state-hover")}},function(){a(this).removeClass("ui-state-hover")}).focus(function(){if(!c.disabled){a(".ui-slider .ui-state-focus").removeClass("ui-state-focus");a(this).addClass("ui-state-focus")}else{a(this).blur()}}).blur(function(){a(this).removeClass("ui-state-focus")});this.handles.each(function(d){a(this).data("index.ui-slider-handle",d)});this.handles.keydown(function(i){var f=true;var e=a(this).data("index.ui-slider-handle");if(b.options.disabled){return}switch(i.keyCode){case a.ui.keyCode.HOME:case a.ui.keyCode.END:case a.ui.keyCode.UP:case a.ui.keyCode.RIGHT:case a.ui.keyCode.DOWN:case a.ui.keyCode.LEFT:f=false;if(!b._keySliding){b._keySliding=true;a(this).addClass("ui-state-active");b._start(i,e)}break}var g,d,h=b._step();if(b.options.values&&b.options.values.length){g=d=b.values(e)}else{g=d=b.value()}switch(i.keyCode){case a.ui.keyCode.HOME:d=b._valueMin();break;case a.ui.keyCode.END:d=b._valueMax();break;case a.ui.keyCode.UP:case a.ui.keyCode.RIGHT:if(g==b._valueMax()){return}d=g+h;break;case a.ui.keyCode.DOWN:case a.ui.keyCode.LEFT:if(g==b._valueMin()){return}d=g-h;break}b._slide(i,e,d);return f}).keyup(function(e){var d=a(this).data("index.ui-slider-handle");if(b._keySliding){b._stop(e,d);b._change(e,d);b._keySliding=false;a(this).removeClass("ui-state-active")}});this._refreshValue()},destroy:function(){this.handles.remove();this.range.remove();this.element.removeClass("ui-slider ui-slider-horizontal ui-slider-vertical ui-slider-disabled ui-widget ui-widget-content ui-corner-all").removeData("slider").unbind(".slider");this._mouseDestroy()},_mouseCapture:function(d){var e=this.options;if(e.disabled){return false}this.elementSize={width:this.element.outerWidth(),height:this.element.outerHeight()};this.elementOffset=this.element.offset();var h={x:d.pageX,y:d.pageY};var j=this._normValueFromMouse(h);var c=this._valueMax()-this._valueMin()+1,f;var k=this,i;this.handles.each(function(l){var m=Math.abs(j-k.values(l));if(c>m){c=m;f=a(this);i=l}});if(e.range==true&&this.values(1)==e.min){f=a(this.handles[++i])}this._start(d,i);k._handleIndex=i;f.addClass("ui-state-active").focus();var g=f.offset();var b=!a(d.target).parents().andSelf().is(".ui-slider-handle");this._clickOffset=b?{left:0,top:0}:{left:d.pageX-g.left-(f.width()/2),top:d.pageY-g.top-(f.height()/2)-(parseInt(f.css("borderTopWidth"),10)||0)-(parseInt(f.css("borderBottomWidth"),10)||0)+(parseInt(f.css("marginTop"),10)||0)};j=this._normValueFromMouse(h);this._slide(d,i,j);return true},_mouseStart:function(b){return true},_mouseDrag:function(d){var b={x:d.pageX,y:d.pageY};var c=this._normValueFromMouse(b);this._slide(d,this._handleIndex,c);return false},_mouseStop:function(b){this.handles.removeClass("ui-state-active");this._stop(b,this._handleIndex);this._change(b,this._handleIndex);this._handleIndex=null;this._clickOffset=null;return false},_detectOrientation:function(){this.orientation=this.options.orientation=="vertical"?"vertical":"horizontal"},_normValueFromMouse:function(d){var c,h;if("horizontal"==this.orientation){c=this.elementSize.width;h=d.x-this.elementOffset.left-(this._clickOffset?this._clickOffset.left:0)}else{c=this.elementSize.height;h=d.y-this.elementOffset.top-(this._clickOffset?this._clickOffset.top:0)}var f=(h/c);if(f>1){f=1}if(f<0){f=0}if("vertical"==this.orientation){f=1-f}var e=this._valueMax()-this._valueMin(),i=f*e,b=i%this.options.step,g=this._valueMin()+i-b;if(b>(this.options.step/2)){g+=this.options.step}return parseFloat(g.toFixed(5))},_start:function(d,c){var b={handle:this.handles[c],value:this.value()};if(this.options.values&&this.options.values.length){b.value=this.values(c);b.values=this.values()}this._trigger("start",d,b)},_slide:function(f,e,d){var g=this.handles[e];if(this.options.values&&this.options.values.length){var b=this.values(e?0:1);if((this.options.values.length==2&&this.options.range===true)&&((e==0&&d>b)||(e==1&&d1){this.options.values[b]=e;this._refreshValue(c);if(!d){this._change(null,b)}}if(arguments.length){if(this.options.values&&this.options.values.length){return this._values(b)}else{return this.value()}}else{return this._values()}},_setData:function(b,d,c){a.widget.prototype._setData.apply(this,arguments);switch(b){case"disabled":if(d){this.handles.filter(".ui-state-focus").blur();this.handles.removeClass("ui-state-hover");this.handles.attr("disabled","disabled")}else{this.handles.removeAttr("disabled")}case"orientation":this._detectOrientation();this.element.removeClass("ui-slider-horizontal ui-slider-vertical").addClass("ui-slider-"+this.orientation);this._refreshValue(c);break;case"value":this._refreshValue(c);break}},_step:function(){var b=this.options.step;return b},_value:function(){var b=this.options.value;if(bthis._valueMax()){b=this._valueMax()}return b},_values:function(b){if(arguments.length){var c=this.options.values[b];if(cthis._valueMax()){c=this._valueMax()}return c}else{return this.options.values}},_valueMin:function(){var b=this.options.min;return b},_valueMax:function(){var b=this.options.max;return b},_refreshValue:function(c){var f=this.options.range,d=this.options,l=this;if(this.options.values&&this.options.values.length){var i,h;this.handles.each(function(p,n){var o=(l.values(p)-l._valueMin())/(l._valueMax()-l._valueMin())*100;var m={};m[l.orientation=="horizontal"?"left":"bottom"]=o+"%";a(this).stop(1,1)[c?"animate":"css"](m,d.animate);if(l.options.range===true){if(l.orientation=="horizontal"){(p==0)&&l.range.stop(1,1)[c?"animate":"css"]({left:o+"%"},d.animate);(p==1)&&l.range[c?"animate":"css"]({width:(o-lastValPercent)+"%"},{queue:false,duration:d.animate})}else{(p==0)&&l.range.stop(1,1)[c?"animate":"css"]({bottom:(o)+"%"},d.animate);(p==1)&&l.range[c?"animate":"css"]({height:(o-lastValPercent)+"%"},{queue:false,duration:d.animate})}}lastValPercent=o})}else{var j=this.value(),g=this._valueMin(),k=this._valueMax(),e=k!=g?(j-g)/(k-g)*100:0;var b={};b[l.orientation=="horizontal"?"left":"bottom"]=e+"%";this.handle.stop(1,1)[c?"animate":"css"](b,d.animate);(f=="min")&&(this.orientation=="horizontal")&&this.range.stop(1,1)[c?"animate":"css"]({width:e+"%"},d.animate);(f=="max")&&(this.orientation=="horizontal")&&this.range[c?"animate":"css"]({width:(100-e)+"%"},{queue:false,duration:d.animate});(f=="min")&&(this.orientation=="vertical")&&this.range.stop(1,1)[c?"animate":"css"]({height:e+"%"},d.animate);(f=="max")&&(this.orientation=="vertical")&&this.range[c?"animate":"css"]({height:(100-e)+"%"},{queue:false,duration:d.animate})}}}));a.extend(a.ui.slider,{getter:"value values",version:"1.7.3",eventPrefix:"slide",defaults:{animate:false,delay:0,distance:0,max:100,min:0,orientation:"horizontal",range:false,step:1,value:0,values:null}})})(jQuery);; \ No newline at end of file diff --git a/3.0/themes/pear4gallery3/js/jquery.parsequery.js b/3.0/themes/pear4gallery3/js/jquery.parsequery.js new file mode 100644 index 00000000..b54d8522 --- /dev/null +++ b/3.0/themes/pear4gallery3/js/jquery.parsequery.js @@ -0,0 +1,19 @@ +/** + * A simple querystring parser. + * Example usage: var q = $.parseQuery(); q.fooreturns "bar" if query contains "?foo=bar"; multiple values are added to an array. + * Values are unescaped by default and plus signs replaced with spaces, or an alternate processing function can be passed in the params object . + * http://actingthemaggot.com/jquery + * + * Copyright (c) 2008 Michael Manning (http://actingthemaggot.com) + * Dual licensed under the MIT (MIT-LICENSE.txt) + * and GPL (GPL-LICENSE.txt) licenses. + **/ +jQuery.parseQuery = function(qs,options) { + var q = (typeof qs === 'string'?qs:window.location.search), o = {'f':function(v){return unescape(v).replace(/\+/g,' ');}}, options = (typeof qs === 'object' && typeof options === 'undefined')?qs:options, o = jQuery.extend({}, o, options), params = {}; + jQuery.each(q.match(/^\??(.*)$/)[1].split('&'),function(i,p){ + p = p.split('='); + p[1] = o.f(p[1]); + params[p[0]] = params[p[0]]?((params[p[0]] instanceof Array)?(params[p[0]].push(p[1]),params[p[0]]):[params[p[0]],p[1]]):p[1]; + }); + return params; +} diff --git a/3.0/themes/pear4gallery3/js/pear.js b/3.0/themes/pear4gallery3/js/pear.js new file mode 100644 index 00000000..8f5ace87 --- /dev/null +++ b/3.0/themes/pear4gallery3/js/pear.js @@ -0,0 +1,468 @@ +var skimimg = 0; +var hash=""; +var bgcolor="black"; +var detailViewMode=false; +var savedHeight = 0; +var savedWidth = 0; + +$(window).resize(function (e) { + if (window.innerHeight == savedHeight && + window.innerWidth == savedWidth) { e.stop(); } + savedHeight = window.innerHeight; + savedWidth = window.innerWidth; + mosaicResize(); +}); + +function swatchSkin(intSkin){ + setCookie('swatchSkin',intSkin,1); + $('#black').removeClass().addClass("swatch"); + $('#dkgrey').removeClass().addClass("swatch"); + $('#ltgrey').removeClass().addClass("swatch"); + $('#white').removeClass().addClass("swatch"); + switch(intSkin) { + // dkgrey + case 'dkgrey' : + case 1 : + $('div.gallery-thumb-round').css('backgroundPosition' , "-200px 0px"); + $('#mosaicTable').css('backgroundColor' , "#262626"); + $('p.giTitle').css("color", "#a9a9a9"); + $("#dkgrey").addClass("dkgrey sel dkgrey-with-sel-with-swatch"); + bgcolor="dkgrey"; + break + // ltgrey + case 'ltgrey' : + case 2 : + $('div.gallery-thumb-round').css('backgroundPosition' , "-400px 0px"); + $('#mosaicTable').css('backgroundColor' , "#d9d9d9"); + $('p.giTitle').css("color", "#333333"); + $("#ltgrey").addClass("ltgrey sel ltgrey-with-sel-with-swatch"); + bgcolor="ltgrey"; + break; + // white + case 'white' : + case 3 : + $('div.gallery-thumb-round').css('backgroundPosition' , "-600px 0px"); + $('#mosaicTable').css('backgroundColor' , "#ffffff"); + $('p.giTitle').css("color", "#444444"); + $("#white").addClass("white sel white-with-sel-with-swatch"); + bgcolor="white"; + break; + // Black + case 'black' : + case 0 : + default: + $('div.gallery-thumb-round').css('backgroundPosition' , "0px 0px"); + $('#mosaicTable').css('backgroundColor' , "#000"); + $('p.giTitle').css("color", "#a3a3a3"); + $("#black").addClass("black sel black-with-sel-with-swatch"); + bgcolor="black"; + break; + } + updateHash(); +} + +function scaleIt(v,sliding){ + //if(maxSize<100)maxSize=150; + + // Remap the 0-1 scale to fit the desired range + //v=.26+(v*(1.0-.26)); + size = (mosaicView) ? v/2 : v; + + toggleReflex(true); + $(".p-photo").each(function (i) { + $(this).attr({height: size+'px',width: size + 'px'}); + $(this).css({height: size+'px',width: size+'px'});}); + if(!mosaicView && !sliding) + toggleReflex(false); +} +function setCookie(c_name,value,expiredays) +{ + var exdate=new Date(); + exdate.setDate(exdate.getDate()+expiredays); + document.cookie=c_name+ "=" +escape(value)+ + ((expiredays==null) ? "" : ";expires="+exdate.toGMTString()); +} + +function getCookie(c_name) +{ + if (document.cookie.length>0) + { + c_start=document.cookie.indexOf(c_name + "="); + if (c_start!=-1) + { + c_start=c_start + c_name.length+1; + c_end=document.cookie.indexOf(";",c_start); + if (c_end==-1) c_end=document.cookie.length; + return unescape(document.cookie.substring(c_start,c_end)); + } + } + return ""; +} + +function checkCookie() +{ + var co=getCookie('slider'); + if (co!=null && co!="") + { + $('#imgSlider').slider("value", co); + } + co=getCookie('swatchSkin'); + if (co!=null && co!="") + { + swatchSkin(co); + } + else + {swatchSkin('black');} +} +var iRatio = iWidth = iHeight=0; +//Set a updating timer so users can't update before the image has appeard.. +function swatchImg(imageId) +{ + if( imageId < 0 || imageId >= slideshowImages.length) return; + currentImg=imageId; + + iWidth=parseFloat(slideshowImages[imageId][2].replace(/,/gi, ".")); + iHeight=parseFloat(slideshowImages[imageId][3].replace(/,/gi, ".")); + iRatio=iWidth/iHeight; + if(isNaN(iRatio)) iRatio=1.3333; + + if( mosaicView ) + { + $('#mosaicDetail').hide(); + $('#imageTitle').html("

    "+slideshowImages[imageId][4]+"

    "); + + $('#mosaicImg').attr('src', slideshowImages[imageId][0]); + $('#mosaicImg').css('cursor', "pointer"); + $('#mosaicDetail').show("slow"); + } + mosaicResize(); + + /* Set controls for hover view. */ + (currentImg==0) ? $('#prev_detail').addClass('prev_detail_disabled') : $('#prev_detail').removeClass('prev_detail_disabled'); + (currentImg!=0) ? $('#prev_detail').addClass('prev_detail') : $('#prev_detail').removeClass('prev_detail'); + (currentImg==slideshowImages.length-1) ? $('#next_detail').addClass('next_detail_disabled') : $('#next_detail').removeClass('next_detail_disabled'); + (currentImg!=slideshowImages.length-1) ? $('#next_detail').addClass('next_detail') : $('#next_detail').removeClass('next_detail'); + /* Update image and title in focus view */ + $('#img_detail').attr('src', slideshowImages[currentImg][0]); + $('#imageTitleLabel').html("

    "+slideshowImages[imageId][4]+"

    "); + if( detailViewMode ) + { + //Image count. + $.get(slideshowImages[currentImg][6]); + } + updateHash(); + $('#info_detail').attr('href', slideshowImages[currentImg][1]); +} + +function updateHash() +{ + viewMode = detailViewMode ? "detail" : (mosaicView ? "mosaic" : "grid"); + hash = "#img=" + currentImg + "&viewMode=" + viewMode + "&bgcolor=" + bgcolor; + window.location.hash = hash; +} +function getAlbumHash(img) +{ + viewMode = detailViewMode ? "detail" : (mosaicView ? "mosaic" : "grid"); + return "#img=" + img + "&viewMode=" + viewMode + "&bgcolor=" + bgcolor; +} + +var currentImg=0; +var mosaicView=false; + +function mosaicResize() +{ + if($('#mosaicGridContainer').length == 0) return; //no element found + var myWidth = 0, myHeight = 0; + if( typeof( window.innerWidth ) == 'number' ) { + //Non-IE + myWidth = window.innerWidth; + myHeight = window.innerHeight; + } else if( document.documentElement && ( document.documentElement.clientWidth || document.documentElement.clientHeight ) ) { + //IE 6+ in 'standards compliant mode' + myWidth = document.documentElement.clientWidth; + myHeight = document.documentElement.clientHeight; + } else if( document.body && ( document.body.clientWidth || document.body.clientHeight ) ) { + //IE 4 compatible + myWidth = document.body.clientWidth; + myHeight = document.body.clientHeight; + } + if($('#pearImageFlow').length != 0) + $('#pearImageFlow').css({'height' : (myHeight-87)+'px', 'width': myWidth+'px', 'minHeight': ((myHeight-70)*0.9)+'px'}); + if($('#imageflow').length != 0) + $('#imageflow').css({'height': (myHeight-53)+'px', 'width': (((myWidth*0.5)<(myHeight-53)) ? myWidth : ((myHeight-65)*2)) +'px'}); + $('#detailImageView').css({'height': myHeight-165+"px"}); + (iRatio>(myWidth/(myHeight-165))) ? $('#img_detail').css({'height': myWidth/iRatio+"px",'width': myWidth+"px"}) : $('#img_detail').css({'height': myHeight-165+"px",'width': (myHeight-165)*iRatio+"px"}); + if(iHeight<(myHeight-165)&&iWidth(myWidth/myHeight)) ? $('#mosaicImg').attr({height: myWidth/iRatio,width: myWidth}) : $('#mosaicImg').attr({height: myHeight,width: myHeight*iRatio}); + if(iHeight slideshowImages.length) + { + id = 0; + } + swatchImg(id); + slideShow = setTimeout("slideShowUpdate("+ (id+1) +")", 1000); +} +function togglePlayPause() +{ + if(slideShow == null)//We are paused + { + $('#play_detail').hide(); + $('#pause_detail').show(); + slideShow = setTimeout("slideShowUpdate("+ (slideShowId+1) +")", 1000); + } + else //We are playing + { + $('#pause_detail').hide(); + $('#play_detail').show(); + clearTimeout(slideShow); + slideShow=null; + } +} +function focusImage(id, redirected) +{ + currentImg=id; + $('#imageTitleLabel').html("

    "+slideshowImages[id][4]+"

    "); + $('#play_detail').hide(); + $('#pause_detail').hide(); + swatchImg(id); + $('#detailView').fadeIn('slow'); + hideHoverV = setTimeout("hideHoverView()",3000); + detailViewMode=true; + updateHash(); + //Image count. + if(!redirected) + $.get(slideshowImages[currentImg][6]); + $('#info_detail').attr('href', slideshowImages[currentImg][1]); +} +var pearCarousel; +function startImageFlow() +{ + $('#mosaicTable').hide(); + + $('#pearImageFlow').show(); + + toggleReflex(true); + + for (var i = 0; i < slideshowImages.length; i++) { + var img = '
    '+$('#mosaicGridContainer img').eq(i).attr('alt')+'"
    '; + var img = ''+slideshowImages[i][4]+''; + console.log(img); + $('#pearImageFlow').append(img); + } + if(!pearCarousel){ + pearCarousel = new ImageFlow(); + pearCarousel.init({ImageFlowID: 'pearImageFlow', aspectRatio: 2.4, imagesHeight: 0.6, opacity: true, reflections: false, startID: currentImg, onClick: function() {focusImage($(this).attr('longdesc'));}, startAnimation: true, xStep: 200, imageFocusM: 1.7, imageFocusMax: 4, opacityArray: [10, 9, 6, 2], percentOther: 130, captions: false, slider: false}); + } +/* + current=(currentImg)*-xstep; + caption_id=currentImg; + refresh(true); + + iShow(conf_images); + iShow(conf_scrollbar); + initMouseWheel(); + initMouseDrag(); + mosaicResize(); + + moveTo(current); + glideTo(current, caption_id); +*/ + switchMode('carousel'); +} +function setKeys() +{ + /* Fixes the back button issue */ +/* window.onunload = function() + { + document = null; + } +*/ $(document).keydown(function(e) + { + var charCode = (e.keyCode ? e.keyCode: e.which); + switch (charCode) + { + case 32: /* Space */ + if( slideShowMode) togglePlayPause(); + case 39: /* Right arrow key */ + case 78: /* N */ + swatchImg(currentImg+1); + // if($('imageflow')) handle(-1); + break; + case 80: /* P */ + case 37: /* Left arrow key */ + swatchImg(currentImg-1); + // if($('imageflow')) handle(1); + break; + } + }); +} +function showHoverView(){ + if(hideHoverV != null) clearTimeout(hideHoverV); + $('#hoverView').show(); + hideHoverV = setTimeout("hideHoverView()",3000); +} +function hideHoverView(){ + if(!hovering) $('#hoverView').fadeOut(); + hideHoverV = null; +} +var hideHoverV=null; +var hovering=false; +function switchMode(mode){ + $('#mosaic,#grid,#carousel').removeClass("sel sel-with-viewSwitcher"); + $('#'+mode).addClass("sel sel-with-viewSwitcher"); +} + +function preFetch() +{ +/* for (var i = 0; i < slideshowImages.length; i++) { + var tempImage = new Element('img', {'src': slideshowImages[i][0]}); + }*/ +} + +function toggleReflex(hide) +{ + if(hide) { + // $$('.Fer').each(function(s) { cvi_reflex.remove(s); }); + $('mosaicGridContainer').select('img[class="Fer"]').each(function(s,index){ Event.observe(s, 'click', function(){ mosaicView ? swatchImg(index) : focusImage(index) ;}); }); + } + else { + // $$('.Fer').each(function(s) { cvi_reflex.add(s, {height: 20, distance: 0 }); }); + $('mosaicGridContainer').select('canvas[class="Fer"]').each(function(s,index){ Event.observe(s, 'click', function(){ mosaicView ? swatchImg(index) : focusImage(index) ;}); }); + } +} + +function hideDetailView() +{ + $('#detailView').hide(); + slideShowMode=detailViewMode=false; + if(slideShow!=null) + clearTimeout(slideShow); + slideShow=null; + updateHash(); +} diff --git a/3.0/themes/pear4gallery3/js/ui.init.js b/3.0/themes/pear4gallery3/js/ui.init.js new file mode 100644 index 00000000..2c67bf3a --- /dev/null +++ b/3.0/themes/pear4gallery3/js/ui.init.js @@ -0,0 +1,131 @@ +/** + * Initialize jQuery UI and Gallery Plugins + */ + +$(document).ready(function() { + + // Initialize Superfish menus (hidden, then shown to address IE issue) + $("#g-site-menu .g-menu").hide().addClass("sf-menu"); + $("#g-site-menu .g-menu").superfish({ + delay: 500, + animation: { + opacity:'show', + height:'show' + }, + pathClass: "g-selected", + speed: 'fast' + }).show(); + + // Initialize status message effects + $("#g-action-status li").gallery_show_message(); + + // Initialize dialogs + $(".g-dialog-link").gallery_dialog(); + + // Initialize short forms + $(".g-short-form").gallery_short_form(); + + // Apply jQuery UI icon, hover, and rounded corner styles + $("input[type=submit]:not(.g-short-form input)").addClass("ui-state-default ui-corner-all"); + if ($("#g-view-menu").length) { + $("#g-view-menu ul").removeClass("g-menu").removeClass("sf-menu"); + $("#g-view-menu a").addClass("ui-icon"); + } + + // Apply jQuery UI icon and hover styles to context menus + if ($(".g-context-menu").length) { + $(".g-context-menu li").addClass("ui-state-default"); + $(".g-context-menu a").addClass("g-button ui-icon-left"); + $(".g-context-menu a").prepend(""); + $(".g-context-menu a span").each(function() { + var iconClass = $(this).parent().attr("class").match(/ui-icon-.[^\s]+/).toString(); + $(this).addClass(iconClass); + }); + } + + // Remove titles for menu options since we're displaying that text anyway + $(".sf-menu a, .sf-menu li").removeAttr("title"); + + // Album and search results views + if ($("#g-album-grid").length) { + // Set equal height for album items and vertically align thumbnails/metadata + $('.g-item').equal_heights().gallery_valign(); + + // Initialize thumbnail hover effect + $(".g-item").hover( + function() { + // Insert a placeholder to hold the item's position in the grid + var placeHolder = $(this).clone().attr("id", "g-place-holder"); + $(this).after($(placeHolder)); + // Style and position the hover item + var position = $(this).position(); + $(this).css("top", position.top).css("left", position.left); + $(this).addClass("g-hover-item"); + // Initialize the contextual menu + $(this).gallery_context_menu(); + // Set the hover item's height + $(this).height("auto"); + var context_menu = $(this).find(".g-context-menu"); + var adj_height = $(this).height() + context_menu.height(); + if ($(this).next().height() > $(this).height()) { + $(this).height($(this).next().height()); + } else if ($(this).prev().height() > $(this).height()) { + $(this).height($(this).prev().height()); + } else { + $(this).height(adj_height); + } + }, + function() { + // Reset item height and position + if ($(this).next().height()) { + var sib_height = $(this).next().height(); + } else { + var sib_height = $(this).prev().height(); + } + if ($.browser.msie && $.browser.version >= 8) { + sib_height = sib_height + 1; + } + $(this).css("height", sib_height); + $(this).css("position", "relative"); + $(this).css("top", 0).css("left", 0); + // Remove the placeholder and hover class from the item + $(this).removeClass("g-hover-item"); + $(this).gallery_valign(); + $("#g-place-holder").remove(); + } + ); + + // Realign any thumbnails that change so that when we rotate a thumb it stays centered. + $(".g-item").bind("gallery.change", function() { + $(".g-item").each(function() { + $(this).height($(this).find("img").height() + 2); + }); + $(".g-item").equal_heights().gallery_valign(); + }); + } + + // Photo/Item item view + if ($("#g-photo,#g-movie").length) { + // Ensure the resized image fits within its container + $("#g-photo,#g-movie").gallery_fit_photo(); + + // Initialize context menus + $("#g-photo,#g-movie").hover(function(){ + $(this).gallery_context_menu(); + }); + + // Add scroll effect for links to named anchors + $.localScroll({ + queue: true, + duration: 1000, + hash: true + }); + + $(this).find(".g-dialog-link").gallery_dialog(); + $(this).find(".g-ajax-link").gallery_ajax(); + } + + // Initialize button hover effect + $.fn.gallery_hover_init(); + +}); diff --git a/3.0/themes/pear4gallery3/theme.info b/3.0/themes/pear4gallery3/theme.info new file mode 100644 index 00000000..ff825e84 --- /dev/null +++ b/3.0/themes/pear4gallery3/theme.info @@ -0,0 +1,10 @@ +name = ".Pear Theme" +description = "A theme with the intention to mimic Apples mobile me gallery." +version = 2.2 +author = "Fredrik Erlandsson " +site = 1 +admin = 0 +author_name = "Fredrik Erlandsson" +author_url = "mailto:fredrik.e@gmail.com" +info_url = "http://codex.gallery2.org/Gallery3:Themes:pear4gallery3" +discuss_url = "http://gallery.menalto.com/node/102280" diff --git a/3.0/themes/pear4gallery3/thumbnail.png b/3.0/themes/pear4gallery3/thumbnail.png new file mode 100644 index 00000000..061c65f3 Binary files /dev/null and b/3.0/themes/pear4gallery3/thumbnail.png differ diff --git a/3.0/themes/pear4gallery3/views/album.html.php b/3.0/themes/pear4gallery3/views/album.html.php new file mode 100644 index 00000000..1b2920e5 --- /dev/null +++ b/3.0/themes/pear4gallery3/views/album.html.php @@ -0,0 +1,90 @@ + + + + + + +
    +
    + +
    +
    +*/?> + + + + admin || access::can("add", $item)): ?> + id") ?> +
  • Add some.", + array("attrs" => html::mark_clean("href=\"$addurl\" class=\"g-dialog-link\""))) ?>
  • + +
  • + + + +
    +album_bottom() ?> + +paginator() ?> + diff --git a/3.0/themes/pear4gallery3/views/block.html.php b/3.0/themes/pear4gallery3/views/block.html.php new file mode 100644 index 00000000..699d7c22 --- /dev/null +++ b/3.0/themes/pear4gallery3/views/block.html.php @@ -0,0 +1,10 @@ + + + + +
    +

    +
    + +
    +
    diff --git a/3.0/themes/pear4gallery3/views/dynamic.html.php b/3.0/themes/pear4gallery3/views/dynamic.html.php new file mode 100644 index 00000000..a8a4d362 --- /dev/null +++ b/3.0/themes/pear4gallery3/views/dynamic.html.php @@ -0,0 +1,29 @@ + +
    +
    + dynamic_top() ?> +
    +

    +
    + +
      + $child): ?> +
    • "> + thumb_top($child) ?> + + photo + +

      title) ?>

      + thumb_bottom($child) ?> + +
    • + +
    +dynamic_bottom() ?> + +paginator() ?> diff --git a/3.0/themes/pear4gallery3/views/hoverView.html.php b/3.0/themes/pear4gallery3/views/hoverView.html.php new file mode 100644 index 00000000..b38ad8f7 --- /dev/null +++ b/3.0/themes/pear4gallery3/views/hoverView.html.php @@ -0,0 +1,23 @@ + +
    +
    +
    +
    + +
    +
    +
    +
    +
    +
    +
    + + +
    + +
    +
    +
    +
    diff --git a/3.0/themes/pear4gallery3/views/movie.html.php b/3.0/themes/pear4gallery3/views/movie.html.php new file mode 100644 index 00000000..158857db --- /dev/null +++ b/3.0/themes/pear4gallery3/views/movie.html.php @@ -0,0 +1,19 @@ + +
    + photo_top() ?> + + paginator() ?> + +
    + resize_top($item) ?> + movie_img(array("class" => "g-movie", "id" => "g-item-id-{$item->id}")) ?> + resize_bottom($item) ?> +
    + +
    +

    title) ?>

    +
    description)) ?>
    +
    + + photo_bottom() ?> +
    diff --git a/3.0/themes/pear4gallery3/views/no_sidebar.html.php b/3.0/themes/pear4gallery3/views/no_sidebar.html.php new file mode 100644 index 00000000..58c57256 --- /dev/null +++ b/3.0/themes/pear4gallery3/views/no_sidebar.html.php @@ -0,0 +1,11 @@ + +
      +
    • + + + + + + "> +
    • +
    diff --git a/3.0/themes/pear4gallery3/views/page.html.php b/3.0/themes/pear4gallery3/views/page.html.php new file mode 100644 index 00000000..eb2ce1d7 --- /dev/null +++ b/3.0/themes/pear4gallery3/views/page.html.php @@ -0,0 +1,194 @@ + +page_subtype == "photo"): + foreach (end($parents)->viewable()->children() as $i => $child) + if(!($child->is_album() || $child->is_movie())) + if($child->url() == $_SERVER['REQUEST_URI']):?> + + + + + + + +html_attributes() ?> xml:lang="en" lang="en"> + + + start_combining("script,css") ?> + + <? if ($page_title): ?> + <?= $page_title ?> + <? else: ?> + <? if ($theme->item()): ?> + <?= $theme->item()->title ?> + <? elseif ($theme->tag()): ?> + <?= t("Photos tagged with %tag_title", array("tag_title" => $theme->tag()->name)) ?> + <? else: /* Not an item, not a tag, no page_title specified. Help! */ ?> + <?= item::root()->title ?> + <? endif ?> + <? endif ?> + + " + type="image/x-icon" /> + + page_type == "collection"): ?> + + + + + + + + script("json2-min.js") ?> + script("jquery.js") ?> + script("jquery.form.js") ?> + script("jquery-ui.js") ?> + script("jquery-ui-1.7.3.custom.min.js") ?> + script("gallery.common.js") ?> + + + script("gallery.ajax.js") ?> + script("gallery.dialog.js") ?> + script("superfish/js/superfish.js") ?> + script("jquery.localscroll.js") ?> + + + page_subtype == "photo"): ?> + script("jquery.scrollTo.js") ?> + script("gallery.show_full_size.js") ?> + page_subtype == "movie"): ?> + script("flowplayer.js") ?> + + + head() ?> + + + script("ui.init.js") ?> + script("jquery.parsequery.js") ?> + script("imageflow.packed.js") ?> + css("yui/reset-fonts-grids.css") ?> + css("superfish/css/superfish.css") ?> + css("themeroller/ui.base.css") ?> + css("screen.css") ?> + css("imageflow.packed.css") ?> + + + + get_combined("script") ?> + + + get_combined("css") ?> + " media="screen,print,projection" /> + " media="screen,print,projection" /> + + + + + + body_attributes() ?>> + + page_top() ?> + site_status() ?> +page_subtype == "login") or ($theme->page_subtype == "reauthenticate")): ?> + + +
    + +
    + +
    item()->title, 40)) ?>   + (item()->children()) ?>) +
    + +
    + +
    +
    + + + + + +
    +
    +
    +
    +
    +
    +
    +
    + +
    +
    Color:
    +
    +
    +
    +
    +
    + +
    +
    +
    Grid
    +
    +
    + +
    Mosaic
    +
    + +
    + +
    Slideshow
    +
    +
    +
    + +
    +
    + + + diff --git a/3.0/themes/pear4gallery3/views/paginator.html.php b/3.0/themes/pear4gallery3/views/paginator.html.php new file mode 100644 index 00000000..a0595f4f --- /dev/null +++ b/3.0/themes/pear4gallery3/views/paginator.html.php @@ -0,0 +1,74 @@ + + + +
      +
    • + + + "> + + + + + "> + +   +
    • + +
    • + + + $first_visible_position, + "to_number" => $last_visible_position, + "count" => $total)) ?> + + $position, "total" => $total)) ?> + + + + +
    • + +
    • + + + "> + + + + "> + + +   +
    • +
    + diff --git a/3.0/themes/pear4gallery3/views/photo.html.php b/3.0/themes/pear4gallery3/views/photo.html.php new file mode 100644 index 00000000..b42ab987 --- /dev/null +++ b/3.0/themes/pear4gallery3/views/photo.html.php @@ -0,0 +1,51 @@ + + +item())): ?> + + + + +
    + photo_top() ?> + + paginator() ?> + + + +
    +

    title) ?>

    +
    description)) ?>
    +
    + + photo_bottom() ?> +
    diff --git a/3.0/themes/pear4gallery3/views/sidebar.html.php b/3.0/themes/pear4gallery3/views/sidebar.html.php new file mode 100644 index 00000000..086d1359 --- /dev/null +++ b/3.0/themes/pear4gallery3/views/sidebar.html.php @@ -0,0 +1,16 @@ + +sidebar_top() ?> +
    + + album_menu() ?> + + photo_menu() ?> + + movie_menu() ?> + + tag_menu() ?> + +
    + +sidebar_blocks() ?> +sidebar_bottom() ?> diff --git a/3.0/themes/sobriety/css/comment.css b/3.0/themes/sobriety/css/comment.css new file mode 100644 index 00000000..2aeb1794 --- /dev/null +++ b/3.0/themes/sobriety/css/comment.css @@ -0,0 +1,84 @@ +#g-content #g-comments { + display: block; + margin-top: 2em; + position: relative; +} + +#g-content #g-comments h2 { + margin: 0; +} + +#g-content #g-comments #g-add-comment { + position: absolute; + right: 0; + top: 2px; +} + +#g-content #g-comments ul { + list-style-type: none; + margin: 0; + padding: 0; +} + +#g-content #g-comments #g-comment-detail > ul li { + padding: 1em 0; + border-bottom: 1px dotted #aaab9b; +} + +#g-content #g-comments ul li .g-author { + margin: 0 0 0.5em; + font-style: italic; + font-width: normal; + /*font-size: 85%;*/ +} + +#g-content #g-comments ul li .g-author a:first-child { + border: none; +} + +#g-content #g-comments ul li .g-author a img.g-avatar { + width: 13px; + height: 13px; + margin-right: 5px; +} + +#g-content #g-comments ul li div { + margin-left: 23px; +} + +#g-content #g-comments #g-comment-detail #g-comment-form fieldset { + border: 0; + margin: 1em 0 0 0; + padding: 0; +} + +#g-content #g-comments #g-comment-detail #g-comment-form fieldset legend { + font-size: 2em; + margin-bottom: 0.5em; +} + +#g-content #g-comments #g-comment-detail #g-comment-form fieldset ul li { + clear: both; + padding-top: 0.5em; +} + +#g-content #g-comments #g-comment-detail #g-comment-form fieldset ul li label { + float: left; + width: 30%; + padding-top: 5px; +} + +#g-content #g-comments #g-comment-detail #g-comment-form fieldset ul li input[type="text"] { + float: left; + width: 40%; +} + +#g-content #g-comments #g-comment-detail #g-comment-form fieldset ul li input[type="submit"] { + float: right; +} + +#g-content #g-comments #g-comment-detail #g-comment-form fieldset ul li textarea { + float: left; + width: 69%; + height: 10em; +} diff --git a/3.0/themes/sobriety/css/screen.css b/3.0/themes/sobriety/css/screen.css index ea8bfaf0..3fb13ede 100644 --- a/3.0/themes/sobriety/css/screen.css +++ b/3.0/themes/sobriety/css/screen.css @@ -60,10 +60,70 @@ div#g-header { border-bottom: 3px solid #bba; } -div#g-banner { +a#g-logo, form#g-quick-search-form, div#g-site-menu { display: none; } +#g-header-text{ + color: #fff; + font: oblique small-caps bold 1em Georgia,serif; + position: absolute; + left: 15px; + height: 1.5em; + line-height: 1.5em; +} + +ul#g-login-menu { + list-style-type: none; + + position: absolute; + top: 0; + right: 0; + + display: block; + margin: 0; + /*padding: 0.5em;*/ + padding: 0; + + width: 20em; + width: 2.5em; + height: 2.5em; + background: url('../images/icons/g-login-menu.png') no-repeat center center; + z-index: 2; +} + +ul#g-login-menu > li { + display: none; + text-align: right; + padding: 2px 0; + width: 20em; + margin-left: -17.6em ; /* -(20-2.5) */ + background-color: #fcfcfc; + color: #000; +} + +ul#g-login-menu > li:first-child { + margin-top: 2.4em; +} + +ul#g-login-menu > li > a { + margin-right: 0.5em; +} + +ul#g-login-menu > li:hover, ul#g-login-menu > li:hover > a { + background-color: #5266f3; + color: #fff; + border-color: #fff; /* a:hover */ +} + +ul#g-login-menu:hover { + background-color: #5266f3; +} + +ul#g-login-menu:hover > li { + display: block; +} + ul.g-breadcrumbs { margin: 0; padding: 0; @@ -443,15 +503,17 @@ span.ui-icon-key { background-position: -112px -128px; } background: #b7b7a7; } -#g-item #g-movie { - display: block; -} - #g-item #g-photo a { border: none; } -#g-item #g-photo a img { +#g-item #g-movie, +#g-item #g-movie a { + display: block; +} + +#g-item #g-photo img, +#g-item #g-movie object { border: 10px solid #fff; -webkit-box-shadow: 3px 3px 0px #b7b7a7; -moz-box-shadow: 3px 3px 0px #b7b7a7; @@ -531,7 +593,8 @@ span.ui-icon-key { background-position: -112px -128px; } } #g-item .g-block { - display: none; + display: block; + margin: auto; } #g-item .g-block#g-metadata { @@ -559,9 +622,6 @@ span.ui-icon-key { background-position: -112px -128px; } padding: 0; } -#g-item .g-block#g-comments { - display: block; -} @@ -590,21 +650,6 @@ span.ui-icon-key { background-position: -112px -128px; } -#g-login-menu { - position: absolute; - right: 0; - padding: 0; - margin: 0; -} -#g-login-menu li { - display: inline; -} -#g-login-menu li:first-child { - /*display: none;*/ -} -#g-logo, #g-quick-search-form, #g-site-menu { - display: none; -} @@ -754,6 +799,18 @@ div#g-action-status { height: 8em; } +#g-dialog input[type=submit].submit { + float: right; +} + +#g-dialog a.g-cancel { + float: right; + -moz-appearance: button; + -webkit-appearance: push-button; + /*clear: left;*/ +} + + #g-add-photos-canvas-sd { height: 33px; /*margin-right: 63px;*/ @@ -811,7 +868,7 @@ div#g-action-status { height: 22px; width: 0%; background-image: url("../images/backgrounds/pbar-ani.gif"); - background-repeat: x-repeat; + background-repeat: repeat-x; } #g-add-photos-progressbar.stop { background-image: url("../images/backgrounds/pbar-ani-stop.gif"); diff --git a/3.0/themes/sobriety/images/avatar.jpg b/3.0/themes/sobriety/images/avatar.jpg new file mode 100644 index 00000000..17a31829 Binary files /dev/null and b/3.0/themes/sobriety/images/avatar.jpg differ diff --git a/3.0/themes/sobriety/images/ico-denied-inactive.png b/3.0/themes/sobriety/images/ico-denied-inactive.png new file mode 100644 index 00000000..56db3ff5 Binary files /dev/null and b/3.0/themes/sobriety/images/ico-denied-inactive.png differ diff --git a/3.0/themes/sobriety/images/ico-denied-passive.png b/3.0/themes/sobriety/images/ico-denied-passive.png new file mode 100644 index 00000000..1e992230 Binary files /dev/null and b/3.0/themes/sobriety/images/ico-denied-passive.png differ diff --git a/3.0/themes/sobriety/images/ico-denied.png b/3.0/themes/sobriety/images/ico-denied.png new file mode 100644 index 00000000..08f24936 Binary files /dev/null and b/3.0/themes/sobriety/images/ico-denied.png differ diff --git a/3.0/themes/greydragon/css/colorpacks/greydragon/images/ico-error.png b/3.0/themes/sobriety/images/ico-error.png similarity index 100% rename from 3.0/themes/greydragon/css/colorpacks/greydragon/images/ico-error.png rename to 3.0/themes/sobriety/images/ico-error.png diff --git a/3.0/themes/sobriety/images/ico-info.png b/3.0/themes/sobriety/images/ico-info.png new file mode 100644 index 00000000..12cd1aef Binary files /dev/null and b/3.0/themes/sobriety/images/ico-info.png differ diff --git a/3.0/themes/sobriety/images/ico-lock.png b/3.0/themes/sobriety/images/ico-lock.png new file mode 100644 index 00000000..2ebc4f6f Binary files /dev/null and b/3.0/themes/sobriety/images/ico-lock.png differ diff --git a/3.0/themes/sobriety/images/ico-separator-rtl.gif b/3.0/themes/sobriety/images/ico-separator-rtl.gif new file mode 100644 index 00000000..d9061a46 Binary files /dev/null and b/3.0/themes/sobriety/images/ico-separator-rtl.gif differ diff --git a/3.0/themes/sobriety/images/ico-separator.gif b/3.0/themes/sobriety/images/ico-separator.gif new file mode 100644 index 00000000..3de2d0d3 Binary files /dev/null and b/3.0/themes/sobriety/images/ico-separator.gif differ diff --git a/3.0/themes/sobriety/images/ico-success-inactive.png b/3.0/themes/sobriety/images/ico-success-inactive.png new file mode 100644 index 00000000..74b2032f Binary files /dev/null and b/3.0/themes/sobriety/images/ico-success-inactive.png differ diff --git a/3.0/themes/sobriety/images/ico-success-passive.png b/3.0/themes/sobriety/images/ico-success-passive.png new file mode 100644 index 00000000..dc8d1ded Binary files /dev/null and b/3.0/themes/sobriety/images/ico-success-passive.png differ diff --git a/3.0/themes/greydragon/css/colorpacks/greydragon/images/ico-success.png b/3.0/themes/sobriety/images/ico-success.png similarity index 100% rename from 3.0/themes/greydragon/css/colorpacks/greydragon/images/ico-success.png rename to 3.0/themes/sobriety/images/ico-success.png diff --git a/3.0/themes/sobriety/images/ico-warning.png b/3.0/themes/sobriety/images/ico-warning.png new file mode 100644 index 00000000..628cf2da Binary files /dev/null and b/3.0/themes/sobriety/images/ico-warning.png differ diff --git a/3.0/themes/sobriety/images/icon_pushpin.gif b/3.0/themes/sobriety/images/icon_pushpin.gif deleted file mode 100644 index b9e8461e..00000000 Binary files a/3.0/themes/sobriety/images/icon_pushpin.gif and /dev/null differ diff --git a/3.0/themes/sobriety/images/icons/g-login-menu.png b/3.0/themes/sobriety/images/icons/g-login-menu.png new file mode 100644 index 00000000..33e686cb Binary files /dev/null and b/3.0/themes/sobriety/images/icons/g-login-menu.png differ diff --git a/3.0/themes/sobriety/images/loading-large.gif b/3.0/themes/sobriety/images/loading-large.gif new file mode 100644 index 00000000..cc70a7a8 Binary files /dev/null and b/3.0/themes/sobriety/images/loading-large.gif differ diff --git a/3.0/themes/sobriety/images/loading-small.gif b/3.0/themes/sobriety/images/loading-small.gif new file mode 100644 index 00000000..d0bce154 Binary files /dev/null and b/3.0/themes/sobriety/images/loading-small.gif differ diff --git a/3.0/themes/sobriety/js/ui.init.js b/3.0/themes/sobriety/js/ui.init.js index 4393a04a..eeaa1b6d 100644 --- a/3.0/themes/sobriety/js/ui.init.js +++ b/3.0/themes/sobriety/js/ui.init.js @@ -90,9 +90,18 @@ $(document).ready(function() { $(this).css("top", 0).css("left", 0); // Remove the placeholder and hover class from the item $(this).removeClass("g-hover-item"); + $(this).gallery_valign(); $("#g-place-holder").remove(); } ); + + // Realign any thumbnails that change so that when we rotate a thumb it stays centered. + $(".g-item").bind("gallery.change", function() { + $(".g-item").each(function() { + $(this).height($(this).find("img").height() + 2); + }); + $(".g-item").equal_heights().gallery_valign(); + }); }*/ // Photo/Item item view diff --git a/3.0/themes/sobriety/theme.info b/3.0/themes/sobriety/theme.info index 545a0815..faf05de1 100644 --- a/3.0/themes/sobriety/theme.info +++ b/3.0/themes/sobriety/theme.info @@ -4,5 +4,9 @@ version = 1 author = "Romain LE DISEZ" site = 1 admin = 0 -;wind commit = 3b05db2685d92ca538d7993c960b06ea32f3a8df -;wind date = Wed Jun 23 11:16:56 2010 -0700 +;wind commit = 3a9bdebafda1807bb2294c041e655f6464841bf0 +;wind date = Tue Sep 21 21:38:32 2010 -0700 +author_name = "" +author_url = "" +info_url = "http://codex.gallery2.org/Gallery3:Themes:sobriety" +discuss_url = "http://gallery.menalto.com/forum_theme_sobriety" diff --git a/3.0/themes/sobriety/views/album.html.php b/3.0/themes/sobriety/views/album.html.php index b9072e2b..1a56af67 100644 --- a/3.0/themes/sobriety/views/album.html.php +++ b/3.0/themes/sobriety/views/album.html.php @@ -16,7 +16,9 @@
  • thumb_top($child) ?> + has_thumb()): ?> thumb_img(array("class" => "g-thumbnail")) ?> + thumb_bottom($child) ?> context_menu($child, "#g-item-id-{$child->id} .g-thumbnail") ?> @@ -29,7 +31,7 @@ admin || access::can("add", $item)): ?> - id") ?> + id") ?>
  • Add some.", array("attrs" => html::mark_clean("href=\"$addurl\" class=\"g-dialog-link\""))) ?>
  • diff --git a/3.0/themes/sobriety/views/page.html.php b/3.0/themes/sobriety/views/page.html.php index cf10b85e..7458820f 100644 --- a/3.0/themes/sobriety/views/page.html.php +++ b/3.0/themes/sobriety/views/page.html.php @@ -23,13 +23,12 @@ - " type="image/x-icon" /> + " type="image/x-icon" /> css("_DISABLED_yui/reset-fonts-grids.css") ?> css("_DISABLED_superfish/css/superfish.css") ?> css("_DISABLED_themeroller/ui.base.css") ?> - css("_DISABLED_gallery.common.css") ?> css("screen.css") ?> - @@ -51,7 +50,7 @@ head() they get combined */ ?> page_subtype == "photo"): ?> script("_DISABLED_jquery.scrollTo.js") ?> - script("_DISABLED_gallery.show_full_size.js") ?> + script("gallery.show_full_size.js") ?> page_subtype == "movie"): ?> script("flowplayer.js") ?> @@ -90,17 +89,22 @@ > - - item()->id}" : null) ?>">title), 15) ?> + causes Gallery3 to display the page + // containing that photo. For now, we just do it for + // the immediate parent so that when you go back up a + // level you're on the right page. ?> + item()->id}" : null) ?>"> + + title, + module::get_var("gallery", "visible_title_length"))) ?> +
  • "> - item()->title), 15) ?> + item()->title, + module::get_var("gallery", "visible_title_length"))) ?>
  • diff --git a/3.0/themes/sobriety/views/photo.html.php b/3.0/themes/sobriety/views/photo.html.php index c5393547..55b5f4cd 100644 --- a/3.0/themes/sobriety/views/photo.html.php +++ b/3.0/themes/sobriety/views/photo.html.php @@ -4,10 +4,23 @@ diff --git a/3.0/themes/sobriety/views/sobriety_actions.html.php b/3.0/themes/sobriety/views/sobriety_actions.html.php index a781a558..2338546b 100644 --- a/3.0/themes/sobriety/views/sobriety_actions.html.php +++ b/3.0/themes/sobriety/views/sobriety_actions.html.php @@ -5,7 +5,7 @@ module::event("site_menu", $menu, $this->theme, ""); ?> -elements['add_menu']->elements) || isset($menu->elements['options_menu']->elements) ): ?> +elements['add_menu']->elements) || !empty($menu->elements['options_menu']->elements) ): ?>

    diff --git a/3.0/themes/three_nids/admin/helpers/three_nids_event.php b/3.0/themes/three_nids/admin/helpers/three_nids_event.php index c8a0db51..abb221fc 100644 --- a/3.0/themes/three_nids/admin/helpers/three_nids_event.php +++ b/3.0/themes/three_nids/admin/helpers/three_nids_event.php @@ -1,7 +1,7 @@ t("About This Album")); + } + + static function get($block_id, $theme) { + switch ($block_id) { + case "aboutthisalbum": + $item = $theme->item; + if ((!$item) or (!$theme->item->is_album())) { + return ""; + } + if ($theme->item->is_album()) { + $block = new Block(); + $block->css_id = "g-about-this-album"; + $block->content = new View("about_this_album.html"); + + if ($theme->item()->id == item::root()->id) { + $block->title = t("About this Site"); + $block->content->album_count = ORM::factory("item")->where("type", "=", "album")->where("id", "<>", 1)->count_all(); + $block->content->photo_count = ORM::factory("item")->where("type", "=", "photo")->count_all(); + $block->content->vcount = Database::instance()->query("SELECT SUM({items}.view_count) as c FROM {items} WHERE type=\"photo\"")->current()->c; + } Else { + $block->title = t("About this Album"); + $block->content->album_count = $item->descendants_count(array(array("type", "=", "album"))); + $block->content->photo_count = $item->descendants_count(array(array("type", "=", "photo"))); + // $block->content->vcount= $theme->item()->view_count; + $descds = $item->descendants(); + $descds_view = 0; + foreach ($descds as $descd) { + if ($descd->is_photo()) { + $descds_view += $descd->view_count; + } + } + $block->content->vcount = $descds_view; + if ($item->description) { + $block->content->description = html::clean($item->description); + } + } + + + $all_tags = ORM::factory("tag") + ->join("items_tags", "items_tags.tag_id", "tags.id") + ->join("items", "items.id", "items_tags.item_id", "LEFT") + ->where("items.parent_id", "=", $item->id) + ->order_by("tags.id", "ASC") + ->find_all(); + if (count($all_tags) > 0) { + $block->content->all_tags = $all_tags; + } + } + break; + } + return $block; + } +} diff --git a/3.1/modules/about_this_album/module.info b/3.1/modules/about_this_album/module.info new file mode 100644 index 00000000..19a0e6f1 --- /dev/null +++ b/3.1/modules/about_this_album/module.info @@ -0,0 +1,7 @@ +name = "About this Album" +description = "Show some simple, specific and useful info about a given album" +version = 1 +author_name = "" +author_url = "" +info_url = "http://codex.gallery2.org/Gallery3:Modules:about_this_album" +discuss_url = "http://gallery.menalto.com/forum_module_about_this_album" diff --git a/3.1/modules/about_this_album/views/about_this_album.html.php b/3.1/modules/about_this_album/views/about_this_album.html.php new file mode 100644 index 00000000..01dee4f7 --- /dev/null +++ b/3.1/modules/about_this_album/views/about_this_album.html.php @@ -0,0 +1,68 @@ + + + diff --git a/3.1/modules/about_this_photo/helpers/about_this_photo_block.php b/3.1/modules/about_this_photo/helpers/about_this_photo_block.php new file mode 100644 index 00000000..267f3904 --- /dev/null +++ b/3.1/modules/about_this_photo/helpers/about_this_photo_block.php @@ -0,0 +1,71 @@ + t("About This Photo")); + } + + static function get($block_id, $theme) { + $block = new Block(); + switch ($block_id) { + case "simple": + $item = $theme->item; + if ((!$item) or (!$item->is_photo())) { + return ""; + } + $block->css_id = "g-about-this-photo"; + $block->title = t("About this photo"); + $block->content = new View("about_this_photo.html"); + + // exif API doesn't give easy access to individual keys, so do this the hard way + if (module::is_active("exif")) { + $exif = ORM::factory("exif_record")->where("item_id", "=", $theme->item()->id)->find(); + if ($exif->loaded()) { + $exif = unserialize($exif->data); + $timestamp = strtotime($exif["DateTime"]); + //$block->content->date = gallery::date($timestamp); + $block->content->date = date('D j M Y', $timestamp); + $block->content->time = gallery::time($timestamp); + } + } + + $block->content->vcount = $theme->item()->view_count; + + // IPTC - copied more or less from iptc.php + if (module::is_active("iptc")) { + $record = ORM::factory("iptc_record")->where("item_id", "=", $theme->item()->id)->find(); + if ($record->loaded()) { + $record = unserialize($record->data); + $block->content->name = $record["ObjectName"]; + $block->content->caption = $record["Caption"]; + + } + } + + if (module::is_active("tag")) { + $block->content->tags = tag::item_tags($theme->item()); + } + break; + } + return $block; + } +} + diff --git a/3.1/modules/about_this_photo/module.info b/3.1/modules/about_this_photo/module.info new file mode 100644 index 00000000..876b111b --- /dev/null +++ b/3.1/modules/about_this_photo/module.info @@ -0,0 +1,7 @@ +name = "About this Photo" +description = "Show some simple, specific and useful info about a given photo" +version = 3 +author_name = "" +author_url = "" +info_url = "http://codex.gallery2.org/Gallery3:Modules:about_this_photo" +discuss_url = "http://gallery.menalto.com/forum_module_about_this_photo" diff --git a/3.1/modules/about_this_photo/views/about_this_photo.html.php b/3.1/modules/about_this_photo/views/about_this_photo.html.php new file mode 100644 index 00000000..f0ef130a --- /dev/null +++ b/3.1/modules/about_this_photo/views/about_this_photo.html.php @@ -0,0 +1,34 @@ + + + diff --git a/3.1/modules/adsense/controllers/admin_adsense.php b/3.1/modules/adsense/controllers/admin_adsense.php index 13be83d8..05f0c6ad 100644 --- a/3.1/modules/adsense/controllers/admin_adsense.php +++ b/3.1/modules/adsense/controllers/admin_adsense.php @@ -1,7 +1,7 @@ content = new View("admin_albumpassword.html"); + + // Generate a form for controlling the admin section. + $view->content->albumpassword_form = $this->_get_admin_form(); + + // Display the page. + print $view; + } + + private function _get_admin_form() { + // Make a new form for changing admin settings for this module. + $form = new Forge("admin/albumpassword/saveprefs", "", "post", + array("id" => "g-album-password-admin-form")); + + // Should protected items be hidden, or completely in-accessable? + $albumpassword_group = $form->group("album_password_group"); + $albumpassword_group->checkbox("hideonly") + ->label(t("Do not require passwords")) + ->checked(module::get_var("albumpassword", "hideonly")); + + // Add a save button to the form. + $albumpassword_group->submit("save_settings")->value(t("Save")); + + // Return the newly generated form. + return $form; + } + + public function saveprefs() { + // Save user specified preferences. + + // Prevent Cross Site Request Forgery + access::verify_csrf(); + + // Retrieve submitted form data. + if (Input::instance()->post("hideonly") == false) { + module::set_var("albumpassword", "hideonly", false); + } else { + module::set_var("albumpassword", "hideonly", true); + } + // Display a success message and redirect back to the TagsMap admin page. + message::success(t("Your settings have been saved.")); + url::redirect("admin/albumpassword"); + } +} diff --git a/3.1/modules/albumpassword/controllers/albumpassword.php b/3.1/modules/albumpassword/controllers/albumpassword.php index b014b749..bf79698d 100644 --- a/3.1/modules/albumpassword/controllers/albumpassword.php +++ b/3.1/modules/albumpassword/controllers/albumpassword.php @@ -1,7 +1,7 @@ where("album_id", "=", $id)->find(); - if ($existing_password->loaded()) { + // Check for and delete the password and any cached ids assigned to it. + $existing_password = ORM::factory("items_albumpassword")->where("album_id", "=", $id)->find_all(); + if (count($existing_password) > 0) { + foreach ($existing_password as $one_password) { + db::build()->delete("albumpassword_idcaches")->where("password_id", "=", $one_password->id)->execute(); + } db::build()->delete("items_albumpasswords")->where("album_id", "=", $id)->execute(); message::success(t("Password Removed.")); } @@ -68,11 +71,14 @@ class albumpassword_Controller extends Controller { // Convert submitted data to local variables. $album_id = Input::instance()->post("item_id"); - $album_password = Input::instance()->post("assignpassword_password"); + $album_password = strtolower(Input::instance()->post("assignpassword_password")); - // Check for, and remove, any existing passwords. - $existing_password = ORM::factory("items_albumpassword")->where("album_id", "=", $album_id)->find(); - if ($existing_password->loaded()) { + // Check for, and remove, any existing passwords and cached ids. + $existing_password = ORM::factory("items_albumpassword")->where("album_id", "=", $album_id)->find_all(); + if (count($existing_password) > 0) { + foreach ($existing_password as $one_password) { + db::build()->delete("albumpassword_idcaches")->where("password_id", "=", $one_password->id)->execute(); + } db::build()->delete("items_albumpasswords")->where("album_id", "=", $album_id)->execute(); } @@ -82,6 +88,25 @@ class albumpassword_Controller extends Controller { $new_password->password = $album_password; $new_password->save(); + // Add the album to the id cache. + $cached_album = ORM::factory("albumpassword_idcache"); + $cached_album->password_id = $new_password->id; + $cached_album->item_id = $album_id; + $cached_album->save(); + + // Check for any sub-items within the album, add all of them to the id cache. + $items = ORM::factory("item", $album_id) + ->viewable() + ->descendants(); + if (count($items) > 0) { + foreach ($items as $one_item) { + $cached_item = ORM::factory("albumpassword_idcache"); + $cached_item->password_id = $new_password->id; + $cached_item->item_id = $one_item->id; + $cached_item->save(); + } + } + // Display a success message and close the dialog. message::success(t("Password saved.")); json::reply(array("result" => "success")); @@ -90,6 +115,7 @@ class albumpassword_Controller extends Controller { public function logout() { // Delete a stored password cookie. cookie::delete("g3_albumpassword"); + cookie::delete("g3_albumpassword_id"); url::redirect(url::abs_site("albums/1")); } @@ -100,7 +126,7 @@ class albumpassword_Controller extends Controller { access::verify_csrf(); // Convert submitted data to local variables. - $album_password = Input::instance()->post("albumpassword_password"); + $album_password = strtolower(Input::instance()->post("albumpassword_password")); // See if the submitted password matches any in the database. $existing_password = ORM::factory("items_albumpassword") @@ -110,6 +136,7 @@ class albumpassword_Controller extends Controller { if (count($existing_password) > 0) { // If the password if valid, then store it, and display a success message. // If not, close the dialog and display a rejected message. + cookie::delete("g3_albumpassword_id"); cookie::set("g3_albumpassword", $album_password); message::success(t("Password Accepted.")); json::reply(array("result" => "success")); @@ -129,7 +156,7 @@ class albumpassword_Controller extends Controller { $assignpassword_group->input("assignpassword_password") ->id('assignpassword_password') ->label(t("Password:")); - $form->submit("save_password")->value(t("Save")); + $assignpassword_group->submit("save_password")->value(t("Save")); // Return the newly generated form. return $form; @@ -139,12 +166,14 @@ class albumpassword_Controller extends Controller { // Generate a form for allowing visitors to enter in their passwords. $form = new Forge("albumpassword/checkpassword", "", "post", array("id" => "g-login-password-form")); + $assignpassword_group = $form->group("Enter Password") ->label(t("Enter Password:")); - $assignpassword_group->input("albumpassword_password") + $assignpassword_group->password("albumpassword_password") ->id('albumpassword_password') ->label(t("Password:")); - $form->submit("login_password")->value(t("Login")); + + $assignpassword_group->submit("")->value(t("Login")); // Return the newly generated form. return $form; diff --git a/3.1/modules/albumpassword/helpers/MY_access.php b/3.1/modules/albumpassword/helpers/MY_access.php new file mode 100644 index 00000000..bda1db32 --- /dev/null +++ b/3.1/modules/albumpassword/helpers/MY_access.php @@ -0,0 +1,49 @@ +where("item_id", "=", $item->id)->order_by("cache_id")->find_all(); + if (count($item_protected) > 0) { + $existing_password = ORM::factory("items_albumpassword")->where("id", "=", $item_protected[0]->password_id)->find(); + if ($existing_password->loaded()) { + if ((cookie::get("g3_albumpassword") != $existing_password->password) && + (identity::active_user()->id != $item->owner_id) && + (!identity::active_user()->admin)) { + throw new Kohana_404_Exception(); + } + } + } + } + } +} diff --git a/3.1/modules/albumpassword/helpers/MY_item.php b/3.1/modules/albumpassword/helpers/MY_item.php index 3e09a64d..07f81906 100644 --- a/3.1/modules/albumpassword/helpers/MY_item.php +++ b/3.1/modules/albumpassword/helpers/MY_item.php @@ -1,7 +1,7 @@ where("id", "=", $model->id)->find(); - // Figure out if the user can access this album. - $deny_access = false; - $existing_password = ORM::factory("items_albumpassword")->where("album_id", "=", $model->id)->find(); - if ($existing_password->loaded()) { - if ((cookie::get("g3_albumpassword") != $existing_password->password) && - (identity::active_user()->id != $album_item->owner_id)) - $deny_access = true; - } + // If the user is an admin, don't hide anything anything. + // If not, hide whatever is restricted by an album password + // that the current user is not the owner of. + if (!identity::active_user()->admin) { - // set access::DENY if necessary. - if ($deny_access == true) { - $view_restrictions = array(); - if (!identity::active_user()->admin) { - foreach (identity::group_ids_for_active_user() as $id) { - $view_restrictions[] = array("items.view_$id", "=", access::DENY); + // Display items that are not in idcaches. + $model->and_open()->join("albumpassword_idcaches", "items.id", "albumpassword_idcaches.item_id", "LEFT OUTER") + ->and_where("albumpassword_idcaches.item_id", "IS", NULL); + + // If in hide only mode, check and see if the current item is protected. + // If it is, log the user in with the password to view it. + if (module::get_var("albumpassword", "hideonly") == true) { + $existing_cacheditem = ORM::factory("albumpassword_idcache")->where("item_id", "=", $model->id)->order_by("cache_id")->find_all(); + if (count($existing_cacheditem) > 0) { + $existing_cacheditem_password = ORM::factory("items_albumpassword")->where("id", "=", $existing_cacheditem[0]->password_id)->find_all(); + if (cookie::get("g3_albumpassword") != $existing_cacheditem_password[0]->password) { + cookie::set("g3_albumpassword", $existing_cacheditem_password[0]->password); + cookie::set("g3_albumpassword_id", $existing_cacheditem_password[0]->id); + $model->or_where("albumpassword_idcaches.password_id", "=", $existing_cacheditem_password[0]->id); + } } } - } - if (count($view_restrictions)) { - $model->and_open()->merge_or_where($view_restrictions)->close(); + + // ... Unless their password id corresponds with a valid password. + $existing_password = ORM::factory("items_albumpassword")->where("password", "=", cookie::get("g3_albumpassword"))->find_all(); + if (count($existing_password) > 0) { + foreach ($existing_password as $one_password) { + if (cookie::get("g3_albumpassword_id") != "") { + if (cookie::get("g3_albumpassword_id") == $one_password->id) { + $model->or_where("albumpassword_idcaches.password_id", "=", $one_password->id); + } + } else { + $model->or_where("albumpassword_idcaches.password_id", "=", $one_password->id); + } + } + } + + // Or the current user is the owner of the item. + $model->or_where("items.owner_id", "=", identity::active_user()->id)->close(); } return $model; diff --git a/3.1/modules/albumpassword/helpers/albumpassword_event.php b/3.1/modules/albumpassword/helpers/albumpassword_event.php index dd83c4d9..b6b93e81 100644 --- a/3.1/modules/albumpassword/helpers/albumpassword_event.php +++ b/3.1/modules/albumpassword/helpers/albumpassword_event.php @@ -1,7 +1,7 @@ id("albumpassword_login") ->css_id("g-album-password-login") ->url(url::site("albumpassword/login")) - ->label(t("Enter password"))); + ->label(t("Unlock albums"))); } else { // If a password has been entered already // display the log out link, and links to the protected albums @@ -48,9 +48,17 @@ class albumpassword_event_Core { ->css_id("g-album-password-logout") ->url(url::site("albumpassword/logout")) ->label(t("Clear password"))); - $existing_password = ORM::factory("items_albumpassword") + $existing_password = ""; + if (cookie::get("g3_albumpassword_id") != "") { + $existing_password = ORM::factory("items_albumpassword") + ->where("password", "=", cookie::get("g3_albumpassword")) + ->where("id", "=", cookie::get("g3_albumpassword_id")) + ->find_all(); + } else { + $existing_password = ORM::factory("items_albumpassword") ->where("password", "=", cookie::get("g3_albumpassword")) ->find_all(); + } if (count($existing_password) > 0) { $counter = 0; while ($counter < count($existing_password)) { @@ -80,25 +88,71 @@ class albumpassword_event_Core { ->label(t("Remove password")) ->css_id("g-album-password-remove") ->url(url::site("albumpassword/remove/" . $item->id))); - } else { - $menu->get("options_menu") - ->append(Menu::factory("dialog") - ->id("albumpassword_assign") - ->label(t("Assign password")) - ->css_id("g-album-password-assign") - ->url(url::site("albumpassword/assign/" . $item->id))); + } elseif ($item->id != 1) { + $passworded_subitems = ORM::factory("item", $item->id) + ->and_open()->join("albumpassword_idcaches", "items.id", "albumpassword_idcaches.item_id", "LEFT OUTER") + ->where("albumpassword_idcaches.item_id", "IS NOT", NULL)->close() + ->descendants(); + + $existing_cacheditem = ORM::factory("albumpassword_idcache")->where("item_id", "=", $item->id)->order_by("cache_id")->find_all(); + if ((count($existing_cacheditem) == 0) && count($passworded_subitems) == 0) { + $menu->get("options_menu") + ->append(Menu::factory("dialog") + ->id("albumpassword_assign") + ->label(t("Assign password")) + ->css_id("g-album-password-assign") + ->url(url::site("albumpassword/assign/" . $item->id))); + } } } } } static function item_deleted($item) { - // If an album is deleted, remove any associated passwords. - $existingPasswords = ORM::factory("items_albumpassword") - ->where("album_id", "=", $item->id) - ->find_all(); - if (count($existingPasswords) > 0) { - db::build()->delete("items_albumpassword")->where("album_id", "=", $item->id)->execute(); + // Check for and delete the password and any cached ids assigned to it. + $existing_password = ORM::factory("items_albumpassword")->where("album_id", "=", $item->id)->find_all(); + if (count($existing_password) > 0) { + foreach ($existing_password as $one_password) { + db::build()->delete("albumpassword_idcaches")->where("password_id", "=", $one_password->id)->execute(); + } + db::build()->delete("items_albumpasswords")->where("album_id", "=", $item->id)->execute(); + message::success(t("Password Removed.")); + } else { + db::build()->delete("albumpassword_idcaches")->where("item_id", "=", $item->id)->execute(); } } + + static function item_created($item) { + // Check for any already existing password on parent album(s), if found, generate cache data for the new item. + $existing_password = ORM::factory("albumpassword_idcache")->where("item_id", "=", $item->parent_id)->order_by("cache_id")->find_all(); + if (count($existing_password) > 0) { + $new_cachedid = ORM::factory("albumpassword_idcache"); + $new_cachedid->password_id = $existing_password[0]->password_id; + $new_cachedid->item_id = $item->id; + $new_cachedid->save(); + } + } + + static function item_moved($item, $old_parent) { + // Delete any existing cache data. + db::build()->delete("albumpassword_idcaches")->where("item_id", "=", $item->id)->execute(); + + // Check for a password on the new parent, generate cache data if necessary. + $existing_password = ORM::factory("albumpassword_idcache")->where("item_id", "=", $item->parent_id)->order_by("cache_id")->find_all(); + if (count($existing_password) > 0) { + $new_cachedid = ORM::factory("albumpassword_idcache"); + $new_cachedid->password_id = $existing_password[0]->password_id; + $new_cachedid->item_id = $item->id; + $new_cachedid->save(); + } + } + + static function admin_menu($menu, $theme) { + // Add a link to the Album Password admin page to the Content menu. + $menu->get("settings_menu") + ->append(Menu::factory("link") + ->id("albumpassword") + ->label(t("Album Password Settings")) + ->url(url::site("admin/albumpassword"))); + } } diff --git a/3.1/modules/albumpassword/helpers/albumpassword_installer.php b/3.1/modules/albumpassword/helpers/albumpassword_installer.php index e59faffb..93a6d0c0 100644 --- a/3.1/modules/albumpassword/helpers/albumpassword_installer.php +++ b/3.1/modules/albumpassword/helpers/albumpassword_installer.php @@ -1,7 +1,7 @@ query("CREATE TABLE IF NOT EXISTS {albumpassword_idcaches} ( + `cache_id` int(9) NOT NULL auto_increment, + `password_id` int(9) NOT NULL, + `item_id` int(9) NOT NULL, + PRIMARY KEY (`cache_id`)) + DEFAULT CHARSET=utf8;"); + + // Set the default value for this module's behavior. + module::set_var("albumpassword", "hideonly", true); // Set the module's version number. - module::set_version("albumpassword", 1); + module::set_version("albumpassword", 3); + } + + static function upgrade($version) { + $db = Database::instance(); + if ($version == 1) { + // Set the default value for this module's behavior. + module::set_var("albumpassword", "hideonly", true); + module::set_version("albumpassword", $version = 2); + } + if ($version == 2) { + // Create a table to store a list of all protected items in. + $db->query("CREATE TABLE IF NOT EXISTS {albumpassword_idcaches} ( + `cache_id` int(9) NOT NULL auto_increment, + `password_id` int(9) NOT NULL, + `item_id` int(9) NOT NULL, + PRIMARY KEY (`cache_id`)) + DEFAULT CHARSET=utf8;"); + module::set_version("albumpassword", $version = 3); + } } static function uninstall() { // Delete the password table before uninstalling. $db = Database::instance(); - $db->query("DROP TABLE IF EXISTS {items_albumpassword};"); + $db->query("DROP TABLE IF EXISTS {items_albumpasswords};"); + $db->query("DROP TABLE IF EXISTS {albumpassword_idcaches};"); module::delete("albumpassword"); } } diff --git a/3.1/modules/albumpassword/helpers/albumpassword_task.php b/3.1/modules/albumpassword/helpers/albumpassword_task.php new file mode 100644 index 00000000..07f620e1 --- /dev/null +++ b/3.1/modules/albumpassword/helpers/albumpassword_task.php @@ -0,0 +1,197 @@ +join("albumpassword_idcaches", "items_albumpasswords.id", "albumpassword_idcaches.password_id", "LEFT OUTER") + ->and_where("albumpassword_idcaches.password_id", "IS", NULL)->count_all(); + + $tasks = array(); + + $tasks[] = Task_Definition::factory() + ->callback("albumpassword_task::update_idcaches") + ->name(t("Rebuild Album Password ID Caches DB")) + ->description(t("Logs the contents of all protected albums into the db.")) + ->severity($bad_albums ? log::WARNING : log::SUCCESS); + + $tasks[] = Task_Definition::factory() + ->callback("albumpassword_task::lowercase_passwords") + ->name(t("Fix Password DB Casing")) + ->description(t("Fixes case sensitivity issues.")) + ->severity(log::SUCCESS); + + return $tasks; + } + + static function lowercase_passwords($task) { + // Converts all passwords to lower case. + + $start = microtime(true); + $total = $task->get("total"); + $existing_passwords = ORM::factory("items_albumpassword")->find_all(); + + if (empty($total)) { + // Set the initial values for all variables. + $task->set("total", count($existing_passwords)); + $total = $task->get("total"); + $task->set("last_password_id", 0); + $task->set("completed_passwords", 0); + } + + // Retrieve the values for variables from the last time this + // function was run. + $last_password_id = $task->get("last_password_id"); + $completed_passwords = $task->get("completed_passwords"); + + foreach (ORM::factory("items_albumpassword") + ->where("id", ">", $last_password_id) + ->order_by("id") + ->find_all(100) as $one_password) { + $one_password->password = strtolower($one_password->password); + $one_password->save(); + + $last_password_id = $one_password->id; + $completed_passwords++; + + if ($completed_passwords == count($existing_passwords) || microtime(true) - $start > 1.5) { + break; + } + } + + $task->set("last_password_id", $last_password_id); + $task->set("completed_passwords", $completed_passwords); + + if ($completed_passwords == count($existing_passwords)) { + $task->done = true; + $task->state = "success"; + $task->percent_complete = 100; + } else { + $task->percent_complete = round(100 * $completed_passwords / count($existing_passwords)); + } + $task->status = t2("One password fixed", "%count / %total passwords fixed", $completed_passwords, + array("total" => count($existing_passwords))); + } + + static function update_idcaches($task) { + // Populate the idcaches table with the contents of all protected albums. + + $start = microtime(true); + $total = $task->get("total"); + $existing_passwords = ORM::factory("items_albumpassword")->find_all(); + // If this is the first time this function has been run, + // delete and re-create the idcaches table, and set up + // some initial variables. + if (empty($total)) { + // Delete the idcache table and make a new one. + $db = Database::instance(); + $db->query("DROP TABLE IF EXISTS {albumpassword_idcaches};"); + $db->query("CREATE TABLE IF NOT EXISTS {albumpassword_idcaches} ( + `cache_id` int(9) NOT NULL auto_increment, + `password_id` int(9) NOT NULL, + `item_id` int(9) NOT NULL, + PRIMARY KEY (`cache_id`)) + DEFAULT CHARSET=utf8;"); + + // Set the initial values for all variables. + $task->set("total", count($existing_passwords)); + $total = $task->get("total"); + $task->set("last_album_counter", 0); + $task->set("last_id", 0); + $task->set("completed_albums", 0); + $task->set("completed_items", 0); + $task->set("total_items", 0); + } + + // Retrieve the values for variables from the last time this + // function was run. + $last_album_counter = $task->get("last_album_counter"); + $completed_albums = $task->get("completed_albums"); + $completed_items = $task->get("completed_items"); + $total_items = $task->get("total_items"); + $last_id = $task->get("last_id"); + + // If completed_items is 0, then we're just starting to process this + // album. Add the album to idcaches before adding it's contents. + if ($completed_items == 0) { + // Add the album to the id cache. + $cached_album = ORM::factory("albumpassword_idcache"); + $cached_album->password_id = $existing_passwords[$last_album_counter]->id; + $cached_album->item_id = $existing_passwords[$last_album_counter]->album_id; + $cached_album->save(); + + // Set total_items to the number of items in this album. + $total_items = ORM::factory("item", $existing_passwords[$last_album_counter]->album_id) + ->descendants_count(); + $task->set("total_items", $total_items); + } + + // Add each item in the album to idcaches. + foreach (ORM::factory("item", $existing_passwords[$last_album_counter]->album_id) + ->where("id", ">", $last_id) + ->order_by("id") + ->descendants(100) as $item) { + + $cached_item = ORM::factory("albumpassword_idcache"); + $cached_item->password_id =$existing_passwords[$last_album_counter]->id; + $cached_item->item_id = $item->id; + $cached_item->save(); + + $last_id = $item->id; + $completed_items++; + + // Set a time limit so the script doesn't time out. + if (microtime(true) - $start > 1.5) { + break; + } + } // end foreach + + // If completed_items equals total_items, then we've + // processed everything in the current album. + // Increase variables and set everything up for the + // next album. + if ($completed_items == $total_items) { + $completed_items = 0; + $last_album_counter++; + $completed_albums++; + $last_id = 0; + } + + // Store the current values of the variables for the next + // time this function is called. + $task->set("last_album_counter", $last_album_counter); + $task->set("last_id", $last_id); + $task->set("completed_albums", $completed_albums); + $task->set("completed_items", $completed_items); + + // Display the number of albums that have been completed before exiting. + if ($total == $completed_albums) { + $task->done = true; + $task->state = "success"; + $task->percent_complete = 100; + $task->status = t("Scanning Protected Album $completed_albums of $total"); + } else { + $task->percent_complete = round(100 * $completed / $total); + $task->status = t("Scanning Protected Album $completed_albums of $total -- $completed_items / $total_items files"); + } + } +} diff --git a/3.1/modules/albumpassword/models/albumpassword_idcache.php b/3.1/modules/albumpassword/models/albumpassword_idcache.php new file mode 100644 index 00000000..e3d80667 --- /dev/null +++ b/3.1/modules/albumpassword/models/albumpassword_idcache.php @@ -0,0 +1,21 @@ + +

    + +

    +
    +
    + +

    +
    diff --git a/3.1/modules/albumpassword/views/assignpassword.html.php b/3.1/modules/albumpassword/views/assignpassword.html.php index 14cd2767..c1a60b8d 100644 --- a/3.1/modules/albumpassword/views/assignpassword.html.php +++ b/3.1/modules/albumpassword/views/assignpassword.html.php @@ -1,20 +1,3 @@ -
    • diff --git a/3.1/modules/albumpassword/views/loginpassword.html.php b/3.1/modules/albumpassword/views/loginpassword.html.php index 9ebb47fd..750ffbed 100644 --- a/3.1/modules/albumpassword/views/loginpassword.html.php +++ b/3.1/modules/albumpassword/views/loginpassword.html.php @@ -1,20 +1,3 @@ -
      • diff --git a/3.1/modules/albumtree/helpers/albumtree_block.php b/3.1/modules/albumtree/helpers/albumtree_block.php index 8d184f51..f812ab17 100644 --- a/3.1/modules/albumtree/helpers/albumtree_block.php +++ b/3.1/modules/albumtree/helpers/albumtree_block.php @@ -1,7 +1,7 @@ css_id = "g-albumtree"; $block->title = t("Album Tree"); - $block->content = new View("albumtree_block.html"); + $block->content = new View("albumtree_block_{$style}.html"); $block->content->root = item::root(); break; } diff --git a/3.1/modules/albumtree/helpers/albumtree_installer.php b/3.1/modules/albumtree/helpers/albumtree_installer.php new file mode 100644 index 00000000..77c7066f --- /dev/null +++ b/3.1/modules/albumtree/helpers/albumtree_installer.php @@ -0,0 +1,33 @@ + -children(null, null, array(array("type", "=", "album"))) as $child): ?> +viewable()->children(null, null, array(array("type", "=", "album"))) as $child): ?> diff --git a/3.1/modules/albumtree/views/albumtree_block_dtree.html.php b/3.1/modules/albumtree/views/albumtree_block_dtree.html.php new file mode 100644 index 00000000..257181f1 --- /dev/null +++ b/3.1/modules/albumtree/views/albumtree_block_dtree.html.php @@ -0,0 +1,414 @@ + + + + +
        +
        + +
        +
        diff --git a/3.1/modules/albumtree/views/albumtree_block_list.html.php b/3.1/modules/albumtree/views/albumtree_block_list.html.php new file mode 100644 index 00000000..62d8c0ad --- /dev/null +++ b/3.1/modules/albumtree/views/albumtree_block_list.html.php @@ -0,0 +1,30 @@ + + + +
          + +
        • + title ?> +
        • +viewable()->children(null, null, array(array("type", "=", "album"))) as $child){ + makelist($child,$level+1); + } +} +makelist($root,0); +?> +
        + + diff --git a/3.1/modules/albumtree/views/albumtree_block_select.html.php b/3.1/modules/albumtree/views/albumtree_block_select.html.php new file mode 100644 index 00000000..c4633d27 --- /dev/null +++ b/3.1/modules/albumtree/views/albumtree_block_select.html.php @@ -0,0 +1,16 @@ + + diff --git a/3.1/modules/atom/module.info b/3.1/modules/atom/module.info new file mode 100644 index 00000000..77f5c0b8 --- /dev/null +++ b/3.1/modules/atom/module.info @@ -0,0 +1,7 @@ +name = "Atom" +description = "Enable Atom feeds in your Gallery" +version = 1 +author_name = "" +author_url = "" +info_url = "http://codex.gallery2.org/Gallery3:Modules:atom" +discuss_url = "http://gallery.menalto.com/forum_module_atom" diff --git a/3.1/modules/autorotate/helpers/autorotate.php b/3.1/modules/autorotate/helpers/autorotate.php index 5bfe1afe..50cc1ab3 100644 --- a/3.1/modules/autorotate/helpers/autorotate.php +++ b/3.1/modules/autorotate/helpers/autorotate.php @@ -1,7 +1,7 @@ file_path(), $tmpfile, array("degrees" => $degrees)); + gallery_graphics::rotate($item->file_path(), $tmpfile, array("degrees" => $degrees), $item); // Update EXIF info $data = new PelDataWindow(file_get_contents($tmpfile)); if (PelJpeg::isValid($data)) { diff --git a/3.1/modules/autorotate/helpers/autorotate_event.php b/3.1/modules/autorotate/helpers/autorotate_event.php index 1eb14dd7..fe23ef8e 100644 --- a/3.1/modules/autorotate/helpers/autorotate_event.php +++ b/3.1/modules/autorotate/helpers/autorotate_event.php @@ -1,7 +1,7 @@ css("basket.css"); + return $theme->css("basket.css"); } static function header_top($theme) { @@ -37,7 +37,7 @@ class basket_theme_Core { static function admin_head($theme) { if (strpos(Router::$current_uri, "admin/product_lines") !== false) { - $theme->script("gallery.panel.js"); + return $theme->script("gallery.panel.js"); } } static function photo_top($theme){ diff --git a/3.1/modules/basket/module.info b/3.1/modules/basket/module.info index 559c59aa..965a7df3 100644 --- a/3.1/modules/basket/module.info +++ b/3.1/modules/basket/module.info @@ -1,3 +1,7 @@ name = "Shopping Basket" description = "Provides a simple shopping basket and checkout with paypal integration" version = 5 +author_name = "" +author_url = "" +info_url = "http://codex.gallery2.org/Gallery3:Modules:basket" +discuss_url = "http://gallery.menalto.com/forum_module_basket" diff --git a/3.1/modules/batchtag/controllers/batchtag.php b/3.1/modules/batchtag/controllers/batchtag.php index ec012719..01f2e7ff 100644 --- a/3.1/modules/batchtag/controllers/batchtag.php +++ b/3.1/modules/batchtag/controllers/batchtag.php @@ -1,7 +1,7 @@ post('name')}&item_id={$input->post('item_id')}&tag_subitems={$input->post('tag_subitems')}&csrf={$input->post('csrf')}")); + } + + public function tagitems2() { + // Tag all non-album items in the current album with the specified tags. + + // Prevent Cross Site Request Forgery + access::verify_csrf(); + + $input = Input::instance(); + + // Variables + if (($input->get("batchtag_max") == false) || ($input->get("batchtag_max") == "0")) { + $batchtag_max = "50"; + } else { + $batchtag_max = $input->get("batchtag_max"); + } + if ($input->get("batchtag_items_processed") == false) { + $batchtag_items_processed = "0"; + } else { + $batchtag_items_processed = $input->get("batchtag_items_processed"); + } + // Figure out if the contents of sub-albums should also be tagged - $str_tag_subitems = $input->post("tag_subitems"); + $str_tag_subitems = $input->get("tag_subitems"); $children = ""; if ($str_tag_subitems == false) { // Generate an array of all non-album items in the current album. $children = ORM::factory("item") - ->where("parent_id", "=", $input->post("item_id")) + ->where("parent_id", "=", $input->get("item_id")) ->where("type", "!=", "album") ->find_all(); } else { // Generate an array of all non-album items in the current album // and any sub albums. - $item = ORM::factory("item", $input->post("item_id")); + $item = ORM::factory("item", $input->get("item_id")); $children = $item->descendants(); } + // Loop through each item in the album and make sure the user has // access to view and edit it. - foreach ($children as $child) { - if (access::can("view", $child) && access::can("edit", $child) && !$child->is_album()) { + $children_count = "0"; + $tag_count = "0"; - // Assuming the user can view/edit the current item, loop - // through each tag that was submitted and apply it to - // the current item. - foreach (explode(",", $input->post("name")) as $tag_name) { - $tag_name = trim($tag_name); - if ($tag_name) { - tag::add($child, $tag_name); + //echo Kohana::debug($children); + + echo ''; + + foreach ($children as $child) { + + if ($tag_count < $batchtag_max) { + + if ($children_count >= $batchtag_items_processed) { + if (access::can("view", $child) && access::can("edit", $child) && !$child->is_album()) { + + // Assuming the user can view/edit the current item, loop + // through each tag that was submitted and apply it to + // the current item. + foreach (explode(",", $input->get("name")) as $tag_name) { + $tag_name = trim($tag_name); + if ($tag_name) { + tag::add($child, $tag_name); + } + // $tag_count should be inside the foreach loop as it is depending on the number of time tag:add is run + $tag_count++; + } } - } - } + echo '' . "\n"; + $children_count++; + $batchtag_max_new = $tag_count; + echo ''; + } else { $children_count++; } + + } else { break; } + } - // Redirect back to the album. - $item = ORM::factory("item", $input->post("item_id")); - url::redirect(url::abs_site("{$item->type}s/{$item->id}")); + if ($tag_count < $batchtag_max) { + // Redirect back to the album. + $item = ORM::factory("item", $input->get("item_id")); + url::redirect(url::abs_site("{$item->type}s/{$item->id}")); + //echo url::abs_site("{$item->type}s/{$item->id}"); + } else { + url::redirect(url::abs_site("batchtag/tagitems2?name={$input->get('name')}&item_id={$input->get('item_id')}&tag_subitems={$input->get('tag_subitems')}&batchtag_items_processed=$children_count&batchtag_max=$batchtag_max&csrf={$input->get('csrf')}")); + //echo url::abs_site("batchtag/tagitems2?name={$input->get('name')}&item_id={$input->get('item_id')}&tag_subitems={$input->get('tag_subitems')}&batchtag_items_processed=$children_count&batchtag_max=$batchtag_max&csrf={$input->get('csrf')}"); + } } } diff --git a/3.1/modules/batchtag/helpers/batchtag_block.php b/3.1/modules/batchtag/helpers/batchtag_block.php index f1be1387..01fe1216 100644 --- a/3.1/modules/batchtag/helpers/batchtag_block.php +++ b/3.1/modules/batchtag/helpers/batchtag_block.php @@ -1,7 +1,7 @@ module == "tag") { + $data->messages["warn"][] = t("The BatchTag module requires the Tags module."); + } + } + static function module_change($changes) { // See if the Tags module is installed, // tell the user to install it if it isn't. diff --git a/3.1/modules/batchtag/helpers/batchtag_installer.php b/3.1/modules/batchtag/helpers/batchtag_installer.php index bdf64d5a..d0c03163 100644 --- a/3.1/modules/batchtag/helpers/batchtag_installer.php +++ b/3.1/modules/batchtag/helpers/batchtag_installer.php @@ -1,7 +1,7 @@ - \ No newline at end of file + + diff --git a/3.1/modules/bitly/README b/3.1/modules/bitly/README new file mode 100644 index 00000000..3c385366 --- /dev/null +++ b/3.1/modules/bitly/README @@ -0,0 +1,12 @@ +ABOUT: +Shorten Gallery's album and item links using bit.ly's URL shortening service. + +INSTALLATION AND CONFIGURATION: +http://codex.gallery2.org/Gallery3:Modules:bitly + +SUPPORT/BUG REPORTS: +http://gallery.menalto.com/node/100816 + +ROADMAP: +* Provide multi-user support. +* Display shortened link statistics (clicks, etc.) diff --git a/3.1/modules/bitly/controllers/admin_bitly.php b/3.1/modules/bitly/controllers/admin_bitly.php new file mode 100644 index 00000000..535a375d --- /dev/null +++ b/3.1/modules/bitly/controllers/admin_bitly.php @@ -0,0 +1,95 @@ +validate()) { + $new_login = $form->configure_bitly->login->value; + $new_key = $form->configure_bitly->api_key->value; + $new_domain = $form->configure_bitly->domain->value; + + module::set_var("bitly", "login", $new_login); + module::set_var("bitly", "api_key", $new_key); + module::set_var("bitly", "domain", $new_domain); + + if (!bitly::check_config()) { + url::redirect("admin/bitly"); + } else { + if ($login && !$new_login) { + message::success(t("Your bit.ly login has been cleared.")); + } else if ($login && $new_login && $login != $new_login) { + message::success(t("Your bit.ly login has been changed.")); + } else if (!$login && $new_login) { + message::success(t("Your bit.ly login has been saved.")); + } + if ($api_key && !$new_key) { + message::success(t("Your bit.ly API key has been cleared.")); + } else if ($api_key && $new_key && $api_key != $new_key) { + message::success(t("Your bit.ly API key has been changed.")); + } else if (!$api_key && $new_key) { + message::success(t("Your bit.ly API key has been saved.")); + } + if ($domain && $new_domain && $domain != $new_domain) { + message::success(t("Your preferrend bit.ly domain has been changed.")); + } else if (!$domain && $new_domain) { + message::success(t("Your preferred bit.ly domain has been saved.")); + } + log::success("bitly", t("bit.ly login changed to %new_login", + array("new_login" => $new_login))); + log::success("bitly", t("bit.ly API key changed to %new_key", + array("new_key" => $new_key))); + + (!$new_login || !$new_key) ? $valid_config = false : $valid_config = true; + } + } + } + + $view = new Admin_View("admin.html"); + $view->page_title = t("bit.ly url shortner"); + $view->content = new View("admin_bitly.html"); + $view->content->login = $form->configure_bitly->login->value; + $view->content->api_key = $form->configure_bitly->api_key->value; + $view->content->domain = $form->configure_bitly->domain->value; + $view->content->form = $form; + + $link = ORM::factory("bitly_link")->where("item_id", "=", 1)->find(); + + if ($link->loaded()) { + $view->content->g3_url = bitly::url($link->hash); + } else if ($valid_config && !empty($login) && !empty($api_key) && !empty($domain)) { + $view->content->g3_url = bitly::shorten_url(1); + } + + print $view; + } + +} \ No newline at end of file diff --git a/3.1/modules/bitly/controllers/bitly.php b/3.1/modules/bitly/controllers/bitly.php new file mode 100644 index 00000000..7a0b53c0 --- /dev/null +++ b/3.1/modules/bitly/controllers/bitly.php @@ -0,0 +1,49 @@ +relative_url_cache)); + } + + // Redirect back to the item + url::redirect(url::abs_site($item->relative_url_cache)); + } + +} \ No newline at end of file diff --git a/3.1/modules/bitly/helpers/bitly.php b/3.1/modules/bitly/helpers/bitly.php new file mode 100644 index 00000000..f006362e --- /dev/null +++ b/3.1/modules/bitly/helpers/bitly.php @@ -0,0 +1,217 @@ + 'expand', + 'shorten' => 'shorten', + 'validate' => 'validate', + 'clicks' => 'clicks', + 'referrers' => 'referrers', + 'countries' => 'countries', + 'clicks_by_minute' => 'clicks_by_minute', + 'clicks_by_day' => 'clicks_by_day', + 'lookup' => 'lookup', + 'info' => 'info', + ); + + static function get_configure_form() { + $form = new Forge("admin/bitly", "", "post", array("id" => "g-configure-bitly-form")); + $group = $form->group("configure_bitly")->label(t("Configure bit.ly")); + $group->input("login") + ->label(t("Login")) + ->value(module::get_var("bitly", "login")) + ->rules("required") + ->error_messages("required", t("You must enter a login")); + $group->input("api_key") + ->label(t("API Key")) + ->value(module::get_var("bitly", "api_key")) + ->rules("required") + ->error_messages("required", t("You must enter an API key")); + $group->dropdown("domain") + ->label(t("Preferred Domain")) + ->options(array("bit.ly" => "bit.ly", "j.mp" => "j.mp")) + ->selected(module::get_var("bitly", "domain")); + $group->submit("")->value(t("Save")); + return $form; + } + + /** + * Check a login and an API Key against bit.ly to make sure they're valid + * @param string $login bit.ly login + * @param string $api_key bit.ly API key + * @return boolean + */ + static function validate_config($login, $api_key) { + if (!empty($login) && !empty($api_key)) { + $parameters = array( + 'login' => $login, + 'apiKey' => $api_key, + 'x_login' => $login, + 'x_apiKey' => $api_key + ); + $request = self::_build_http_request('validate', $parameters); + $response = self::_http_post($request, "api.bit.ly"); + $json_decoded = json_decode($response->body[0]); + if (!$json_decoded->data->valid) { + if ("INVALID_LOGIN" == $json_decoded->status_txt) { + message::error(t("Your bit.ly login is incorrect")); + } else if ("INVALID_APIKEY" == $json_decoded->status_txt) { + message::error(t("Your bit.ly API Key is incorrect.")); + } + return false; + } else { + return true; + } + } + } + + /** + * Check whether the module's configured correctly + * @return boolean + */ + static function check_config() { + $login = module::get_var("bitly", "login"); + $api_key = module::get_var("bitly", "api_key"); + if (empty($login) || empty($api_key)) { + site_status::warning( + t("bit.ly is not quite ready! Please provide a login and API Key", + array("url" => html::mark_clean(url::site("admin/bitly")))), + "bitly_config"); + + } else if (!self::validate_config($login, $api_key)) { + site_status::warning( + t("bit.ly is not properly configured! URLs will not be shortened until its configuration is updated.", + array("url" => html::mark_clean(url::site("admin/bitly")))), + "bitly_config"); + } else { + site_status::clear("bitly_config"); + return true; + } + return false; + } + + /** + * Assemble a bitly API request + * @param string $type Type of API request, ex. shorten + * @param array $params Query string key/value pairs + * @return string + */ + private static function _build_http_request($type, $params) { + $http_request = ''; + if (!empty($type) && count($params)) { + foreach($params as $k => $v) { + $query_string[] = "$k=" . urlencode($v); + } + $path = "/" . self::$api_version . "/$type?" . implode('&', $query_string); + $module_version = module::get_version("bitly"); + + $http_request = "GET $path HTTP/1.0\r\n"; + $http_request .= "Host: " . self::$api_host . "\r\n"; + $http_request .= "User-Agent: Gallery/3 | bitly/" . module::get_version("bitly") . "\r\n"; + $http_request .= "\r\n"; + $http_request .= $path; + } + return $http_request; + } + + /** + * Send an http POST request + * @param string $http_request + * @param string $host + * @return object + */ + private static function _http_post($http_request) { + $response = ''; + if (false !== ($fs = @fsockopen(self::$api_host, 80, $errno, $errstr, 5))) { + fwrite($fs, $http_request); + while ( !feof($fs) ) { + $response .= fgets($fs, 1160); // One TCP-IP packet + } + fclose($fs); + list($headers, $body) = explode("\r\n\r\n", $response); + $headers = explode("\r\n", $headers); + $body = explode("\r\n", $body); + $response = new ArrayObject( + array("headers" => $headers, "body" => $body), ArrayObject::ARRAY_AS_PROPS); + } else { + throw new Exception("@todo CONNECTION TO URL SHORTENING SERVICE FAILED"); + } + Kohana_Log::add("debug", "Received response\n" . print_r($response, 1)); + + return $response; + } + + /** + * Shorten a Gallery URL + * @param int $item_id + * @param string $format + * @return mixed string|false + */ + static function shorten_url($item_id, $format='json') { + $item = ORM::factory("item", $item_id); + $short_url = ''; + $long_url = url::abs_site($item->relative_url_cache); + $parameters = array( + "login" => module::get_var("bitly", "login"), + 'apiKey' => module::get_var("bitly", "api_key"), + 'longUrl' => $long_url, + 'domain' => module::get_var("bitly", "domain"), + 'format' => $format, + ); + $request = self::_build_http_request('shorten', $parameters); + $response = self::_http_post($request, self::$api_host); + $json_response = json_decode($response->body[0]); + $status_txt = $json_response->status_txt; + + if ('OK' == $status_txt) { + $short_url = $json_response->data->url; + // Save the link hash to the database + $link = ORM::factory("bitly_link"); + $link->item_id = $item_id; + $link->hash = $json_response->data->hash; + $link->global_hash = $json_response->data->global_hash; + $link->save(); + return $json_response->data->url; + } else { + $status_code = $json_response->status_code; + log::error("content", "Shortened URL", "Error: $status_code $status_txt item"); + return false; + } + } + + /** + * Build a bit.ly link for a specified hash + * @param string $hash + * @return string + */ + static function url($hash) { + if (!empty($hash)) { + return "http://" . module::get_var("bitly", "domain") . "/$hash"; + } + } + +} diff --git a/3.1/modules/bitly/helpers/bitly_event.php b/3.1/modules/bitly/helpers/bitly_event.php new file mode 100644 index 00000000..1efeb264 --- /dev/null +++ b/3.1/modules/bitly/helpers/bitly_event.php @@ -0,0 +1,67 @@ +get("settings_menu") + ->append(Menu::factory("link") + ->id("bitly_menu") + ->label(t("bit.ly")) + ->url(url::site("admin/bitly"))); + } + + static function site_menu($menu, $theme) { + $link = ORM::factory("bitly_link")->where("item_id", "=", $theme->item->id)->find(); + if (!$link->loaded() && $theme->item->owner->id == identity::active_user()->id) { + $menu->get("options_menu") + ->append(Menu::factory("link") + ->id("bitly") + ->label(t("Shorten link with bit.ly")) + ->url(url::site("bitly/shorten/{$theme->item->id}?csrf={$theme->csrf}")) + ->css_id("g-bitly-shorten") + ->css_class("g-bitly-shorten")); + } + } + + static function context_menu($menu, $theme, $item) { + $link = ORM::factory("bitly_link")->where("item_id", "=", $item->id)->find(); + if (!$link->loaded() && $theme->item->owner->id == identity::active_user()->id) { + $menu->get("options_menu") + ->append(Menu::factory("link") + ->id("bitly") + ->label(t("Shorten link with bit.ly")) + ->url(url::site("bitly/shorten/{$item->id}?csrf={$theme->csrf}")) + ->css_class("g-bitly-shorten ui-icon-link")); + } + } + + static function info_block_get_metadata($block, $item) { + $link = ORM::factory("bitly_link")->where("item_id", "=", $item->id)->find(); + if ($link->loaded()) { + $info = $block->content->metadata; + $info["bitly_url"] = array( + "label" => t("bit.ly url:"), + "value" => bitly::url($link->hash) + ); + $block->content->metadata = $info; + } + } + +} diff --git a/3.1/modules/bitly/helpers/bitly_installer.php b/3.1/modules/bitly/helpers/bitly_installer.php new file mode 100644 index 00000000..18d2ab73 --- /dev/null +++ b/3.1/modules/bitly/helpers/bitly_installer.php @@ -0,0 +1,38 @@ +query("CREATE TABLE {bitly_links} ( + `id` int(9) NOT NULL AUTO_INCREMENT, + `item_id` int(9) NOT NULL, + `hash` char(6) NOT NULL, + `global_hash` char(6) NOT NULL, + PRIMARY KEY (`id`)) + DEFAULT CHARSET=utf8;"); + module::set_version("bitly", 1); + bitly::check_config(); + } + + static function deactivate() { + site_status::clear("bitly_config"); + } +} diff --git a/3.1/modules/bitly/helpers/bitly_theme.php b/3.1/modules/bitly/helpers/bitly_theme.php new file mode 100644 index 00000000..392d2c48 --- /dev/null +++ b/3.1/modules/bitly/helpers/bitly_theme.php @@ -0,0 +1,24 @@ +script("bitly.js"); + } +} diff --git a/3.1/modules/bitly/js/bitly.js b/3.1/modules/bitly/js/bitly.js new file mode 100644 index 00000000..96dcb427 --- /dev/null +++ b/3.1/modules/bitly/js/bitly.js @@ -0,0 +1,6 @@ +$(document).ready(function() { + $(".g-bitly-shorten").click(function(e) { + e.preventDefault(); + return window.location = ($(this).attr("href")); + }); +}); diff --git a/3.1/modules/videos/models/videos_file.php b/3.1/modules/bitly/models/bitly_link.php similarity index 91% rename from 3.1/modules/videos/models/videos_file.php rename to 3.1/modules/bitly/models/bitly_link.php index 8104db66..cfbb795b 100644 --- a/3.1/modules/videos/models/videos_file.php +++ b/3.1/modules/bitly/models/bitly_link.php @@ -1,7 +1,7 @@ +
        +

        +

        + bit.ly account which will provide an API Key, which is also free.", + array("api_key_url" => "http://bit.ly/a/your_api_key", + "bitly_url" => "http://bit.ly")) ?> +

        +
        + +
        + %g3_url", array('g3_url' => $g3_url)) ?> +
        + + + +
        +
        diff --git a/3.1/modules/calendarview/controllers/calendarview.php b/3.1/modules/calendarview/controllers/calendarview.php index d5d23943..c1302ba5 100644 --- a/3.1/modules/calendarview/controllers/calendarview.php +++ b/3.1/modules/calendarview/controllers/calendarview.php @@ -1,7 +1,7 @@ css("calendarview_calendar.css"); $template->set_global("calendar_user", $display_user); $template->page_title = t("Gallery :: Calendar"); $template->content = new View("calendarview_year.html"); diff --git a/3.1/modules/calendarview/helpers/calendarview_event.php b/3.1/modules/calendarview/helpers/calendarview_event.php index 4564b500..731a662a 100644 --- a/3.1/modules/calendarview/helpers/calendarview_event.php +++ b/3.1/modules/calendarview/helpers/calendarview_event.php @@ -1,7 +1,7 @@ css("calendarview_menu.css"); + return $theme->css("calendarview_calendar.css"); } } diff --git a/3.1/modules/calendarview/libraries/Calendar_Breadcrumb.php b/3.1/modules/calendarview/libraries/Calendar_Breadcrumb.php index 60502667..751af272 100644 --- a/3.1/modules/calendarview/libraries/Calendar_Breadcrumb.php +++ b/3.1/modules/calendarview/libraries/Calendar_Breadcrumb.php @@ -1,7 +1,7 @@

        "; - - // Figure out if any photos were taken for the current month. - if ($calendar_user == "-1") { - $month_count = ORM::factory("item") - ->viewable() - ->where("type", "!=", "album") - ->where("captured", ">=", mktime(0, 0, 0, $counter_months, 1, $calendar_year)) - ->where("captured", "<", mktime(0, 0, 0, $counter_months+1, 1, $calendar_year)) - ->find_all() - ->count(); - } else { - $month_count = ORM::factory("item") - ->viewable() - ->where("owner_id", "=", $calendar_user) - ->where("type", "!=", "album") - ->where("captured", ">=", mktime(0, 0, 0, $counter_months, 1, $calendar_year)) - ->where("captured", "<", mktime(0, 0, 0, $counter_months+1, 1, $calendar_year)) - ->find_all() - ->count(); - } - if ($month_count > 0) { - $month_url = url::site("calendarview/month/" . $calendar_year . "/" . $calendar_user . "/" . $counter_months . "/"); - } else { - $month_url = ""; - } - $calendar = new PHPCalendar($counter_months, $calendar_year, $month_url); - - // If there are photos, loop through each day in the month and display links on the correct dates. - if ($month_count > 0) { - $curr_day = 1; - $MAX_DAYS = date('t', mktime(00, 00, 00, $counter_months, 1, $calendar_year)); - while ($curr_day < $MAX_DAYS) { - if ($calendar_user == "-1") { - $day_count = ORM::factory("item") - ->viewable() - ->where("type", "!=", "album") - ->where("captured", ">=", mktime(0, 0, 0, $counter_months, $curr_day, $calendar_year)) - ->where("captured", "<", mktime(0, 0, 0, $counter_months, ($curr_day + 1), $calendar_year)) - ->find_all() - ->count(); - } else { - $day_count = ORM::factory("item") - ->viewable() - ->where("owner_id", "=", $calendar_user) - ->where("type", "!=", "album") - ->where("captured", ">=", mktime(0, 0, 0, $counter_months, $curr_day, $calendar_year)) - ->where("captured", "<", mktime(0, 0, 0, $counter_months, ($curr_day + 1), $calendar_year)) - ->find_all() - ->count(); - } - if ($day_count > 0) { - $calendar->event($curr_day, url::site("calendarview/day/" . $calendar_year . "/" . $calendar_user . "/" . $counter_months . "/" . $curr_day)); - } - $curr_day++; - } - - // Do the last day of the month seperately, because the mktime code is different. - if ($calendar_user == "-1") { - $day_count = ORM::factory("item") - ->viewable() - ->where("type", "!=", "album") - ->where("captured", ">=", mktime(0, 0, 0, $counter_months, $MAX_DAYS, $calendar_year)) - ->where("captured", "<",mktime(0, 0, 0, ($counter_months + 1), 1, $calendar_year)) - ->find_all() - ->count(); - } else { - $day_count = ORM::factory("item") - ->viewable() - ->where("owner_id", "=", $calendar_user) - ->where("type", "!=", "album") - ->where("captured", ">=", mktime(0, 0, 0, $counter_months, $MAX_DAYS, $calendar_year)) - ->where("captured", "<", mktime(0, 0, 0, ($counter_months + 1), 1, $calendar_year)) - ->find_all() - ->count(); - } - if ($day_count > 0) { - $calendar->event($MAX_DAYS, url::site("calendarview/day/" . $calendar_year . "/" . $calendar_user . "/" . $counter_months . "/" . $MAX_DAYS)); - } - } - echo $calendar->render(); - print "
      "; - $counter_months++; - } - - // Do December seperately, because the mktime code is different. - print "
      "; + // Search the db for all photos that were taken during the selected year. if ($calendar_user == "-1") { - $month_count = ORM::factory("item") + $items_for_year = ORM::factory("item") ->viewable() ->where("type", "!=", "album") - ->where("captured", ">=", mktime(0, 0, 0, $counter_months, 1, $calendar_year)) + ->where("captured", ">=", mktime(0, 0, 0, 1, 1, $calendar_year)) ->where("captured", "<", mktime(0, 0, 0, 1, 1, ($calendar_year + 1))) - ->find_all() - ->count(); + ->order_by("captured") + ->find_all(); } else { - $month_count = ORM::factory("item") + $items_for_year = ORM::factory("item") ->viewable() ->where("owner_id", "=", $calendar_user) ->where("type", "!=", "album") - ->where("captured", ">=", mktime(0, 0, 0, $counter_months, 1, $calendar_year)) + ->where("captured", ">=", mktime(0, 0, 0, 1, 1, $calendar_year)) ->where("captured", "<", mktime(0, 0, 0, 1, 1, ($calendar_year + 1))) - ->find_all() - ->count(); + ->order_by("captured") + ->find_all(); } - if ($month_count > 0) { + + // Set up some initial variables. + $counter_months = 1; + $counter_days = 0; + $counter = 0; + + // Set up the January Calendar. + // Check and see if any photos were taken in January, + // If so, make the month title into a clickable link. + print "
      "; + if ((count($items_for_year) > 0) && (date("n", $items_for_year[$counter]->captured) == 1)) { $month_url = url::site("calendarview/month/" . $calendar_year . "/" . $calendar_user . "/" . $counter_months . "/"); } else { $month_url = ""; } $calendar = new PHPCalendar($counter_months, $calendar_year, $month_url); - if ($month_count > 0) { - $curr_day = 1; - $MAX_DAYS = date('t', mktime(00, 00, 00, $counter_months, 1, $calendar_year)); - while ($curr_day < $MAX_DAYS) { - if ($calendar_user == "-1") { - $day_count = ORM::factory("item") - ->viewable() - ->where("type", "!=", "album") - ->where("captured", ">=", mktime(0, 0, 0, $counter_months, $curr_day, $calendar_year)) - ->where("captured", "<", mktime(0, 0, 0, $counter_months, ($curr_day + 1), $calendar_year)) - ->find_all() - ->count(); + + // Loop through each photo taken during this year, and see what month and day they were taken on. + // Make the corresponding dates on the calendars into clickable links. + while ($counter < (count($items_for_year))) { + + // Check and see if we've switched to a new month. + // If so, render the current calendar and set up a new one. + while (date("n", $items_for_year[$counter]->captured) > $counter_months) { + echo $calendar->render(); + print "
      "; + $counter_months++; + $counter_days = 0; + print "
      "; + if (date("n", $items_for_year[$counter]->captured) == $counter_months) { + $month_url = url::site("calendarview/month/" . $calendar_year . "/" . $calendar_user . "/" . $counter_months . "/"); } else { - $day_count = ORM::factory("item") - ->viewable() - ->where("owner_id", "=", $calendar_user) - ->where("type", "!=", "album") - ->where("captured", ">=", mktime(0, 0, 0, $counter_months, $curr_day, $calendar_year)) - ->where("captured", "<", mktime(0, 0, 0, $counter_months, ($curr_day + 1), $calendar_year)) - ->find_all() - ->count(); + $month_url = ""; } - if ($day_count > 0) { - $calendar->event($curr_day, url::site("calendarview/day/" . $calendar_year . "/" . $calendar_user . "/" . $counter_months . "/" . $curr_day)); - } - $curr_day++; - } - if ($calendar_user == "-1") { - $day_count = ORM::factory("item") - ->viewable() - ->where("type", "!=", "album") - ->where("captured", ">=", mktime(0, 0, 0, $counter_months, $MAX_DAYS, $calendar_year)) - ->where("captured", "<", mktime(0, 0, 0, 1, 1, $calendar_year+1)) - ->find_all() - ->count(); - } else { - $day_count = ORM::factory("item") - ->viewable() - ->where("owner_id", "=", $calendar_user) - ->where("type", "!=", "album") - ->where("captured", ">=", mktime(0, 0, 0, $counter_months, $MAX_DAYS, $calendar_year)) - ->where("captured", "<", mktime(0, 0, 0, 1, 1, $calendar_year+1)) - ->find_all() - ->count(); - } - if ($day_count > 0) { - $calendar->event($MAX_DAYS, url::site("calendarview/day/" . $calendar_year . "/" . $calendar_user . "/" . $counter_months . "/" . $MAX_DAYS)); + $calendar = new PHPCalendar($counter_months, $calendar_year, $month_url); } + + // If the day of the current photo is different then the day of the previous photo, + // then add a link to the calendar for this date and set the current day to this day. + if (date("j", $items_for_year[$counter]->captured) > $counter_days) { + $counter_days = date("j", $items_for_year[$counter]->captured); + $calendar->event($counter_days, url::site("calendarview/day/" . $calendar_year . "/" . $calendar_user . "/" . $counter_months . "/" . $counter_days)); + } + + // Move onto the next photo. + $counter++; } - $counter_months++; + + // Print out the last calendar to be generated. echo $calendar->render(); print "
      "; -?> \ No newline at end of file + $counter_months++; + + // If the calendar that was previously rendered was not December, + // then print out a few empty months for the rest of the year. + while ($counter_months < 13) { + print "
      "; + $month_url = ""; + $calendar = new PHPCalendar($counter_months, $calendar_year, $month_url); + echo $calendar->render(); + print "
      "; + $counter_months++; + } +?> +dynamic_bottom() ?> diff --git a/3.1/modules/calendarview/views/calpage.html.php b/3.1/modules/calendarview/views/calpage.html.php index f98352b9..3dab5fc0 100644 --- a/3.1/modules/calendarview/views/calpage.html.php +++ b/3.1/modules/calendarview/views/calpage.html.php @@ -1,51 +1,42 @@ - +html_attributes() ?> xml:lang="en" lang="en"> + start_combining("script,css") ?> <? if ($page_title): ?> <?= $page_title ?> <? else: ?> <? if ($theme->item()): ?> - <? if ($theme->item()->is_album()): ?> - <?= t("Browse Album :: %album_title", array("album_title" => $theme->item()->title)) ?> - <? elseif ($theme->item()->is_photo()): ?> - <?= t("Photo :: %photo_title", array("photo_title" => $theme->item()->title)) ?> - <? else: ?> - <?= t("Movie :: %movie_title", array("movie_title" => $theme->item()->title)) ?> - <? endif ?> + <?= $theme->item()->title ?> <? elseif ($theme->tag()): ?> - <?= t("Browse Tag :: %tag_title", array("tag_title" => $theme->tag()->name)) ?> + <?= t("Photos tagged with %tag_title", array("tag_title" => $theme->tag()->name)) ?> <? else: /* Not an item, not a tag, no page_title specified. Help! */ ?> - <?= t("Gallery") ?> + <?= item::root()->title ?> <? endif ?> <? endif ?> - " type="image/x-icon" /> - css("yui/reset-fonts-grids.css") ?> - css("superfish/css/superfish.css") ?> - css("themeroller/ui.base.css") ?> - css("gallery.common.css") ?> - css("screen.css") ?> - + " + type="image/x-icon" /> + page_type == "collection"): ?> - - - + + + + + script("json2-min.js") ?> script("jquery.js") ?> script("jquery.form.js") ?> script("jquery-ui.js") ?> @@ -58,9 +49,8 @@ script("gallery.dialog.js") ?> script("superfish/js/superfish.js") ?> script("jquery.localscroll.js") ?> - script("ui.init.js") ?> - head() they get combined */ ?> + page_subtype == "photo"): ?> script("jquery.scrollTo.js") ?> script("gallery.show_full_size.js") ?> @@ -69,6 +59,23 @@ head() ?> + + + script("ui.init.js") ?> + css("yui/reset-fonts-grids.css") ?> + css("superfish/css/superfish.css") ?> + css("themeroller/ui.base.css") ?> + css("screen.css") ?> + + + + get_combined("script") ?> + + + get_combined("css") ?> body_attributes() ?>> @@ -87,15 +94,16 @@ user_menu() ?> header_top() ?> - + header_bottom() ?>
      + @@ -120,6 +128,8 @@ + +
    @@ -151,4 +161,4 @@
    page_bottom() ?> - + \ No newline at end of file diff --git a/3.1/modules/captionator/controllers/captionator.php b/3.1/modules/captionator/controllers/captionator.php index 007ee86f..8b380f66 100644 --- a/3.1/modules/captionator/controllers/captionator.php +++ b/3.1/modules/captionator/controllers/captionator.php @@ -1,7 +1,7 @@ content = new View("captionator_dialog.html"); $v->content->album = $album; + $v->content->enable_tags = module::is_active("tag"); + if ($v->content->enable_tags) { + $v->content->tags = array(); + foreach ($album->viewable()->children() as $child) { + $item = ORM::factory("item", $child->id); + $tag_names = array(); + foreach (tag::item_tags($item) as $tag) { + $tag_names[] = $tag->name; + } + $v->content->tags[$child->id] = implode(", ", $tag_names); + } + } print $v; } @@ -42,12 +54,27 @@ class Captionator_Controller extends Controller { if (Input::instance()->post("save")) { $titles = Input::instance()->post("title"); $descriptions = Input::instance()->post("description"); + $filenames = Input::instance()->post("filename"); + $internetaddresses = Input::instance()->post("internetaddress"); + $tags = Input::instance()->post("tags"); + $enable_tags = module::is_active("tag"); foreach (array_keys($titles) as $id) { $item = ORM::factory("item", $id); if ($item->loaded() && access::can("edit", $item)) { $item->title = $titles[$id]; $item->description = $descriptions[$id]; + $item->name = $filenames[$id]; + $item->slug = $internetaddresses[$id]; $item->save(); + if ($enable_tags) { + tag::clear_all($item); + foreach (explode(",", $tags[$id]) as $tag_name) { + if ($tag_name) { + tag::add($item, trim($tag_name)); + } + } + tag::compact(); + } } } message::success(t("Captions saved")); diff --git a/3.1/modules/captionator/helpers/captionator_event.php b/3.1/modules/captionator/helpers/captionator_event.php index d00c04ae..43e501f8 100644 --- a/3.1/modules/captionator/helpers/captionator_event.php +++ b/3.1/modules/captionator/helpers/captionator_event.php @@ -1,7 +1,7 @@
    +
    id}") ?>" method="post" id="g-captionator-form">
    @@ -23,6 +29,20 @@ + +
  • + + +
  • + +
  • + + +
  • +
  • + + +
  • diff --git a/3.1/modules/contactowner/controllers/admin_contactowner.php b/3.1/modules/contactowner/controllers/admin_contactowner.php index 73a82ee3..26b684ab 100644 --- a/3.1/modules/contactowner/controllers/admin_contactowner.php +++ b/3.1/modules/contactowner/controllers/admin_contactowner.php @@ -1,7 +1,7 @@ name; } + // If item_id is set, include a link to the item. + $email_body = ""; + if ($item_id <> "") { + $item = ORM::factory("item", $item_id); + $email_body = "This message refers to type}s/{$item->id}") . "\">this page."; + } + // Make a new form with a couple of text boxes. $form = new Forge("contactowner/sendemail/{$user_id}", "", "post", array("id" => "g-contact-owner-send-form")); @@ -53,7 +60,7 @@ class ContactOwner_Controller extends Controller { ->error_messages("required", t("You must enter a subject")); $sendmail_fields->textarea("email_body") ->label(t("Message:")) - ->value("") + ->value($email_body) ->id("g-contactowner-email-body") ->rules('required') ->error_messages("required", t("You must enter a message")); @@ -67,7 +74,7 @@ class ContactOwner_Controller extends Controller { return $form; } - public function emailowner() { + public function emailowner($item_id) { // Display a form that a vistor can use to contact the site owner. // If this page is disabled, show a 404 error. @@ -78,11 +85,11 @@ class ContactOwner_Controller extends Controller { // Set up and display the actual page. $template = new Theme_View("page.html", "other", "Contact"); $template->content = new View("contactowner_emailform.html"); - $template->content->sendmail_form = $this->get_email_form("-1"); + $template->content->sendmail_form = $this->get_email_form("-1", $item_id); print $template; } - public function emailid($user_id) { + public function emailid($user_id, $item_id) { // Display a form that a vistor can use to contact a registered user. // If this page is disabled, show a 404 error. @@ -93,7 +100,7 @@ class ContactOwner_Controller extends Controller { // Set up and display the actual page. $template = new Theme_View("page.html", "other", "Contact"); $template->content = new View("contactowner_emailform.html"); - $template->content->sendmail_form = $this->get_email_form($user_id); + $template->content->sendmail_form = $this->get_email_form($user_id, $item_id); print $template; } diff --git a/3.1/modules/contactowner/helpers/contactowner_block.php b/3.1/modules/contactowner/helpers/contactowner_block.php index b10252b3..b2c31500 100644 --- a/3.1/modules/contactowner/helpers/contactowner_block.php +++ b/3.1/modules/contactowner/helpers/contactowner_block.php @@ -1,7 +1,7 @@ 0) && ($userDetails[0]->email != "") && (module::get_var("contactowner", "contact_user_link") == true)) { $block->content->userLink = "item->owner_id) . "\">" . t("Contact") . " " . + $theme->item->owner_id) . "/" . $theme->item->id . "\">" . t("Contact") . " " . $userDetails[0]->name . ""; $displayBlock = true; } @@ -61,8 +61,13 @@ class contactowner_block_Core { // Figure out if the contact site owner link should be displayed. if (module::get_var("contactowner", "contact_owner_link")) { - $block->content->ownerLink = "" . t(module::get_var("contactowner", "contact_button_text")) . ""; + if ($theme->item()) { + $block->content->ownerLink = "item->id . + "\">" . t(module::get_var("contactowner", "contact_button_text")) . ""; + } else { + $block->content->ownerLink = "" . t(module::get_var("contactowner", "contact_button_text")) . ""; + } $displayBlock = true; } diff --git a/3.1/modules/contactowner/helpers/contactowner_event.php b/3.1/modules/contactowner/helpers/contactowner_event.php index 5c8483d3..7c527155 100644 --- a/3.1/modules/contactowner/helpers/contactowner_event.php +++ b/3.1/modules/contactowner/helpers/contactowner_event.php @@ -1,7 +1,7 @@ /** * Gallery - a web based photo album viewer and editor - * Copyright (C) 2000-2010 Bharat Mediratta + * Copyright (C) 2000-2011 Bharat Mediratta * * 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 diff --git a/3.1/modules/developer/views/block.txt.php b/3.1/modules/developer/views/block.txt.php index aae11c89..28a8d9db 100644 --- a/3.1/modules/developer/views/block.txt.php +++ b/3.1/modules/developer/views/block.txt.php @@ -3,7 +3,7 @@ /** * Gallery - a web based photo album viewer and editor - * Copyright (C) 2000-2010 Bharat Mediratta + * Copyright (C) 2000-2011 Bharat Mediratta * * 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 diff --git a/3.1/modules/developer/views/controller.txt.php b/3.1/modules/developer/views/controller.txt.php index b73ae815..664ff987 100644 --- a/3.1/modules/developer/views/controller.txt.php +++ b/3.1/modules/developer/views/controller.txt.php @@ -2,7 +2,7 @@ /** * Gallery - a web based photo album viewer and editor - * Copyright (C) 2000-2010 Bharat Mediratta + * Copyright (C) 2000-2011 Bharat Mediratta * * 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 diff --git a/3.1/modules/developer/views/event.txt.php b/3.1/modules/developer/views/event.txt.php index ac5db4e3..32a48520 100644 --- a/3.1/modules/developer/views/event.txt.php +++ b/3.1/modules/developer/views/event.txt.php @@ -2,7 +2,7 @@ /** * Gallery - a web based photo album viewer and editor - * Copyright (C) 2000-2010 Bharat Mediratta + * Copyright (C) 2000-2011 Bharat Mediratta * * 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 diff --git a/3.1/modules/developer/views/installer.txt.php b/3.1/modules/developer/views/installer.txt.php index 6748ac46..cf6662d5 100644 --- a/3.1/modules/developer/views/installer.txt.php +++ b/3.1/modules/developer/views/installer.txt.php @@ -2,7 +2,7 @@ /** * Gallery - a web based photo album viewer and editor - * Copyright (C) 2000-2010 Bharat Mediratta + * Copyright (C) 2000-2011 Bharat Mediratta * * 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 diff --git a/3.1/modules/developer/views/theme.txt.php b/3.1/modules/developer/views/theme.txt.php index 190ff828..e4467f43 100644 --- a/3.1/modules/developer/views/theme.txt.php +++ b/3.1/modules/developer/views/theme.txt.php @@ -2,7 +2,7 @@ /** * Gallery - a web based photo album viewer and editor - * Copyright (C) 2000-2010 Bharat Mediratta + * Copyright (C) 2000-2011 Bharat Mediratta * * 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 diff --git a/3.1/modules/displaytags/helpers/displaytags_block.php b/3.1/modules/displaytags/helpers/displaytags_block.php index ea63bb77..8fc530f1 100644 --- a/3.1/modules/displaytags/helpers/displaytags_block.php +++ b/3.1/modules/displaytags/helpers/displaytags_block.php @@ -1,7 +1,7 @@ module == "tag") { + $data->messages["warn"][] = t("The DisplayTags module requires the Tags module."); + } + } + + static function module_change($changes) { + if (!module::is_active("tag") || in_array("tag", $changes->deactivate)) { + site_status::warning( + t("The DisplayTags module requires the Tags module. Activate the Tags module now", + array("url" => html::mark_clean(url::site("admin/modules")))), + "displaytags_needs_tag"); + } else { + site_status::clear("displaytags_needs_tag"); + } + } +} diff --git a/3.1/themes/greydragon/helpers/greydragon_installer.php b/3.1/modules/displaytags/helpers/displaytags_installer.php similarity index 66% rename from 3.1/themes/greydragon/helpers/greydragon_installer.php rename to 3.1/modules/displaytags/helpers/displaytags_installer.php index 461e6914..808def8a 100644 --- a/3.1/themes/greydragon/helpers/greydragon_installer.php +++ b/3.1/modules/displaytags/helpers/displaytags_installer.php @@ -1,30 +1,36 @@ - \ No newline at end of file +init($id); - $files = $this->getFilesList($album); + public function zip($container_type, $id) { + switch($container_type) { + case "album": + $container = ORM::factory("item", $id); + if (!$container->is_album()) { + throw new Kohana_Exception('container is not an album: '.$container->relative_path()); + } + + $zipname = (empty($container->name)) + ? 'Gallery.zip' // @todo purified_version_of($container->title).'.zip' + : $container->name.'.zip'; + break; + + case "tag": + // @todo: if the module is not installed, it crash + $container = ORM::factory("tag", $id); + if (is_null($container->name)) { + throw new Kohana_Exception('container is not a tag: '.$id); + } + + $zipname = $container->name.'.zip'; + break; + + default: + throw new Kohana_Exception('unhandled container type: '.$container_type); + } + + $files = $this->getFilesList($container); // Calculate ZIP size (look behind for details) $zipsize = 22; - foreach($files as $f) { - $zipsize += 76 + 2*strlen($f) + filesize($f); + foreach($files as $f_name => $f_path) { + $zipsize += 76 + 2*strlen($f_name) + filesize($f_path); } // Send headers $this->prepareOutput(); - $this->sendHeaders($album->name.'.zip', $zipsize); + $this->sendHeaders($zipname, $zipsize); // Generate and send ZIP file // http://www.pkware.com/documents/casestudies/APPNOTE.TXT (v6.3.2) $lfh_offset = 0; $cds = ''; $cds_offset = 0; - foreach($files as $f) { - $f_namelen = strlen($f); - $f_size = filesize($f); - $f_mtime = $this->unix2dostime(filemtime($f)); - $f_crc32 = $this->fixBug45028(hexdec(hash_file('crc32b', $f, false))); + foreach($files as $f_name => $f_path) { + $f_namelen = strlen($f_name); + $f_size = filesize($f_path); + $f_mtime = $this->unix2dostime(filemtime($f_path)); + $f_crc32 = $this->fixBug45028(hexdec(hash_file('crc32b', $f_path, false))); // Local file header echo pack('VvvvVVVVvva' . $f_namelen, @@ -60,12 +85,12 @@ class downloadalbum_Controller extends Controller { $f_namelen, // file name length (2 bytes) 0, // extra field length (2 bytes) - $f // file name (variable size) + $f_name // file name (variable size) // extra field (variable size) => n/a ); // File data - readfile($f); + readfile($f_path); // Data descriptor (n/a) @@ -88,7 +113,7 @@ class downloadalbum_Controller extends Controller { 0x81b40000, // external file attributes (4 bytes) => chmod 664 $lfh_offset, // relative offset of local header (4 bytes) - $f // file name (variable size) + $f_name // file name (variable size) // extra field (variable size) => n/a // file comment (variable size) => n/a ); @@ -128,59 +153,58 @@ class downloadalbum_Controller extends Controller { } - /** - * Init - */ - private function init($id) { - $item = ORM::factory("item", $id); - - // Only send an album - if (!$item->is_album()) { - // @todo: throw an exception? - Kohana::log('error', 'item is not an album: '.$item->relative_path()); - exit; - } - - // Must have view_full to download the originals files - access::required("view_full", $item); - - return $item; - } - /** * Return the files that must be included in the archive. */ - private function getFilesList($album) { + private function getFilesList($container) { $files = array(); - // Go to the parent of album so the ZIP will not contains all the - // server hierarchy - if (!chdir($album->file_path().'/../')) { - // @todo: throw an exception? - Kohana::log('error', 'unable to chdir('.$item->file_path().'/../)'); - exit; - } - $cwd = getcwd(); + if( $container instanceof Item_Model && $container->is_album() ) { + $container_realpath = realpath($container->file_path().'/../'); - $items = $album->viewable() - ->descendants(null, null, array(array("type", "<>", "album"))); - foreach($items as $i) { - if (!access::can('view_full', $i)) { - continue; + $items = $container->viewable() + ->descendants(null, null, array(array("type", "<>", "album"))); + foreach($items as $i) { + if (!access::can('view_full', $i)) { + continue; + } + + $i_realpath = realpath($i->file_path()); + if (!is_readable($i_realpath)) { + continue; + } + + $i_relative_path = str_replace($container_realpath.DIRECTORY_SEPARATOR, '', $i_realpath); + $i_relative_path = str_replace(DIRECTORY_SEPARATOR, '/', $i_relative_path); + $files[$i_relative_path] = $i_realpath; } - $relative_path = str_replace($cwd.'/', '', realpath($i->file_path())); - if (!is_readable($relative_path)) { - continue; - } + } else if( $container instanceof Tag_Model ) { + $items = $container->items(); + foreach($items as $i) { + if (!access::can('view_full', $i)) { + continue; + } - $files[] = $relative_path; + if( $i->is_album() ) { + foreach($this->getFilesList($i) as $f_name => $f_path) { + $files[$container->name.'/'.$f_name] = $f_path; + } + + } else { + $i_realpath = realpath($i->file_path()); + if (!is_readable($i_realpath)) { + continue; + } + + $i_relative_path = $container->name.'/'.$i->name; + $files[$i_relative_path] = $i_realpath; + } + } } if (count($files) === 0) { - // @todo: throw an exception? - Kohana::log('error', 'no zippable files in ['.$album->relative_path().']'); - exit; + throw new Kohana_Exception('no zippable files in ['.$container->name.']'); } return $files; @@ -264,9 +288,13 @@ class downloadalbum_Controller extends Controller { * See http://bugs.php.net/bug.php?id=45028 */ private function fixBug45028($hash) { - return (version_compare(PHP_VERSION, '5.2.7', '<')) - ? (($hash & 0x000000ff) << 24) + (($hash & 0x0000ff00) << 8) - + (($hash & 0x00ff0000) >> 8) + (($hash & 0xff000000) >> 24) - : $hash; + $output = $hash; + + if( version_compare(PHP_VERSION, '5.2.7', '<') ) { + $str = str_pad(dechex($hash), 8, '0', STR_PAD_LEFT); + $output = hexdec($str{6}.$str{7}.$str{4}.$str{5}.$str{2}.$str{3}.$str{0}.$str{1}); + } + + return $output; } } diff --git a/3.1/modules/downloadalbum/helpers/downloadalbum_event.php b/3.1/modules/downloadalbum/helpers/downloadalbum_event.php index e2fe4420..e8159003 100644 --- a/3.1/modules/downloadalbum/helpers/downloadalbum_event.php +++ b/3.1/modules/downloadalbum/helpers/downloadalbum_event.php @@ -1,7 +1,7 @@ item)) { - $downloadLink = url::site("downloadalbum/zip/{$theme->item->id}"); - $menu - ->append(Menu::factory("link") - ->id("downloadalbum") - ->label(t("Download Album")) - ->url($downloadLink) - ->css_id("g-download-album-link")); - } + $downloadLink = url::site("downloadalbum/zip/album/{$theme->item->id}"); + $menu + ->append(Menu::factory("link") + ->id("downloadalbum") + ->label(t("Download Album")) + ->url($downloadLink) + ->css_id("g-download-album-link")); } + + static function tag_menu($menu, $theme) { + $downloadLink = url::site("downloadalbum/zip/tag/{$theme->tag()->id}"); + $menu + ->append(Menu::factory("link") + ->id("downloadalbum") + ->label(t("Download Album")) + ->url($downloadLink) + ->css_id("g-download-album-link")); + } } diff --git a/3.1/modules/downloadalbum/helpers/downloadalbum_theme.php b/3.1/modules/downloadalbum/helpers/downloadalbum_theme.php index 2fd23552..8cda59fc 100644 --- a/3.1/modules/downloadalbum/helpers/downloadalbum_theme.php +++ b/3.1/modules/downloadalbum/helpers/downloadalbum_theme.php @@ -1,7 +1,7 @@ item && access::can("view_full", $theme->item)) { - $theme->css("downloadalbum_menu.css"); - } + return $theme->css("downloadalbum_menu.css"); } } diff --git a/3.1/modules/downloadalbum/module.info b/3.1/modules/downloadalbum/module.info index 177ad4a8..f547fd4a 100644 --- a/3.1/modules/downloadalbum/module.info +++ b/3.1/modules/downloadalbum/module.info @@ -1,3 +1,7 @@ name = "DownloadAlbum" description = "Displays a link to download a ZIP archive of the current album." -version = 1 +version = 2 +author_name = "" +author_url = "" +info_url = "http://codex.gallery2.org/Gallery3:Modules:downloadalbum" +discuss_url = "http://gallery.menalto.com/forum_module_downloadalbum" diff --git a/3.1/modules/downloadfullsize/controllers/admin_downloadfullsize.php b/3.1/modules/downloadfullsize/controllers/admin_downloadfullsize.php index 1b55bd5c..6836c9c8 100644 --- a/3.1/modules/downloadfullsize/controllers/admin_downloadfullsize.php +++ b/3.1/modules/downloadfullsize/controllers/admin_downloadfullsize.php @@ -1,7 +1,7 @@ item && access::can("view_full", $theme->item)) { - $theme->css("downloadfullsize_menu.css"); + return $theme->css("downloadfullsize_menu.css"); } } } diff --git a/3.1/modules/downloadfullsize/module.info b/3.1/modules/downloadfullsize/module.info index 6c732c9d..078371a9 100644 --- a/3.1/modules/downloadfullsize/module.info +++ b/3.1/modules/downloadfullsize/module.info @@ -1,3 +1,7 @@ name = "DownloadFullsize" description = "Displays a link to download the fullsize version of the current photo." version = 1 +author_name = "" +author_url = "" +info_url = "http://codex.gallery2.org/Gallery3:Modules:downloadfullsize" +discuss_url = "http://gallery.menalto.com/forum_module_downloadfullsize" diff --git a/3.1/modules/dynamic/controllers/admin_dynamic.php b/3.1/modules/dynamic/controllers/admin_dynamic.php index 0180fef3..0f87329f 100644 --- a/3.1/modules/dynamic/controllers/admin_dynamic.php +++ b/3.1/modules/dynamic/controllers/admin_dynamic.php @@ -1,6 +1,6 @@ get("page", "1"); $album_defn = unserialize(module::get_var("dynamic", $album)); - $children_count = $album_defn->limit; - if (empty($children_count)) { - $children_count = ORM::factory("item") - ->viewable() - ->where("type", "!=", "album") - ->count_all(); + $display_limit = $album_defn->limit; + $children_count = ORM::factory("item") + ->viewable() + ->where("type", "!=", "album") + ->count_all(); + if (!empty($display_limit)) { + $children_count = min($children_count, $display_limit); } - $offset = ($page-1) * $page_size; - - $max_pages = ceil($children_count / $page_size); + $offset = ($page - 1) * $page_size; + $max_pages = max(ceil($children_count / $page_size), 1); // Make sure that the page references a valid offset if ($page < 1 || ($children_count && $page > ceil($children_count / $page_size))) { diff --git a/3.1/modules/dynamic/helpers/dynamic_block.php b/3.1/modules/dynamic/helpers/dynamic_block.php index 42861c51..bf7dcd8f 100644 --- a/3.1/modules/dynamic/helpers/dynamic_block.php +++ b/3.1/modules/dynamic/helpers/dynamic_block.php @@ -1,6 +1,6 @@ _get_admin_form(); if ($form->validate()) { - module::set_var("ecard", "sender", $form->ecard->sender->value); + module::set_var("ecard","send_plain",$form->ecard->send_plain->value); + module::set_var("ecard", "sender", $form->ecard->sender->value); module::set_var("ecard", "bcc", $form->ecard->bcc->value); module::set_var("ecard", "subject", $form->ecard->subject->value); module::set_var("ecard", "message", $form->ecard->message->value); + module::set_var("ecard", "max_length", $form->ecard->max_length->value); module::set_var("ecard", "access_permissions", $form->ecard->access_permissions->value); module::set_var("ecard", "location", $form->ecard->location->value); message::success(t("eCard settings updated")); @@ -54,9 +56,18 @@ class Admin_ecard_Controller extends Admin_Controller { ->value(module::get_var("ecard", "bcc", "")); $ecard_settings->input("subject")->label(t("E-mail subject")) ->value(module::get_var("ecard", "subject")); - $ecard_settings->textarea("message")->label(t("E-mail message. Valid keywords are \"%toname\" (recipient's name) and \"%fromname\" (sender's name))")) + $ecard_settings->textarea("message")->label(t("E-mail message. Valid keywords are \"%fromname\" (sender's name))")) ->value(module::get_var("ecard", "message")); - $ecard_settings->dropdown("access_permissions") + $ecard_settings->input("max_length") + ->label(t("Maximum message length")) + ->value(module::get_var("ecard","max_length")); + if(module::is_active("watermark")) { + $ecard_settings->checkbox("send_plain") + ->label(t("Allow users to send non-watermarked versions")) + ->value(true) + ->checked(module::get_var("ecard","send_plain")); + } + $ecard_settings->dropdown("access_permissions") ->label(t("Who can send eCards?")) ->options(array("everybody" => t("Everybody"), "registered_users" => t("Only registered users"))) diff --git a/3.1/modules/ecard/controllers/ecard.php b/3.1/modules/ecard/controllers/ecard.php index 6ca30df7..21a87080 100644 --- a/3.1/modules/ecard/controllers/ecard.php +++ b/3.1/modules/ecard/controllers/ecard.php @@ -1,7 +1,7 @@ item = $item; - $v->subject = module::get_var("ecard", "subject"); - $to_name = $form->send_ecard->to_name->value; - $from_name = $form->send_ecard->from_name->value; - $bcc = module::get_var("ecard", "bcc"); - $v->message = t(module::get_var("ecard", "message"), array("toname" => $to_name, "fromname" => $from_name)); - $v->custom_message = $form->send_ecard->text->value; - $v->image = $item->name; - $to = $form->send_ecard->inputs["to_email"]->value; - $from = $form->send_ecard->inputs["from_email"]->value; - $headers = array("from" => $from_name."<".$from.">", "to" => $to, "subject" => module::get_var("ecard", "subject")); - require_once(MODPATH. "ecard/lib/mime.php"); - $mime = new Mail_mime("\n"); - $mime->setHTMLBody($v->render()); - $mime->addHTMLImage($item->resize_path(),$item->mime_type,$item->name); - $body = $mime->get(array('html_charset' => 'UTF-8', 'text_charset' => 'UTF-8','text_encoding' => '8bit','head_charset' => 'UTF-8')); - self::_notify($headers['to'], $headers['from'], $headers['subject'], $item, $body, $mime->headers(), $bcc); + $to_array = explode(",",$form->send_ecard->inputs["to_email"]->value); + foreach($to_array as $to) { + $v = new View("ecard_email.html"); + $v->item = $item; + $v->subject = module::get_var("ecard", "subject"); + $from_name = $form->send_ecard->from_name->value; + $bcc = module::get_var("ecard", "bcc"); + if($form->send_ecard->send_to_self->checked == true) { + $cc = $form->send_ecard->inputs["from_email"]->value; + } + $v->message = t(module::get_var("ecard", "message"), array("fromname" => $from_name)); + $v->custom_message = $form->send_ecard->text->value; + $v->image = $item->name; + $from = $form->send_ecard->inputs["from_email"]->value; + $headers = array("from" => $from_name."<".$from.">", "to" => $to, "subject" => module::get_var("ecard", "subject")); + require_once(MODPATH. "ecard/lib/mime.php"); + $mime = new Mail_mime("\n"); + $mime->setHTMLBody($v->render()); + if($form->send_ecard->send_fresh->checked == true) { + $tmpfile = tempnam(TMPPATH, "clean"); + if($form->send_ecard->send_thumbnail->checked == true) { + $options = array("width" => module::get_var("gallery", "thumb_size"), "height" => module::get_var("gallery", "thumb_size"), "master" => Image::AUTO); + gallery_graphics::resize($item->file_path(), $tmpfile, $options, $item); + $mime->addHTMLImage($tmpfile,$item->mime_type,$item->name); + } else { + $options = array("width" => module::get_var("gallery", "resize_size"), "height" => module::get_var("gallery", "resize_size"), "master" => Image::AUTO); + gallery_graphics::resize($item->file_path(), $tmpfile, $options, $item); + $mime->addHTMLImage($tmpfile,$item->mime_type,$item->name); + } + } else { + if($form->send_ecard->send_thumbnail->checked == true) { + $mime->addHTMLImage($item->thumb_path(),$item->mime_type,$item->name); + } else { + $mime->addHTMLImage($item->resize_path(),$item->mime_type,$item->name); + } + } + $body = $mime->get(array('html_charset' => 'UTF-8', 'text_charset' => 'UTF-8','text_encoding' => '8bit','head_charset' => 'UTF-8')); + self::_notify($headers['to'], $headers['from'], $headers['subject'], $item, $body, $mime->headers(), $bcc, $cc); + } + unlink($tmpfile); message::success("eCard successfully sent"); json::reply(array("result" => "success")); - } else { + } else { json::reply(array("result" => "error", "html" => (string) $form)); - } + } } /** * Present a form for sending a new ecard. @@ -73,9 +95,11 @@ class Ecard_Controller extends Controller { if (!ecard::can_send_ecard()) { access::forbidden(); } - print ecard::prefill_send_form(ecard::get_send_form($item)); + $v_form = new View("ecard_form.html"); + $v_form->item_id = $item_id; + print $v_form->render(); } - private static function _notify($to, $from, $subject, $item, $text, $headers, $bcc) { + private static function _notify($to, $from, $subject, $item, $text, $headers, $bcc, $cc) { $sendmail = Sendmail::factory(); $sendmail ->to($to) @@ -84,6 +108,9 @@ class Ecard_Controller extends Controller { if(isset($bcc)) { $sendmail->header("bcc",$bcc); } + if(isset($cc)) { + $sendmail->header("cc",$cc); + } foreach($headers as $key => $value) { $sendmail->header($key,$value); } diff --git a/3.1/modules/ecard/helpers/ecard.php b/3.1/modules/ecard/helpers/ecard.php index 13485954..a786521b 100644 --- a/3.1/modules/ecard/helpers/ecard.php +++ b/3.1/modules/ecard/helpers/ecard.php @@ -1,7 +1,7 @@ id}", "", "post", array("id" => "g-ecard-form")); + static function get_send_form($item_id) { + $form = new Forge("ecard/send/{$item_id}", "", "post", array("id" => "g-ecard-form")); $group = $form->group("send_ecard")->label(t("Send eCard")); $group->input("from_name") ->label(t("Your name")) @@ -38,23 +38,32 @@ class ecard_Core { ->rules("required|valid_email") ->error_messages("required", t("You must enter a valid email address")) ->error_messages("invalid", t("You must enter a valid email address")); - $group->input("to_name") - ->label(t("Recipient's Name")) - ->id("g-recipient") - ->rules("required") - ->error_messages("required", t("You must enter a recipient's name")); $group->input("to_email") - ->label(t("Recipient's e-mail")) + ->label(t("Recipient's e-mail. Separate multiple recipients with a comma.")) ->id("g-recip-email") - ->rules("required|valid_email") - ->error_messages("required", t("You must enter a valid email address")) - ->error_messages("invalid", t("You must enter a valid email address")); + ->rules("required") + ->error_messages("required", t("You must enter a valid email address")); $group->textarea("text") - ->label(t("Message")) + ->label(t("Message (".module::get_var("ecard","max_length")." chars max)")) ->id("g-text") + ->maxlength(module::get_var("ecard","max_length")) ->rules("required") ->error_messages("required", t("You must enter a message")); - $group->hidden("item_id")->value($item->id); + $group->checkbox("send_to_self") + ->label(t("Send yourself a copy")) + ->value(true) + ->checked(false); + $group->checkbox("send_thumbnail") + ->label(t("Send thumbnail image, instead of resized image.")) + ->value(true) + ->checked(false); + if(module::get_var("ecard","send_plain") == true && module::is_active("watermark")) { + $group->checkbox("send_fresh") + ->label(t("Send non-watermarked image.")) + ->value(true) + ->checked(false); + } + $group->hidden("item_id")->value($item_id); module::event("ecard_send_form", $form); module::event("captcha_protect_form", $form); $group->submit("")->value(t("Send"))->class("ui-state-default ui-corner-all"); diff --git a/3.1/modules/ecard/helpers/ecard_block.php b/3.1/modules/ecard/helpers/ecard_block.php index 051c55c6..d90755ab 100644 --- a/3.1/modules/ecard/helpers/ecard_block.php +++ b/3.1/modules/ecard/helpers/ecard_block.php @@ -1,7 +1,7 @@ item() && $theme->item()->is_photo() && module::get_var("ecard", "location") == "sidebar") { $block = new Block(); - $block->css_id = "g-send-ecard"; + $block->css_id = "g-sendecard"; $block->title = t("eCard"); $block->content = new View("ecard_block.html"); } diff --git a/3.1/modules/ecard/helpers/ecard_event.php b/3.1/modules/ecard/helpers/ecard_event.php index 06165b8f..ebbd5442 100644 --- a/3.1/modules/ecard/helpers/ecard_event.php +++ b/3.1/modules/ecard/helpers/ecard_event.php @@ -1,7 +1,7 @@ css("ecard.css"); + return $theme->css("ecard.css"); } } \ No newline at end of file diff --git a/3.1/modules/ecard/module.info b/3.1/modules/ecard/module.info index 95c8f6a4..2300f1ad 100644 --- a/3.1/modules/ecard/module.info +++ b/3.1/modules/ecard/module.info @@ -1,4 +1,7 @@ name = "E-Card" description = "Send a photo as a postcard" -version = 4 - +version = 11 +author_name = "" +author_url = "" +info_url = "http://codex.gallery2.org/Gallery3:Modules:ecard" +discuss_url = "http://gallery.menalto.com/forum_module_ecard" diff --git a/3.1/modules/ecard/views/ecard_block.html.php b/3.1/modules/ecard/views/ecard_block.html.php index 3f307a1d..d8aa4e4e 100644 --- a/3.1/modules/ecard/views/ecard_block.html.php +++ b/3.1/modules/ecard/views/ecard_block.html.php @@ -1,6 +1,6 @@ -id}") ?>" id="g-send-ecard" +id}") ?>" class="g-dialog-link g-button ui-state-default ui-corner-all"> - + diff --git a/3.1/modules/ecard/views/ecard_form.html.php b/3.1/modules/ecard/views/ecard_form.html.php new file mode 100644 index 00000000..fc22e95b --- /dev/null +++ b/3.1/modules/ecard/views/ecard_form.html.php @@ -0,0 +1 @@ + Send eCard \ No newline at end of file diff --git a/3.1/modules/editcreation/helpers/editcreation_event.php b/3.1/modules/editcreation/helpers/editcreation_event.php index c76e730d..8820d8fa 100644 --- a/3.1/modules/editcreation/helpers/editcreation_event.php +++ b/3.1/modules/editcreation/helpers/editcreation_event.php @@ -1,7 +1,7 @@ item(); if ( $item && access::can("edit", $item) ) { - $theme->css("editcreation.css"); + return $theme->css("editcreation.css"); } } } diff --git a/3.1/modules/editcreation/module.info b/3.1/modules/editcreation/module.info index 3b98c089..fef83519 100755 --- a/3.1/modules/editcreation/module.info +++ b/3.1/modules/editcreation/module.info @@ -1,3 +1,7 @@ name = "Edit Creation" description = "Manually edit the creation date of an item in Gallery." version = 2 +author_name = "" +author_url = "" +info_url = "http://codex.gallery2.org/Gallery3:Modules:editcreation" +discuss_url = "http://gallery.menalto.com/forum_module_editcreation" diff --git a/3.1/modules/embed_videos/controllers/embedded_videos.php b/3.1/modules/embed_videos/controllers/embedded_videos.php index 6c86e3a0..f49d4220 100644 --- a/3.1/modules/embed_videos/controllers/embedded_videos.php +++ b/3.1/modules/embed_videos/controllers/embedded_videos.php @@ -1,7 +1,7 @@ "modules/embed_videos/images/embed_video_icon.png", "position" => "center", "transparency" => 95)); + gallery_graphics::composite($temp_filename, $temp_filename, array("file" => "modules/embed_videos/images/embed_video_icon.png", "position" => "center", "transparency" => 95), $item); $item->set_data_file($temp_filename); $item->name = basename($itemname); $item->title = $title; diff --git a/3.1/modules/embed_videos/helpers/embed_videos.php b/3.1/modules/embed_videos/helpers/embed_videos.php index 75b47ec2..64e0f403 100644 --- a/3.1/modules/embed_videos/helpers/embed_videos.php +++ b/3.1/modules/embed_videos/helpers/embed_videos.php @@ -1,7 +1,7 @@ item(); if ($item && $item->is_photo()) { $embedded_video = ORM::factory("embedded_video") diff --git a/3.1/modules/embed_videos/models/embedded_video.php b/3.1/modules/embed_videos/models/embedded_video.php index 6ea97e8f..7f0ae949 100644 --- a/3.1/modules/embed_videos/models/embedded_video.php +++ b/3.1/modules/embed_videos/models/embedded_video.php @@ -1,7 +1,7 @@ order_by("exif_coordinates.latitude", "ASC") ->descendants(); $curr_album = ORM::factory("item")->where("id", "=", $type_id)->find_all(); - $map_title = $curr_album[0]->name; + $map_title = $curr_album[0]->title; } elseif ($map_type == "user") { // Generate an array of all items uploaded by the current user that // have exif gps coordinates and order by latitude (to group items diff --git a/3.1/modules/exif_gps/helpers/exif_gps.php b/3.1/modules/exif_gps/helpers/exif_gps.php index d3440424..823b4b29 100644 --- a/3.1/modules/exif_gps/helpers/exif_gps.php +++ b/3.1/modules/exif_gps/helpers/exif_gps.php @@ -1,7 +1,7 @@ get("completed"); // Generate an array of the next 100 photos to check. - $all_photos = ORM::factory("item") - ->where("id", ">", $last_id) - ->where("type", "=", "photo") - ->find_all(100); + //$all_photos = ORM::factory("item") + // ->where("id", ">", $last_id) + // ->where("type", "=", "photo") + // ->order_by("id") + // ->find_all(100); // Check each photo in the array to see if it already has exif gps data associated with it. // If it doesn't, attempt to extract gps coordinates. foreach (ORM::factory("item") ->where("id", ">", $last_id) ->where("type", "=", "photo") + ->order_by("id") ->find_all(100) as $item) { $record = ORM::factory("exif_coordinate")->where("item_id", "=", $item->id)->find(); diff --git a/3.1/modules/exif_gps/helpers/exif_gps_theme.php b/3.1/modules/exif_gps/helpers/exif_gps_theme.php index 160373a2..90431195 100644 --- a/3.1/modules/exif_gps/helpers/exif_gps_theme.php +++ b/3.1/modules/exif_gps/helpers/exif_gps_theme.php @@ -1,7 +1,7 @@ css("exif_gps_menu.css"); + return $theme->css("exif_gps_menu.css"); } } diff --git a/3.1/modules/exif_gps/models/exif_coordinate.php b/3.1/modules/exif_gps/models/exif_coordinate.php index 481da1cd..e3286d93 100644 --- a/3.1/modules/exif_gps/models/exif_coordinate.php +++ b/3.1/modules/exif_gps/models/exif_coordinate.php @@ -1,7 +1,7 @@ + - + diff --git a/3.1/modules/exif_gps/views/exif_gps_dynamic_sidebar.html.php b/3.1/modules/exif_gps/views/exif_gps_dynamic_sidebar.html.php index d5b497dc..ff28e101 100644 --- a/3.1/modules/exif_gps/views/exif_gps_dynamic_sidebar.html.php +++ b/3.1/modules/exif_gps/views/exif_gps_dynamic_sidebar.html.php @@ -19,4 +19,4 @@ google.setOnLoadCallback(initialize); - + diff --git a/3.1/modules/exif_gps/views/exif_gps_map.html.php b/3.1/modules/exif_gps/views/exif_gps_map.html.php index 6c8a59ee..95f6221c 100644 --- a/3.1/modules/exif_gps/views/exif_gps_map.html.php +++ b/3.1/modules/exif_gps/views/exif_gps_map.html.php @@ -62,14 +62,14 @@ infowindow.open(map,marker); }); - + // If there is a maximum auto-zoom value, then set up an event to check the zoom // level the first time it is changed, and adjust it if necessary. // (if we call map.getZoom right after .fitBounds, getZoom will return the initial // zoom level, not the auto zoom level, this way we get the auto zoomed value). google.maps.event.addListener(map, 'zoom_changed', function() { if (google_zoom_hack) { - if (map.getZoom() > 18) map.setZoom(18); + if (map.getZoom() > ) map.setZoom(); google_zoom_hack = false; } }); diff --git a/3.1/modules/export_facebook/controllers/export_facebook.php b/3.1/modules/export_facebook/controllers/export_facebook.php index 62f2e6df..e40f9a40 100644 --- a/3.1/modules/export_facebook/controllers/export_facebook.php +++ b/3.1/modules/export_facebook/controllers/export_facebook.php @@ -1,7 +1,7 @@ css("favourites.css"); - $theme->script("favourites.js"); + return $theme->css("favourites.css") + . $theme->script("favourites.js"); } static function header_top($theme) { diff --git a/3.1/modules/favourites/module.info b/3.1/modules/favourites/module.info index aa2df84a..a3d6b898 100644 --- a/3.1/modules/favourites/module.info +++ b/3.1/modules/favourites/module.info @@ -1,3 +1,7 @@ name = "Favourites" description = "Allows users and guests to create favourite lists and then e-mail them to people." version = 1 +author_name = "" +author_url = "" +info_url = "http://codex.gallery2.org/Gallery3:Modules:favourites" +discuss_url = "http://gallery.menalto.com/forum_module_favourites" diff --git a/3.1/modules/gmaps/module.info b/3.1/modules/gmaps/module.info index 12dd61d4..e524eb69 100644 --- a/3.1/modules/gmaps/module.info +++ b/3.1/modules/gmaps/module.info @@ -1,3 +1,7 @@ name = "Google Maps" description = "Integrate with the Google Maps service" version = 1 +author_name = "" +author_url = "" +info_url = "http://codex.gallery2.org/Gallery3:Modules:gmaps" +discuss_url = "http://gallery.menalto.com/forum_module_gmaps" diff --git a/3.1/modules/google_analytics/controllers/admin_google_analytics.php b/3.1/modules/google_analytics/controllers/admin_google_analytics.php index 84b7daeb..4a28ad8d 100644 --- a/3.1/modules/google_analytics/controllers/admin_google_analytics.php +++ b/3.1/modules/google_analytics/controllers/admin_google_analytics.php @@ -1,7 +1,7 @@ file_path(), $item->file_path(), array("degrees" => $degrees)); + gallery_graphics::rotate($item->file_path(), $item->file_path(), array("degrees" => $degrees), $item); list($item->width, $item->height) = getimagesize($item->file_path()); $item->resize_dirty= 1; diff --git a/3.0/modules/gwtorganise/helpers/gwtorganise_event.php b/3.1/modules/gwtorganize/helpers/gwtorganise_event.php similarity index 96% rename from 3.0/modules/gwtorganise/helpers/gwtorganise_event.php rename to 3.1/modules/gwtorganize/helpers/gwtorganise_event.php index d22a8478..dd7696a9 100644 --- a/3.0/modules/gwtorganise/helpers/gwtorganise_event.php +++ b/3.1/modules/gwtorganize/helpers/gwtorganise_event.php @@ -1,7 +1,7 @@ script("highroller.js"); - printf("", url::site("highroller/pick_theme")); + return $theme->script("highroller.js") + . sprintf("", url::site("highroller/pick_theme")); } static function header_top($theme) { diff --git a/3.1/modules/highroller/module.info b/3.1/modules/highroller/module.info index 9b573a98..7b89e9cb 100644 --- a/3.1/modules/highroller/module.info +++ b/3.1/modules/highroller/module.info @@ -1,3 +1,7 @@ name = "High Roller" description = "Let users choose from a selection of ThemeRoller themes" version = 1 +author_name = "" +author_url = "" +info_url = "http://codex.gallery2.org/Gallery3:Modules:highroller" +discuss_url = "http://gallery.menalto.com/forum_module_highroller" diff --git a/3.1/modules/html_uploader/controllers/uploader.php b/3.1/modules/html_uploader/controllers/uploader.php index 78c64468..0b9b5351 100644 --- a/3.1/modules/html_uploader/controllers/uploader.php +++ b/3.1/modules/html_uploader/controllers/uploader.php @@ -1,7 +1,7 @@ script("kbd_nav.js"); - } -} \ No newline at end of file diff --git a/3.1/modules/kbd_nav/js/kbd_nav.js b/3.1/modules/kbd_nav/js/kbd_nav.js deleted file mode 100644 index 25eb7210..00000000 --- a/3.1/modules/kbd_nav/js/kbd_nav.js +++ /dev/null @@ -1,102 +0,0 @@ -/** -* -* Copyright (c) 2010 Serguei Dosyukov, http://blog.dragonsoft.us -* -* Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation -* files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, -* modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the -* Software is furnished to do so, subject to the following conditions: -* -* The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES -* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR -* IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -* -*/ - -$.fn.KbdNavigation = function(options, callback) { - - this.options = options || {}; - var opt = this.options; - this.callback = callback || null; - var clbk = this.callback; - - $(this).bind("keydown", function(event) { - if ($('#sb-body-inner>img#sb-content').is(':visible')) { - return false; - } - // ignore shortcuts when inside a jQuery dialog; otherwise it becomes impossible - // to navigate the cursor inside an input box - if ($('.ui-widget-overlay').is(':visible')) { - return true; - } - - var direction = "ltr"; - if (document.body) { - if (window.getComputedStyle) { - direction = window.getComputedStyle(document.body, null).direction; - } else if (document.body.currentStyle) { - direction = document.body.currentStyle.direction; - } - } - - var lnk = ""; - var lnk_first, lnk_prev, lnk_parent, lnk_next, lnk_last; - - if(opt.first) { lnk_first = opt.first; } else { lnk_first = $("#g-navi-first").attr("href"); } - if(opt.prev) { lnk_prev = opt.prev; } else { lnk_prev = $("#g-navi-prev").attr("href"); } - if(opt.parent) { lnk_parent = opt.parent; } else { lnk_parent = $("#g-navi-parent").attr("href"); } - if(opt.next) { lnk_next = opt.next; } else { lnk_next = $("#g-navi-next").attr("href"); } - if(opt.last) { lnk_last = opt.last; } else { lnk_last = $("#g-navi-last").attr("href"); } - - // Support for standard Wind Theme tags - if(!lnk_first) { lnk_first = $(".g-paginator .ui-icon-seek-first").parent().attr("href"); } - if(!lnk_prev) { lnk_prev = $(".g-paginator .ui-icon-seek-prev").parent().attr("href"); } - if(!lnk_next) { lnk_next = $(".g-paginator .ui-icon-seek-next").parent().attr("href"); } - if(!lnk_last) { lnk_last = $(".g-paginator .ui-icon-seek-end").parent().attr("href"); } - - var keyCode = event.keyCode; - - if (direction == "rtl") { - switch(keyCode) { - case 0x25: // Left - keyCode = 0x27; - break; - case 0x27: // Right - keyCode = 0x25; - break; - } - } - - switch(keyCode) { - case 0x25: // Ctr+Left/Left - if(event.ctrlKey) { lnk = lnk_first; } else { lnk = lnk_prev; } - break; - case 0x26: // Ctrl+Up - if(event.ctrlKey) { lnk = lnk_parent; } - break; - case 0x27: // Ctrl+Right/Right - if(event.ctrlKey) { lnk = lnk_last; } else { lnk = lnk_next; } - break; - } - - if(lnk) { - if(typeof clbk == 'function') { - clbk(); - return false; - } else { - window.location = lnk; - return true; - } - } - - return true; - }); -} - -$(document).ready( function() { - $(document).KbdNavigation({}); - if ($('#sb-content').is(':visible')) { return true; } -}); diff --git a/3.1/modules/kbd_nav/module.info b/3.1/modules/kbd_nav/module.info deleted file mode 100644 index 2eda7c73..00000000 --- a/3.1/modules/kbd_nav/module.info +++ /dev/null @@ -1,3 +0,0 @@ -name = "Kbd Navigation" -description = "Adds keyboard navigation to the gallery.
    Version 1.5 | By Serguei Dosyukov | Visit plugin Site | Support" -version = 5 diff --git a/3.1/modules/keeporiginal/controllers/keeporiginal.php b/3.1/modules/keeporiginal/controllers/keeporiginal.php index 0bb3aa4f..36f6affe 100644 --- a/3.1/modules/keeporiginal/controllers/keeporiginal.php +++ b/3.1/modules/keeporiginal/controllers/keeporiginal.php @@ -1,7 +1,7 @@ css("language_flags_sidebar.css"); + return $theme->css("language_flags_sidebar.css"); } } diff --git a/3.1/modules/language_flags/module.info b/3.1/modules/language_flags/module.info index d0838d10..56fa94ab 100644 --- a/3.1/modules/language_flags/module.info +++ b/3.1/modules/language_flags/module.info @@ -1,3 +1,7 @@ name = "Language Flags" description = "Replaces the language selection drop-down box with clickable flags." -version = 1 \ No newline at end of file +version = 1 +author_name = "" +author_url = "" +info_url = "http://codex.gallery2.org/Gallery3:Modules:language_flags" +discuss_url = "http://gallery.menalto.com/forum_module_language_flags" diff --git a/3.1/modules/latestalbums/helpers/latestalbums_rss.php b/3.1/modules/latestalbums/helpers/latestalbums_rss.php index 8aca12a7..aa34088c 100644 --- a/3.1/modules/latestalbums/helpers/latestalbums_rss.php +++ b/3.1/modules/latestalbums/helpers/latestalbums_rss.php @@ -1,7 +1,7 @@ "ldap", "allow_updates" => false, "params" => array( - "groups" => array("eng", "google", "guest"), + "groups" => array("engineering", "everybody", "guest"), "everybody_group" => "guest", - "registered_users_group" => "google", - "admins" => array("mediratta", "martinm"), - "url" => "ldaps://ldap.corp.google.com/", - "group_domain" => "ou=Posix,ou=Groups,dc=google,dc=com", - "user_domain" => "ou=People,dc=google,dc=com", + "registered_users_group" => "everybody", + "admins" => array("alice", "bob"), + "url" => "ldaps://ldap.mycompany.com/", + "group_domain" => "ou=Posix,ou=Groups,dc=ymcompany,dc=com", + "user_domain" => "ou=People,dc=MyCompany,dc=com", "bind_rdn" => null, "bind_password" => null, ) diff --git a/3.1/modules/ldap/helpers/ldap_installer.php b/3.1/modules/ldap/helpers/ldap_installer.php index 37269748..d9bdbfd4 100644 --- a/3.1/modules/ldap/helpers/ldap_installer.php +++ b/3.1/modules/ldap/helpers/ldap_installer.php @@ -1,7 +1,7 @@ data_file, PATHINFO_EXTENSION); gallery_graphics::resize( $item->data_file, $tmpfile, - array("width" => $max_size, "height" => $max_size, "master" => Image::AUTO)); + array("width" => $max_size, "height" => $max_size, "master" => Image::AUTO), + $item); rename($tmpfile, $item->data_file); unlink($tempnam); } diff --git a/3.1/modules/max_size/helpers/max_size_installer.php b/3.1/modules/max_size/helpers/max_size_installer.php index bd268b9c..1a7f2be9 100644 --- a/3.1/modules/max_size/helpers/max_size_installer.php +++ b/3.1/modules/max_size/helpers/max_size_installer.php @@ -1,7 +1,7 @@ module == "tag") { + $data->messages["warn"][] = t("The MetaDescription module requires the Tags module."); + } + } } diff --git a/3.1/modules/metadescription/helpers/metadescription_installer.php b/3.1/modules/metadescription/helpers/metadescription_installer.php index 4ca8f169..6609ecd9 100644 --- a/3.1/modules/metadescription/helpers/metadescription_installer.php +++ b/3.1/modules/metadescription/helpers/metadescription_installer.php @@ -1,7 +1,7 @@ item()) { + if ($theme->item() || $theme->tag()) { $metaView = new View("metadescription_block.html"); $metaView->tags = $tagsItem; return $metaView; diff --git a/3.1/modules/metadescription/module.info b/3.1/modules/metadescription/module.info index 19c2cd48..7010a0d1 100644 --- a/3.1/modules/metadescription/module.info +++ b/3.1/modules/metadescription/module.info @@ -1,3 +1,7 @@ name = "MetaDescription" description = "Automatically generates and inserts KEYWORD and DESCRIPTION meta tags into any theme." version = 1 +author_name = "rWatcher" +author_url = "http://codex.gallery2.org/User:RWatcher" +info_url = "http://codex.gallery2.org/Gallery3:Modules:metadescription" +discuss_url = "http://gallery.menalto.com/node/102477" diff --git a/3.1/modules/minislideshow/controllers/admin_minislideshow.php b/3.1/modules/minislideshow/controllers/admin_minislideshow.php index 0e4cd54f..f66a495a 100644 --- a/3.1/modules/minislideshow/controllers/admin_minislideshow.php +++ b/3.1/modules/minislideshow/controllers/admin_minislideshow.php @@ -1,7 +1,7 @@ "g-mini-slideshow-admin-form")); - // Get location of slideshow files. $group_slideshow_files = $form->group("Minislideshow"); $group_slideshow_files->input("slideshow_url") @@ -124,4 +123,4 @@ class Admin_Minislideshow_Controller extends Admin_Controller { // Return the newly generated form. return $form; } -} \ No newline at end of file +} diff --git a/3.1/modules/minislideshow/controllers/minislideshow.php b/3.1/modules/minislideshow/controllers/minislideshow.php index 1eccdd8f..bd52f67f 100644 --- a/3.1/modules/minislideshow/controllers/minislideshow.php +++ b/3.1/modules/minislideshow/controllers/minislideshow.php @@ -1,7 +1,7 @@ module == "rss") { + $data->messages["warn"][] = t("The MiniSlide Show module requires the RSS module."); + } + } + static function album_menu($menu, $theme) { // Add an option to access the slideshow from the album view. $menu diff --git a/3.1/modules/minislideshow/helpers/minislideshow_installer.php b/3.1/modules/minislideshow/helpers/minislideshow_installer.php index 5c40e83c..3edcf98a 100644 --- a/3.1/modules/minislideshow/helpers/minislideshow_installer.php +++ b/3.1/modules/minislideshow/helpers/minislideshow_installer.php @@ -1,7 +1,7 @@ item()) { - return; - } - - return new View("minislideshow_header_block.html"); + return $theme->css("minislideshow_menu.css"); } } diff --git a/3.1/modules/minislideshow/module.info b/3.1/modules/minislideshow/module.info index a64a54e2..923b02d5 100644 --- a/3.1/modules/minislideshow/module.info +++ b/3.1/modules/minislideshow/module.info @@ -1,3 +1,7 @@ name = "MiniSlide Show" description = "Display MiniSlide Show on your Gallery." version = 1 +author_name = "rWatcher" +author_url = "http://codex.gallery2.org/User:RWatcher" +info_url = "http://codex.gallery2.org/Gallery3:Modules:minislideshow" +discuss_url = "http://gallery.menalto.com/node/90362" diff --git a/3.1/modules/minislideshow/views/minislideshow_dialog.html.php b/3.1/modules/minislideshow/views/minislideshow_dialog.html.php index c9507594..9ae60c0b 100644 --- a/3.1/modules/minislideshow/views/minislideshow_dialog.html.php +++ b/3.1/modules/minislideshow/views/minislideshow_dialog.html.php @@ -15,4 +15,4 @@ flashvars="xmlUrl= Embed: " width="485" height="300" align="middle" pluginspage="http://www.macromedia.com/go/getflashplayer" type="application/x-shockwave-flash" name="minislide" wmode="transparent" allowFullscreen="true" allowScriptAccess="always" quality="high" flashvars="xmlUrl=">" readonly> -
    \ No newline at end of file +
    diff --git a/3.1/modules/minislideshow/views/minislideshow_header_block.html.php b/3.1/modules/minislideshow/views/minislideshow_header_block.html.php deleted file mode 100644 index c52d0117..00000000 --- a/3.1/modules/minislideshow/views/minislideshow_header_block.html.php +++ /dev/null @@ -1,5 +0,0 @@ - - -" /> - - diff --git a/3.1/modules/moduleorder/controllers/admin_moduleorder.php b/3.1/modules/moduleorder/controllers/admin_moduleorder.php index 05b8efa0..3eb7fca1 100644 --- a/3.1/modules/moduleorder/controllers/admin_moduleorder.php +++ b/3.1/modules/moduleorder/controllers/admin_moduleorder.php @@ -1,7 +1,7 @@ script("jquery.jcarousel.min.js"); - $theme->css("skin.css"); $showelements = module::get_var("navcarousel", "showelements", "7"); $childcount = $theme->item->parent()->viewable()->children_count(); $itemoffset = intval(floor($showelements / 2)); @@ -64,7 +62,10 @@ class navcarousel_theme_Core { $onwinload = "});\n $(window).load(function () {\n"; } - Return "\n + return + $theme->script("jquery.jcarousel.min.js") + . $theme->css("skin.css") + . "\n + + + + script("json2-min.js") ?> + script("jquery.js") ?> + script("jquery.form.js") ?> + script("jquery-ui.js") ?> + script("gallery.common.js") ?> + + + script("gallery.ajax.js") ?> + script("gallery.dialog.js") ?> + script("superfish/js/superfish.js") ?> + script("jquery.localscroll.js") ?> + + + page_subtype == "photo"): ?> + script("jquery.scrollTo.js") ?> + script("gallery.show_full_size.js") ?> + page_subtype == "movie"): ?> + script("flowplayer.js") ?> + + + head() ?> + + + script("ui.init.js") ?> + css("yui/reset-fonts-grids.css") ?> + css("superfish/css/superfish.css") ?> + + css("dark/themeroller/ui.base.css") ?> + css("dark/screen_colors.css") ?> + css("dark/screen_candy.css") ?> + + css("clean/themeroller/ui.base.css") ?> + css("clean/screen_colors.css") ?> + css("clean/screen_candy.css") ?> + + css("screen_layout_base.css") ?> + css("screen_fonts.css") ?> + + css("screen_layout_wide.css") ?> + + css("screen_layout_fixed.css") ?> + + + + + get_combined("script") ?> + + + get_combined("css") ?> + + + body_attributes() ?>> + page_top() ?> + +
    + +
    + + site_status() ?> +
    +
    + + + + + + user_menu() ?> + header_top() ?> +
    + + 1 ) { ?> + $display_name) { ?> + + + + installed_locales = array_merge(array("" => t("« none »")), $locales); ?> + selected = (string) locales::cookie_locale(); ?> + + +
    + + + + + header_bottom() ?> +
    + + + +
      + + + > + + url) : ?> + title) ?> + + title) ?> + + + + +
    + + + +
    +
    +
    +
    +
    + messages() ?> + +
    +
    +
    + item() && !empty($parents))): ?> + + +
    + page_subtype != "login"): ?> + + +
    +
    + +
    + page_bottom() ?> + + diff --git a/3.1/modules/tag_albums/-- Theme Files/greydragon/views/calpage.html.php b/3.1/modules/tag_albums/-- Theme Files/greydragon/views/calpage.html.php new file mode 100644 index 00000000..9d3341de --- /dev/null +++ b/3.1/modules/tag_albums/-- Theme Files/greydragon/views/calpage.html.php @@ -0,0 +1,297 @@ + + +load_sessioninfo(); ?> + +html_attributes() ?> xml:lang="en" lang="en" is_rtl)? "dir=rtl" : null; ?> > +item(); + if (($theme->enable_pagecache) and (isset($item))): + // Page will expire in 60 seconds + header('Expires: ' . gmdate('D, d M Y H:i:s', time() + 60).'GMT'); + header("Cache-Control: public"); + header("Cache-Control: post-check=3600, pre-check=43200", false); + header("Content-Type: text/html; charset=UTF-8"); + header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT"); + endif; +?> + + + +start_combining("script,css") ?> + + + +item()): ?> +bb2html($theme->item()->title, 2); ?> +tag()): ?> + $theme->bb2html($theme->tag()->name, 2))) ?> + +bb2html(item::root()->title, 2); ?> + + +<?= $_title ?> +disable_seosupport): ?> + + + + + + +blendpagetrans): ?> + + + + + + " /> + +allow_root_page): ?> +: ; action-uri=url(); ?>?root=yes; icon-uri=favicon.ico" /> +: ; action-uri=url(); ?>?root=no; icon-uri=favicon.ico" /> + +: ; action-uri=url(); ?>; icon-uri=favicon.ico" /> + +admin): ?> + +: ; action-uri=; icon-uri=favicon.ico" /> + + + + +appletouchicon): ?> + + +script("json2-min.js") ?> +script("jquery.js") ?> +script("jquery.form.js") ?> +script("jquery-ui.js") ?> +script("gallery.common.js") ?> + + +script("gallery.ajax.js"); ?> +script("gallery.dialog.js"); ?> + + +page_subtype == "photo"): ?> +script("jquery.scrollTo.js"); ?> +page_subtype == "movie"): ?> +script("flowplayer.js") ?> + + +head() ?> + + +script("animation.js"); ?> +script("ui.support.js"); ?> + +theme_css_inject(); ?> + + +get_combined("css"); ?> + +css_link("colorpacks/" . $theme->colorpack . "/colors.css", FALSE); ?> +css_link("framepacks/" . $theme->framepack . "/frame.css", FALSE); ?> +custom_css_path != ""): ?> +css_link($theme->custom_css_path, TRUE); ?> + + +get_combined("script") ?> + + +thumb_inpage): ?> + + + +item()): ?> +item(); ?> + + + +body_attributes() ?>show_root_page)? ' id="g-rootpage"' : null; ?> is_rtl)? "class=\"rtl\"" : null; ?> > +page_top() ?> +site_status() ?> +guest) or ($theme->show_guest_menu)) and ($theme->mainmenu_position == "bar")): ?> + +
    + site_menu($theme->item() ? "#g-item-id-{$theme->item()->id}" : "") ?> +
    + +
    +header_top() ?> + +bb2html($header_text, 1) ?> + + + + +guest) or ($theme->show_guest_menu)) and ($theme->mainmenu_position != "bar")): ?> +
    + site_menu($theme->item() ? "#g-item-id-{$theme->item()->id}" : "") ?> +
    + + +messages() ?> +header_bottom() ?> + +loginmenu_position == "header"): ?> +user_menu() ?> + + + +breadcrumb_menu($theme, null); ?> + +breadcrumbs_position == "hide"): + else: + $limit_title_length = module::get_var("gallery", "visible_title_length", 999); + + $breadcrumb_content .= ''; + endif; + + print $breadcrumb_content; + + // End Edit. +?> + +custom_header(); ?> +
    +page_subtype != "login") and ($theme->page_subtype != "reauthenticate") and ($theme->sidebarvisible == "top")): ?> +
    + +
    + +
    +
    +show_root_page): ?> + sidebar_menu($item->url()) ?> +
    "> + + album_menu() ?> + + photo_menu() ?> + + movie_menu() ?> + + tag_menu() ?> + +
    + +sidebarvisible): + case "left": + echo '
    '; + $closediv = TRUE; + break; + case "none": + case "top": + case "bottom": + if (($theme->thumb_inpage) and ($page_subtype == "photo")): + echo '
    '; + $closediv = TRUE; + else: + $closediv = FALSE; + endif; + break; + default: + echo '
    '; + $closediv = TRUE; + break; + endswitch; ?> +page_subtype != "login") and ($theme->page_subtype != "reauthenticate")): ?> +sidebarvisible == "none") or ($theme->sidebarvisible == "bottom") or ($theme->sidebarvisible == "top")): ?> +thumb_inpage) and ($page_subtype == "photo")): ?> +

     

    '; ?> +get_block_html("thumbnav"); ?> + + + + + +" : null; ?> + +sidebarvisible): + case "left": + echo '
    '; + break; + case "none": + case "top": + case "bottom": + if (($theme->thumb_inpage) and ($page_subtype == "photo")): + echo '
    '; + else: + echo '
    '; + endif; + break; + default: + echo '
    '; + break; + endswitch; + + if ($theme->show_root_page): + echo new View("rootpage.html"); + else: + echo $content; + endif; ?> +
    +
    +
    +page_subtype != "login") and ($theme->page_subtype != "reauthenticate") and ($theme->sidebarvisible == "bottom")): ?> +
    + +
    + + +page_bottom() ?> + + diff --git a/3.0/themes/greydragon/views/paginator.html.php b/3.1/modules/tag_albums/-- Theme Files/greydragon/views/paginator.html.php similarity index 81% rename from 3.0/themes/greydragon/views/paginator.html.php rename to 3.1/modules/tag_albums/-- Theme Files/greydragon/views/paginator.html.php index 9b5e725e..5918299c 100644 --- a/3.0/themes/greydragon/views/paginator.html.php +++ b/3.1/modules/tag_albums/-- Theme Files/greydragon/views/paginator.html.php @@ -1,23 +1,19 @@ id . "/" . $tag_id . "/" . $album_id); + } elseif ($page_type == "") { + } + endfor; + else: + // End rWatcher Mod. + switch ($page_type) { case "collection": - if ($item): + if (isset($item)): $parent = $item->parent(); endif; $current_page = $page; @@ -61,15 +73,17 @@ endfor; break; case "item": - if ($item): + if (isset($item)): $parent = $item->parent(); endif; $current_page = $position; $total_pages = $total; - $siblings = $item->parent()->children(); - for ($i = 1; $i <= $total; $i++): - $_pagelist[$i] = $siblings[$i-1]->url(); - endfor; + if (isset($parent)): + $siblings = $parent->children(); + for ($i = 1; $i <= $total; $i++): + $_pagelist[$i] = $siblings[$i-1]->url(); + endfor; + endif; break; default: $current_page = 1; @@ -77,6 +91,9 @@ $_pagelist[1] = url::site(); break; } +// rWatcher Mod + endif; +// End rWatcher Mod. if ($total_pages <= 1): $pagination_msg = " "; @@ -167,11 +184,15 @@   - + + + " id="g-navi-parent" href="">  + " id="g-navi-parent" href="url() ?>">    + " class="ui-right" id="g-navi-next" href="">  diff --git a/3.1/modules/tag_albums/-- Theme Files/greydragon/views/photo.html.php b/3.1/modules/tag_albums/-- Theme Files/greydragon/views/photo.html.php new file mode 100644 index 00000000..5d3ede73 --- /dev/null +++ b/3.1/modules/tag_albums/-- Theme Files/greydragon/views/photo.html.php @@ -0,0 +1,122 @@ + +desc_allowbbcode): + $_description = $theme->bb2html($item->description, 1); + else: + $_description = nl2br(html::purify($item->description)); + endif; + + if ($theme->is_photometa_visible): + $_description .= ''; + endif; + + switch ($theme->photo_popupbox): + case "preview": + $include_list = FALSE; + $include_single = TRUE; + break; + case "none": + $include_list = FALSE; + $include_single = FALSE; + break; + default: + $include_list = TRUE; + $include_single = TRUE; + break; + endswitch; +?> + +
    + bb2html(html::purify($item->title), 1); ?> +
    +

    +
    + add_paginator("top"); ?> + photo_top() ?> + photo_descmode == "top") and ($_description)): ?> +
    + +
    + resize_top($item) ?> + resize_width; + +// rWatcher Modification. + $siblings = ""; + if (isset($dynamic_siblings)) { + $siblings = $dynamic_siblings; + } else { + $siblings = $item->parent()->children(); + } +// End rWatcher Modification + ?> + +
    + \n"; + $script .= " if (document.images) {\n"; + for ($i = 0; ($i <= count($siblings) - 1); $i++): + if ($siblings[$i]->rand_key == $item->rand_key): ?> + " title="bb2html(html::purify($item->title), 2) ?>" href="file_url() : $item->resize_url(); ?>"> + resize_img(array("id" => "g-photo-id-{$item->id}", "class" => "g-resize", "alt" => $_title)) ?> + + resize_url() . "\";\n"; + endif; + if ($i > 0): + $script .= " var image_preload_p = new Image();\n image_preload_p.src = \"" . $siblings[$i-1]->resize_url() . "\";\n"; + endif; + else: + if ($include_list): ?> + is_album()): ?> + file_url() : $siblings[$i]->resize_url(); ?>">  + + + + + \n"; ?> + photo_descmode): + case "overlay_top": + $_align = "g-align-top"; + break; + case "overlay_bottom": + $_align = "g-align-bottom"; + break; + default: + break; + endswitch; + endif; ?> + + +
    + + +
    + +
    + resize_bottom($item) ?> +
    + photo_descmode == "bottom") and ($_description)): ?> +
    + + add_paginator("bottom"); ?> + photo_bottom() ?> +
    + \ No newline at end of file diff --git a/3.1/modules/tag_albums/-- Theme Files/greydragon/views/tag_albums_album.html.php b/3.1/modules/tag_albums/-- Theme Files/greydragon/views/tag_albums_album.html.php new file mode 100644 index 00000000..3a348d3b --- /dev/null +++ b/3.1/modules/tag_albums/-- Theme Files/greydragon/views/tag_albums_album.html.php @@ -0,0 +1,135 @@ + +album_top() was changed to $theme->dynamic_top(). + // $item->title and $item->description have been changed to $title and $description. + // + // The g-album-grid block was also taken from album.html.php. The section for uploading new photos to an empty album + // has been removed. Also, $theme->context_menu has been removed as well (it was crashing the page). +?> + +
    + dynamic_top() ?> +

    bb2html(html::purify($title), 1) ?>

    +
    + +add_paginator("top"); ?> + +album_descmode == "top") and ($description)): ?> +
    bb2html(html::purify($description), 1) ?>
    + + + +
    +
    +
    +
    + + +
    +
      + + $child): ?> +thumb_height > $thumb_item->thumb_width); + + $item_class = $child->is_album() ? "g-album" : "g-photo"; + $content = '
    • thumb_top($child); + + if ($theme->thumb_topalign): + $_shift = ""; + else: + if (($theme->crop_factor == 1) and (!$is_portrait)): + $_shift = 'style="margin-top: ' . intval(($theme->_thumb_size_y - $thumb_item->thumb_height) / 2) . 'px;"'; + else: + if (($theme->crop_factor > 0) and ($is_portrait)): + $_shift = 'style="margin-top: -' . intval(($thumb_item->thumb_height - $theme->_thumb_size_y) / 2) . 'px;"'; + else: + $_shift = ""; + endif; + endif; + endif; + + // $ss = 'z-index: 22; opacity: 1; -ms-transform: rotate(' . (-15 + rand(0, 31)) . 'deg);'; style="' . $ss . '" + + $content .= '

      '; + $content .= ''; + if ($thumb_item->has_thumb()): + $content .= $thumb_item->thumb_img(); + else: + $content .= 'No Image'; + endif; + $content .= '

      '; + + if (($theme->thumb_metamode != "hide") and ($_thumb_descmode == "overlay_bottom")): + $_thumb_metamode = "merged"; + else: + $_thumb_metamode = $theme->thumb_metamode; + endif; + + if (($_thumb_descmode == "overlay") or ($_thumb_descmode == "overlay_top") or ($_thumb_descmode == "overlay_bottom")): + $content .= '
        bb2html(html::purify($child->title), 2) . ''; + if ($_thumb_metamode == "merged"): + $content .= $theme->thumb_info($child); + endif; + $content .= '
      '; + endif; + + if (($_thumb_metamode == "default") and ($_thumb_descmode != "overlay_bottom")): + $content .= ''; + endif; + + if ($_thumb_descmode == "bottom"): + $content .= '
        '; + $content .= '
      • ' . $theme->bb2html(html::purify($child->title), 2) . '
      • '; + if ($_thumb_metamode == "merged"): + $content .= $theme->thumb_info($child); + endif; + $content .= '
      '; + endif; + + /* + if ($addcontext): + $_text = $this->context_menu($child, "#g-item-id-{$child->id} .g-thumbnail"); + $content .= (stripos($_text, '
    • '))? $_text : null; + endif; + */ + + $content .= '
    '; + $content .= $theme->thumb_bottom($child); + $content .= ''; + + print $content; + // End rWatcher Edit. +?> + + +
  • + + +
    +dynamic_bottom() ?> + +album_descmode == "bottom") and ($description)): ?> +
    bb2html(html::purify($description), 1) ?>
    + + +add_paginator("bottom"); ?> diff --git a/3.1/modules/tag_albums/controllers/admin_tag_albums.php b/3.1/modules/tag_albums/controllers/admin_tag_albums.php new file mode 100644 index 00000000..6267e33c --- /dev/null +++ b/3.1/modules/tag_albums/controllers/admin_tag_albums.php @@ -0,0 +1,123 @@ +content = new View("admin_tag_albums.html"); + + // Generate a form for the admin Settings. + $view->content->tag_albums_form = $this->_get_admin_form(); + + // Display the page. + print $view; + } + + private function _get_admin_form() { + $form = new Forge("admin/tag_albums/saveprefs", "", "post", + array("id" => "g-tag-albums-admin-form")); + + $tag_albums_tagsort_group = $form->group("Tag_Albums_Tag_Sort")->label(t("\"All Tags\" Album Preferences")); + $tag_albums_tagsort_group->input("tag_page_title") + ->label(t("Page Title")) + ->value(module::get_var("tag_albums", "tag_page_title")); + $tag_albums_tagsort_group->dropdown("tag_index") + ->label(t("Tag album's index should display:")) + ->options( + array("default" => "(default) Individual Tag Albums", + "tagcloudpage" => "Tag Cloud Page Module", + "alltags" => "All Tags Module")) + ->selected(module::get_var("tag_albums", "tag_index")); + + $tag_albums_tagsort_group->dropdown("tag_sort_by") + ->label(t("Sort \"All Tags\" Albums By:")) + ->options( + array("name" => "Name", + "count" => "Count", + "id" => "ID Number")) + ->selected(module::get_var("tag_albums", "tag_sort_by")); + $tag_albums_tagsort_group->dropdown("tag_sort_direction") + ->label(t("Display Albums In:")) + ->options( + array("ASC" => "Ascending Order", + "DESC" => "Descending")) + ->selected(module::get_var("tag_albums", "tag_sort_direction")); + + $tag_index_scope_options["tag_index_scope"] = Array(t("Use tag album index setting for \"*\" albums as well?"), module::get_var("tag_albums", "tag_index_scope")); + $tag_albums_tagsort_group->checklist("tag_index_scope") + ->options($tag_index_scope_options); + + $tag_index_filter_options["tag_index_filter"] = Array(t("Display filter links on \"All Tags\" album pages?"), module::get_var("tag_albums", "tag_index_filter")); + $tag_albums_tagsort_group->checklist("tag_index_filter") + ->options($tag_index_filter_options); + + $tag_albums_tagitemsort_group = $form->group("Tag_Albums_Tag_Item_Sort")->label(t("\"All Tags\" Sub-Album Preferences")); + $tag_albums_tagitemsort_group->dropdown("subalbum_sort_by") + ->label(t("Sort Contents of Sub-Albums By:")) + ->options( + array("title" => "Title", + "name" => "File name", + "captured" => "Date captured", + "created" => "Date uploaded", + "updated" => "Date modified", + "view_count" => "Number of views")) + ->selected(module::get_var("tag_albums", "subalbum_sort_by")); + $tag_albums_tagitemsort_group->dropdown("subalbum_sort_direction") + ->label(t("Display Contents of Sub-Albums In:")) + ->options( + array("ASC" => "Ascending Order", + "DESC" => "Descending")) + ->selected(module::get_var("tag_albums", "subalbum_sort_direction")); + + // Add a save button to the form. + $form->submit("SaveSettings")->value(t("Save")); + + // Return the newly generated form. + return $form; + } + + public function saveprefs() { + // Prevent Cross Site Request Forgery + access::verify_csrf(); + + $form = $this->_get_admin_form(); + if ($form->validate()) { + Kohana_Log::add("error",print_r($form,1)); + module::set_var("tag_albums", "tag_page_title", $form->Tag_Albums_Tag_Sort->tag_page_title->value); + module::set_var("tag_albums", "tag_index", $form->Tag_Albums_Tag_Sort->tag_index->value); + module::set_var("tag_albums", "tag_index_scope", count($form->Tag_Albums_Tag_Sort->tag_index_scope->value)); + module::set_var("tag_albums", "tag_index_filter", count($form->Tag_Albums_Tag_Sort->tag_index_filter->value)); + module::set_var("tag_albums", "tag_sort_by", $form->Tag_Albums_Tag_Sort->tag_sort_by->value); + module::set_var("tag_albums", "tag_sort_direction", $form->Tag_Albums_Tag_Sort->tag_sort_direction->value); + module::set_var("tag_albums", "subalbum_sort_by", $form->Tag_Albums_Tag_Item_Sort->subalbum_sort_by->value); + module::set_var("tag_albums", "subalbum_sort_direction", $form->Tag_Albums_Tag_Item_Sort->subalbum_sort_direction->value); + message::success(t("Your settings have been saved.")); + + url::redirect("admin/tag_albums"); + } + + // Else show the page with errors + $view = new Admin_View("admin.html"); + $view->content = new View("admin_tag_albums.html"); + $view->content->tag_albums_form = $form; + print $view; + } +} diff --git a/3.1/modules/tag_albums/controllers/tag_albums.php b/3.1/modules/tag_albums/controllers/tag_albums.php new file mode 100644 index 00000000..c4b981d7 --- /dev/null +++ b/3.1/modules/tag_albums/controllers/tag_albums.php @@ -0,0 +1,853 @@ +where("id", "=", $id) + ->find_all(); + + // If it doesn't exist, redirect to the modules root page. + if (count($album_tags) == 0) { + url::redirect("tag_albums/"); + } + + // If it does exist, and is set to *, load a list of all tags. + if ($album_tags[0]->tags == "*") { + $this->index($id, ""); + } else { + // Otherwise, populate this page with the specified items. + + // Inherit permissions, title and description from the album that linked to this page. + $album = ORM::factory("item", $album_tags[0]->album_id); + access::required("view", $album); + $page_title = $album->title; + $page_description = $album->description; + + // Determine page sort order. + $sort_page_field = $album->sort_column; + $sort_page_direction = $album->sort_order; + + // Determine search type (AND/OR) and generate an array of the tag ids. + $tag_ids = Array(); + foreach (explode(",", $album_tags[0]->tags) as $tag_name) { + $tag = ORM::factory("tag")->where("name", "=", trim($tag_name))->find(); + if ($tag->loaded()) { + $tag_ids[] = $tag->id; + } + } + $album_tags_search_type = $album_tags[0]->search_type; + + // Figure out how many items to display on each page. + $page_size = module::get_var("gallery", "page_size", 9); + + // If this page was reached from a breadcrumb, figure out what page to load from the show id. + $show = Input::instance()->get("show"); + if ($show) { + $child = ORM::factory("item", $show); + $index = $this->_get_position($child->$sort_page_field, $child->id, $tag_ids, "items." . $sort_page_field, $sort_page_direction, $album_tags_search_type, true); + if ($index) { + $page = ceil($index / $page_size); + url::redirect("tag_albums/album/" . $id . "/" . urlencode($album->name) . "?page=$page"); + } + } + + // Figure out how many items are in this "virtual album" + $count = $this->_count_records($tag_ids, $album_tags_search_type, true); + + // Figure out which page # the visitor is on and + // don't allow the visitor to go below page 1. + $page = Input::instance()->get("page", 1); + if ($page < 1) { + url::redirect("tag_albums/album/" . $id); + } + + // First item to display. + $offset = ($page - 1) * $page_size; + + // Figure out what the highest page number is. + $max_pages = ceil($count / $page_size); + + // Don't let the visitor go past the last page. + if ($max_pages && $page > $max_pages) { + url::redirect("tag_albums/album/{$id}/?page=$max_pages"); + } + + // Figure out which items to display on this page and store their details in $children. + $tag_children = $this->_get_records($tag_ids, $page_size, $offset, "items." . $sort_page_field, $sort_page_direction, $album_tags_search_type, true); + $children = Array(); + foreach ($tag_children as $one_child) { + $child_tag = new Tag_Albums_Item($one_child->title, url::site("tag_albums/show/" . $one_child->id . "/0/" . $id . "/" . urlencode($one_child->name)), $one_child->type); + $child_tag->id = $one_child->id; + $child_tag->view_count = $one_child->view_count; + $child_tag->owner = identity::lookup_user($one_child->owner_id); + if ($one_child->has_thumb()) { + $child_tag->set_thumb($one_child->thumb_url(), $one_child->thumb_width, $one_child->thumb_height); + } + $children[] = $child_tag; + } + + // Set up the previous and next page buttons. + if ($page > 1) { + $previous_page = $page - 1; + $view->previous_page_link = url::site("tag_albums/album/{$id}/?page={$previous_page}"); + } + if ($page < $max_pages) { + $next_page = $page + 1; + $view->next_page_link = url::site("tag_albums/album/{$id}/?page={$next_page}"); + } + + // Set up breadcrumbs. + $tag_album_breadcrumbs = Array(); + $counter = 0; + $tag_album_breadcrumbs[$counter++] = new Tag_Albums_Breadcrumb($album->title, ""); + $parent_item = ORM::factory("item", $album->parent_id); + while ($parent_item->id != 1) { + $tag_album_breadcrumbs[$counter++] = new Tag_Albums_Breadcrumb($parent_item->title, $parent_item->url()); + $parent_item = ORM::factory("item", $parent_item->parent_id); + } + $tag_album_breadcrumbs[$counter++] = new Tag_Albums_Breadcrumb($parent_item->title, $parent_item->url()); + $tag_album_breadcrumbs[1]->url .= "?show=" . $album->id; + $tag_album_breadcrumbs = array_reverse($tag_album_breadcrumbs, true); + + // Set up and display the actual page. + $parent_album = ORM::factory("item", $album->parent_id); + $template = new Theme_View("calpage.html", "other", "Tag Albums"); + $template->page_title = $page_title; + $template->set_global("page", $page); + $template->set_global("page_size", $page_size); + $template->set_global("max_pages", $max_pages); + $template->set_global("children", $children); + $template->set_global("children_count", $count); + $template->set_global("parent_url", $parent_album->url()); // Used by Grey Dragon. + $template->content = new View("tag_albums_album.html"); + $template->content->title = $page_title; + $template->content->description = $page_description; + $template->set_global("breadcrumbs", $tag_album_breadcrumbs); + print $template; + } + } + + public function filter($id, $filter) { + // Display the index page, but only show albums for + // tags whose name begins with $filter. + $this->index($id, $filter); + } + + public function index($id, $filter) { + // Load a page containing sub-albums for each tag in the gallery. + + // Check to see if the user has overridden default behavior, and act accordingly. + if ((module::get_var("tag_albums", "tag_index_scope", "false")) || ($id == "")) { + $tag_album_index_type = module::get_var("tag_albums", "tag_index", "default"); + if (($tag_album_index_type == "tagcloudpage") && (module::is_active("tag_cloud_page"))) { + $redirect_url = "tag_cloud_page/"; + if ($id) { + $redirect_url .= "?album={$id}"; + } + url::redirect($redirect_url); + return; + } elseif (($tag_album_index_type == "alltags") && (module::is_active("all_tags"))) { + $redirect_url = "all_tags/"; + if ($id) { + $redirect_url .= "?album={$id}"; + } + url::redirect($redirect_url); + return; + } + } + + // If an ID was specified, make sure it's valid. + $album_tags = ORM::factory("tags_album_id") + ->where("id", "=", $id) + ->find_all(); + if (count($album_tags) == 0) { + $id = ""; + } + + // Inherit permissions, title and description from the album that linked to this page, + // if available, if not use the root album and some default values. + $album = ""; + $page_title = module::get_var("tag_albums", "tag_page_title", "All Tags"); + $page_description = ""; + if ($id == "") { + $album = ORM::factory("item", 1); + access::required("view", $album); + } else { + $album = ORM::factory("item", $album_tags[0]->album_id); + access::required("view", $album); + $page_title = $album->title; + $page_description = $album->description; + } + + // Figure out sort order from module preferences. + $sort_page_field = module::get_var("tag_albums", "tag_sort_by", "name"); + $sort_page_direction = module::get_var("tag_albums", "tag_sort_direction", "ASC"); + + // Figure out how many items to display on each page. + $page_size = module::get_var("gallery", "page_size", 9); + + // If this page was reached from a breadcrumb, figure out what page to load from the show id. + $show = Input::instance()->get("show"); + if ($show) { + $child = ORM::factory("tag", $show); + $comp = ""; + if (!strcasecmp($sort_page_direction, "DESC")) { + $comp = ">"; + } else { + $comp = "<"; + } + $index = ORM::factory("tag") + ->where($sort_page_field, $comp, $child->$sort_page_field) + ->order_by("tags." . $sort_page_field, $sort_page_direction) + ->count_all(); + $tag_model = ORM::factory("tag") + ->where($sort_page_field, "=", $child->$sort_page_field) + ->order_by("tags." . $sort_page_field, $sort_page_direction) + ->find_all(); + foreach ($tag_model as $one_tag) { + $index++; + if ($one_tag->id == $show) { + break; + } + } + if ($index) { + $page = ceil($index / $page_size); + if ($id == "") { + url::redirect("tag_albums/?page=$page"); + } else { + url::redirect("tag_albums/album/" . $id . "/" . urlencode($album->title) . "?page=$page"); + } + } + } + + // Figure out which page # the visitor is on and + // don't allow the visitor to go below page 1. + $page = Input::instance()->get("page", 1); + if ($page < 1) { + url::redirect("tag_albums/"); + } + + // First item to display. + $offset = ($page - 1) * $page_size; + + // Determine the total number of items, + // for page numbering purposes. + $all_tags_count_model = ORM::factory("tag"); + if ($filter != "") { + if ($filter == "NUM") { + $all_tags_count_model->open(); + $all_tags_count_model->where("tags.name", "LIKE", "0%"); + $counter = 1; + while ($counter < 10) { + $all_tags_count_model->or_where("tags.name", "LIKE", ($counter++) . "%"); + } + $all_tags_count_model->close(); + } else { + $all_tags_count_model->where("tags.name", "LIKE", $filter . "%"); + } + } + $all_tags_count = $all_tags_count_model->count_all(); + + // Figure out what the highest page number is. + $max_pages = ceil($all_tags_count / $page_size); + + // Don't let the visitor go past the last page. + if ($max_pages && $page > $max_pages) { + url::redirect("tag_albums/?page=$max_pages"); + } + + // Figure out which items to display on this page. + $display_tags_model = ORM::factory("tag"); + if ($filter != "") { + if ($filter == "NUM") { + $display_tags_model->open(); + $display_tags_model->where("tags.name", "LIKE", "0%"); + $counter = 1; + while ($counter < 10) { + $display_tags_model->or_where("tags.name", "LIKE", ($counter++) . "%"); + } + $display_tags_model->close(); + } else { + $display_tags_model->where("tags.name", "LIKE", $filter . "%"); + } + } + $display_tags_model->order_by("tags." . $sort_page_field, $sort_page_direction); + $display_tags = $display_tags_model->find_all($page_size, $offset); + + // Set up the previous and next page buttons. + if ($page > 1) { + $previous_page = $page - 1; + $view->previous_page_link = url::site("tag_albums/album/" . $id . "/?page={$previous_page}"); + } + if ($page < $max_pages) { + $next_page = $page + 1; + $view->next_page_link = url::site("tag_albums/album/" . $id . "/?page={$next_page}"); + } + + // Generate an arry of "fake" items, one for each tag on the page. + // Grab thumbnails from the most recently uploaded item for each tag, if available. + $children = Array(); + foreach ($display_tags as $one_tag) { + $tag_item = ORM::factory("item") + ->viewable() + ->join("items_tags", "items.id", "items_tags.item_id") + ->where("items_tags.tag_id", "=", $one_tag->id) + ->order_by("items.id", "DESC") + ->find_all(1, 0); + $child_tag = new Tag_Albums_Item($one_tag->name, url::site("tag_albums/tag/" . $one_tag->id . "/" . $id . "/" . urlencode($one_tag->name)), "album"); + if (count($tag_item) > 0) { + if ($tag_item[0]->has_thumb()) { + $child_tag->set_thumb($tag_item[0]->thumb_url(), $tag_item[0]->thumb_width, $tag_item[0]->thumb_height); + } + } + $children[] = $child_tag; + } + + // Set up breadcrumbs. + $tag_album_breadcrumbs = Array(); + $parent_url = ""; + if ($id != "") { + $counter = 0; + $tag_album_breadcrumbs[$counter++] = new Tag_Albums_Breadcrumb($album->title, ""); + $parent_item = ORM::factory("item", $album->parent_id); + $parent_url = $parent_item->url(); + while ($parent_item->id != 1) { + $tag_album_breadcrumbs[$counter++] = new Tag_Albums_Breadcrumb($parent_item->title, $parent_item->url()); + $parent_item = ORM::factory("item", $parent_item->parent_id); + } + $tag_album_breadcrumbs[$counter++] = new Tag_Albums_Breadcrumb($parent_item->title, $parent_item->url()); + $tag_album_breadcrumbs[1]->url .= "?show=" . $album->id; + $tag_album_breadcrumbs = array_reverse($tag_album_breadcrumbs, true); + } else { + $parent_url = item::root()->url(); + $tag_album_breadcrumbs[0] = new Tag_Albums_Breadcrumb(item::root()->title, item::root()->url()); + $tag_album_breadcrumbs[1] = new Tag_Albums_Breadcrumb($page_title, ""); + } + + // Set up and display the actual page. + $template = new Theme_View("calpage.html", "other", "Tag Albums"); + $template->page_title = $page_title; + $template->set_global("page", $page); + $template->set_global("page_size", $page_size); + $template->set_global("max_pages", $max_pages); + $template->set_global("children", $children); + $template->set_global("children_count", $all_tags_count); + $template->set_global("parent_url", $parent_url); // Used by Grey Dragon. + $template->content = new View("tag_albums_album.html"); + $template->content->title = $page_title; + $template->content->description = $page_description; + $template->content->filter_text = $this->_get_filter_html($id, $filter); + $template->set_global("breadcrumbs", $tag_album_breadcrumbs); + print $template; + } + + public function tag($id, $album_id) { + // Display a dynamic album containing everything tagged with a specific tag where, + // TAG is $id. + // Optionally, set the breadcrumbs to make this page look like an album where the + // album is $album_id. + + // Make sure $album_id is valid, clear it out if it isn't. + $album_tags = ORM::factory("tags_album_id") + ->where("id", "=", $album_id) + ->find_all(); + if (count($album_tags) == 0) { + $album_id = ""; + } + + // Figure out sort order from module preferences. + $sort_page_field = module::get_var("tag_albums", "subalbum_sort_by", "title"); + $sort_page_direction = module::get_var("tag_albums", "subalbum_sort_direction", "ASC"); + + // Figure out how many items to display on each page. + $page_size = module::get_var("gallery", "page_size", 9); + + // If this page was reached from a breadcrumb, figure out what page to load from the show id. + $show = Input::instance()->get("show"); + if ($show) { + $child = ORM::factory("item", $show); + $index = $this->_get_position($child->$sort_page_field, $child->id, Array($id), "items." . $sort_page_field, $sort_page_direction, "OR", true); + if ($index) { + $page = ceil($index / $page_size); + url::redirect("tag_albums/tag/" . $id . "/" . $album_id . "?page=$page"); + } + } + + // Figure out which page # the visitor is on and + // don't allow the visitor to go below page 1. + $page = Input::instance()->get("page", 1); + if ($page < 1) { + url::redirect("tag_albums/tag/" . $id . "/" . $album_id); + } + + // First item to display. + $offset = ($page - 1) * $page_size; + + // Determine the total number of items, + // for page numbering purposes. + $count = $this->_count_records(Array($id), "OR", true); + + // Figure out what the highest page number is. + $max_pages = ceil($count / $page_size); + + // Don't let the visitor go past the last page. + if ($max_pages && $page > $max_pages) { + url::redirect("tag_albums/tag/{$id}/" . $album_id . "/?page=$max_pages"); + } + + // Figure out which items to display on this page. + $tag_children = $this->_get_records(Array($id), $page_size, $offset, "items." . $sort_page_field, $sort_page_direction, "OR", true); + + // Create an array of "fake" items to display on the page. + $children = Array(); + foreach ($tag_children as $one_child) { + $child_tag = new Tag_Albums_Item($one_child->title, url::site("tag_albums/show/" . $one_child->id . "/" . $id . "/" . $album_id . "/" . urlencode($one_child->name)), $one_child->type); + $child_tag->id = $one_child->id; + $child_tag->view_count = $one_child->view_count; + $child_tag->owner = identity::lookup_user($one_child->owner_id); + if ($one_child->has_thumb()) { + $child_tag->set_thumb($one_child->thumb_url(), $one_child->thumb_width, $one_child->thumb_height); + } + $children[] = $child_tag; + } + + // Set up the previous and next page buttons. + if ($page > 1) { + $previous_page = $page - 1; + $view->previous_page_link = url::site("tag_albums/tag/{$id}/" . $album_id . "/?page={$previous_page}"); + } + if ($page < $max_pages) { + $next_page = $page + 1; + $view->next_page_link = url::site("tag_albums/tag/{$id}/" . $album_id . "/?page={$next_page}"); + } + + // Load the current tag. + $display_tag = ORM::factory("tag", $id); + + // Set up breadcrumbs for the page. + $tag_album_breadcrumbs = Array(); + $parent_url = ""; + if ($album_id != "") { + $counter = 0; + $tag_album_breadcrumbs[$counter++] = new Tag_Albums_Breadcrumb($display_tag->name, ""); + $parent_item = ORM::factory("item", $album_tags[0]->album_id); + if ($album_tags[0]->tags != "*") { + $parent_item = ORM::factory("item", $parent_item->parent_id); + } + $parent_url = $parent_item->url(); // Used by Grey Dragon. + while ($parent_item->id != 1) { + $tag_album_breadcrumbs[$counter++] = new Tag_Albums_Breadcrumb($parent_item->title, $parent_item->url()); + $parent_item = ORM::factory("item", $parent_item->parent_id); + } + $tag_album_breadcrumbs[$counter++] = new Tag_Albums_Breadcrumb($parent_item->title, $parent_item->url()); + $parent_item = ORM::factory("item", $album_tags[0]->album_id); + if ((module::get_var("tag_albums", "tag_index_scope", "false")) && (module::get_var("tag_albums", "tag_index", "default") != "default")) { + $tag_album_breadcrumbs[1]->url = url::site("tag_albums/album/" . $album_id . "/" . urlencode($parent_item->name)); + } else { + $tag_album_breadcrumbs[1]->url = url::site("tag_albums/album/" . $album_id . "/" . urlencode($parent_item->name)) . "?show=" . $id; + } + $tag_album_breadcrumbs = array_reverse($tag_album_breadcrumbs, true); + } else { + $parent_url = url::site("tag_albums/"); + $tag_album_breadcrumbs[0] = new Tag_Albums_Breadcrumb(item::root()->title, item::root()->url()); + if (module::get_var("tag_albums", "tag_index", "default") == "default") { + $tag_album_breadcrumbs[1] = new Tag_Albums_Breadcrumb(module::get_var("tag_albums", "tag_page_title", "All Tags"), url::site("tag_albums/") . "?show=" . $id); + } else { + $tag_album_breadcrumbs[1] = new Tag_Albums_Breadcrumb(module::get_var("tag_albums", "tag_page_title", "All Tags"), url::site("tag_albums/")); + } + $tag_album_breadcrumbs[2] = new Tag_Albums_Breadcrumb($display_tag->name, ""); + } + + // Set up and display the actual page. + $template = new Theme_View("calpage.html", "other", "Tag Albums"); + $template->page_title = $display_tag->name; + $template->set_global("page", $page); + $template->set_global("page_size", $page_size); + $template->set_global("max_pages", $max_pages); + $template->set_global("children", $children); + $template->set_global("children_count", $count); + $template->set_global("parent_url", $parent_url); // Used by Grey Dragon. + $template->content = new View("tag_albums_album.html"); + $template->content->title = $display_tag->name; + $template->set_global("breadcrumbs", $tag_album_breadcrumbs); + print $template; + } + + public function show($item_id, $tag_id, $album_id) { + // Display the specified photo or video ($item_id) with breadcrumbs + // that point back to a virtual album ($tag_id / $album_id). + + // Make sure #album_id is valid, clear it out if it isn't. + $album_tags = ORM::factory("tags_album_id") + ->where("id", "=", $album_id) + ->find_all(); + if (count($album_tags) == 0) { + $album_id = ""; + } + + // Load the tag and item, make sure the user has access to the item. + $display_tag = ORM::factory("tag", $tag_id); + $item = ORM::factory("item", $item_id); + access::required("view", $item); + $parent_url = ""; + + // Figure out sort order from module preferences. + $sort_page_field = ""; + $sort_page_direction = ""; + if (($tag_id > 0) || (count($album_tags) == 0)) { + $sort_page_field = module::get_var("tag_albums", "subalbum_sort_by", "title"); + $sort_page_direction = module::get_var("tag_albums", "subalbum_sort_direction", "ASC"); + } else { + $parent_album = ORM::factory("item", $album_tags[0]->album_id); + $sort_page_field = $parent_album->sort_column; + $sort_page_direction = $parent_album->sort_order; + } + + // Load the number of items in the parent album, and determine previous and next items. + $sibling_count = ""; + $tag_children = ""; + $previous_item = ""; + $next_item = ""; + $position = 0; + $dynamic_siblings = ""; + if ($tag_id > 0) { + $sibling_count = $this->_count_records(Array($tag_id), "OR", false); + $position = $this->_get_position($item->$sort_page_field, $item->id, Array($tag_id), "items." . $sort_page_field, $sort_page_direction, $album_tags_search_type, false); + if ($position > 1) { + $previous_item_object = $this->_get_records(Array($tag_id), 1, $position-2, "items." . $sort_page_field, $sort_page_direction, $album_tags_search_type, false); + if (count($previous_item_object) > 0) { + $previous_item = new Tag_Albums_Item($previous_item_object[0]->title, url::site("tag_albums/show/" . $previous_item_object[0]->id . "/" . $tag_id . "/" . $album_id), $previous_item_object[0]->type); + } + } + $next_item_object = $this->_get_records(Array($tag_id), 1, $position, "items." . $sort_page_field, $sort_page_direction, $album_tags_search_type, false); + if (count($next_item_object) > 0) { + $next_item = new Tag_Albums_Item($next_item_object[0]->title, url::site("tag_albums/show/" . $next_item_object[0]->id . "/" . $tag_id . "/" . $album_id), $next_item_object[0]->type); + } + $dynamic_siblings = $this->_get_records(Array($tag_id), null, null, "items." . $sort_page_field, $sort_page_direction, $album_tags_search_type, false); + } else { + $tag_ids = Array(); + foreach (explode(",", $album_tags[0]->tags) as $tag_name) { + $tag = ORM::factory("tag")->where("name", "=", trim($tag_name))->find(); + if ($tag->loaded()) { + $tag_ids[] = $tag->id; + } + } + $album_tags_search_type = $album_tags[0]->search_type; + $sibling_count = $this->_count_records($tag_ids, $album_tags_search_type, false); + $position = $this->_get_position($item->$sort_page_field, $item->id, $tag_ids, "items." . $sort_page_field, $sort_page_direction, $album_tags_search_type, false); + if ($position > 1) { + $previous_item_object = $this->_get_records($tag_ids, 1, $position-2, "items." . $sort_page_field, $sort_page_direction, $album_tags_search_type, false); + if (count($previous_item_object) > 0) { + $previous_item = new Tag_Albums_Item($previous_item_object[0]->title, url::site("tag_albums/show/" . $previous_item_object[0]->id . "/" . $tag_id . "/" . $album_id), $previous_item_object[0]->type); + } + } + $next_item_object = $this->_get_records($tag_ids, 1, $position, "items." . $sort_page_field, $sort_page_direction, $album_tags_search_type, false); + if (count($next_item_object) > 0) { + $next_item = new Tag_Albums_Item($next_item_object[0]->title, url::site("tag_albums/show/" . $next_item_object[0]->id . "/" . $tag_id . "/" . $album_id), $next_item_object[0]->type); + } + $dynamic_siblings = $this->_get_records($tag_ids, null, null, "items." . $sort_page_field, $sort_page_direction, $album_tags_search_type, false); + } + + // Set up breadcrumbs + $tag_album_breadcrumbs = Array(); + if ($album_id != "") { + $counter = 0; + $tag_album_breadcrumbs[$counter++] = new Tag_Albums_Breadcrumb($item->title, ""); + if ($album_tags[0]->tags == "*") { + $tag_album_breadcrumbs[$counter++] = new Tag_Albums_Breadcrumb($display_tag->name, url::site("tag_albums/tag/" . $display_tag->id . "/" . $album_id)); + } + $parent_item = ORM::factory("item", $album_tags[0]->album_id); + if ($album_tags[0]->tags == "*") { + $parent_url = url::site("tag_albums/tag/" . $display_tag->id . "/" . $album_id); + } else { + $parent_url = $parent_item->url(); + } + $tag_album_breadcrumbs[$counter++] = new Tag_Albums_Breadcrumb($parent_item->title, url::site("tag_albums/album/" . $album_id)); + $parent_item = ORM::factory("item", $parent_item->parent_id); + while ($parent_item->id != 1) { + $tag_album_breadcrumbs[$counter++] = new Tag_Albums_Breadcrumb($parent_item->title, $parent_item->url()); + $parent_item = ORM::factory("item", $parent_item->parent_id); + } + $tag_album_breadcrumbs[$counter++] = new Tag_Albums_Breadcrumb($parent_item->title, $parent_item->url()); + $tag_album_breadcrumbs[1]->url .= "?show=" . $item->id; + $tag_album_breadcrumbs = array_reverse($tag_album_breadcrumbs, true); + } else { + $tag_album_breadcrumbs[0] = new Tag_Albums_Breadcrumb(item::root()->title, item::root()->url()); + $tag_album_breadcrumbs[1] = new Tag_Albums_Breadcrumb(module::get_var("tag_albums", "tag_page_title", "All Tags"), url::site("tag_albums/")); + $tag_album_breadcrumbs[2] = new Tag_Albums_Breadcrumb($display_tag->name, url::site("tag_albums/tag/" . $display_tag->id) . "?show=" . $item->id); + $tag_album_breadcrumbs[3] = new Tag_Albums_Breadcrumb($item->title, ""); + $parent_url = url::site("tag_albums/tag/" . $display_tag->id); + } + + // Increase the items view count. + $item->increment_view_count(); + + // Load the page. + if ($item->is_photo()) { + $template = new Theme_View("calpage.html", "item", "photo"); + $template->page_title = $item->title; + $template->set_global("children", Array()); + $template->set_global("item", $item); + $template->set_global("previous_item", $previous_item); + $template->set_global("next_item", $next_item); + $template->set_global("is_tagalbum_page", true); // used for grey dragon + $template->set_global("tag_id", $tag_id); // used for grey dragon + $template->set_global("album_id", $album_id); // used for grey dragon + $template->set_global("parent_url", $parent_url); // Used by Grey Dragon. + $template->set_global("dynamic_siblings", $dynamic_siblings); // Used by Grey Dragon. + $template->set_global("children_count", 0); + $template->set_global("position", $position); + $template->set_global("sibling_count", $sibling_count); + $template->content = new View("photo.html"); + $template->content->title = $item->title; + $template->set_global("breadcrumbs", $tag_album_breadcrumbs); + print $template; + } elseif ($item->is_movie()) { + $template = new Theme_View("calpage.html", "item", "movie"); + $template->page_title = $item->title; + $template->set_global("children", Array()); + $template->set_global("item", $item); + $template->set_global("previous_item", $previous_item); + $template->set_global("next_item", $next_item); + $template->set_global("is_tagalbum_page", true); // used for grey dragon + $template->set_global("tag_id", $tag_id); // used for grey dragon + $template->set_global("album_id", $album_id); // used for grey dragon + $template->set_global("parent_url", $parent_url); // Used by Grey Dragon. + $template->set_global("dynamic_siblings", $dynamic_siblings); // Used by Grey Dragon. + $template->set_global("children_count", 0); + $template->set_global("position", $position); + $template->set_global("sibling_count", $sibling_count); + $template->content = new View("movie.html"); + $template->content->title = $item->title; + $template->set_global("breadcrumbs", $tag_album_breadcrumbs); + print $template; + } else { + // If it's something we don't know how to deal with, just redirect to its real page. + url::redirect(url::abs_site("{$item->type}s/{$item->id}")); + } + } + + private function _get_position($item_title, $item_id, $tag_ids, $sort_field, $sort_direction, $search_type, $include_albums) { + // Determine an item's position within a virtual album. + + // Convert ASC/DESC to < or > characters. + if (!strcasecmp($sort_direction, "DESC")) { + $comp = ">"; + } else { + $comp = "<"; + } + + // Figure out how many items are _before the current item. + $items_model = ORM::factory("item"); + if ($search_type == "AND") { + $items_model->select('COUNT("*") AS result_count'); + } else { + $items_model->select("items.id"); + } + $items_model->viewable(); + $items_model->join("items_tags", "items.id", "items_tags.item_id"); + $items_model->open(); + $items_model->where("items_tags.tag_id", "=", $tag_ids[0]); + $counter = 1; + while ($counter < count($tag_ids)) { + $items_model->or_where("items_tags.tag_id", "=", $tag_ids[$counter]); + $counter++; + } + $items_model->close(); + if ($include_albums == false) { + $items_model->and_where("items.type", "!=", "album"); + } + $items_model->and_where($sort_field, $comp, $item_title); + $items_model->order_by($sort_field, $sort_direction); + $items_model->group_by("items.id"); + if ($search_type == "AND") { + $items_model->having("result_count", "=", count($tag_ids)); + } + $position = count($items_model->find_all()); + + // In case multiple items have identical sort criteria, query for + // everything with the same criteria, and increment the position + // one at a time until we find the right item. + $items_model = ORM::factory("item"); + if ($search_type == "AND") { + $items_model->select("items.id"); + $items_model->select('COUNT("*") AS result_count'); + } else { + $items_model->select("items.id"); + } + $items_model->viewable(); + $items_model->join("items_tags", "items.id", "items_tags.item_id"); + $items_model->open(); + $items_model->where("items_tags.tag_id", "=", $tag_ids[0]); + $counter = 1; + while ($counter < count($tag_ids)) { + $items_model->or_where("items_tags.tag_id", "=", $tag_ids[$counter]); + $counter++; + } + $items_model->close(); + if ($include_albums == false) { + $items_model->and_where("items.type", "!=", "album"); + } + $items_model->and_where($sort_field, "=", $item_title); + $items_model->order_by($sort_field, $sort_direction); + $items_model->group_by("items.id"); + if ($search_type == "AND") { + $items_model->having("result_count", "=", count($tag_ids)); + } + $match_items = $items_model->find_all(); + foreach ($match_items as $one_item) { + $position++; + if ($one_item->id == $item_id) { + break; + } + } + + return ($position); + } + + private function _get_records($tag_ids, $page_size, $offset, $sort_field, $sort_direction, $search_type, $include_albums) { + // Returns an array of items to be displayed on the current page. + + $items_model = ORM::factory("item"); + if ($search_type == "AND") { + // For some reason, if I do 'select("*")' the item ids all have values that are 1000+ + // higher then they should be. So instead, I'm manually selecting each column that I need. + $items_model->select("items.id"); + $items_model->select("items.name"); + $items_model->select("items.title"); + $items_model->select("items.view_count"); + $items_model->select("items.owner_id"); + $items_model->select("items.rand_key"); + $items_model->select("items.type"); + $items_model->select("items.thumb_width"); + $items_model->select("items.thumb_height"); + $items_model->select("items.left_ptr"); + $items_model->select("items.right_ptr"); + $items_model->select("items.relative_path_cache"); + $items_model->select('COUNT("*") AS result_count'); + } + $items_model->viewable(); + $items_model->join("items_tags", "items.id", "items_tags.item_id"); + $items_model->open(); + $items_model->where("items_tags.tag_id", "=", $tag_ids[0]); + $counter = 1; + while ($counter < count($tag_ids)) { + $items_model->or_where("items_tags.tag_id", "=", $tag_ids[$counter]); + $counter++; + } + $items_model->close(); + if ($include_albums == false) { + $items_model->and_where("items.type", "!=", "album"); + } + $items_model->order_by($sort_field, $sort_direction); + $items_model->group_by("items.id"); + if ($search_type == "AND") { + $items_model->having("result_count", "=", count($tag_ids)); + } + return $items_model->find_all($page_size, $offset); + } + + private function _get_filter_html($album_id, $str_filter) { + // Generate HTML to display filter links on the index page. + + // Make sure $album_id is set. + if ($album_id == "") { + $album_id = 0; + } + + // Generate the links. + $str_html = "Filter: "; + if ($str_filter != "") { + if ($album_id > 0) { + $str_html .= "(All) "; + } else { + $str_html .= "(All) "; + } + } + if ($str_filter == "NUM") { + $str_html .= "# "; + } else { + $str_html .= "# "; + } + foreach(range('A','Z') as $letter) { + if ($letter == $str_filter) { + $str_html .= $letter . " "; + } else { + $str_html .= ""; + $str_html .= $letter . " "; + } + } + + // Return the HTML. + return $str_html; + } + + private function _count_records($tag_ids, $search_type, $include_albums) { + // Count the number of viewable items for the designated tag(s) + // and return that number. + + if (count($tag_ids) == 0) { + // If no tags were specified, return 0. + return 0; + + } elseif (count($tag_ids) == 1) { + // if one tag was specified, we can use count_all to get the number. + $count = ORM::factory("item") + ->viewable() + ->join("items_tags", "items.id", "items_tags.item_id") + ->where("items_tags.tag_id", "=", $tag_ids[0]); + if ($include_albums == false) { + $count->and_where("items.type", "!=", "album"); + } + return $count->count_all(); + + } else { + // If multiple tags were specified, count_all won't work, + // so we'll have to do count(find_all) instead. + $items_model = ORM::factory("item"); + if ($search_type == "AND") { + $items_model->select('COUNT("*") AS result_count'); + } else { + $items_model->select('items.id'); + } + $items_model->viewable(); + $items_model->join("items_tags", "items.id", "items_tags.item_id"); + $items_model->where("items_tags.tag_id", "=", $tag_ids[0]); + $counter = 1; + while ($counter < count($tag_ids)) { + $items_model->or_where("items_tags.tag_id", "=", $tag_ids[$counter]); + $counter++; + } + if ($include_albums == false) { + $items_model->and_where("items.type", "!=", "album"); + } + $items_model->group_by("items.id"); + if ($search_type == "AND") { + $items_model->having("result_count", "=", count($tag_ids)); + } + + return count($items_model->find_all()); + } + } +} diff --git a/3.1/modules/tag_albums/helpers/tag_albums_block.php b/3.1/modules/tag_albums/helpers/tag_albums_block.php new file mode 100644 index 00000000..7243722c --- /dev/null +++ b/3.1/modules/tag_albums/helpers/tag_albums_block.php @@ -0,0 +1,40 @@ + t("Tag Albums")); + } + + static function get($block_id, $theme) { + $block = ""; + + switch ($block_id) { + case "tag_albums": + // Make a new sidebar block. + $block = new Block(); + $block->css_id = "g-tag-albums"; + $block->title = t("Tag Albums"); + $block->content = new View("tag_albums_block.html"); + + break; + } + return $block; + } +} diff --git a/3.1/modules/tag_albums/helpers/tag_albums_event.php b/3.1/modules/tag_albums/helpers/tag_albums_event.php new file mode 100644 index 00000000..033293f1 --- /dev/null +++ b/3.1/modules/tag_albums/helpers/tag_albums_event.php @@ -0,0 +1,110 @@ +module == "tag") { + $data->messages["warn"][] = t("The Tag Albums module requires the Tags module."); + } + } + + static function module_change($changes) { + // See if the Tags module is installed, + // tell the user to install it if it isn't. + if (!module::is_active("tag") || in_array("tag", $changes->deactivate)) { + site_status::warning( + t("The Tag Albums module requires the Tags module. " . + "Activate the Tags module now", + array("url" => url::site("admin/modules"))), + "tag_albums_needs_tag"); + } else { + site_status::clear("tag_albums_needs_tag"); + } + } + + static function admin_menu($menu, $theme) { + // Add a link to the admin page to the Content menu. + $menu->get("settings_menu") + ->append(Menu::factory("link") + ->id("tag_albums") + ->label(t("Tag Albums Settings")) + ->url(url::site("admin/tag_albums"))); + } + + static function item_edit_form($item, $form) { + // Create fields on the album edit screen to allow the user to link + // the album to a tag_albums page. + if (!($item->is_album())) { + return; + } + + $url = url::site("tags/autocomplete"); + $form->script("") + ->text("$('form input[name=tag_albums]').ready(function() { + $('form input[name=tag_albums]').autocomplete( + '$url', {max: 30, multiple: true, multipleSeparator: ',', cacheLength: 1}); + });"); + + $album_tags = ORM::factory("tags_album_id") + ->where("album_id", "=", $item->id) + ->find_all(); + + $tag_names = ""; + $tag_album_type = "OR"; + if (count($album_tags) > 0) { + $tag_names = $album_tags[0]->tags; + $tag_album_type = $album_tags[0]->search_type; + } + + $tags_album_group = $form->edit_item->group("tags_album_group"); + $tags_album_group->dropdown("tags_album_type") + ->options( + array("OR" => t("Display items that contain ANY of the following tags:"), + "AND" => t("Display items that contain ALL of the following tags:"))) + ->selected($tag_album_type); + $tags_album_group->input("tag_albums") + ->value($tag_names); + } + + static function item_deleted($item) { + // Whenever an item is deleted, delete any corresponding data. + db::build()->delete("tags_album_ids")->where("album_id", "=", $item->id)->execute(); + } + + static function item_edit_form_completed($item, $form) { + // Update the database with any changes to the tag_albums field. + if (!($item->is_album())) { + return; + } + + $record = ORM::factory("tags_album_id")->where("album_id", "=", $item->id)->find(); + + if ($form->edit_item->tags_album_group->tag_albums->value != "") { + if (!$record->loaded()) { + $record->album_id = $item->id; + } + $record->tags = $form->edit_item->tags_album_group->tag_albums->value; + $record->search_type = $form->edit_item->tags_album_group->tags_album_type->value; + $record->save(); + } else { + db::build()->delete("tags_album_ids")->where("album_id", "=", $item->id)->execute(); + } + } +} diff --git a/3.1/modules/tag_albums/helpers/tag_albums_installer.php b/3.1/modules/tag_albums/helpers/tag_albums_installer.php new file mode 100644 index 00000000..ee3df5e2 --- /dev/null +++ b/3.1/modules/tag_albums/helpers/tag_albums_installer.php @@ -0,0 +1,69 @@ +query("CREATE TABLE IF NOT EXISTS {tags_album_ids} ( + `id` int(9) NOT NULL auto_increment, + `album_id` int(9) NOT NULL, + `tags` varchar(2048) default NULL, + `search_type` varchar(128) NOT NULL, + PRIMARY KEY (`id`), + KEY(`album_id`, `id`)) + DEFAULT CHARSET=utf8;"); + + // Set up some default values. + module::set_var("tag_albums", "tag_sort_by", "name"); + module::set_var("tag_albums", "tag_sort_direction", "ASC"); + module::set_var("tag_albums", "subalbum_sort_by", "title"); + module::set_var("tag_albums", "subalbum_sort_direction", "ASC"); + module::set_var("tag_albums", "tag_index", "default"); + module::set_var("tag_albums", "tag_index_scope", "0"); + module::set_var("tag_albums", "tag_index_filter", "0"); + + // Set the module's version number. + module::set_version("tag_albums", 2); + } + + static function upgrade($version) { + if ($version == 1) { + module::set_var("tag_albums", "tag_index", "default"); + module::set_var("tag_albums", "tag_index_scope", "0"); + module::set_var("tag_albums", "tag_index_filter", "0"); + module::set_version("tag_albums", 2); + } + } + + static function deactivate() { + site_status::clear("tag_albums_needs_tag"); + } + + static function can_activate() { + $messages = array(); + if (!module::is_active("tag")) { + $messages["warn"][] = t("The Tag Albums module requires the Tags module."); + } + return $messages; + } + + static function uninstall() { + module::delete("tag_albums"); + } +} diff --git a/3.1/modules/tag_albums/helpers/tag_albums_theme.php b/3.1/modules/tag_albums/helpers/tag_albums_theme.php new file mode 100644 index 00000000..84f9a633 --- /dev/null +++ b/3.1/modules/tag_albums/helpers/tag_albums_theme.php @@ -0,0 +1,34 @@ +item()) { + $album_tags = ORM::factory("tags_album_id") + ->where("album_id", "=", $theme->item->id) + ->find_all(); + if (count($album_tags) > 0) { + url::redirect(url::abs_site("tag_albums/album/" . $album_tags[0]->id . "/" . urlencode($theme->item->name))); + } + } + return; + } +} diff --git a/3.1/modules/tag_albums/libraries/Tag_Albums_Breadcrumb.php b/3.1/modules/tag_albums/libraries/Tag_Albums_Breadcrumb.php new file mode 100644 index 00000000..ba576e49 --- /dev/null +++ b/3.1/modules/tag_albums/libraries/Tag_Albums_Breadcrumb.php @@ -0,0 +1,31 @@ +title = $new_title; + $this->url = $new_url; + } +} diff --git a/3.1/modules/tag_albums/libraries/Tag_Albums_Item.php b/3.1/modules/tag_albums/libraries/Tag_Albums_Item.php new file mode 100644 index 00000000..a90c5239 --- /dev/null +++ b/3.1/modules/tag_albums/libraries/Tag_Albums_Item.php @@ -0,0 +1,114 @@ +item_type == "album") { + return true; + } else { + return false; + } + } + + public function has_thumb() { + if ($this->thumb_url != "") { + return true; + } else { + return false; + } + } + + public function thumb_img($extra_attrs=array(), $max=null, $center_vertically=false) { + list ($height, $width) = $this->scale_dimensions($max); + if ($center_vertically && $max) { + // The constant is divide by 2 to calculate the file and 10 to convert to em + $margin_top = (int)(($max - $height) / 20); + $extra_attrs["style"] = "margin-top: {$margin_top}em"; + $extra_attrs["title"] = $this->title; + } + $attrs = array_merge($extra_attrs, + array( + "src" => $this->thumb_url(), + "alt" => $this->title, + "width" => $width, + "height" => $height) + ); + // html::image forces an absolute url which we don't want + return ""; + } + + public function scale_dimensions($max) { + $width = $this->thumb_width; + $height = $this->thumb_height; + + if ($width <= $max && $height <= $max) { + return array($height, $width); + } + + if ($height) { + if (isset($max)) { + if ($width > $height) { + $height = (int)($max * $height / $width); + $width = $max; + } else { + $width = (int)($max * $width / $height); + $height = $max; + } + } + } else { + // Missing thumbnail, can happen on albums with no photos yet. + // @todo we should enforce a placeholder for those albums. + $width = 0; + $height = 0; + } + return array($height, $width); + } + + public function thumb_url() { + return $this->thumb_url; + } + + public function url() { + return $this->url; + } + + public function set_thumb($new_url, $new_width, $new_height) { + $this->thumb_url = $new_url; + $this->thumb_width = $new_width; + $this->thumb_height = $new_height; + } + + public function __construct($new_title, $new_url, $new_type) { + $this->title = $new_title; + $this->url = $new_url; + $this->item_type = $new_type; + $this->type = $new_type; + } +} diff --git a/3.1/modules/tag_albums/models/tag.php b/3.1/modules/tag_albums/models/tag.php new file mode 100644 index 00000000..0cc47030 --- /dev/null +++ b/3.1/modules/tag_albums/models/tag.php @@ -0,0 +1,145 @@ +loaded()) { + // Set reasonable defaults + $this->count = 0; + } + } + + /** + * Return all viewable items associated with this tag. + * @param integer $limit number of rows to limit result to + * @param integer $offset offset in result to start returning rows from + * @param string $type the type of item (album, photo) + * @return ORM_Iterator + */ + public function items($limit=null, $offset=null, $type=null) { + $model = ORM::factory("item") + ->viewable() + ->join("items_tags", "items.id", "items_tags.item_id") + ->where("items_tags.tag_id", "=", $this->id); + if ($type) { + $model->where("items.type", "=", $type); + } + return $model->find_all($limit, $offset); + } + + /** + * Return the count of all viewable items associated with this tag. + * @param string $type the type of item (album, photo) + * @return integer + */ + public function items_count($type=null) { + $model = ORM::factory("item") + ->viewable() + ->join("items_tags", "items.id", "items_tags.item_id") + ->where("items_tags.tag_id", "=", $this->id); + + if ($type) { + $model->where("items.type", "=", $type); + } + return $model->count_all(); + } + + /** + * Overload ORM::save() to trigger an item_related_update event for all items that are related + * to this tag. + */ + public function save() { + $related_item_ids = array(); + foreach (db::build() + ->select("item_id") + ->from("items_tags") + ->where("tag_id", "=", $this->id) + ->execute() as $row) { + $related_item_ids[$row->item_id] = 1; + } + + if (isset($this->object_relations["items"])) { + $added = array_diff($this->changed_relations["items"], $this->object_relations["items"]); + $removed = array_diff($this->object_relations["items"], $this->changed_relations["items"]); + if (isset($this->changed_relations["items"])) { + $changed = array_merge($added, $removed); + } + $this->count = count($this->object_relations["items"]) + count($added) - count($removed); + } + + $result = parent::save(); + + if (!empty($changed)) { + foreach (ORM::factory("item")->where("id", "IN", $changed)->find_all() as $item) { + module::event("item_related_update", $item); + } + } + + return $result; + } + + /** + * Overload ORM::delete() to trigger an item_related_update event for all items that are + * related to this tag, and delete all items_tags relationships. + */ + public function delete($ignored_id=null) { + $related_item_ids = array(); + foreach (db::build() + ->select("item_id") + ->from("items_tags") + ->where("tag_id", "=", $this->id) + ->execute() as $row) { + $related_item_ids[$row->item_id] = 1; + } + + db::build()->delete("items_tags")->where("tag_id", "=", $this->id)->execute(); + $result = parent::delete(); + + if ($related_item_ids) { + foreach (ORM::factory("item") + ->where("id", "IN", array_keys($related_item_ids)) + ->find_all() as $item) { + module::event("item_related_update", $item); + } + } + return $result; + } + + /** + * Return the server-relative url to this item, eg: + * /gallery3/index.php/tags/35 + * + * @param string $query the query string (eg "page=3") + */ + public function url($query=null) { + $album_id = Input::instance()->get("album"); + if (!($album_id)) { + $album_id = 0; + } + $url = url::site("/tag_albums/tag/{$this->id}/{$album_id}/" . urlencode($this->name)); + if ($query) { + $url .= "?$query"; + } + return $url; + } +} diff --git a/3.1/modules/tag_albums/models/tags_album_id.php b/3.1/modules/tag_albums/models/tags_album_id.php new file mode 100644 index 00000000..a9b16b4f --- /dev/null +++ b/3.1/modules/tag_albums/models/tags_album_id.php @@ -0,0 +1,21 @@ + +

    + +

    +
    +
    + +
    diff --git a/3.1/modules/tag_albums/views/calpage.html.php b/3.1/modules/tag_albums/views/calpage.html.php new file mode 100644 index 00000000..3dab5fc0 --- /dev/null +++ b/3.1/modules/tag_albums/views/calpage.html.php @@ -0,0 +1,164 @@ + + +html_attributes() ?> xml:lang="en" lang="en"> + + + start_combining("script,css") ?> + + <? if ($page_title): ?> + <?= $page_title ?> + <? else: ?> + <? if ($theme->item()): ?> + <?= $theme->item()->title ?> + <? elseif ($theme->tag()): ?> + <?= t("Photos tagged with %tag_title", array("tag_title" => $theme->tag()->name)) ?> + <? else: /* Not an item, not a tag, no page_title specified. Help! */ ?> + <?= item::root()->title ?> + <? endif ?> + <? endif ?> + + " + type="image/x-icon" /> + + page_type == "collection"): ?> + + + + + + + + script("json2-min.js") ?> + script("jquery.js") ?> + script("jquery.form.js") ?> + script("jquery-ui.js") ?> + script("gallery.common.js") ?> + + + script("gallery.ajax.js") ?> + script("gallery.dialog.js") ?> + script("superfish/js/superfish.js") ?> + script("jquery.localscroll.js") ?> + + + page_subtype == "photo"): ?> + script("jquery.scrollTo.js") ?> + script("gallery.show_full_size.js") ?> + page_subtype == "movie"): ?> + script("flowplayer.js") ?> + + + head() ?> + + + script("ui.init.js") ?> + css("yui/reset-fonts-grids.css") ?> + css("superfish/css/superfish.css") ?> + css("themeroller/ui.base.css") ?> + css("screen.css") ?> + + + + get_combined("script") ?> + + + get_combined("css") ?> + + + body_attributes() ?>> + page_top() ?> +
    + site_status() ?> +
    +
    + + + + + + user_menu() ?> + header_top() ?> + + + + + + header_bottom() ?> +
    + + + + +
      + + + > + + url) : ?> + title) ?> + + title) ?> + + + + +
    + + + + + +
    +
    +
    +
    +
    + messages() ?> + +
    +
    +
    +
    + page_subtype != "login"): ?> + + +
    +
    + +
    + page_bottom() ?> + + \ No newline at end of file diff --git a/3.1/modules/tag_albums/views/tag_albums_album.html.php b/3.1/modules/tag_albums/views/tag_albums_album.html.php new file mode 100644 index 00000000..620d3c81 --- /dev/null +++ b/3.1/modules/tag_albums/views/tag_albums_album.html.php @@ -0,0 +1,50 @@ + +album_top() was changed to $theme->dynamic_top(). + // $item->title and $item->description have been changed to $title and $description. + // + // The g-album-grid block was also taken from album.html.php. The section for uploading new photos to an empty album + // has been removed. Also, $theme->context_menu has been removed as well (it was crashing the page). +?> +
    + dynamic_top() ?> +

    +
    +
    + + +
    +
    +
    +
    + + + +dynamic_bottom() ?> + +paginator() ?> diff --git a/3.1/modules/tag_albums/views/tag_albums_block.html.php b/3.1/modules/tag_albums/views/tag_albums_block.html.php new file mode 100644 index 00000000..d4b08087 --- /dev/null +++ b/3.1/modules/tag_albums/views/tag_albums_block.html.php @@ -0,0 +1,4 @@ + + diff --git a/3.1/modules/tag_cloud/controllers/admin_tag_cloud.php b/3.1/modules/tag_cloud/controllers/admin_tag_cloud.php index 777b9b7c..2d42e703 100644 --- a/3.1/modules/tag_cloud/controllers/admin_tag_cloud.php +++ b/3.1/modules/tag_cloud/controllers/admin_tag_cloud.php @@ -1,7 +1,7 @@ script("swfobject.js"); - $theme->script("tag_cloud.js"); + return $theme->script("swfobject.js") + . $theme->script("tag_cloud.js"); } } \ No newline at end of file diff --git a/3.1/modules/tag_cloud/module.info b/3.1/modules/tag_cloud/module.info index af8f9ce1..72c95532 100644 --- a/3.1/modules/tag_cloud/module.info +++ b/3.1/modules/tag_cloud/module.info @@ -1,3 +1,7 @@ name = "Tag Cloud" description = "3D tag cloud" version = 1 +author_name = "" +author_url = "" +info_url = "http://codex.gallery2.org/Gallery3:Modules:tag_cloud" +discuss_url = "http://gallery.menalto.com/forum_module_tag_cloud" diff --git a/3.1/modules/tag_cloud_page/controllers/tag_cloud_page.php b/3.1/modules/tag_cloud_page/controllers/tag_cloud_page.php new file mode 100644 index 00000000..2fc045df --- /dev/null +++ b/3.1/modules/tag_cloud_page/controllers/tag_cloud_page.php @@ -0,0 +1,66 @@ +content = new View("tag_cloud_page_cloud.html"); + $template->content->title = t("Tag Cloud"); + + // If the tag cloud module is active, load its settings from the database. + if (module::is_active("tag_cloud")) { + $options = array(); + foreach (array("tagcolor", "background_color", "mouseover", "transparent", "speed", "distribution") + as $option) { + $value = module::get_var("tag_cloud", $option, null); + if (!empty($value)) { + switch ($option) { + case "tagcolor": + $options["tcolor"] = $value; + break; + case "mouseover": + $options["hicolor"] = $value; + break; + case "background_color": + $options["bgColor"] = $value; + break; + case "transparent": + $options["wmode"] = "transparent"; + break; + case "speed": + $options["tspeed"] = $value; + break; + case "distribution": + $options["distr"] = "true"; + break; + } + } + } + $template->content->options = $options; + } + + // Display the page. + print $template; + } +} diff --git a/3.1/modules/tag_cloud_page/css/tag_cloud_page.css b/3.1/modules/tag_cloud_page/css/tag_cloud_page.css new file mode 100644 index 00000000..1eacad23 --- /dev/null +++ b/3.1/modules/tag_cloud_page/css/tag_cloud_page.css @@ -0,0 +1,73 @@ +/* Tag cloud page ~~~~~~~~~~~~~~~~~~~~~~~ */ + +#g-tag-cloud-page ul { + font-size: 1.2em; + text-align: justify; +} + +#g-tag-cloud-page ul li { + display: inline; + line-height: 1.5em; + text-align: justify; +} + +#g-tag-cloud-page ul li a { + text-decoration: none; +} + +#g-tag-cloud-page ul li span { + display: none; +} + +#g-tag-cloud-page ul li.size0 a { + color: #9cf; + font-size: 70%; + font-weight: 100; +} + +#g-tag-cloud-page ul li.size1 a { + color: #9cf; + font-size: 80%; + font-weight: 100; +} + +#g-tag-cloud-page ul li.size2 a { + color: #69f; + font-size: 90%; + font-weight: 300; +} + +#g-tag-cloud-page ul li.size3 a { + color: #69c; + font-size: 100%; + font-weight: 500; +} + +#g-tag-cloud-page ul li.size4 a { + color: #369; + font-size: 110%; + font-weight: 700; +} + +#g-tag-cloud-page ul li.size5 a { + color: #0e2b52; + font-size: 120%; + font-weight: 900; +} + +#g-tag-cloud-page ul li.size6 a { + color: #0e2b52; + font-size: 130%; + font-weight: 900; +} + +#g-tag-cloud-page ul li.size7 a { + color: #0e2b52; + font-size: 140%; + font-weight: 900; +} + +#g-tag-cloud-page ul li a:hover { + color: #f30; + text-decoration: underline; +} diff --git a/3.1/modules/tag_cloud_page/helpers/tag_cloud_page_block.php b/3.1/modules/tag_cloud_page/helpers/tag_cloud_page_block.php new file mode 100644 index 00000000..4ac5278b --- /dev/null +++ b/3.1/modules/tag_cloud_page/helpers/tag_cloud_page_block.php @@ -0,0 +1,40 @@ + t("Tag Cloud Page Link")); + } + + static function get($block_id, $theme) { + // Generate the sidebar block for linking to the tag cloud page. + $block = ""; + switch ($block_id) { + case "tag_cloud_page": + $block = new Block(); + $block->css_id = "g-tag-cloud-page"; + $block->title = t("Tag Cloud"); + $block->content = new View("tag_cloud_page_block.html"); + + break; + } + return $block; + } +} diff --git a/3.1/modules/tag_cloud_page/helpers/tag_cloud_page_event.php b/3.1/modules/tag_cloud_page/helpers/tag_cloud_page_event.php new file mode 100644 index 00000000..32f0ada0 --- /dev/null +++ b/3.1/modules/tag_cloud_page/helpers/tag_cloud_page_event.php @@ -0,0 +1,40 @@ +deactivate)) { + site_status::warning( + t("The Tag Cloud Page module requires the Tags module. " . + "Activate the Tags module now", + array("url" => url::site("admin/modules"))), + "tag_cloud_page_needs_tag"); + } else { + site_status::clear("tag_cloud_page_needs_tag"); + } + } + + static function pre_deactivate($data) { + if ($data->module == "tag") { + $data->messages["warn"][] = t("The Tag Cloud Page module requires the Tags module."); + } + } +} diff --git a/3.1/modules/tag_cloud_page/helpers/tag_cloud_page_installer.php b/3.1/modules/tag_cloud_page/helpers/tag_cloud_page_installer.php new file mode 100644 index 00000000..4f12115a --- /dev/null +++ b/3.1/modules/tag_cloud_page/helpers/tag_cloud_page_installer.php @@ -0,0 +1,32 @@ +script("tag_cloud_page.js"); + } + + // Load the tag cloud page's css code. + return $theme->css("tag_cloud_page.css"); + } +} diff --git a/3.1/modules/tag_cloud_page/js/tag_cloud_page.js b/3.1/modules/tag_cloud_page/js/tag_cloud_page.js new file mode 100644 index 00000000..66d1ddab --- /dev/null +++ b/3.1/modules/tag_cloud_page/js/tag_cloud_page.js @@ -0,0 +1,89 @@ +(function($) { + $.widget("ui.gallery_tag_cloud_page", { + _init: function() { + var self = this; + self._set_tag_cloud(); + this._ajax_form(); + this._autocomplete(); + }, + + _autocomplete: function() { + var url = $("#g-tag-cloud-page-animation").attr("ref") + "/autocomplete"; + $("#g-add-tag-form input:text").autocomplete( + url, { + max: 30, + multiple: true, + multipleSeparator: ',', + cacheLength: 1} + ); + }, + + _ajax_form: function() { + var self = this; + var form = $("#g-add-tag-form"); + form.ajaxForm({ + dataType: "json", + success: function(data) { + if (data.result == "success") { + $.get($("#g-tag-cloud-page-animation").attr("ref"), function(data, textStatus) { + $("#g-tag-cloud-movie-page").remove(); + $("#g-tag-cloud-page-animation").append("
    " + data + "
    "); + self._set_tag_cloud(); + }); + } + form.resetForm(); + $("#g-add-tag-form :text").blur(); + } + }); + }, + + _set_tag_cloud: function() { + var self = this; + var taglist = $("#g-tag-cloud-page-animation a"); + + if (taglist.length == 0) { + return; + } + var width = $("#g-tag-cloud-page-animation").width(); + var tags = document.createElement("tags"); + taglist.each(function(i) { + var addr = $(this).clone(); + $(addr).attr("style", "font-size: 14pt;"); + $(tags).append(addr); + }); + + var flashvars = { + tcolor: self.options.tcolor, + tcolor2: self.options.tcolor2, + mode: "tags", + distr: self.options.distr, + tspeed: self.options.tspeed, + hicolor: self.options.hicolor, + tagcloud: escape("" + $(tags).html() + "").toLowerCase() + }; + var params = { + bgcolor: self.options.bgColor, + wmode: self.options.wmode, + allowscriptaccess: self.options.scriptAccess + }; + + swfobject.embedSWF(self.options.movie, "g-tag-cloud-movie-page", width, .60 * width, "9", false, + flashvars, params); + } + }); + + $.extend($.ui.gallery_tag_cloud_page, { + defaults: { + bgColor: "0xFFFFFF", + wmode: "transparent", + scriptAccess: "always", + tcolor: "0x333333", + tcolor2: "0x009900", + hicolor: "0x000000", + tspeed: "100", + distr: "true", + mode: "tag" + } + }); + +})(jQuery); diff --git a/3.1/modules/tag_cloud_page/module.info b/3.1/modules/tag_cloud_page/module.info new file mode 100644 index 00000000..aebb40cb --- /dev/null +++ b/3.1/modules/tag_cloud_page/module.info @@ -0,0 +1,7 @@ +name = "Tag Cloud Page" +description = "Displays a tag cloud of all tags used in the Gallery on a seperate page." +version = 1 +author_name = "" +author_url = "" +info_url = "http://codex.gallery2.org/Gallery3:Modules:tag_cloud_page" +discuss_url = "http://gallery.menalto.com/forum_module_tag_cloud_page" diff --git a/3.1/modules/tag_cloud_page/views/tag_cloud_page_block.html.php b/3.1/modules/tag_cloud_page/views/tag_cloud_page_block.html.php new file mode 100644 index 00000000..46fd70ea --- /dev/null +++ b/3.1/modules/tag_cloud_page/views/tag_cloud_page_block.html.php @@ -0,0 +1,2 @@ + +">View cloud diff --git a/3.1/modules/tag_cloud_page/views/tag_cloud_page_cloud.html.php b/3.1/modules/tag_cloud_page/views/tag_cloud_page_cloud.html.php new file mode 100644 index 00000000..acd31ed4 --- /dev/null +++ b/3.1/modules/tag_cloud_page/views/tag_cloud_page_cloud.html.php @@ -0,0 +1,35 @@ + +
    +
    + dynamic_top() ?> +
    +

    +
    +
    + + + +
    +
    "> +
    + count_all()); ?> +
    +
    +
    + + +
    + count_all()); ?> +
    + + +dynamic_bottom() ?> diff --git a/3.1/modules/tag_it/controllers/tag_it.php b/3.1/modules/tag_it/controllers/tag_it.php index ba2ab6db..53dc5bf3 100644 --- a/3.1/modules/tag_it/controllers/tag_it.php +++ b/3.1/modules/tag_it/controllers/tag_it.php @@ -1,7 +1,7 @@ t("Tags In Album")); + } + + static function get($block_id, $theme) { + $block = ""; + + switch ($block_id) { + case "tagsinalbum": + if (($theme->item) && ($theme->item->is_album())) { + $item = $theme->item; + $all_tags = ORM::factory("tag") + ->join("items_tags", "items_tags.tag_id", "tags.id") + ->join("items", "items.id", "items_tags.item_id", "LEFT") + ->where("items.parent_id", "=", $item->id) + ->order_by("tags.id", "ASC") + ->find_all(); + if (count($all_tags) > 0) { + $block = new Block(); + $block->css_id = "g-tags-in-album-block"; + $block->title = t("In this album"); + $block->content = new View("tagsinalbum_sidebar.html"); + $block->content->all_tags = $all_tags; + } + } + break; + } + return $block; + } +} diff --git a/3.1/modules/tagsinalbum/helpers/tagsinalbum_event.php b/3.1/modules/tagsinalbum/helpers/tagsinalbum_event.php new file mode 100644 index 00000000..fe7339ae --- /dev/null +++ b/3.1/modules/tagsinalbum/helpers/tagsinalbum_event.php @@ -0,0 +1,37 @@ +module == "tag") { + $data->messages["warn"][] = t("The Tags In Album module requires the Tags module."); + } + } + + static function module_change($changes) { + if (!module::is_active("tag") || in_array("tag", $changes->deactivate)) { + site_status::warning( + t("The Tags In Album module requires the Tags module. Activate the Tags module now", + array("url" => html::mark_clean(url::site("admin/modules")))), + "tagsinalbum_needs_tag"); + } else { + site_status::clear("tagsinalbum_needs_tag"); + } + } +} diff --git a/3.1/modules/tagsinalbum/helpers/tagsinalbum_installer.php b/3.1/modules/tagsinalbum/helpers/tagsinalbum_installer.php new file mode 100644 index 00000000..09f82108 --- /dev/null +++ b/3.1/modules/tagsinalbum/helpers/tagsinalbum_installer.php @@ -0,0 +1,44 @@ + +id) { + $tag = ORM::factory("tag", $one_tag->id); + $display_tags[] = array(html::clean($tag->name), $tag->url()); + $last_tagid = $one_tag->id; + } + if (module::get_var("tagsinalbum", "max_display_tags") > 0) { + if (count($display_tags) == module::get_var("tagsinalbum", "max_display_tags")) { + break; + } + } + } + + // Sort the array. + asort($display_tags); + + // Print out the list of tags as clickable links. + $not_first = 0; + foreach ($display_tags as $one_tag) { + if ($not_first++ > 0) { + print ", "; + } + print "" . $one_tag[0] . ""; + } +?> diff --git a/3.1/modules/tagsmap/controllers/admin_tagsmap.php b/3.1/modules/tagsmap/controllers/admin_tagsmap.php index 6a774521..40d87119 100644 --- a/3.1/modules/tagsmap/controllers/admin_tagsmap.php +++ b/3.1/modules/tagsmap/controllers/admin_tagsmap.php @@ -1,7 +1,7 @@ dropdown("google_default_type") ->label(t("Default Map Type")) ->options( - array("G_NORMAL_MAP", "G_SATELLITE_MAP", "G_HYBRID_MAP", - "G_PHYSICAL_MAP", "G_SATELLITE_3D_MAP")); + array("G_NORMAL_MAP" => "Normal", + "G_SATELLITE_MAP" => "Satellite", + "G_HYBRID_MAP" => "Hybrid", + "G_PHYSICAL_MAP" => "Physical", + "G_SATELLITE_3D_MAP" => "Google Earth")) + ->selected(module::get_var("tagsmap", "googlemap_type")); // Add a save button to the form. $form->submit("SaveSettings")->value(t("Save")); diff --git a/3.1/modules/tagsmap/controllers/tagsmap.php b/3.1/modules/tagsmap/controllers/tagsmap.php index f5554e72..8725db86 100644 --- a/3.1/modules/tagsmap/controllers/tagsmap.php +++ b/3.1/modules/tagsmap/controllers/tagsmap.php @@ -1,7 +1,7 @@ module == "tag") { + $data->messages["warn"][] = t("The TagsMap module requires the Tags module."); + } + } + static function admin_menu($menu, $theme) { // Add a link to the TagsMap admin page to the Content menu. $menu->get("content_menu") diff --git a/3.1/modules/tagsmap/helpers/tagsmap_installer.php b/3.1/modules/tagsmap/helpers/tagsmap_installer.php index 9f91f6d8..4567d4df 100644 --- a/3.1/modules/tagsmap/helpers/tagsmap_installer.php +++ b/3.1/modules/tagsmap/helpers/tagsmap_installer.php @@ -1,7 +1,7 @@ css("tagsmap_menu.css"); + return $theme->css("tagsmap_menu.css"); } } diff --git a/3.1/modules/tagsmap/models/tags_gps.php b/3.1/modules/tagsmap/models/tags_gps.php index e219d245..31f7943f 100644 --- a/3.1/modules/tagsmap/models/tags_gps.php +++ b/3.1/modules/tagsmap/models/tags_gps.php @@ -1,7 +1,7 @@ name(t("Generate theme")); $v->task = task::create($task_def, - array("path" => $extract_path, - "original_name" => $form->theme->original->value, - "theme_name" => $form->theme->theme_name->value, - "display_name" => $form->theme->display_name->value, - "description" => $form->theme->description->value, - "is_admin" => $session->get("themeroller_is_admin"))); + array("path" => $extract_path, + "user_name" => SafeString::purify(identity::active_user()->name), + "original_name" => SafeString::purify($form->theme->original->value), + "theme_name" => SafeString::purify($form->theme->theme_name->value), + "display_name" => SafeString::purify($form->theme->display_name->value), + "description" => SafeString::purify($form->theme->description->value), + "author_url" => SafeString::purify($form->theme->author_url->value), + "info_url" => SafeString::purify($form->theme->info_url->value), + "discuss_url" => SafeString::purify($form->theme->discuss_url->value), + "is_admin" => $session->get("themeroller_is_admin"))); json::reply(array("html" => (string) $v)); } else { @@ -169,9 +173,13 @@ class Admin_Themeroller_Controller extends Admin_Controller { } $form_group->textarea("description")->label(t("Description")) ->id("g-description") - ->value(t("A generated theme based on the ui themeroller '%name' styling", array("name" => str_replace("admin_", "", $theme_name)))) + ->value(t("A generated theme based on the ui themeroller '%name' styling", + array("name" => str_replace("admin_", "", $theme_name)))) ->rules("required") ->error_messages("required", t("You must enter a theme description name")); + $form_group->input("author_url")->label(t("Author url"))->id("g-author-url"); + $form_group->input("info_url")->label(t("Info url"))->id("g-info-url"); + $form_group->input("discuss_url")->label(t("Theme Name"))->id("g-discuss-url"); $form_group->submit("")->value(t("Create")); return $form; diff --git a/3.1/modules/themeroller/data/views/page.html.php b/3.1/modules/themeroller/data/views/page.html.php index ffd5a173..06851344 100644 --- a/3.1/modules/themeroller/data/views/page.html.php +++ b/3.1/modules/themeroller/data/views/page.html.php @@ -4,47 +4,40 @@ + start_combining("script,css") ?> <? if ($page_title): ?> <?= $page_title ?> <? else: ?> <? if ($theme->item()): ?> - <? if ($theme->item()->is_album()): ?> - <?= t("Browse Album :: %album_title", array("album_title" => $theme->item()->title)) ?> - <? elseif ($theme->item()->is_photo()): ?> - <?= t("Photo :: %photo_title", array("photo_title" => $theme->item()->title)) ?> - <? else: ?> - <?= t("Movie :: %movie_title", array("movie_title" => $theme->item()->title)) ?> - <? endif ?> + <?= $theme->item()->title ?> <? elseif ($theme->tag()): ?> - <?= t("Browse Tag :: %tag_title", array("tag_title" => $theme->tag()->name)) ?> + <?= t("Photos tagged with %tag_title", array("tag_title" => $theme->tag()->name)) ?> <? else: /* Not an item, not a tag, no page_title specified. Help! */ ?> - <?= t("Gallery") ?> + <?= item::root()->title ?> <? endif ?> <? endif ?> - " type="image/x-icon" /> - css("yui/reset-fonts-grids.css") ?> - css("superfish/css/superfish.css") ?> - css("themeroller/ui.base.css") ?> - css("screen.css") ?> - + " + type="image/x-icon" /> + " /> page_type == "collection"): ?> - + + + script("json2-min.js") ?> script("jquery.js") ?> script("jquery.form.js") ?> script("jquery-ui.js") ?> @@ -57,7 +50,6 @@ script("gallery.dialog.js") ?> script("superfish/js/superfish.js") ?> script("jquery.localscroll.js") ?> - script("ui.init.js") ?> head() they get combined */ ?> page_subtype == "photo"): ?> @@ -68,6 +60,26 @@ head() ?> + + + script("ui.init.js") ?> + css("yui/reset-fonts-grids.css") ?> + css("superfish/css/superfish.css") ?> + css("themeroller/ui.base.css") ?> + css("screen.css") ?> + + css("screen-rtl.css") ?> + + + + + get_combined("css") ?> + + + get_combined("script") ?> body_attributes() ?>> @@ -100,19 +112,22 @@ > - + causes Gallery3 to display the page + // containing that photo. For now, we just do it for + // the immediate parent so that when you go back up a + // level you're on the right page. ?> item()->id}" : null) ?>"> - title, 15)) ?> + + title, + module::get_var("gallery", "visible_title_length"))) ?>
  • "> - item()->title, 15)) ?> + item()->title, + module::get_var("gallery", "visible_title_length"))) ?>
  • diff --git a/3.1/modules/themeroller/helpers/themeroller.php b/3.1/modules/themeroller/helpers/themeroller.php index 561fa169..44a102cc 100644 --- a/3.1/modules/themeroller/helpers/themeroller.php +++ b/3.1/modules/themeroller/helpers/themeroller.php @@ -1,6 +1,6 @@ display_name = $task->get("display_name"); - foreach ($parameters["colors"] as $color => $value) { - $v->$color = $value; + foreach (array("screen", "screen-rtl") as $file) { + $css_file = "{$theme_path}/css/$file.css"; + $v = new View(($is_admin ? "admin" : "site") . "_{$file}.css"); + $v->display_name = $task->get("display_name"); + foreach ($parameters["colors"] as $color => $value) { + $v->$color = $value; + } + ob_start(); + print $v->render(); + file_put_contents($css_file, ob_get_contents()); + ob_end_clean(); } - ob_start(); - print $v->render(); - file_put_contents($file, ob_get_contents()); - ob_end_clean(); $completed++; $task->log(t("Generated screen css: %path", array("path" => $file))); $task->status = t("Screen css generated"); @@ -229,14 +232,18 @@ class themeroller_task_Core { $task->status = t("Thumbnail generated"); $task->set("mode", "generate_theme_info"); $completed++; - $task->log(t("Generated theme thumbnail: %path", array("path" => "{$theme_path}thumbnail.png"))); + $task->log(t("Generated theme thumbnail: %path", + array("path" => "{$theme_path}thumbnail.png"))); break; case "generate_theme_info": $file = "{$theme_path}/theme.info"; $v = new View("theme.info"); $v->display_name = $task->get("display_name"); $v->description = $task->get("description"); - $v->user_name = identity::active_user()->name; + $v->user_name = $task->get("user_name"); + $v->author_url = $task->get("author_url"); + $v->info_url = $task->get("info_url"); + $v->discuss_url = $task->get("discuss_url"); $v->is_admin = $is_admin; $v->definition = json_encode($parameters["colors"]); ob_start(); diff --git a/3.1/modules/themeroller/module.info b/3.1/modules/themeroller/module.info index 0e50286e..aaa16bd6 100755 --- a/3.1/modules/themeroller/module.info +++ b/3.1/modules/themeroller/module.info @@ -1,3 +1,7 @@ -name = "Theme generator" +name = "Theme Roller" description = "Use a JQuery UI theme to create a Gallery3 Theme" version = 1 +author_name = "" +author_url = "" +info_url = "http://codex.gallery2.org/Gallery3:Modules:themeroller" +discuss_url = "http://gallery.menalto.com/forum_module_themeroller" diff --git a/3.1/modules/themeroller/views/admin_screen-rtl.css.php b/3.1/modules/themeroller/views/admin_screen-rtl.css.php new file mode 100644 index 00000000..196d5313 --- /dev/null +++ b/3.1/modules/themeroller/views/admin_screen-rtl.css.php @@ -0,0 +1,299 @@ +/** + * Gallery 3 Admin Right yo left language styles + */ + +.rtl { + direction: rtl; +} + + #g-header, + #g-content, + #g-sidebar, + #g-footer, + caption, + th, + #g-dialog, + .g-context-menu li a, + .g-message-box li, + #g-site-status li { + text-align: right; +} + + .g-text-right { + text-align: left; +} + + .g-error, + .g-info, + .g-success, + .g-warning, + #g-add-photos-status .g-success, + #g-add-photos-status .g-error { + background-position: center right; + padding-right: 30px !important; +} + + form li.g-error, + form li.g-info, + form li.g-success, + form li.g-warning { + padding-right: 0 !important; +} + + .g-left, + .g-inline li, + #g-content #g-album-grid .g-item, + .sf-menu li, + .g-breadcrumbs li, + .g-paginator li, + .g-buttonset li, + .ui-icon-left .ui-icon, + .g-short-form li, + form ul ul li, + input[type="submit"], + input[type="reset"], + input.checkbox, + input[type=checkbox], + input.radio, + input[type=radio] { + float: right; +} + + .g-right, + .ui-icon-right .ui-icon { + float: left; +} + + .g-inline li { + margin-right: 1em; +} + + .g-inline li.g-first { + margin-right: 0; +} + + .g-breadcrumbs li { + background: transparent url('../images/ico-separator-rtl.png') no-repeat scroll right center; + padding: 1em 18px 1em 8px; +} + + .g-breadcrumbs .g-first { + background: none; + padding-right: 0; +} + + input.checkbox { + margin-left: .4em; +} + + #g-add-comment { + right: inherit; + left: 0; +} + + .ui-icon-left .ui-icon { + margin-left: .2em; +} + + .ui-icon-right .ui-icon { + margin-right: .2em; +} + +/* RTL Corner radius ~~~~~~~~~~~~~~~~~~~~~~ */ + .g-buttonset .ui-corner-tl { + -moz-border-radius-topleft: 0; + -webkit-border-top-left-radius: 0; + border-top-left-radius: 0; + -moz-border-radius-topright: 5px !important; + -webkit-border-top-right-radius: 5px !important; + border-top-right-radius: 5px !important; +} + + .g-buttonset .ui-corner-tr { + -moz-border-radius-topright: 0; + -webkit-border-top-right-radius: 0; + border-top-right-radius: 0; + -moz-border-radius-topleft: 5px !important; + -webkit-border-top-left-radius: 5px !important; + border-top-left-radius: 5px !important; +} + + .g-buttonset .ui-corner-bl { + -moz-border-radius-bottomleft: 0; + -webkit-border-bottom-left-radius: 0; + border-bottom-left-radius: 0; + -moz-border-radius-bottomright: 5px !important; + -webkit-border-bottom-right-radius: 5px !important; + border-bottom-right-radius: 5px !important; +} + + .g-buttonset .ui-corner-br { + -moz-border-radius-bottomright: 0; + -webkit-border-bottom-right-radius: 0; + border-bottom-right-radius: 0; + -moz-border-radius-bottomleft: 5px !important; + -webkit-border-bottom-left-radius: 5px !important; + border-bottom-left-radius: 5px !important; +} + + .g-buttonset .ui-corner-right, + .ui-progressbar .ui-corner-right { + -moz-border-radius-topright: 0; + -webkit-border-top-right-radius: 0; + border-top-right-radius: 0; + -moz-border-radius-topleft: 5px !important; + -webkit-border-top-left-radius: 5px !important; + border-top-left-radius: 5px !important; + -moz-border-radius-bottomright: 0; + -webkit-border-bottom-right-radius: 0; + border-bottom-right-radius: 0; + -moz-border-radius-bottomleft: 5px !important; + -webkit-border-bottom-left-radius: 5px !important; + border-bottom-left-radius: 5px !important; +} + + .g-buttonset .ui-corner-left, + .ui-progressbar .ui-corner-left { + -moz-border-radius-topleft: 0; + -webkit-border-top-left-radius: 0; + border-top-left-radius: 0; + -moz-border-radius-topright: 5px !important; + -webkit-border-top-right-radius: 5px !important; + border-top-right-radius: 5px !important; + -moz-border-radius-bottomleft: 0; + -webkit-border-bottom-left-radius: 0; + border-bottom-left-radius: 0; + -moz-border-radius-bottomright: 5px !important; + -webkit-border-bottom-right-radius: 5px !important; + border-bottom-right-radius: 5px !important; +} + +/* RTL Superfish ~~~~~~~~~~~~~~~~~~~~~~~~~ */ + + .sf-menu a { + border-left: none; + border-right:1px solid #; +} + + .sf-menu a.sf-with-ul { + padding-left: 2.25em; + padding-right: 1em; +} + + .sf-sub-indicator { + background: url("themeroller/images/ui-icons__256x240.png") no-repeat -96px -16px; /* 8-bit indexed alpha png. IE6 gets solid image only */ + left: .75em !important; + right: auto; +} + + a > .sf-sub-indicator { /* give all except IE6 the correct values */ + top: .8em; + background-position: -10px -100px; /* use translucent arrow for modern browsers*/ +} +/* apply hovers to modern browsers */ + a:focus > .sf-sub-indicator, + a:hover > .sf-sub-indicator, + a:active > .sf-sub-indicator, + li:hover > a > .sf-sub-indicator, + li.sfHover > a > .sf-sub-indicator { + background-position: 0 -100px; /* arrow hovers for modern browsers*/ +} + +/* point right for anchors in subs */ + .sf-menu ul .sf-sub-indicator { background-position: 0 0; } + .sf-menu ul a > .sf-sub-indicator { background-position: -10px 0; } +/* apply hovers to modern browsers */ + .sf-menu ul a:focus > .sf-sub-indicator, + .sf-menu ul a:hover > .sf-sub-indicator, + .sf-menu ul a:active > .sf-sub-indicator, + .sf-menu ul li:hover > a > .sf-sub-indicator, + .sf-menu ul li.sfHover > a > .sf-sub-indicator { + background-position: 0 0; /* arrow hovers for modern browsers*/ +} + + .sf-menu li:hover ul, + .sf-menu li.sfHover ul { + right: 0; + left: auto; +} + + ul.sf-menu li li:hover ul, + ul.sf-menu li li.sfHover ul { + right: 12em; /* match ul width */ + left: auto; +} + ul.sf-menu li li li:hover ul, + ul.sf-menu li li li.sfHover ul { + right: 12em; /* match ul width */ + left: auto; +} + +/*** shadows for all but IE6 ***/ + .sf-shadow ul { + background: url('../images/superfish-shadow.png') no-repeat bottom left; + border-top-right-radius: 0; + border-bottom-left-radius: 0; + -moz-border-radius-topright: 0; + -moz-border-radius-bottomleft: 0; + -webkit-border-top-right-radius: 0; + -webkit-border-bottom-left-radius: 0; + -moz-border-radius-topleft: 17px; + -moz-border-radius-bottomright: 17px; + -webkit-border-top-left-radius: 17px; + -webkit-border-bottom-right-radius: 17px; + border-top-left-radius: 17px; + border-bottom-right-radius: 17px; +} + +/* RTL ThemeRoller ~~~~~~~~~~~~~~~~~~~~~~~~ */ + + .ui-dialog .ui-dialog-titlebar { + padding: 0.5em 1em 0.3em 0.3em; +} + + .ui-dialog .ui-dialog-title { + float: right; +} + + .ui-dialog .ui-dialog-titlebar-close { + left: 0.3em; + right: auto; +} + + #g-content #g-album-grid .g-item, + #g-site-theme, + #g-admin-theme, + .g-selected img, + .g-available .g-block img, + #g-content #g-photo-stream .g-item, + li.g-group, + #g-server-add-admin { + float: right; +} + + #g-admin-graphics .g-available .g-block { + float: right; + margin-left: 1em; + margin-right: 0em; +} + + #g-site-admin-menu { + left: auto; + right: 150px; +} + + #g-header #g-login-menu { + float: left; +} + + #g-header #g-login-menu li { + margin-left: 0; + padding-left: 0; + padding-right: 1.2em; +} + + .g-selected img, + .g-available .g-block img { + margin: 0 0 1em 1em; +} + diff --git a/3.1/modules/themeroller/views/admin_screen.css.php b/3.1/modules/themeroller/views/admin_screen.css.php index 54ea97f4..68659be2 100644 --- a/3.1/modules/themeroller/views/admin_screen.css.php +++ b/3.1/modules/themeroller/views/admin_screen.css.php @@ -13,7 +13,6 @@ * 7) Navigation and menus * 8) jQuery and jQuery UI * 9) Module color overrides - * 10) Right-to-left language styles * * @todo Review g-buttonset-vertical */ @@ -98,7 +97,16 @@ a:hover, text-decoration: none; } +/* Lists ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ + +ul.g-text li, +.g-text ul li { + list-style-type: disc; + margin-left: 1em; +} + /* Forms ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ + form { margin: 0; } @@ -415,11 +423,6 @@ th { background-color: #; } -ul.enumeration li { - list-style-type: disc; - margin-left: 20px; -} - /*** ****************************************************************** * 3) Page layout containers *********************************************************************/ @@ -1126,303 +1129,3 @@ a > .sf-sub-indicator { .g-default-group .g-user { color: # !important; } - -/** ******************************************************************* - * 10) Right to left styles - *********************************************************************/ - -.rtl { - direction: rtl; -} - -.rtl #g-header, -.rtl #g-content, -.rtl #g-sidebar, -.rtl #g-footer, -.rtl caption, -.rtl th, -.rtl #g-dialog, -.rtl .g-context-menu li a, -.rtl .g-message-box li, -.rtl #g-site-status li { - text-align: right; -} - -.rtl .g-text-right { - text-align: left; -} - -.rtl .g-error, -.rtl .g-info, -.rtl .g-success, -.rtl .g-warning, -.rtl #g-add-photos-status .g-success, -.rtl #g-add-photos-status .g-error { - background-position: center right; - padding-right: 30px !important; -} - -.rtl form li.g-error, -.rtl form li.g-info, -.rtl form li.g-success, -.rtl form li.g-warning { - padding-right: 0 !important; -} - -.rtl .g-left, -.rtl .g-inline li, -.rtl #g-content #g-album-grid .g-item, -.rtl .sf-menu li, -.rtl .g-breadcrumbs li, -.rtl .g-paginator li, -.rtl .g-buttonset li, -.rtl .ui-icon-left .ui-icon, -.rtl .g-short-form li, -.rtl form ul ul li, -.rtl input[type="submit"], -.rtl input[type="reset"], -.rtl input.checkbox, -.rtl input[type=checkbox], -.rtl input.radio, -.rtl input[type=radio] { - float: right; -} - -.rtl .g-right, -.rtl .ui-icon-right .ui-icon { - float: left; -} - -.rtl .g-inline li { - margin-right: 1em; -} - -.rtl .g-inline li.g-first { - margin-right: 0; -} - -.rtl .g-breadcrumbs li { - background: transparent url('../images/ico-separator-rtl.png') no-repeat scroll right center; - padding: 1em 18px 1em 8px; -} - -.rtl .g-breadcrumbs .g-first { - background: none; - padding-right: 0; -} - -.rtl input.checkbox { - margin-left: .4em; -} - -.rtl #g-add-comment { - right: inherit; - left: 0; -} - -.rtl .ui-icon-left .ui-icon { - margin-left: .2em; -} - -.rtl .ui-icon-right .ui-icon { - margin-right: .2em; -} - -/* RTL Corner radius ~~~~~~~~~~~~~~~~~~~~~~ */ -.rtl .g-buttonset .ui-corner-tl { - -moz-border-radius-topleft: 0; - -webkit-border-top-left-radius: 0; - border-top-left-radius: 0; - -moz-border-radius-topright: 5px !important; - -webkit-border-top-right-radius: 5px !important; - border-top-right-radius: 5px !important; -} - -.rtl .g-buttonset .ui-corner-tr { - -moz-border-radius-topright: 0; - -webkit-border-top-right-radius: 0; - border-top-right-radius: 0; - -moz-border-radius-topleft: 5px !important; - -webkit-border-top-left-radius: 5px !important; - border-top-left-radius: 5px !important; -} - -.rtl .g-buttonset .ui-corner-bl { - -moz-border-radius-bottomleft: 0; - -webkit-border-bottom-left-radius: 0; - border-bottom-left-radius: 0; - -moz-border-radius-bottomright: 5px !important; - -webkit-border-bottom-right-radius: 5px !important; - border-bottom-right-radius: 5px !important; -} - -.rtl .g-buttonset .ui-corner-br { - -moz-border-radius-bottomright: 0; - -webkit-border-bottom-right-radius: 0; - border-bottom-right-radius: 0; - -moz-border-radius-bottomleft: 5px !important; - -webkit-border-bottom-left-radius: 5px !important; - border-bottom-left-radius: 5px !important; -} - -.rtl .g-buttonset .ui-corner-right, -.rtl .ui-progressbar .ui-corner-right { - -moz-border-radius-topright: 0; - -webkit-border-top-right-radius: 0; - border-top-right-radius: 0; - -moz-border-radius-topleft: 5px !important; - -webkit-border-top-left-radius: 5px !important; - border-top-left-radius: 5px !important; - -moz-border-radius-bottomright: 0; - -webkit-border-bottom-right-radius: 0; - border-bottom-right-radius: 0; - -moz-border-radius-bottomleft: 5px !important; - -webkit-border-bottom-left-radius: 5px !important; - border-bottom-left-radius: 5px !important; -} - -.rtl .g-buttonset .ui-corner-left, -.rtl .ui-progressbar .ui-corner-left { - -moz-border-radius-topleft: 0; - -webkit-border-top-left-radius: 0; - border-top-left-radius: 0; - -moz-border-radius-topright: 5px !important; - -webkit-border-top-right-radius: 5px !important; - border-top-right-radius: 5px !important; - -moz-border-radius-bottomleft: 0; - -webkit-border-bottom-left-radius: 0; - border-bottom-left-radius: 0; - -moz-border-radius-bottomright: 5px !important; - -webkit-border-bottom-right-radius: 5px !important; - border-bottom-right-radius: 5px !important; -} - -/* RTL Superfish ~~~~~~~~~~~~~~~~~~~~~~~~~ */ - -.rtl .sf-menu a { - border-left: none; - border-right:1px solid #; -} - -.rtl .sf-menu a.sf-with-ul { - padding-left: 2.25em; - padding-right: 1em; -} - -.rtl .sf-sub-indicator { - background: url("themeroller/images/ui-icons__256x240.png") no-repeat -96px -16px; /* 8-bit indexed alpha png. IE6 gets solid image only */ - left: .75em !important; - right: auto; -} - -.rtl a > .sf-sub-indicator { /* give all except IE6 the correct values */ - top: .8em; - background-position: -10px -100px; /* use translucent arrow for modern browsers*/ -} -/* apply hovers to modern browsers */ -.rtl a:focus > .sf-sub-indicator, -.rtl a:hover > .sf-sub-indicator, -.rtl a:active > .sf-sub-indicator, -.rtl li:hover > a > .sf-sub-indicator, -.rtl li.sfHover > a > .sf-sub-indicator { - background-position: 0 -100px; /* arrow hovers for modern browsers*/ -} - -/* point right for anchors in subs */ -.rtl .sf-menu ul .sf-sub-indicator { background-position: 0 0; } -.rtl .sf-menu ul a > .sf-sub-indicator { background-position: -10px 0; } -/* apply hovers to modern browsers */ -.rtl .sf-menu ul a:focus > .sf-sub-indicator, -.rtl .sf-menu ul a:hover > .sf-sub-indicator, -.rtl .sf-menu ul a:active > .sf-sub-indicator, -.rtl .sf-menu ul li:hover > a > .sf-sub-indicator, -.rtl .sf-menu ul li.sfHover > a > .sf-sub-indicator { - background-position: 0 0; /* arrow hovers for modern browsers*/ -} - -.rtl .sf-menu li:hover ul, -.rtl .sf-menu li.sfHover ul { - right: 0; - left: auto; -} - -.rtl ul.sf-menu li li:hover ul, -.rtl ul.sf-menu li li.sfHover ul { - right: 12em; /* match ul width */ - left: auto; -} -.rtl ul.sf-menu li li li:hover ul, -.rtl ul.sf-menu li li li.sfHover ul { - right: 12em; /* match ul width */ - left: auto; -} - -/*** shadows for all but IE6 ***/ -.rtl .sf-shadow ul { - background: url('../images/superfish-shadow.png') no-repeat bottom left; - border-top-right-radius: 0; - border-bottom-left-radius: 0; - -moz-border-radius-topright: 0; - -moz-border-radius-bottomleft: 0; - -webkit-border-top-right-radius: 0; - -webkit-border-bottom-left-radius: 0; - -moz-border-radius-topleft: 17px; - -moz-border-radius-bottomright: 17px; - -webkit-border-top-left-radius: 17px; - -webkit-border-bottom-right-radius: 17px; - border-top-left-radius: 17px; - border-bottom-right-radius: 17px; -} - -/* RTL ThemeRoller ~~~~~~~~~~~~~~~~~~~~~~~~ */ - -.rtl .ui-dialog .ui-dialog-titlebar { - padding: 0.5em 1em 0.3em 0.3em; -} - -.rtl .ui-dialog .ui-dialog-title { - float: right; -} - -.rtl .ui-dialog .ui-dialog-titlebar-close { - left: 0.3em; - right: auto; -} - -.rtl #g-content #g-album-grid .g-item, -.rtl #g-site-theme, -.rtl #g-admin-theme, -.rtl .g-selected img, -.rtl .g-available .g-block img, -.rtl #g-content #g-photo-stream .g-item, -.rtl li.g-group, -.rtl #g-server-add-admin { - float: right; -} - -.rtl #g-admin-graphics .g-available .g-block { - float: right; - margin-left: 1em; - margin-right: 0em; -} - -.rtl #g-site-admin-menu { - left: auto; - right: 150px; -} - -.rtl #g-header #g-login-menu { - float: left; -} - -.rtl #g-header #g-login-menu li { - margin-left: 0; - padding-left: 0; - padding-right: 1.2em; -} - -.rtl .g-selected img, -.rtl .g-available .g-block img { - margin: 0 0 1em 1em; -} - diff --git a/3.1/modules/themeroller/views/site_screen-rtl.css.php b/3.1/modules/themeroller/views/site_screen-rtl.css.php new file mode 100644 index 00000000..991234cb --- /dev/null +++ b/3.1/modules/themeroller/views/site_screen-rtl.css.php @@ -0,0 +1,320 @@ + +/** + * Gallery 3 right to left language styles + */ + +.rtl { + direction: rtl; +} + + #g-header, + #g-content, + #g-sidebar, + #g-footer, + caption, + th, + #g-dialog, + .g-context-menu li a, + .g-message-box li, + #g-site-status li { + text-align: right; +} + + .g-text-right { + text-align: left; +} + + .g-error, + .g-info, + .g-success, + .g-warning, + #g-add-photos-status .g-success, + #g-add-photos-status .g-error { + background-position: center right; + padding-right: 30px !important; +} + + form li.g-error, + form li.g-info, + form li.g-success, + form li.g-warning { + padding-right: 0 !important; +} + + .g-left, + .g-inline li, + #g-content #g-album-grid .g-item, + .sf-menu li, + .g-breadcrumbs li, + .g-paginator li, + .g-buttonset li, + .ui-icon-left .ui-icon, + .g-short-form li, + form ul ul li, + input[type="submit"], + input[type="reset"], + input.checkbox, + input[type=checkbox], + input.radio, + input[type=radio] { + float: right; +} + + .g-right, + .ui-icon-right .ui-icon { + float: left; +} + + .g-inline li { + margin-right: 1em; +} + + .g-inline li.g-first { + margin-right: 0; +} + + .g-breadcrumbs li { + background: transparent url('../images/ico-separator-rtl.png') no-repeat scroll right center; + padding: 1em 18px 1em 8px; +} + + .g-breadcrumbs .g-first { + background: none; + padding-right: 0; +} + + input.checkbox { + margin-left: .4em; +} + + #g-add-comment { + right: inherit; + left: 0; +} + + .ui-icon-left .ui-icon { + margin-left: .2em; +} + + .ui-icon-right .ui-icon { + margin-right: .2em; +} + +/* RTL Corner radius ~~~~~~~~~~~~~~~~~~~~~~ */ + .g-buttonset .ui-corner-tl { + -moz-border-radius-topleft: 0; + -webkit-border-top-left-radius: 0; + border-top-left-radius: 0; + -moz-border-radius-topright: 5px !important; + -webkit-border-top-right-radius: 5px !important; + border-top-right-radius: 5px !important; +} + + .g-buttonset .ui-corner-tr { + -moz-border-radius-topright: 0; + -webkit-border-top-right-radius: 0; + border-top-right-radius: 0; + -moz-border-radius-topleft: 5px !important; + -webkit-border-top-left-radius: 5px !important; + border-top-left-radius: 5px !important; +} + + .g-buttonset .ui-corner-bl { + -moz-border-radius-bottomleft: 0; + -webkit-border-bottom-left-radius: 0; + border-bottom-left-radius: 0; + -moz-border-radius-bottomright: 5px !important; + -webkit-border-bottom-right-radius: 5px !important; + border-bottom-right-radius: 5px !important; +} + + .g-buttonset .ui-corner-br { + -moz-border-radius-bottomright: 0; + -webkit-border-bottom-right-radius: 0; + border-bottom-right-radius: 0; + -moz-border-radius-bottomleft: 5px !important; + -webkit-border-bottom-left-radius: 5px !important; + border-bottom-left-radius: 5px !important; +} + + .g-buttonset .ui-corner-right, + .ui-progressbar .ui-corner-right { + -moz-border-radius-topright: 0; + -webkit-border-top-right-radius: 0; + border-top-right-radius: 0; + -moz-border-radius-topleft: 5px !important; + -webkit-border-top-left-radius: 5px !important; + border-top-left-radius: 5px !important; + -moz-border-radius-bottomright: 0; + -webkit-border-bottom-right-radius: 0; + border-bottom-right-radius: 0; + -moz-border-radius-bottomleft: 5px !important; + -webkit-border-bottom-left-radius: 5px !important; + border-bottom-left-radius: 5px !important; +} + + .g-buttonset .ui-corner-left, + .ui-progressbar .ui-corner-left { + -moz-border-radius-topleft: 0; + -webkit-border-top-left-radius: 0; + border-top-left-radius: 0; + -moz-border-radius-topright: 5px !important; + -webkit-border-top-right-radius: 5px !important; + border-top-right-radius: 5px !important; + -moz-border-radius-bottomleft: 0; + -webkit-border-bottom-left-radius: 0; + border-bottom-left-radius: 0; + -moz-border-radius-bottomright: 5px !important; + -webkit-border-bottom-right-radius: 5px !important; + border-bottom-right-radius: 5px !important; +} + +/* RTL Superfish ~~~~~~~~~~~~~~~~~~~~~~~~~ */ + + .sf-menu a { + border-left: none; + border-right:1px solid #; +} + + .sf-menu a.sf-with-ul { + padding-left: 2.25em; + padding-right: 1em; +} + + .sf-sub-indicator { + left: .75em !important; + right: auto; + background: url("themeroller/images/ui-icons__256x240.png") no-repeat -10px -100px; /* 8-bit indexed alpha png. IE6 gets solid image only */ +} + + a > .sf-sub-indicator { /* give all except IE6 the correct values */ + top: .8em; + background-position: -10px -100px; /* use translucent arrow for modern browsers*/ +} +/* apply hovers to modern browsers */ + a:focus > .sf-sub-indicator, + a:hover > .sf-sub-indicator, + a:active > .sf-sub-indicator, + li:hover > a > .sf-sub-indicator, + li.sfHover > a > .sf-sub-indicator { + background-position: 0 -100px; /* arrow hovers for modern browsers*/ +} + +/* point right for anchors in subs */ + .sf-menu ul .sf-sub-indicator { background-position: 0 0; } + .sf-menu ul a > .sf-sub-indicator { background-position: -10px 0; } +/* apply hovers to modern browsers */ + .sf-menu ul a:focus > .sf-sub-indicator, + .sf-menu ul a:hover > .sf-sub-indicator, + .sf-menu ul a:active > .sf-sub-indicator, + .sf-menu ul li:hover > a > .sf-sub-indicator, + .sf-menu ul li.sfHover > a > .sf-sub-indicator { + background-position: 0 0; /* arrow hovers for modern browsers*/ +} + + .sf-menu li:hover ul, + .sf-menu li.sfHover ul { + right: 0; + left: auto; +} + + ul.sf-menu li li:hover ul, + ul.sf-menu li li.sfHover ul { + right: 12em; /* match ul width */ + left: auto; +} + ul.sf-menu li li li:hover ul, + ul.sf-menu li li li.sfHover ul { + right: 12em; /* match ul width */ + left: auto; +} + +/*** shadows for all but IE6 ***/ + .sf-shadow ul { + background: url('../../../lib/superfish/images/shadow.png') no-repeat bottom left; + padding: 0 0 9px 8px; + border-top-right-radius: 0; + border-bottom-left-radius: 0; + -moz-border-radius-topright: 0; + -moz-border-radius-bottomleft: 0; + -webkit-border-top-right-radius: 0; + -webkit-border-bottom-left-radius: 0; + -moz-border-radius-topleft: 17px; + -moz-border-radius-bottomright: 17px; + -webkit-border-top-left-radius: 17px; + -webkit-border-bottom-right-radius: 17px; + border-top-left-radius: 17px; + border-bottom-right-radius: 17px; +} + +/* RTL ThemeRoller ~~~~~~~~~~~~~~~~~~~~~~~~ */ + + .ui-dialog .ui-dialog-titlebar { + padding: 0.5em 1em 0.3em 0.3em; +} + + .ui-dialog .ui-dialog-title { + float: right; +} + + .ui-dialog .ui-dialog-titlebar-close { + left: 0.3em; + right: auto; +} + +/* RTL paginator ~~~~~~~~~~~~~~~~~~~~~~~~~~ */ + + .g-paginator .g-info { + width: 35%; +} + + .g-paginator .g-text-right { + margin-left: 0; +} + + .g-paginator .ui-icon-seek-end { + background-position: -80px -160px; +} + + .g-paginator .ui-icon-seek-next { + background-position: -48px -160px; +} + + .g-paginator .ui-icon-seek-prev { + background-position: -32px -160px; +} + + .g-paginator .ui-icon-seek-first { + background-position: -64px -160px; +} + + #g-header #g-login-menu, + #g-header #g-quick-search-form { + clear: left; + float: left; +} + + #g-header #g-login-menu li { + margin-left: 0; + padding-left: 0; + padding-right: 1.2em; +} + + #g-site-menu { + left: auto; + right: 150px; +} + + #g-view-menu #g-slideshow-link { + background-image: url('../images/ico-view-slideshow-rtl.png'); +} + + #g-sidebar .g-block-content { + padding-right: 1em; + padding-left: 0; +} + + #g-footer #g-credits li { + padding-left: 1.2em !important; + padding-right: 0; +} diff --git a/3.1/modules/themeroller/views/site_screen.css.php b/3.1/modules/themeroller/views/site_screen.css.php index 933f8c48..315611f8 100644 --- a/3.1/modules/themeroller/views/site_screen.css.php +++ b/3.1/modules/themeroller/views/site_screen.css.php @@ -15,7 +15,6 @@ * 8) jQuery and jQuery UI * 9) Organize module style * 10) Tag module styles - * 11) Right-to-left language styles */ /** ******************************************************************* @@ -1217,323 +1216,3 @@ div#g-action-status { color: #f30; text-decoration: underline; } - -/** ******************************************************************* - * 11) Right to left language styles - *********************************************************************/ - -.rtl { - direction: rtl; -} - -.rtl #g-header, -.rtl #g-content, -.rtl #g-sidebar, -.rtl #g-footer, -.rtl caption, -.rtl th, -.rtl #g-dialog, -.rtl .g-context-menu li a, -.rtl .g-message-box li, -.rtl #g-site-status li { - text-align: right; -} - -.rtl .g-text-right { - text-align: left; -} - -.rtl .g-error, -.rtl .g-info, -.rtl .g-success, -.rtl .g-warning, -.rtl #g-add-photos-status .g-success, -.rtl #g-add-photos-status .g-error { - background-position: center right; - padding-right: 30px !important; -} - -.rtl form li.g-error, -.rtl form li.g-info, -.rtl form li.g-success, -.rtl form li.g-warning { - padding-right: 0 !important; -} - -.rtl .g-left, -.rtl .g-inline li, -.rtl #g-content #g-album-grid .g-item, -.rtl .sf-menu li, -.rtl .g-breadcrumbs li, -.rtl .g-paginator li, -.rtl .g-buttonset li, -.rtl .ui-icon-left .ui-icon, -.rtl .g-short-form li, -.rtl form ul ul li, -.rtl input[type="submit"], -.rtl input[type="reset"], -.rtl input.checkbox, -.rtl input[type=checkbox], -.rtl input.radio, -.rtl input[type=radio] { - float: right; -} - -.rtl .g-right, -.rtl .ui-icon-right .ui-icon { - float: left; -} - -.rtl .g-inline li { - margin-right: 1em; -} - -.rtl .g-inline li.g-first { - margin-right: 0; -} - -.rtl .g-breadcrumbs li { - background: transparent url('../images/ico-separator-rtl.png') no-repeat scroll right center; - padding: 1em 18px 1em 8px; -} - -.rtl .g-breadcrumbs .g-first { - background: none; - padding-right: 0; -} - -.rtl input.checkbox { - margin-left: .4em; -} - -.rtl #g-add-comment { - right: inherit; - left: 0; -} - -.rtl .ui-icon-left .ui-icon { - margin-left: .2em; -} - -.rtl .ui-icon-right .ui-icon { - margin-right: .2em; -} - -/* RTL Corner radius ~~~~~~~~~~~~~~~~~~~~~~ */ -.rtl .g-buttonset .ui-corner-tl { - -moz-border-radius-topleft: 0; - -webkit-border-top-left-radius: 0; - border-top-left-radius: 0; - -moz-border-radius-topright: 5px !important; - -webkit-border-top-right-radius: 5px !important; - border-top-right-radius: 5px !important; -} - -.rtl .g-buttonset .ui-corner-tr { - -moz-border-radius-topright: 0; - -webkit-border-top-right-radius: 0; - border-top-right-radius: 0; - -moz-border-radius-topleft: 5px !important; - -webkit-border-top-left-radius: 5px !important; - border-top-left-radius: 5px !important; -} - -.rtl .g-buttonset .ui-corner-bl { - -moz-border-radius-bottomleft: 0; - -webkit-border-bottom-left-radius: 0; - border-bottom-left-radius: 0; - -moz-border-radius-bottomright: 5px !important; - -webkit-border-bottom-right-radius: 5px !important; - border-bottom-right-radius: 5px !important; -} - -.rtl .g-buttonset .ui-corner-br { - -moz-border-radius-bottomright: 0; - -webkit-border-bottom-right-radius: 0; - border-bottom-right-radius: 0; - -moz-border-radius-bottomleft: 5px !important; - -webkit-border-bottom-left-radius: 5px !important; - border-bottom-left-radius: 5px !important; -} - -.rtl .g-buttonset .ui-corner-right, -.rtl .ui-progressbar .ui-corner-right { - -moz-border-radius-topright: 0; - -webkit-border-top-right-radius: 0; - border-top-right-radius: 0; - -moz-border-radius-topleft: 5px !important; - -webkit-border-top-left-radius: 5px !important; - border-top-left-radius: 5px !important; - -moz-border-radius-bottomright: 0; - -webkit-border-bottom-right-radius: 0; - border-bottom-right-radius: 0; - -moz-border-radius-bottomleft: 5px !important; - -webkit-border-bottom-left-radius: 5px !important; - border-bottom-left-radius: 5px !important; -} - -.rtl .g-buttonset .ui-corner-left, -.rtl .ui-progressbar .ui-corner-left { - -moz-border-radius-topleft: 0; - -webkit-border-top-left-radius: 0; - border-top-left-radius: 0; - -moz-border-radius-topright: 5px !important; - -webkit-border-top-right-radius: 5px !important; - border-top-right-radius: 5px !important; - -moz-border-radius-bottomleft: 0; - -webkit-border-bottom-left-radius: 0; - border-bottom-left-radius: 0; - -moz-border-radius-bottomright: 5px !important; - -webkit-border-bottom-right-radius: 5px !important; - border-bottom-right-radius: 5px !important; -} - -/* RTL Superfish ~~~~~~~~~~~~~~~~~~~~~~~~~ */ - -.rtl .sf-menu a { - border-left: none; - border-right:1px solid #; -} - -.rtl .sf-menu a.sf-with-ul { - padding-left: 2.25em; - padding-right: 1em; -} - -.rtl .sf-sub-indicator { - left: .75em !important; - right: auto; - background: url("themeroller/images/ui-icons__256x240.png") no-repeat -10px -100px; /* 8-bit indexed alpha png. IE6 gets solid image only */ -} - -.rtl a > .sf-sub-indicator { /* give all except IE6 the correct values */ - top: .8em; - background-position: -10px -100px; /* use translucent arrow for modern browsers*/ -} -/* apply hovers to modern browsers */ -.rtl a:focus > .sf-sub-indicator, -.rtl a:hover > .sf-sub-indicator, -.rtl a:active > .sf-sub-indicator, -.rtl li:hover > a > .sf-sub-indicator, -.rtl li.sfHover > a > .sf-sub-indicator { - background-position: 0 -100px; /* arrow hovers for modern browsers*/ -} - -/* point right for anchors in subs */ -.rtl .sf-menu ul .sf-sub-indicator { background-position: 0 0; } -.rtl .sf-menu ul a > .sf-sub-indicator { background-position: -10px 0; } -/* apply hovers to modern browsers */ -.rtl .sf-menu ul a:focus > .sf-sub-indicator, -.rtl .sf-menu ul a:hover > .sf-sub-indicator, -.rtl .sf-menu ul a:active > .sf-sub-indicator, -.rtl .sf-menu ul li:hover > a > .sf-sub-indicator, -.rtl .sf-menu ul li.sfHover > a > .sf-sub-indicator { - background-position: 0 0; /* arrow hovers for modern browsers*/ -} - -.rtl .sf-menu li:hover ul, -.rtl .sf-menu li.sfHover ul { - right: 0; - left: auto; -} - -.rtl ul.sf-menu li li:hover ul, -.rtl ul.sf-menu li li.sfHover ul { - right: 12em; /* match ul width */ - left: auto; -} -.rtl ul.sf-menu li li li:hover ul, -.rtl ul.sf-menu li li li.sfHover ul { - right: 12em; /* match ul width */ - left: auto; -} - -/*** shadows for all but IE6 ***/ -.rtl .sf-shadow ul { - background: url('../../../lib/superfish/images/shadow.png') no-repeat bottom left; - padding: 0 0 9px 8px; - border-top-right-radius: 0; - border-bottom-left-radius: 0; - -moz-border-radius-topright: 0; - -moz-border-radius-bottomleft: 0; - -webkit-border-top-right-radius: 0; - -webkit-border-bottom-left-radius: 0; - -moz-border-radius-topleft: 17px; - -moz-border-radius-bottomright: 17px; - -webkit-border-top-left-radius: 17px; - -webkit-border-bottom-right-radius: 17px; - border-top-left-radius: 17px; - border-bottom-right-radius: 17px; -} - -/* RTL ThemeRoller ~~~~~~~~~~~~~~~~~~~~~~~~ */ - -.rtl .ui-dialog .ui-dialog-titlebar { - padding: 0.5em 1em 0.3em 0.3em; -} - -.rtl .ui-dialog .ui-dialog-title { - float: right; -} - -.rtl .ui-dialog .ui-dialog-titlebar-close { - left: 0.3em; - right: auto; -} - -/* RTL paginator ~~~~~~~~~~~~~~~~~~~~~~~~~~ */ - -.rtl .g-paginator .g-info { - width: 35%; -} - -.rtl .g-paginator .g-text-right { - margin-left: 0; -} - -.rtl .g-paginator .ui-icon-seek-end { - background-position: -80px -160px; -} - -.rtl .g-paginator .ui-icon-seek-next { - background-position: -48px -160px; -} - -.rtl .g-paginator .ui-icon-seek-prev { - background-position: -32px -160px; -} - -.rtl .g-paginator .ui-icon-seek-first { - background-position: -64px -160px; -} - -.rtl #g-header #g-login-menu, -.rtl #g-header #g-quick-search-form { - clear: left; - float: left; -} - -.rtl #g-header #g-login-menu li { - margin-left: 0; - padding-left: 0; - padding-right: 1.2em; -} - -.rtl #g-site-menu { - left: auto; - right: 150px; -} - -.rtl #g-view-menu #g-slideshow-link { - background-image: url('../images/ico-view-slideshow-rtl.png'); -} - -.rtl #g-sidebar .g-block-content { - padding-right: 1em; - padding-left: 0; -} - -.rtl #g-footer #g-credits li { - padding-left: 1.2em !important; - padding-right: 0; -} diff --git a/3.1/modules/themeroller/views/theme.info.php b/3.1/modules/themeroller/views/theme.info.php index eb8ead8f..ba061661 100644 --- a/3.1/modules/themeroller/views/theme.info.php +++ b/3.1/modules/themeroller/views/theme.info.php @@ -1,9 +1,12 @@ -name = "" -description = "" +name = for_js() . "\n" ?> +description = for_js() . "\n" ?> version = 1 -author = "" -site = "" -admin = "" +author = for_js() . "\n" ?> +site = +admin = +author_url = for_js() . "\n" ?> +info_url = for_js() . "\n" ?> +discuss_url = for_js() . "\n" ?> ; definition = diff --git a/3.1/modules/twitter/README b/3.1/modules/twitter/README new file mode 100644 index 00000000..e761d4e9 --- /dev/null +++ b/3.1/modules/twitter/README @@ -0,0 +1,22 @@ +ABOUT: +Share photos, movies, and albums on Twitter, directly from Gallery. + +INSTALLATION AND CONFIGURATION: +http://codex.gallery2.org/Gallery3:Modules:twitter + +SUPPORT/BUG REPORTS: +http://gallery.menalto.com/node/100791 + +ROADMAP: +* Display Twitter profile/follow links on Gallery user profile pages. +* Provide "Share on Twitter" for anonymous users. +* Display item (re)tweets. +* Twitter identity provider (log into Gallery with Twitter) + +HISTORY: +2011-03-15 - 1 beta2 +- Allow users to change from one Twitter account to another from their profile page. +- Compose Tweet JavaScript widget fixes to read default options, accept custom widget options. +- Disable the "Tweet" button if the message is over 140 characters. +- Truncate default tweet values longer than 140. +2011-02-15 - 1 beta1 \ No newline at end of file diff --git a/3.1/modules/twitter/controllers/admin_twitter.php b/3.1/modules/twitter/controllers/admin_twitter.php new file mode 100644 index 00000000..7d1400ab --- /dev/null +++ b/3.1/modules/twitter/controllers/admin_twitter.php @@ -0,0 +1,61 @@ +validate()) { + $consumer_key = $form->twitter_oauth->consumer_key->value; + $consumer_secret = $form->twitter_oauth->consumer_secret->value; + $reset_tweet = $form->twitter_message->reset_tweet->value; + if ($reset_tweet) { + $default_tweet = twitter::reset_default_tweet(); + } else { + $default_tweet = $form->twitter_message->default_tweet->value; + } + $shorten_urls = $form->urls->shorten_urls->value; + + module::set_var("twitter", "consumer_key", $consumer_key); + module::set_var("twitter", "consumer_secret", $consumer_secret); + module::set_var("twitter", "default_tweet", $default_tweet); + module::set_var("twitter", "shorten_urls", $shorten_urls); + + message::success("Twitter settings saved"); + url::redirect("admin/twitter"); + } + } + $is_registered = twitter::is_registered(); + + $v = new Admin_View("admin.html"); + $v->page_title = t("Twitter"); + $v->content = new View("admin_twitter.html"); + $v->content->form = $form; + $v->content->is_registered = $is_registered; + + print $v; + } + +} \ No newline at end of file diff --git a/3.1/modules/twitter/controllers/twitter.php b/3.1/modules/twitter/controllers/twitter.php new file mode 100644 index 00000000..8c98b24b --- /dev/null +++ b/3.1/modules/twitter/controllers/twitter.php @@ -0,0 +1,279 @@ +get("twitter_oauth_token"); + $oauth_token_secret = Session::instance()->get("twitter_oauth_token_secret"); + $item_url = Session::instance()->get("twitter_item_redirect"); + + // If the oauth_token is old redirect to the connect page + if (isset($_REQUEST['oauth_token']) && $oauth_token !== $_REQUEST['oauth_token']) { + Session::instance()->set("twitter_oauth_status", "old_token"); + $this->_clear_session(); + url::redirect(url::site("twitter/redirect")); + } + + // Create TwitteroAuth object with app key/secret and token key/secret from default phase + $connection = new TwitterOAuth($consumer_key, $consumer_secret, $oauth_token, $oauth_token_secret); + + // Request access tokens from twitter + $access_token = $connection->getAccessToken($_REQUEST['oauth_verifier']); + + // Save the access tokens + Session::instance()->set("twitter_access_token", $access_token); + + // Remove no longer needed request tokens + Session::instance()->delete("twitter_oauth_token"); + Session::instance()->delete("twitter_oauth_token_secret"); + + // If HTTP response is 200 continue otherwise send to connect page to retry + if (200 == $connection->http_code) { + $this->_save_user($access_token); + $item = ORM::factory("item", $item_id); + url::redirect(url::abs_site($item_url)); + } else { + log::error("content", "Twitter", "Unable to retrieve user access token: " . $connection->http_code); + $this->_clear_session(); + url::redirect(url::site("twitter/redirect")); + } + } + + /** + * Display Twitter status dialog. + * @param int $item_id + */ + public function dialog($item_id) { + $item = ORM::factory("item", $item_id); + $form = twitter::get_tweet_form($item); + + // Ensure user has permission + access::required("view", $item); + + $user_id = identity::active_user()->id; + $token_is_set = $this->_is_token_set($user_id); + + $v = new View("twitter_dialog.html"); + $v->is_registered = twitter::is_registered(); + $v->user_token_set = $token_is_set; + + if ($token_is_set) { + $v->type = $item->type; + $v->title = $item->title; + $v->description = $item->description; + $v->form = $form; + $v->character_count = twitter::$character_count; + } else { + $item_url = urlencode(url::abs_site($item->relative_url_cache)); + $v->user_id = $user_id; + $v->twitter_auth_url = url::site("twitter/redirect?item_url=$item_url"); + } + print $v; + } + + /** + * Redirect user to Twitter authorization page. + */ + public function redirect() { + require_once(MODPATH . "twitter/vendor/twitteroauth/twitteroauth.php"); + + $consumer_key = module::get_var("twitter", "consumer_key"); + $consumer_secret = module::get_var("twitter", "consumer_secret"); + $oauth_callback = url::abs_site("twitter/callback"); + + // We'll want this after Twitter kicks back to our callback + if (!empty($_GET['item_url'])) { + Session::instance()->set("twitter_item_redirect", $_GET['item_url']); + } + + // Build TwitterOAuth object with client credentials + $connection = new TwitterOAuth($consumer_key, $consumer_secret); + + // Get temporary credentials. + $request_token = $connection->getRequestToken($oauth_callback); + + // Save temporary credentials to session. + Session::instance()->set("twitter_oauth_token", $request_token['oauth_token']); + Session::instance()->set("twitter_oauth_token_secret", $request_token['oauth_token_secret']); + + // If last connection failed don't display authorization link + if (200 == $connection->http_code) { + // Build authorize URL and redirect user to Twitter + $url = $connection->getAuthorizeURL($request_token["oauth_token"]); + url::redirect($url); + } else { + // Show notification if something went wrong + message::success(t("Could not connect to Twitter. Refresh the page or try again later.")); + url::redirect(urldecode($_GET['item_url'])); + } + } + + /** + * Reset a user's Twitter OAuth access token + * @param int $user_id + */ + public function reset($user_id) { + if (identity::active_user()->id == $user_id) { + $u = ORM::factory("twitter_user")->where("user_id", "=", $user_id)->find(); + if ($u->loaded()) { + $u->oauth_token = ""; + $u->oauth_token_secret = ""; + $u->twitter_user_id = ""; + $u->screen_name = ""; + $u->save(); + message::success(t("Your Twitter access token has been reset.")); + Session::instance()->set("twitter_item_redirect", + url::abs_site("user_profile/show/{$user_id}")); + url::redirect("twitter/redirect"); + } + } + } + + /** + * Post a status update to Twitter + * @param int $item_id + */ + public function tweet($item_id) { + access::verify_csrf(); + + $item = ORM::factory("item", $item_id); + $form = twitter::get_tweet_form($item); + + if ($form->validate()) { + $item_url = url::abs_site($item->relative_url_cache); + $user = $this->_get_twitter_user(identity::active_user()->id); + $consumer_key = module::get_var("twitter", "consumer_key"); + $consumer_secret = module::get_var("twitter", "consumer_secret"); + + require_once(MODPATH . "twitter/vendor/twitteroauth/twitteroauth.php"); + + $connection = new TwitterOAuth( + $consumer_key, + $consumer_secret, + $user->oauth_token, + $user->oauth_token_secret); + + $message = $form->twitter_message->tweet->value; + $response = $connection->post('statuses/update', array('status' => $message)); + + if (200 == $connection->http_code) { + message::success(t("Tweet sent!")); + json::reply(array("result" => "success", "location" => $item->url())); + } else { + message::error(t("Unable to send, your Tweet has been saved. Please try again later.")); + log::error("content", "Twitter", t("Unable to send tweet: %http_code", + array("http_code" => $connection->http_code))); + json::reply(array("result" => "success", "location" => $item->url())); + } + $tweet->item_id = $item_id; + (!empty($response->id)) ? $tweet->twitter_id = $response->id : $tweet->twitter_id = NULL; + $tweet->tweet = $message; + $tweet->id = $form->twitter_message->tweet_id->value; + $this->_save_tweet($tweet); + + } else { + json::reply(array("result" => "error", "html" => (string)$form)); + } + } + + /** + * Clear Twitter module session variables + */ + private function _clear_session() { + Session::instance()->delete("twitter_oauth_token"); + Session::instance()->delete("twitter_oauth_token_secret"); + Session::instance()->delete("twitter_access_token"); + } + + /** + * Get Twitter credentials for the current user. + * @param int $user_id + * @return mixed object|false + */ + private function _get_twitter_user($user_id) { + $twitter_user = ORM::factory("twitter_user")->where("user_id", "=", $user_id)->find(); + if ($twitter_user->loaded()) { + return $twitter_user; + } + return false; + } + + /** + * Check if current user's Twitter credentials have been stored locally. + * @param int $user_id + * @return boolean + */ + private function _is_token_set($user_id) { + $twitter_user = $this->_get_twitter_user($user_id); + if (!empty($twitter_user->oauth_token) && !empty($twitter_user->oauth_token_secret)) { + return true; + } + return false; + } + + /** + * Save new tweets + * @param object $tweet + */ + private function _save_tweet($tweet) { + if (!empty($tweet->item_id) && !empty($tweet->tweet)) { + if ($tweet->id > 0) { + $t = ORM::factory("twitter_tweet")->where("id", "=", $tweet->id)->find(); + } else { + $t = ORM::factory("twitter_tweet"); + } + $t->item_id = $tweet->item_id; + $t->twitter_id = $tweet->twitter_id; + $t->tweet = $tweet->tweet; + $t->sent = (!empty($tweet->twitter_id)) ? time() : NULL; + $t->user_id = identity::active_user()->id; + $t->save(); + } + } + + /** + * Save or update the current user's Twitter credentials. + * @param array $access_token + */ + private function _save_user($access_token) { + $u = ORM::factory("twitter_user") + ->where("user_id", "=", identity::active_user()->id) + ->find(); + if (!$u->loaded()) { + $u = ORM::factory("twitter_user"); + } + $u->oauth_token = $access_token["oauth_token"]; + $u->oauth_token_secret = $access_token["oauth_token_secret"]; + $u->twitter_user_id = $access_token["user_id"]; + $u->screen_name = $access_token["screen_name"]; + $u->user_id = identity::active_user()->id; + $u->save(); + message::success(t("Success! You may now share Gallery items on Twitter.")); + } + +} diff --git a/3.1/modules/twitter/css/twitter.css b/3.1/modules/twitter/css/twitter.css new file mode 100644 index 00000000..8bb82ccf --- /dev/null +++ b/3.1/modules/twitter/css/twitter.css @@ -0,0 +1,5 @@ +#g-twitter-character-count { + float: right; + font-size: 1.4em; + font-weight: bold; +} diff --git a/3.1/modules/twitter/helpers/twitter.php b/3.1/modules/twitter/helpers/twitter.php new file mode 100644 index 00000000..190ad177 --- /dev/null +++ b/3.1/modules/twitter/helpers/twitter.php @@ -0,0 +1,152 @@ + "g-configure-twitter-form")); + + $group_oauth = $form->group("twitter_oauth")->label(t("OAuth Settings")); + $group_oauth->input("consumer_key") + ->label(t("Consumer key")) + ->value(module::get_var("twitter", "consumer_key")); + $group_oauth->input("consumer_secret") + ->label(t("Consumer secret")) + ->value(module::get_var("twitter", "consumer_secret")); + + $group_tweet = $form->group("twitter_message")->label(t("Default Tweet")); + $group_tweet->input("default_tweet") + ->label(t("Default Tweet")) + ->value(module::get_var("twitter", "default_tweet")); + $group_tweet->checkbox("reset_tweet") + ->label(t("Reset to default on save")) + ->value(1); + + if (module::is_active("bitly")) { + $group_url = $form->group("urls")->label(t("Shorten URLs")); + $group_url->checkbox("shorten_urls") + ->label(t("Shorten URLs automatically with bit.ly")) + ->checked(module::get_var("twitter", "shorten_urls")); + } + $form->submit("")->value(t("Save")); + return $form; + } + + /** + * Get tweet form + * @param object $item + * @return Forge + */ + static function get_tweet_form($item) { + $long_url = url::abs_site($item->relative_url_cache); + // Check for saved tweets for this user and item + $saved = self::get_failed($item->id); + if ($saved) { + $default_tweet = $saved->tweet; + $tweet_id = $saved->id; + } else { + $default_tweet = module::get_var("twitter", "default_tweet"); + $tweet_id = 0; + } + $tweet = preg_replace("/%type/", $item->type, $default_tweet); + $tweet = preg_replace("/%title/", $item->title, $tweet); + $tweet = preg_replace("/%description/", $item->description, $tweet); + // If bit.ly module's enabled, get the item's URL and shorten it + if (!empty($item->id) && module::is_active("bitly") + && module::get_var("twitter", "shorten_urls")) { + $url = bitly::shorten_url($item->id); + } else { + $url = url::abs_site($item->relative_url_cache); + } + + // Truncate the default tweet if it's too long + $url_length = strlen($url) + 1; + $tweet_length = strlen($tweet); + + if (($tweet_length + $url_length) > self::$character_count) { + $trim_pos = 0 - (($tweet_length + $url_length) - 140); + $tweet = substr($tweet, 0, $trim_pos); + } + $tweet = $tweet . ' ' . $url; + + $form = new Forge("twitter/tweet/$item->id", "", "post", array("id" => "g-twitter-tweet-form")); + $group = $form->group("twitter_message")->label(t("Compose Tweet")); + $group->textarea("tweet") + ->value($tweet) + ->rules("required") + ->error_messages("required", t("Your tweet cannot be empty!")) + ->id("g-tweet"); + $group->hidden("tweet_id")->value($tweet_id)->id("tweet_id"); + $form->submit("")->value(t("Tweet")); + return $form; + } + + /** + * Get the most recent failed tweet for an item + * @param integer $item_id + * @return mixed object|false + */ + function get_failed($item_id) { + $user_id = identity::active_user()->id; + $t = ORM::factory("twitter_tweet") + ->where("item_id", "=", $item_id) + ->where("user_id", "=", $user_id) + ->where("twitter_id", "IS", NULL) + ->find(); + if ($t->loaded()) { + return $t; + } else { + return false; + } + } + + /** + * Has this Gallery been registered at dev.twitter.com/app? + * @return boolean + */ + static function is_registered() { + $consumer_key = module::get_var("twitter", "consumer_key"); + $consumer_secret = module::get_var("twitter", "consumer_secret"); + if (empty($consumer_key) || empty($consumer_secret)) { + site_status::warning( + t("Twitter module requires attention! Set the consumer key and secret.", + array("url" => html::mark_clean(url::site("admin/twitter")))), + "twitter_config"); + return false; + } else { + site_status::clear("twitter_config"); + return true; + } + } + + static function reset_default_tweet() { + return t("Check out this %type, '%title': %description"); + } + +} diff --git a/3.1/modules/twitter/helpers/twitter_event.php b/3.1/modules/twitter/helpers/twitter_event.php new file mode 100644 index 00000000..72001d3b --- /dev/null +++ b/3.1/modules/twitter/helpers/twitter_event.php @@ -0,0 +1,85 @@ +get("settings_menu") + ->append(Menu::factory("link") + ->id("twitter_menu") + ->label(t("Twitter")) + ->url(url::site("admin/twitter"))); + } + + static function site_menu($menu, $theme) { + $item = $theme->item(); + if ($item && twitter::is_registered() && (identity::active_user()->id > 1)) { + $menu->get("options_menu") + ->append(Menu::factory("dialog") + ->id("twitter") + ->label(t("Share on Twitter")) + ->css_id("g-twitter-link") + ->url(url::site("twitter/dialog/{$item->id}"))); + } + } + + static function context_menu($menu, $theme, $item) { + if ((identity::active_user()->id > 1) && twitter::is_registered()) { + $menu->get("options_menu") + ->append(Menu::factory("dialog") + ->id("twitter") + ->label(t("Share on Twitter")) + ->css_class("ui-icon-link g-twitter-share") + ->url(url::site("twitter/dialog/{$item->id}"))); + } + } + + /** + * Add Twitter account info to user profiles + * @param object $data + */ + static function show_user_profile($data) { + $twitter_account = ORM::factory("twitter_user")->where("user_id", "=", $data->user->id)->find(); + if ($twitter_account->loaded()) { + $v = new View("user_profile_info.html"); + $v->user_profile_data = array(); + $fields = array( + "screen_name" => t("Screen name") + ); + foreach ($fields as $field => $label) { + if (!empty($twitter_account->$field)) { + $value = $twitter_account->$field; + if ($field == "screen_name") { + $value = html::mark_clean(html::anchor(twitter::$url . + $twitter_account->screen_name, + "@{$twitter_account->screen_name}")); + } + $v->user_profile_data[(string) $label] = $value; + } + } + if (identity::active_user()->id == $data->user->id) { + $button = html::mark_clean(html::anchor(url::site("twitter/reset/" + . $data->user->id), t("Switch to another Twitter screen name"))); + $v->user_profile_data[""] = $button; + } + $data->content[] = (object) array("title" => t("Twitter account"), "view" => $v); + } + } + +} diff --git a/3.1/modules/twitter/helpers/twitter_installer.php b/3.1/modules/twitter/helpers/twitter_installer.php new file mode 100644 index 00000000..58016a08 --- /dev/null +++ b/3.1/modules/twitter/helpers/twitter_installer.php @@ -0,0 +1,50 @@ +query("CREATE TABLE {twitter_tweets} ( + `id` int(9) NOT NULL AUTO_INCREMENT, + `item_id` int(9) NOT NULL, + `sent` int(9) NULL, + `twitter_id` decimal(20,0) NULL, + `tweet` varchar(255) NOT NULL, + `user_id` int(9) NOT NULL, + PRIMARY KEY (`id`)) + DEFAULT CHARSET=utf8;"); + Database::instance() + ->query("CREATE TABLE {twitter_users} ( + `id` int(9) NOT NULL AUTO_INCREMENT, + `oauth_token` varchar(64) NOT NULL, + `oauth_token_secret` varchar(64) NOT NULL, + `screen_name` varchar(16) NOT NULL, + `twitter_user_id` int(9) NOT NULL, + `user_id` int(9) NOT NULL, + PRIMARY KEY (`id`)) + DEFAULT CHARSET=utf8;"); + module::set_version("twitter", 1); + twitter::reset_default_tweet(); + } + + static function deactivate() { + site_status::clear("twitter_config"); + } +} diff --git a/3.1/modules/twitter/helpers/twitter_theme.php b/3.1/modules/twitter/helpers/twitter_theme.php new file mode 100644 index 00000000..2862966d --- /dev/null +++ b/3.1/modules/twitter/helpers/twitter_theme.php @@ -0,0 +1,25 @@ +script("twitter.js"); + $theme->css("twitter.css"); + } +} diff --git a/3.1/modules/twitter/js/twitter.js b/3.1/modules/twitter/js/twitter.js new file mode 100644 index 00000000..e44539d8 --- /dev/null +++ b/3.1/modules/twitter/js/twitter.js @@ -0,0 +1,49 @@ +/** + * @todo Add shorten/expand urls toggle button + */ +(function($) { + $.widget("ui.gallery_twitter", { + + _init: function() { + var self = this; + this._set_count(); + this.element.keyup(function(event) { + self._set_count(event.currentTarget); + return false; + }); + }, + + _set_count: function() { + var self = this; + var character_array = $("#g-tweet").val().split(""); + var count = character_array.length; + var remaining = self.options.max_count - count; + var count_container = $("#g-twitter-character-count"); + var color = "#000000"; + if (remaining < 10) { + color = self.options.error_color; + } else if (remaining < 20) { + color = self.options.warn_color; + } + if (remaining < 0) { + $("#g-dialog form :submit").addClass("ui-state-disabled") + .attr("disabled", "disabled"); + } else { + $("#g-dialog form :submit").removeClass("ui-state-disabled") + .attr("disabled", null); + } + $(count_container).css("color", color); + $(count_container).html(remaining); + } + + }); + + $.extend($.ui.gallery_twitter, { + defaults: { + max_count: 140, + warn_color: "#7F0005", + error_color: "#FF0000" + } + }); + +})(jQuery); diff --git a/3.1/modules/twitter/models/twitter_tweet.php b/3.1/modules/twitter/models/twitter_tweet.php new file mode 100644 index 00000000..9a616cfd --- /dev/null +++ b/3.1/modules/twitter/models/twitter_tweet.php @@ -0,0 +1,21 @@ +key = $key; + $this->secret = $secret; + $this->callback_url = $callback_url; + } + + function __toString() { + return "OAuthConsumer[key=$this->key,secret=$this->secret]"; + } +} + +class OAuthToken { + // access tokens and request tokens + public $key; + public $secret; + + /** + * key = the token + * secret = the token secret + */ + function __construct($key, $secret) { + $this->key = $key; + $this->secret = $secret; + } + + /** + * generates the basic string serialization of a token that a server + * would respond to request_token and access_token calls with + */ + function to_string() { + return "oauth_token=" . + OAuthUtil::urlencode_rfc3986($this->key) . + "&oauth_token_secret=" . + OAuthUtil::urlencode_rfc3986($this->secret); + } + + function __toString() { + return $this->to_string(); + } +} + +/** + * A class for implementing a Signature Method + * See section 9 ("Signing Requests") in the spec + */ +abstract class OAuthSignatureMethod { + /** + * Needs to return the name of the Signature Method (ie HMAC-SHA1) + * @return string + */ + abstract public function get_name(); + + /** + * Build up the signature + * NOTE: The output of this function MUST NOT be urlencoded. + * the encoding is handled in OAuthRequest when the final + * request is serialized + * @param OAuthRequest $request + * @param OAuthConsumer $consumer + * @param OAuthToken $token + * @return string + */ + abstract public function build_signature($request, $consumer, $token); + + /** + * Verifies that a given signature is correct + * @param OAuthRequest $request + * @param OAuthConsumer $consumer + * @param OAuthToken $token + * @param string $signature + * @return bool + */ + public function check_signature($request, $consumer, $token, $signature) { + $built = $this->build_signature($request, $consumer, $token); + return $built == $signature; + } +} + +/** + * The HMAC-SHA1 signature method uses the HMAC-SHA1 signature algorithm as defined in [RFC2104] + * where the Signature Base String is the text and the key is the concatenated values (each first + * encoded per Parameter Encoding) of the Consumer Secret and Token Secret, separated by an '&' + * character (ASCII code 38) even if empty. + * - Chapter 9.2 ("HMAC-SHA1") + */ +class OAuthSignatureMethod_HMAC_SHA1 extends OAuthSignatureMethod { + function get_name() { + return "HMAC-SHA1"; + } + + public function build_signature($request, $consumer, $token) { + $base_string = $request->get_signature_base_string(); + $request->base_string = $base_string; + + $key_parts = array( + $consumer->secret, + ($token) ? $token->secret : "" + ); + + $key_parts = OAuthUtil::urlencode_rfc3986($key_parts); + $key = implode('&', $key_parts); + + return base64_encode(hash_hmac('sha1', $base_string, $key, true)); + } +} + +/** + * The PLAINTEXT method does not provide any security protection and SHOULD only be used + * over a secure channel such as HTTPS. It does not use the Signature Base String. + * - Chapter 9.4 ("PLAINTEXT") + */ +class OAuthSignatureMethod_PLAINTEXT extends OAuthSignatureMethod { + public function get_name() { + return "PLAINTEXT"; + } + + /** + * oauth_signature is set to the concatenated encoded values of the Consumer Secret and + * Token Secret, separated by a '&' character (ASCII code 38), even if either secret is + * empty. The result MUST be encoded again. + * - Chapter 9.4.1 ("Generating Signatures") + * + * Please note that the second encoding MUST NOT happen in the SignatureMethod, as + * OAuthRequest handles this! + */ + public function build_signature($request, $consumer, $token) { + $key_parts = array( + $consumer->secret, + ($token) ? $token->secret : "" + ); + + $key_parts = OAuthUtil::urlencode_rfc3986($key_parts); + $key = implode('&', $key_parts); + $request->base_string = $key; + + return $key; + } +} + +/** + * The RSA-SHA1 signature method uses the RSASSA-PKCS1-v1_5 signature algorithm as defined in + * [RFC3447] section 8.2 (more simply known as PKCS#1), using SHA-1 as the hash function for + * EMSA-PKCS1-v1_5. It is assumed that the Consumer has provided its RSA public key in a + * verified way to the Service Provider, in a manner which is beyond the scope of this + * specification. + * - Chapter 9.3 ("RSA-SHA1") + */ +abstract class OAuthSignatureMethod_RSA_SHA1 extends OAuthSignatureMethod { + public function get_name() { + return "RSA-SHA1"; + } + + // Up to the SP to implement this lookup of keys. Possible ideas are: + // (1) do a lookup in a table of trusted certs keyed off of consumer + // (2) fetch via http using a url provided by the requester + // (3) some sort of specific discovery code based on request + // + // Either way should return a string representation of the certificate + protected abstract function fetch_public_cert(&$request); + + // Up to the SP to implement this lookup of keys. Possible ideas are: + // (1) do a lookup in a table of trusted certs keyed off of consumer + // + // Either way should return a string representation of the certificate + protected abstract function fetch_private_cert(&$request); + + public function build_signature($request, $consumer, $token) { + $base_string = $request->get_signature_base_string(); + $request->base_string = $base_string; + + // Fetch the private key cert based on the request + $cert = $this->fetch_private_cert($request); + + // Pull the private key ID from the certificate + $privatekeyid = openssl_get_privatekey($cert); + + // Sign using the key + $ok = openssl_sign($base_string, $signature, $privatekeyid); + + // Release the key resource + openssl_free_key($privatekeyid); + + return base64_encode($signature); + } + + public function check_signature($request, $consumer, $token, $signature) { + $decoded_sig = base64_decode($signature); + + $base_string = $request->get_signature_base_string(); + + // Fetch the public key cert based on the request + $cert = $this->fetch_public_cert($request); + + // Pull the public key ID from the certificate + $publickeyid = openssl_get_publickey($cert); + + // Check the computed signature against the one passed in the query + $ok = openssl_verify($base_string, $decoded_sig, $publickeyid); + + // Release the key resource + openssl_free_key($publickeyid); + + return $ok == 1; + } +} + +class OAuthRequest { + private $parameters; + private $http_method; + private $http_url; + // for debug purposes + public $base_string; + public static $version = '1.0'; + public static $POST_INPUT = 'php://input'; + + function __construct($http_method, $http_url, $parameters=NULL) { + @$parameters or $parameters = array(); + $parameters = array_merge( OAuthUtil::parse_parameters(parse_url($http_url, PHP_URL_QUERY)), $parameters); + $this->parameters = $parameters; + $this->http_method = $http_method; + $this->http_url = $http_url; + } + + + /** + * attempt to build up a request from what was passed to the server + */ + public static function from_request($http_method=NULL, $http_url=NULL, $parameters=NULL) { + $scheme = (!isset($_SERVER['HTTPS']) || $_SERVER['HTTPS'] != "on") + ? 'http' + : 'https'; + @$http_url or $http_url = $scheme . + '://' . $_SERVER['HTTP_HOST'] . + ':' . + $_SERVER['SERVER_PORT'] . + $_SERVER['REQUEST_URI']; + @$http_method or $http_method = $_SERVER['REQUEST_METHOD']; + + // We weren't handed any parameters, so let's find the ones relevant to + // this request. + // If you run XML-RPC or similar you should use this to provide your own + // parsed parameter-list + if (!$parameters) { + // Find request headers + $request_headers = OAuthUtil::get_headers(); + + // Parse the query-string to find GET parameters + $parameters = OAuthUtil::parse_parameters($_SERVER['QUERY_STRING']); + + // It's a POST request of the proper content-type, so parse POST + // parameters and add those overriding any duplicates from GET + if ($http_method == "POST" + && @strstr($request_headers["Content-Type"], + "application/x-www-form-urlencoded") + ) { + $post_data = OAuthUtil::parse_parameters( + file_get_contents(self::$POST_INPUT) + ); + $parameters = array_merge($parameters, $post_data); + } + + // We have a Authorization-header with OAuth data. Parse the header + // and add those overriding any duplicates from GET or POST + if (@substr($request_headers['Authorization'], 0, 6) == "OAuth ") { + $header_parameters = OAuthUtil::split_header( + $request_headers['Authorization'] + ); + $parameters = array_merge($parameters, $header_parameters); + } + + } + + return new OAuthRequest($http_method, $http_url, $parameters); + } + + /** + * pretty much a helper function to set up the request + */ + public static function from_consumer_and_token($consumer, $token, $http_method, $http_url, $parameters=NULL) { + @$parameters or $parameters = array(); + $defaults = array("oauth_version" => OAuthRequest::$version, + "oauth_nonce" => OAuthRequest::generate_nonce(), + "oauth_timestamp" => OAuthRequest::generate_timestamp(), + "oauth_consumer_key" => $consumer->key); + if ($token) + $defaults['oauth_token'] = $token->key; + + $parameters = array_merge($defaults, $parameters); + + return new OAuthRequest($http_method, $http_url, $parameters); + } + + public function set_parameter($name, $value, $allow_duplicates = true) { + if ($allow_duplicates && isset($this->parameters[$name])) { + // We have already added parameter(s) with this name, so add to the list + if (is_scalar($this->parameters[$name])) { + // This is the first duplicate, so transform scalar (string) + // into an array so we can add the duplicates + $this->parameters[$name] = array($this->parameters[$name]); + } + + $this->parameters[$name][] = $value; + } else { + $this->parameters[$name] = $value; + } + } + + public function get_parameter($name) { + return isset($this->parameters[$name]) ? $this->parameters[$name] : null; + } + + public function get_parameters() { + return $this->parameters; + } + + public function unset_parameter($name) { + unset($this->parameters[$name]); + } + + /** + * The request parameters, sorted and concatenated into a normalized string. + * @return string + */ + public function get_signable_parameters() { + // Grab all parameters + $params = $this->parameters; + + // Remove oauth_signature if present + // Ref: Spec: 9.1.1 ("The oauth_signature parameter MUST be excluded.") + if (isset($params['oauth_signature'])) { + unset($params['oauth_signature']); + } + + return OAuthUtil::build_http_query($params); + } + + /** + * Returns the base string of this request + * + * The base string defined as the method, the url + * and the parameters (normalized), each urlencoded + * and the concated with &. + */ + public function get_signature_base_string() { + $parts = array( + $this->get_normalized_http_method(), + $this->get_normalized_http_url(), + $this->get_signable_parameters() + ); + + $parts = OAuthUtil::urlencode_rfc3986($parts); + + return implode('&', $parts); + } + + /** + * just uppercases the http method + */ + public function get_normalized_http_method() { + return strtoupper($this->http_method); + } + + /** + * parses the url and rebuilds it to be + * scheme://host/path + */ + public function get_normalized_http_url() { + $parts = parse_url($this->http_url); + + $port = @$parts['port']; + $scheme = $parts['scheme']; + $host = $parts['host']; + $path = @$parts['path']; + + $port or $port = ($scheme == 'https') ? '443' : '80'; + + if (($scheme == 'https' && $port != '443') + || ($scheme == 'http' && $port != '80')) { + $host = "$host:$port"; + } + return "$scheme://$host$path"; + } + + /** + * builds a url usable for a GET request + */ + public function to_url() { + $post_data = $this->to_postdata(); + $out = $this->get_normalized_http_url(); + if ($post_data) { + $out .= '?'.$post_data; + } + return $out; + } + + /** + * builds the data one would send in a POST request + */ + public function to_postdata() { + return OAuthUtil::build_http_query($this->parameters); + } + + /** + * builds the Authorization: header + */ + public function to_header($realm=null) { + $first = true; + if($realm) { + $out = 'Authorization: OAuth realm="' . OAuthUtil::urlencode_rfc3986($realm) . '"'; + $first = false; + } else + $out = 'Authorization: OAuth'; + + $total = array(); + foreach ($this->parameters as $k => $v) { + if (substr($k, 0, 5) != "oauth") continue; + if (is_array($v)) { + throw new OAuthException('Arrays not supported in headers'); + } + $out .= ($first) ? ' ' : ','; + $out .= OAuthUtil::urlencode_rfc3986($k) . + '="' . + OAuthUtil::urlencode_rfc3986($v) . + '"'; + $first = false; + } + return $out; + } + + public function __toString() { + return $this->to_url(); + } + + + public function sign_request($signature_method, $consumer, $token) { + $this->set_parameter( + "oauth_signature_method", + $signature_method->get_name(), + false + ); + $signature = $this->build_signature($signature_method, $consumer, $token); + $this->set_parameter("oauth_signature", $signature, false); + } + + public function build_signature($signature_method, $consumer, $token) { + $signature = $signature_method->build_signature($this, $consumer, $token); + return $signature; + } + + /** + * util function: current timestamp + */ + private static function generate_timestamp() { + return time(); + } + + /** + * util function: current nonce + */ + private static function generate_nonce() { + $mt = microtime(); + $rand = mt_rand(); + + return md5($mt . $rand); // md5s look nicer than numbers + } +} + +class OAuthServer { + protected $timestamp_threshold = 300; // in seconds, five minutes + protected $version = '1.0'; // hi blaine + protected $signature_methods = array(); + + protected $data_store; + + function __construct($data_store) { + $this->data_store = $data_store; + } + + public function add_signature_method($signature_method) { + $this->signature_methods[$signature_method->get_name()] = + $signature_method; + } + + // high level functions + + /** + * process a request_token request + * returns the request token on success + */ + public function fetch_request_token(&$request) { + $this->get_version($request); + + $consumer = $this->get_consumer($request); + + // no token required for the initial token request + $token = NULL; + + $this->check_signature($request, $consumer, $token); + + // Rev A change + $callback = $request->get_parameter('oauth_callback'); + $new_token = $this->data_store->new_request_token($consumer, $callback); + + return $new_token; + } + + /** + * process an access_token request + * returns the access token on success + */ + public function fetch_access_token(&$request) { + $this->get_version($request); + + $consumer = $this->get_consumer($request); + + // requires authorized request token + $token = $this->get_token($request, $consumer, "request"); + + $this->check_signature($request, $consumer, $token); + + // Rev A change + $verifier = $request->get_parameter('oauth_verifier'); + $new_token = $this->data_store->new_access_token($token, $consumer, $verifier); + + return $new_token; + } + + /** + * verify an api call, checks all the parameters + */ + public function verify_request(&$request) { + $this->get_version($request); + $consumer = $this->get_consumer($request); + $token = $this->get_token($request, $consumer, "access"); + $this->check_signature($request, $consumer, $token); + return array($consumer, $token); + } + + // Internals from here + /** + * version 1 + */ + private function get_version(&$request) { + $version = $request->get_parameter("oauth_version"); + if (!$version) { + // Service Providers MUST assume the protocol version to be 1.0 if this parameter is not present. + // Chapter 7.0 ("Accessing Protected Ressources") + $version = '1.0'; + } + if ($version !== $this->version) { + throw new OAuthException("OAuth version '$version' not supported"); + } + return $version; + } + + /** + * figure out the signature with some defaults + */ + private function get_signature_method(&$request) { + $signature_method = + @$request->get_parameter("oauth_signature_method"); + + if (!$signature_method) { + // According to chapter 7 ("Accessing Protected Ressources") the signature-method + // parameter is required, and we can't just fallback to PLAINTEXT + throw new OAuthException('No signature method parameter. This parameter is required'); + } + + if (!in_array($signature_method, + array_keys($this->signature_methods))) { + throw new OAuthException( + "Signature method '$signature_method' not supported " . + "try one of the following: " . + implode(", ", array_keys($this->signature_methods)) + ); + } + return $this->signature_methods[$signature_method]; + } + + /** + * try to find the consumer for the provided request's consumer key + */ + private function get_consumer(&$request) { + $consumer_key = @$request->get_parameter("oauth_consumer_key"); + if (!$consumer_key) { + throw new OAuthException("Invalid consumer key"); + } + + $consumer = $this->data_store->lookup_consumer($consumer_key); + if (!$consumer) { + throw new OAuthException("Invalid consumer"); + } + + return $consumer; + } + + /** + * try to find the token for the provided request's token key + */ + private function get_token(&$request, $consumer, $token_type="access") { + $token_field = @$request->get_parameter('oauth_token'); + $token = $this->data_store->lookup_token( + $consumer, $token_type, $token_field + ); + if (!$token) { + throw new OAuthException("Invalid $token_type token: $token_field"); + } + return $token; + } + + /** + * all-in-one function to check the signature on a request + * should guess the signature method appropriately + */ + private function check_signature(&$request, $consumer, $token) { + // this should probably be in a different method + $timestamp = @$request->get_parameter('oauth_timestamp'); + $nonce = @$request->get_parameter('oauth_nonce'); + + $this->check_timestamp($timestamp); + $this->check_nonce($consumer, $token, $nonce, $timestamp); + + $signature_method = $this->get_signature_method($request); + + $signature = $request->get_parameter('oauth_signature'); + $valid_sig = $signature_method->check_signature( + $request, + $consumer, + $token, + $signature + ); + + if (!$valid_sig) { + throw new OAuthException("Invalid signature"); + } + } + + /** + * check that the timestamp is new enough + */ + private function check_timestamp($timestamp) { + if( ! $timestamp ) + throw new OAuthException( + 'Missing timestamp parameter. The parameter is required' + ); + + // verify that timestamp is recentish + $now = time(); + if (abs($now - $timestamp) > $this->timestamp_threshold) { + throw new OAuthException( + "Expired timestamp, yours $timestamp, ours $now" + ); + } + } + + /** + * check that the nonce is not repeated + */ + private function check_nonce($consumer, $token, $nonce, $timestamp) { + if( ! $nonce ) + throw new OAuthException( + 'Missing nonce parameter. The parameter is required' + ); + + // verify that the nonce is uniqueish + $found = $this->data_store->lookup_nonce( + $consumer, + $token, + $nonce, + $timestamp + ); + if ($found) { + throw new OAuthException("Nonce already used: $nonce"); + } + } + +} + +class OAuthDataStore { + function lookup_consumer($consumer_key) { + // implement me + } + + function lookup_token($consumer, $token_type, $token) { + // implement me + } + + function lookup_nonce($consumer, $token, $nonce, $timestamp) { + // implement me + } + + function new_request_token($consumer, $callback = null) { + // return a new token attached to this consumer + } + + function new_access_token($token, $consumer, $verifier = null) { + // return a new access token attached to this consumer + // for the user associated with this token if the request token + // is authorized + // should also invalidate the request token + } + +} + +class OAuthUtil { + public static function urlencode_rfc3986($input) { + if (is_array($input)) { + return array_map(array('OAuthUtil', 'urlencode_rfc3986'), $input); + } else if (is_scalar($input)) { + return str_replace( + '+', + ' ', + str_replace('%7E', '~', rawurlencode($input)) + ); + } else { + return ''; + } +} + + + // This decode function isn't taking into consideration the above + // modifications to the encoding process. However, this method doesn't + // seem to be used anywhere so leaving it as is. + public static function urldecode_rfc3986($string) { + return urldecode($string); + } + + // Utility function for turning the Authorization: header into + // parameters, has to do some unescaping + // Can filter out any non-oauth parameters if needed (default behaviour) + public static function split_header($header, $only_allow_oauth_parameters = true) { + $pattern = '/(([-_a-z]*)=("([^"]*)"|([^,]*)),?)/'; + $offset = 0; + $params = array(); + while (preg_match($pattern, $header, $matches, PREG_OFFSET_CAPTURE, $offset) > 0) { + $match = $matches[0]; + $header_name = $matches[2][0]; + $header_content = (isset($matches[5])) ? $matches[5][0] : $matches[4][0]; + if (preg_match('/^oauth_/', $header_name) || !$only_allow_oauth_parameters) { + $params[$header_name] = OAuthUtil::urldecode_rfc3986($header_content); + } + $offset = $match[1] + strlen($match[0]); + } + + if (isset($params['realm'])) { + unset($params['realm']); + } + + return $params; + } + + // helper to try to sort out headers for people who aren't running apache + public static function get_headers() { + if (function_exists('apache_request_headers')) { + // we need this to get the actual Authorization: header + // because apache tends to tell us it doesn't exist + $headers = apache_request_headers(); + + // sanitize the output of apache_request_headers because + // we always want the keys to be Cased-Like-This and arh() + // returns the headers in the same case as they are in the + // request + $out = array(); + foreach( $headers AS $key => $value ) { + $key = str_replace( + " ", + "-", + ucwords(strtolower(str_replace("-", " ", $key))) + ); + $out[$key] = $value; + } + } else { + // otherwise we don't have apache and are just going to have to hope + // that $_SERVER actually contains what we need + $out = array(); + if( isset($_SERVER['CONTENT_TYPE']) ) + $out['Content-Type'] = $_SERVER['CONTENT_TYPE']; + if( isset($_ENV['CONTENT_TYPE']) ) + $out['Content-Type'] = $_ENV['CONTENT_TYPE']; + + foreach ($_SERVER as $key => $value) { + if (substr($key, 0, 5) == "HTTP_") { + // this is chaos, basically it is just there to capitalize the first + // letter of every word that is not an initial HTTP and strip HTTP + // code from przemek + $key = str_replace( + " ", + "-", + ucwords(strtolower(str_replace("_", " ", substr($key, 5)))) + ); + $out[$key] = $value; + } + } + } + return $out; + } + + // This function takes a input like a=b&a=c&d=e and returns the parsed + // parameters like this + // array('a' => array('b','c'), 'd' => 'e') + public static function parse_parameters( $input ) { + if (!isset($input) || !$input) return array(); + + $pairs = explode('&', $input); + + $parsed_parameters = array(); + foreach ($pairs as $pair) { + $split = explode('=', $pair, 2); + $parameter = OAuthUtil::urldecode_rfc3986($split[0]); + $value = isset($split[1]) ? OAuthUtil::urldecode_rfc3986($split[1]) : ''; + + if (isset($parsed_parameters[$parameter])) { + // We have already recieved parameter(s) with this name, so add to the list + // of parameters with this name + + if (is_scalar($parsed_parameters[$parameter])) { + // This is the first duplicate, so transform scalar (string) into an array + // so we can add the duplicates + $parsed_parameters[$parameter] = array($parsed_parameters[$parameter]); + } + + $parsed_parameters[$parameter][] = $value; + } else { + $parsed_parameters[$parameter] = $value; + } + } + return $parsed_parameters; + } + + public static function build_http_query($params) { + if (!$params) return ''; + + // Urlencode both keys and values + $keys = OAuthUtil::urlencode_rfc3986(array_keys($params)); + $values = OAuthUtil::urlencode_rfc3986(array_values($params)); + $params = array_combine($keys, $values); + + // Parameters are sorted by name, using lexicographical byte value ordering. + // Ref: Spec: 9.1.1 (1) + uksort($params, 'strcmp'); + + $pairs = array(); + foreach ($params as $parameter => $value) { + if (is_array($value)) { + // If two or more parameters share the same name, they are sorted by their value + // Ref: Spec: 9.1.1 (1) + natsort($value); + foreach ($value as $duplicate_value) { + $pairs[] = $parameter . '=' . $duplicate_value; + } + } else { + $pairs[] = $parameter . '=' . $value; + } + } + // For each parameter, the name is separated from the corresponding value by an '=' character (ASCII code 61) + // Each name-value pair is separated by an '&' character (ASCII code 38) + return implode('&', $pairs); + } +} + +?> diff --git a/3.1/modules/twitter/vendor/twitteroauth/images/darker.png b/3.1/modules/twitter/vendor/twitteroauth/images/darker.png new file mode 100644 index 00000000..746b6b9f Binary files /dev/null and b/3.1/modules/twitter/vendor/twitteroauth/images/darker.png differ diff --git a/3.1/modules/twitter/vendor/twitteroauth/images/lighter.png b/3.1/modules/twitter/vendor/twitteroauth/images/lighter.png new file mode 100644 index 00000000..297bb034 Binary files /dev/null and b/3.1/modules/twitter/vendor/twitteroauth/images/lighter.png differ diff --git a/3.1/modules/twitter/vendor/twitteroauth/twitteroauth.php b/3.1/modules/twitter/vendor/twitteroauth/twitteroauth.php new file mode 100644 index 00000000..674308ae --- /dev/null +++ b/3.1/modules/twitter/vendor/twitteroauth/twitteroauth.php @@ -0,0 +1,245 @@ +http_status; } + function lastAPICall() { return $this->last_api_call; } + + /** + * construct TwitterOAuth object + */ + function __construct($consumer_key, $consumer_secret, $oauth_token = NULL, $oauth_token_secret = NULL) { + $this->sha1_method = new OAuthSignatureMethod_HMAC_SHA1(); + $this->consumer = new OAuthConsumer($consumer_key, $consumer_secret); + if (!empty($oauth_token) && !empty($oauth_token_secret)) { + $this->token = new OAuthConsumer($oauth_token, $oauth_token_secret); + } else { + $this->token = NULL; + } + } + + + /** + * Get a request_token from Twitter + * + * @returns a key/value array containing oauth_token and oauth_token_secret + */ + function getRequestToken($oauth_callback = NULL) { + $parameters = array(); + if (!empty($oauth_callback)) { + $parameters['oauth_callback'] = $oauth_callback; + } + $request = $this->oAuthRequest($this->requestTokenURL(), 'GET', $parameters); + $token = OAuthUtil::parse_parameters($request); + $this->token = new OAuthConsumer($token['oauth_token'], $token['oauth_token_secret']); + return $token; + } + + /** + * Get the authorize URL + * + * @returns a string + */ + function getAuthorizeURL($token, $sign_in_with_twitter = TRUE) { + if (is_array($token)) { + $token = $token['oauth_token']; + } + if (empty($sign_in_with_twitter)) { + return $this->authorizeURL() . "?oauth_token={$token}"; + } else { + return $this->authenticateURL() . "?oauth_token={$token}"; + } + } + + /** + * Exchange request token and secret for an access token and + * secret, to sign API calls. + * + * @returns array("oauth_token" => "the-access-token", + * "oauth_token_secret" => "the-access-secret", + * "user_id" => "9436992", + * "screen_name" => "abraham") + */ + function getAccessToken($oauth_verifier = FALSE) { + $parameters = array(); + if (!empty($oauth_verifier)) { + $parameters['oauth_verifier'] = $oauth_verifier; + } + $request = $this->oAuthRequest($this->accessTokenURL(), 'GET', $parameters); + $token = OAuthUtil::parse_parameters($request); + $this->token = new OAuthConsumer($token['oauth_token'], $token['oauth_token_secret']); + return $token; + } + + /** + * One time exchange of username and password for access token and secret. + * + * @returns array("oauth_token" => "the-access-token", + * "oauth_token_secret" => "the-access-secret", + * "user_id" => "9436992", + * "screen_name" => "abraham", + * "x_auth_expires" => "0") + */ + function getXAuthToken($username, $password) { + $parameters = array(); + $parameters['x_auth_username'] = $username; + $parameters['x_auth_password'] = $password; + $parameters['x_auth_mode'] = 'client_auth'; + $request = $this->oAuthRequest($this->accessTokenURL(), 'POST', $parameters); + $token = OAuthUtil::parse_parameters($request); + $this->token = new OAuthConsumer($token['oauth_token'], $token['oauth_token_secret']); + return $token; + } + + /** + * GET wrapper for oAuthRequest. + */ + function get($url, $parameters = array()) { + $response = $this->oAuthRequest($url, 'GET', $parameters); + if ($this->format === 'json' && $this->decode_json) { + return json_decode($response); + } + return $response; + } + + /** + * POST wrapper for oAuthRequest. + */ + function post($url, $parameters = array()) { + $response = $this->oAuthRequest($url, 'POST', $parameters); + if ($this->format === 'json' && $this->decode_json) { + return json_decode($response); + } + return $response; + } + + /** + * DELETE wrapper for oAuthReqeust. + */ + function delete($url, $parameters = array()) { + $response = $this->oAuthRequest($url, 'DELETE', $parameters); + if ($this->format === 'json' && $this->decode_json) { + return json_decode($response); + } + return $response; + } + + /** + * Format and sign an OAuth / API request + */ + function oAuthRequest($url, $method, $parameters) { + if (strrpos($url, 'https://') !== 0 && strrpos($url, 'http://') !== 0) { + $url = "{$this->host}{$url}.{$this->format}"; + } + $request = OAuthRequest::from_consumer_and_token($this->consumer, $this->token, $method, $url, $parameters); + $request->sign_request($this->sha1_method, $this->consumer, $this->token); + switch ($method) { + case 'GET': + return $this->http($request->to_url(), 'GET'); + default: + return $this->http($request->get_normalized_http_url(), $method, $request->to_postdata()); + } + } + + /** + * Make an HTTP request + * + * @return API results + */ + function http($url, $method, $postfields = NULL) { + $this->http_info = array(); + $ci = curl_init(); + /* Curl settings */ + curl_setopt($ci, CURLOPT_USERAGENT, $this->useragent); + curl_setopt($ci, CURLOPT_CONNECTTIMEOUT, $this->connecttimeout); + curl_setopt($ci, CURLOPT_TIMEOUT, $this->timeout); + curl_setopt($ci, CURLOPT_RETURNTRANSFER, TRUE); + curl_setopt($ci, CURLOPT_HTTPHEADER, array('Expect:')); + curl_setopt($ci, CURLOPT_SSL_VERIFYPEER, $this->ssl_verifypeer); + curl_setopt($ci, CURLOPT_HEADERFUNCTION, array($this, 'getHeader')); + curl_setopt($ci, CURLOPT_HEADER, FALSE); + + switch ($method) { + case 'POST': + curl_setopt($ci, CURLOPT_POST, TRUE); + if (!empty($postfields)) { + curl_setopt($ci, CURLOPT_POSTFIELDS, $postfields); + } + break; + case 'DELETE': + curl_setopt($ci, CURLOPT_CUSTOMREQUEST, 'DELETE'); + if (!empty($postfields)) { + $url = "{$url}?{$postfields}"; + } + } + + curl_setopt($ci, CURLOPT_URL, $url); + $response = curl_exec($ci); + $this->http_code = curl_getinfo($ci, CURLINFO_HTTP_CODE); + $this->http_info = array_merge($this->http_info, curl_getinfo($ci)); + $this->url = $url; + curl_close ($ci); + return $response; + } + + /** + * Get the header info to store. + */ + function getHeader($ch, $header) { + $i = strpos($header, ':'); + if (!empty($i)) { + $key = str_replace('-', '_', strtolower(substr($header, 0, $i))); + $value = trim(substr($header, $i + 2)); + $this->http_header[$key] = $value; + } + return strlen($header); + } +} diff --git a/3.1/modules/twitter/views/admin_twitter.html.php b/3.1/modules/twitter/views/admin_twitter.html.php new file mode 100644 index 00000000..807a72df --- /dev/null +++ b/3.1/modules/twitter/views/admin_twitter.html.php @@ -0,0 +1,30 @@ + +
    +

    + +

    dev.twitter.com/apps/new.", + array("twitter_apps_reg" => "http://dev.twitter.com/apps/new")) ?>

    +
      +
    • +
    • +
    • url::abs_site())) ?>
    • +
    • +
    • +
    • url::abs_site())) ?>
    • +
    • +
    +

    + +

    Twitter application settings, if necessary.", + array("twitter_apps" => "http://dev.twitter.com/apps")) ?>

    + +

    bit.ly module to shorten + Gallery URLs in tweets.", array("bitly_module_url" => "http://codex.gallery2.org/Gallery3:Modules:bitly")) ?>

    + + +
    + +
    +
    diff --git a/3.1/modules/twitter/views/twitter_dialog.html.php b/3.1/modules/twitter/views/twitter_dialog.html.php new file mode 100644 index 00000000..b39c7928 --- /dev/null +++ b/3.1/modules/twitter/views/twitter_dialog.html.php @@ -0,0 +1,22 @@ + + +
    +

    $type, "title"=> $title)) ?>

    + +

    + +

    +

    " alt="Sign in with Twitter"/>

    + +
    + +
    + +
    +
    + +
    \ No newline at end of file diff --git a/3.1/modules/user_albums/helpers/user_albums_event.php b/3.1/modules/user_albums/helpers/user_albums_event.php index d11e5ac5..1d852e80 100644 --- a/3.1/modules/user_albums/helpers/user_albums_event.php +++ b/3.1/modules/user_albums/helpers/user_albums_event.php @@ -1,7 +1,7 @@ page_title = t("Add videos from server"); + $view->page_title = t("Add from server"); $view->content = new View("admin_videos.html"); $view->content->form = $this->_get_admin_form(); $paths = unserialize(module::get_var("videos", "authorized_paths", "a:0:{}")); diff --git a/3.1/modules/videos/controllers/file_proxy.php b/3.1/modules/videos/controllers/file_proxy.php new file mode 100644 index 00000000..f69bff1b --- /dev/null +++ b/3.1/modules/videos/controllers/file_proxy.php @@ -0,0 +1,144 @@ +server("REQUEST_URI")); + + // get rid of query parameters + // request_uri: gallery3/var/albums/foo/bar.jpg + $request_uri = preg_replace("/\?.*/", "", $request_uri); + + // var_uri: gallery3/var/ + $var_uri = url::file("var/"); + + // Make sure that the request is for a file inside var + $offset = strpos(rawurldecode($request_uri), $var_uri); + if ($offset !== 0) { + throw new Kohana_404_Exception(); + } + + // file_uri: albums/foo/bar.jpg + $file_uri = substr($request_uri, strlen($var_uri)); + + // type: albums + // path: foo/bar.jpg + list ($type, $path) = explode("/", $file_uri, 2); + if ($type != "resizes" && $type != "albums" && $type != "thumbs") { + throw new Kohana_404_Exception(); + } + + // If the last element is .album.jpg, pop that off since it's not a real item + $path = preg_replace("|/.album.jpg$|", "", $path); + + $item = item::find_by_path($path); + if (!$item->loaded()) { + // We didn't turn it up. If we're looking for a .jpg then it's it's possible that we're + // requesting the thumbnail for a movie. In that case, the .flv, .mp4 or .m4v file would + // have been converted to a .jpg. So try some alternate types: + if (preg_match('/.jpg$/', $path)) { + // rWatcher Mod: look for videos with file extensions supported by the videos module in addition to flv mp4 and m4v + // Original Line: foreach (array("flv", "mp4", "m4v") as $ext) { + foreach (array_merge(array("flv", "mp4", "m4v"), unserialize(module::get_var("videos", "allowed_extensions"))) as $ext) { + $movie_path = preg_replace('/.jpg$/', ".$ext", $path); + $item = item::find_by_path($movie_path); + if ($item->loaded()) { + break; + } + } + } + // rWatcher Mod: + // If we're looking for a .flv then it's it's possible that we're requesting a flash resize + // for a movie. + if (strtolower(substr($path, strlen($path)-4)) == ".flv") { + $movie_path = str_ireplace(".flv", "", $path); + $item = ORM::factory("item")->where("relative_path_cache", "=", $movie_path)->find(); + } + // END rWatcher Mod + } + + if (!$item->loaded()) { + throw new Kohana_404_Exception(); + } + + // Make sure we have access to the item + if (!access::can("view", $item)) { + throw new Kohana_404_Exception(); + } + + // Make sure we have view_full access to the original + if ($type == "albums" && !access::can("view_full", $item)) { + throw new Kohana_404_Exception(); + } + + // Don't try to load a directory + if ($type == "albums" && $item->is_album()) { + throw new Kohana_404_Exception(); + } + + if ($type == "albums") { + $file = $item->file_path(); + } else if ($type == "resizes") { + $file = $item->resize_path(); + // rWatcher MOD + // If the resize is for a movie, assume it needs a .flv extension. + if ($item->is_movie()) { + $file = $file . ".flv"; + } + // End rWatcher MOD + } else { + $file = $item->thumb_path(); + } + + if (!file_exists($file)) { + throw new Kohana_404_Exception(); + } + + header("Content-Length: " . filesize($file)); + + header("Pragma:"); + // Check that the content hasn't expired or it wasn't changed since cached + expires::check(2592000, $item->updated); + + // We don't need to save the session for this request + Session::instance()->abort_save(); + + expires::set(2592000, $item->updated); // 30 days + + // Dump out the image. If the item is a movie, then its thumbnail will be a JPG. + if ($item->is_movie() && $type != "albums") { + header("Content-Type: image/jpeg"); + } else { + header("Content-Type: $item->mime_type"); + } + Kohana::close_buffers(false); + readfile($file); + } +} diff --git a/3.1/modules/videos/controllers/videos.php b/3.1/modules/videos/controllers/videos.php index 020817ff..34461b3e 100644 --- a/3.1/modules/videos/controllers/videos.php +++ b/3.1/modules/videos/controllers/videos.php @@ -1,7 +1,7 @@ where("task_id", "NOT IN", db::build()->select("id")->from("tasks")) + ->delete("videos_entries") + ->execute(); + $item = ORM::factory("item", $id); $view = new View("videos_tree_dialog.html"); $view->item = $item; @@ -55,6 +67,7 @@ class Videos_Controller extends Admin_Controller { } if (!is_dir($file)) { $ext = strtolower(pathinfo($file, PATHINFO_EXTENSION)); + // rWatcher Edit //if (!in_array($ext, array("gif", "jpeg", "jpg", "png", "flv", "mp4", "m4v"))) { if (!in_array($ext, unserialize(module::get_var("videos", "allowed_extensions")))) { continue; @@ -74,23 +87,28 @@ class Videos_Controller extends Admin_Controller { } /** - * Begin the task of adding files. + * Begin the task of adding photos. */ public function start() { access::verify_csrf(); $item = ORM::factory("item", Input::instance()->get("item_id")); - foreach (Input::instance()->post("paths") as $path) { - if (videos::is_valid_path($path)) { - $paths[] = array($path, null); - } - } - $task_def = Task_Definition::factory() ->callback("Videos_Controller::add") - ->description(t("Add videos from the local server")) + ->description(t("Add photos or movies from the local server")) ->name(t("Add from server")); - $task = task::create($task_def, array("item_id" => $item->id, "queue" => $paths)); + $task = task::create($task_def, array("item_id" => $item->id)); + + foreach (Input::instance()->post("paths") as $path) { + if (videos::is_valid_path($path)) { + $entry = ORM::factory("videos_entry"); + $entry->path = $path; + $entry->is_directory = intval(is_dir($path)); + $entry->parent_id = null; + $entry->task_id = $task->id; + $entry->save(); + } + } json::reply( array("result" => "started", @@ -99,7 +117,7 @@ class Videos_Controller extends Admin_Controller { } /** - * Run the task of adding files + * Run the task of adding photos */ function run($task_id) { access::verify_csrf(); @@ -119,7 +137,7 @@ class Videos_Controller extends Admin_Controller { /** * This is the task code that adds photos and albums. It first examines all the target files - * and creates a set of Server_Add_File_Models, then runs through the list of models and adds + * and creates a set of Server_Add_Entry_Models, then runs through the list of models and adds * them one at a time. */ static function add($task) { @@ -129,6 +147,7 @@ class Videos_Controller extends Admin_Controller { switch ($mode) { case "init": $task->set("mode", "build-file-list"); + $task->set("dirs_scanned", 0); $task->percent_complete = 0; $task->status = t("Starting up"); batch::start(); @@ -137,59 +156,64 @@ class Videos_Controller extends Admin_Controller { case "build-file-list": // 0% to 10% // We can't fit an arbitrary number of paths in a task, so store them in a separate table. // Don't use an iterator here because we can't get enough control over it when we're dealing - // with a deep hierarchy and we don't want to go over our time quota. The queue is in the - // form [path, parent_id] where the parent_id refers to another Server_Add_File_Model. We - // have this extra level of abstraction because we don't know its Item_Model id yet. - $queue = $task->get("queue"); + // with a deep hierarchy and we don't want to go over our time quota. $paths = unserialize(module::get_var("videos", "authorized_paths")); + $dirs_scanned = $task->get("dirs_scanned"); + while (microtime(true) - $start < 0.5) { + // Process every directory that doesn't yet have a parent id, these are the + // paths that we're importing. + $entry = ORM::factory("videos_entry") + ->where("task_id", "=", $task->id) + ->where("is_directory", "=", 1) + ->where("checked", "=", 0) + ->order_by("id", "ASC") + ->find(); - while ($queue && microtime(true) - $start < 0.5) { - list($file, $parent_entry_id) = array_shift($queue); - // Ignore the staging directories as directories to be imported. - if (empty($paths[$file])) { - $entry = ORM::factory("videos_file"); - $entry->task_id = $task->id; - $entry->file = $file; - $entry->parent_id = $parent_entry_id; - $entry->save(); - $entry_id = $entry->id; - } else { - $entry_id = null; - } - - $file = preg_quote($file); - foreach (glob("$file/*") as $child) { - if (is_dir($child)) { - $queue[] = array($child, $entry_id); - } else { - $ext = strtolower(pathinfo($child, PATHINFO_EXTENSION)); - //if (in_array($ext, array("gif", "jpeg", "jpg", "png", "flv", "mp4", "m4v")) && - if (in_array($ext, unserialize(module::get_var("videos", "allowed_extensions"))) && - filesize($child) > 0) { - $child_entry = ORM::factory("videos_file"); - $child_entry->task_id = $task->id; - $child_entry->file = $child; - $child_entry->parent_id = $entry_id; - $child_entry->save(); - } + if ($entry->loaded()) { + $child_paths = glob(preg_quote($entry->path) . "/*"); + if (!$child_paths) { + $child_paths = glob("{$entry->path}/*"); } + foreach ($child_paths as $child_path) { + if (!is_dir($child_path)) { + $ext = strtolower(pathinfo($child_path, PATHINFO_EXTENSION)); + // rWatcher Edit. + //if (!in_array($ext, array("gif", "jpeg", "jpg", "png", "flv", "mp4", "m4v")) || + // !filesize($child_path)) { + if (!in_array($ext, unserialize(module::get_var("videos", "allowed_extensions"))) || + !filesize($child_path)) { + // Not importable, skip it. + continue; + } + } + + $child_entry = ORM::factory("videos_entry"); + $child_entry->task_id = $task->id; + $child_entry->path = $child_path; + $child_entry->parent_id = $entry->id; // null if the parent was a staging dir + $child_entry->is_directory = is_dir($child_path); + $child_entry->save(); + } + + // We've processed this entry, mark it as done. + $entry->checked = 1; + $entry->save(); + $dirs_scanned++; } } // We have no idea how long this can take because we have no idea how deep the tree // hierarchy rabbit hole goes. Leave ourselves room here for 100 iterations and don't go // over 10% in percent_complete. - $task->set("queue", $queue); + $task->set("dirs_scanned", $dirs_scanned); $task->percent_complete = min($task->percent_complete + 0.1, 10); - $task->status = t2( - "Found one file", "Found %count files", - ORM::factory("videos_file")->where("task_id", "=", $task->id)->count_all()); + $task->status = t2("Scanned one directory", "Scanned %count directories", $dirs_scanned); - if (!$queue) { + if (!$entry->loaded()) { $task->set("mode", "add-files"); $task->set( "total_files", - ORM::factory("videos_file")->where("task_id", "=", $task->id)->count_all()); + ORM::factory("videos_entry")->where("task_id", "=", $task->id)->count_all()); $task->percent_complete = 10; } break; @@ -201,7 +225,7 @@ class Videos_Controller extends Admin_Controller { // Ordering by id ensures that we add them in the order that we created the entries, which // will create albums first. Ignore entries which already have an Item_Model attached, // they're done. - $entries = ORM::factory("videos_file") + $entries = ORM::factory("videos_entry") ->where("task_id", "=", $task->id) ->where("item_id", "IS", null) ->order_by("id", "ASC") @@ -220,43 +244,59 @@ class Videos_Controller extends Admin_Controller { // Look up the parent item for this entry. By now it should exist, but if none was // specified, then this belongs as a child of the current item. - $parent_entry = ORM::factory("videos_file", $entry->parent_id); + $parent_entry = ORM::factory("videos_entry", $entry->parent_id); if (!$parent_entry->loaded()) { $parent = ORM::factory("item", $task->get("item_id")); } else { $parent = ORM::factory("item", $parent_entry->item_id); } - $name = basename($entry->file); + $name = basename($entry->path); $title = item::convert_filename_to_title($name); - if (is_dir($entry->file)) { + if ($entry->is_directory) { $album = ORM::factory("item"); $album->type = "album"; $album->parent_id = $parent->id; $album->name = $name; $album->title = $title; $album->owner_id = $owner_id; + $album->sort_order = $parent->sort_order; + $album->sort_column = $parent->sort_column; $album->save(); $entry->item_id = $album->id; } else { try { $extension = strtolower(pathinfo($name, PATHINFO_EXTENSION)); - if (in_array($extension, unserialize(module::get_var("videos", "allowed_extensions")))) { + if (in_array($extension, array("gif", "png", "jpg", "jpeg"))) { + $photo = ORM::factory("item"); + $photo->type = "photo"; + $photo->parent_id = $parent->id; + $photo->set_data_file($entry->path); + $photo->name = $name; + $photo->title = $title; + $photo->owner_id = $owner_id; + $photo->save(); + $entry->item_id = $photo->id; + // rWatcher EDIT + //} else if (in_array($extension, array("flv", "mp4", "m4v"))) { + } else if (in_array($extension, unserialize(module::get_var("videos", "allowed_extensions")))) { $movie = ORM::factory("item"); $movie->type = "movie"; $movie->parent_id = $parent->id; - $movie->set_data_file($entry->file); + $movie->set_data_file($entry->path); $movie->name = $name; $movie->title = $title; $movie->owner_id = $owner_id; $movie->save(); $entry->item_id = $movie->id; + // rWatcher EDIT: Add record to items_video db. $items_video = ORM::factory("items_video"); $items_video->item_id = $movie->id; $items_video->save(); - if (file_exists($entry->file . ".flv")) { - copy($entry->file . ".flv", $movie->resize_path() . ".flv"); - list ($vid_width, $vid_height, $mime_type) = movie::get_file_metadata($entry->file . ".flv"); + // rWatcher EDIT: Scan for flv resizes and copy to resize directory. + if (file_exists($entry->path . ".flv")) { + copy($entry->path . ".flv", $movie->resize_path() . ".flv"); + list ($vid_width, $vid_height, $mime_type) = movie::get_file_metadata($entry->path . ".flv"); $movie->height = $vid_height; $movie->width = $vid_width; $movie->save(); @@ -266,12 +306,12 @@ class Videos_Controller extends Admin_Controller { // process. But just in, case.. set this to a non-null value so that we skip this // entry. $entry->item_id = 0; - $task->log("Skipping unknown file type: $entry->file"); + $task->log("Skipping unknown file type: {$entry->path}"); } } catch (Exception $e) { // This can happen if a photo file is invalid, like a BMP masquerading as a .jpg $entry->item_id = 0; - $task->log("Skipping invalid file: $entry->file"); + $task->log("Skipping invalid file: {$entry->file}"); } } @@ -290,12 +330,11 @@ class Videos_Controller extends Admin_Controller { $task->done = true; $task->state = "success"; $task->percent_complete = 100; - db::build() - ->delete("videos_files") + ORM::factory("videos_entry") ->where("task_id", "=", $task->id) - ->execute(); - message::info(t2("Successfully added one file", - "Successfully added %count files", + ->delete_all(); + message::info(t2("Successfully added one photo / album", + "Successfully added %count photos / albums", $task->get("completed_files"))); } } diff --git a/3.1/modules/videos/css/videos.css b/3.1/modules/videos/css/videos.css index 36746ab5..559e5481 100644 --- a/3.1/modules/videos/css/videos.css +++ b/3.1/modules/videos/css/videos.css @@ -1,23 +1,23 @@ -#g-server-add button { +#g-videos button { margin-bottom: .5em; } -#g-server-add-tree { +#g-videos-tree { cursor: pointer; padding-left: 4px; width: 95%; } -#g-server-add-tree li { +#g-videos-tree li { padding: 0; float: none; } -#g-server-add-tree span.selected { +#g-videos-tree span.selected { background: #ddd; } -#g-server-add-tree { +#g-videos-tree { border: 1px solid #ccc; height: 20em; overflow: auto; @@ -25,14 +25,14 @@ padding: .5em; } -#g-server-add ul ul li { +#g-videos ul ul li { padding-left: 1.2em; } -#g-server-add-paths li .ui-icon { +#g-videos-paths li .ui-icon { margin-top: .4em; } -#g-server-add-admin-form .textbox { +#g-videos-admin-form .textbox { width: 400px; } diff --git a/3.1/modules/videos/helpers/videos.php b/3.1/modules/videos/helpers/videos.php index b75e4658..f6f3240d 100644 --- a/3.1/modules/videos/helpers/videos.php +++ b/3.1/modules/videos/helpers/videos.php @@ -1,7 +1,7 @@ get("settings_menu") @@ -34,7 +38,7 @@ class videos_event_Core { is_writable($item->is_album() ? $item->file_path() : $item->parent()->file_path())) { $menu->get("add_menu") ->append(Menu::factory("dialog") - ->id("videos") + ->id("Videos") ->label(t("Add videos")) ->url(url::site("videos/browse/$item->id"))); } diff --git a/3.1/modules/videos/helpers/videos_installer.php b/3.1/modules/videos/helpers/videos_installer.php index 137df9cb..36a1b423 100644 --- a/3.1/modules/videos/helpers/videos_installer.php +++ b/3.1/modules/videos/helpers/videos_installer.php @@ -1,7 +1,7 @@ query("CREATE TABLE {videos_files} ( + $db->query("CREATE TABLE {videos_entries} ( `id` int(9) NOT NULL auto_increment, - `file` varchar(255) NOT NULL, + `checked` boolean default 0, + `is_directory` boolean default 0, `item_id` int(9), `parent_id` int(9), + `path` varchar(255) NOT NULL, `task_id` int(9) NOT NULL, PRIMARY KEY (`id`)) DEFAULT CHARSET=utf8;"); + + // rWatcher Edit: My Table. $db->query("CREATE TABLE {items_videos} ( `id` int(9) NOT NULL auto_increment, `item_id` int(9) NOT NULL, PRIMARY KEY (`id`), KEY (`item_id`, `id`)) DEFAULT CHARSET=utf8;"); + // rWatcher Edit: My Variable. module::set_var("videos", "allowed_extensions", serialize(array("avi", "mpg", "mpeg", "mov", "wmv", "asf", "mts"))); - module::set_version("videos", 1); + + module::set_version("videos", 4); videos::check_config(); } + static function upgrade($version) { + $db = Database::instance(); + + if ($version < 4) { + $db->query("DROP TABLE {videos_files}"); + $db->query("CREATE TABLE {videos_entries} ( + `id` int(9) NOT NULL auto_increment, + `checked` boolean default 0, + `is_directory` boolean default 0, + `item_id` int(9), + `parent_id` int(9), + `path` varchar(255) NOT NULL, + `task_id` int(9) NOT NULL, + PRIMARY KEY (`id`)) + DEFAULT CHARSET=utf8;"); + module::set_version("videos", $version = 4); + } + } + static function deactivate() { site_status::clear("videos_configuration"); } - - static function uninstall() { - $db = Database::instance(); - $db->query("DROP TABLE IF EXISTS {videos_files};"); - $db->query("DROP TABLE IF EXISTS {items_videos};"); - module::delete("videos"); - } } diff --git a/3.1/modules/videos/helpers/videos_theme.php b/3.1/modules/videos/helpers/videos_theme.php index 9e994591..61200985 100644 --- a/3.1/modules/videos/helpers/videos_theme.php +++ b/3.1/modules/videos/helpers/videos_theme.php @@ -1,7 +1,7 @@ admin) { - $theme->css("videos.css"); - $theme->script("videos.js"); + $buf .= $theme->css("videos.css"); + $buf .= $theme->script("videos.js"); } $item = $theme->item(); @@ -29,27 +36,26 @@ class videos_theme_Core { $items_video = ORM::factory("items_video") ->where("item_id", "=", $item->id) ->find(); - if ($items_video->loaded()) { - $view = new View("videos_display_js.html"); - //$view->embed_code = addslashes($embedded_video->embed_code); - return $view; + if (($items_video->loaded()) && (!file_exists($item->resize_path() . ".flv"))) { + $buf .= $theme->script("videos_download.js"); } } + return $buf; } static function admin_head($theme) { - $head = array(); + $buf = ""; if (strpos(Router::$current_uri, "admin/videos") !== false) { - $theme->css("videos.css"); - $theme->css("jquery.autocomplete.css"); + $buf .= $theme->css("videos.css") + . $theme->css("jquery.autocomplete.css"); $base = url::site("__ARGS__"); $csrf = access::csrf_token(); - $head[] = ""; + $buf .= ""; - $theme->script("jquery.autocomplete.js"); - $theme->script("admin_videos.js"); + $buf .= $theme->script("jquery.autocomplete.js") + . $theme->script("admin_videos.js"); // rWatcher edit. } - return implode("\n", $head); - } -} \ No newline at end of file + return $buf; + } +} diff --git a/3.1/modules/videos/js/admin_videos.js b/3.1/modules/videos/js/admin_videos.js index 9bb61ed1..2a4f462c 100644 --- a/3.1/modules/videos/js/admin_videos.js +++ b/3.1/modules/videos/js/admin_videos.js @@ -2,6 +2,11 @@ * Set up autocomplete on the server path list * */ +/** + * rWatcher Edit: This file used to be admin.js from server_add module. + * All occurences of server_add have been replaced with videos + * + */ $("document").ready(function() { $("#g-path").autocomplete( base_url.replace("__ARGS__", "admin/videos/autocomplete"), {max: 256}); diff --git a/3.1/modules/videos/js/videos.js b/3.1/modules/videos/js/videos.js index 02dda4c0..27627193 100644 --- a/3.1/modules/videos/js/videos.js +++ b/3.1/modules/videos/js/videos.js @@ -1,36 +1,41 @@ +/** + * rWatcher Edit: This file used to be server_add.js from server_add module. + * All occurences of server-add have been replaced with videos + * + */ (function($) { - $.widget("ui.gallery_server_add", { + $.widget("ui.gallery_videos", { _init: function() { var self = this; - $("#g-server-add-add-button", this.element).click(function(event) { + $("#g-videos-add-button", this.element).click(function(event) { event.preventDefault(); $(".g-progress-bar", this.element). progressbar(). progressbar("value", 0); - $("#g-server-add-progress", this.element).slideDown("fast", function() { self.start_add(); }); + $("#g-videos-progress", this.element).slideDown("fast", function() { self.start_add(); }); }); - $("#g-server-add-pause-button", this.element).click(function(event) { + $("#g-videos-pause-button", this.element).click(function(event) { self.pause = true; - $("#g-server-add-pause-button", this.element).hide(); - $("#g-server-add-continue-button", this.element).show(); + $("#g-videos-pause-button", this.element).hide(); + $("#g-videos-continue-button", this.element).show(); }); - $("#g-server-add-continue-button", this.element).click(function(event) { + $("#g-videos-continue-button", this.element).click(function(event) { self.pause = false; - $("#g-server-add-pause-button", this.element).show(); - $("#g-server-add-continue-button", this.element).hide(); + $("#g-videos-pause-button", this.element).show(); + $("#g-videos-continue-button", this.element).hide(); self.run_add(); }); - $("#g-server-add-close-button", this.element).click(function(event) { + $("#g-videos-close-button", this.element).click(function(event) { $("#g-dialog").dialog("close"); window.location.reload(); }); - $("#g-server-add-tree span.g-directory", this.element).dblclick(function(event) { + $("#g-videos-tree span.g-directory", this.element).dblclick(function(event) { self.open_dir(event); }); - $("#g-server-add-tree span.g-file, #g-server-add-tree span.g-directory", this.element).click(function(event) { + $("#g-videos-tree span.g-file, #g-videos-tree span.g-directory", this.element).click(function(event) { self.select_file(event); }); - $("#g-server-add-tree span.g-directory", this.element).dblclick(function(event) { + $("#g-videos-tree span.g-directory", this.element).dblclick(function(event) { self.open_dir(event); }); $("#g-dialog").bind("dialogclose", function(event, ui) { @@ -48,8 +53,8 @@ paths.push($(this).attr("ref")); }); - $("#g-server-add-add-button", this.element).hide(); - $("#g-server-add-pause-button", this.element).show(); + $("#g-videos-add-button", this.element).hide(); + $("#g-videos-pause-button", this.element).show(); $.ajax({ url: START_URL, @@ -77,10 +82,10 @@ $("#g-status").html(data.status); $(".g-progress-bar", self.element).progressbar("value", data.percent_complete); if (data.done) { - $("#g-server-add-progress", this.element).slideUp(); - $("#g-server-add-add-button", this.element).show(); - $("#g-server-add-pause-button", this.element).hide(); - $("#g-server-add-continue-button", this.element).hide(); + $("#g-videos-progress", this.element).slideUp(); + $("#g-videos-add-button", this.element).show(); + $("#g-videos-pause-button", this.element).hide(); + $("#g-videos-continue-button", this.element).hide(); } else { if (!self.pause) { setTimeout(function() { self.run_add(); }, 25); @@ -99,11 +104,11 @@ $.ajax({ url: GET_CHILDREN_URL.replace("__PATH__", path), success: function(data, textStatus) { - $("#g-server-add-tree", self.element).html(data); - $("#g-server-add-tree span.g-directory", self.element).dblclick(function(event) { + $("#g-videos-tree", self.element).html(data); + $("#g-videos-tree span.g-directory", self.element).dblclick(function(event) { self.open_dir(event); }); - $("#g-server-add-tree span.g-file, #g-server-add-tree span.g-directory", this.element).click(function(event) { + $("#g-videos-tree span.g-file, #g-videos-tree span.g-directory", this.element).click(function(event) { self.select_file(event); }); } @@ -115,10 +120,10 @@ */ select_file: function (event) { $(event.target).toggleClass("selected"); - if ($("#g-server-add span.selected").length) { - $("#g-server-add-add-button").enable(true).removeClass("ui-state-disabled"); + if ($("#g-videos span.selected").length) { + $("#g-videos-add-button").enable(true).removeClass("ui-state-disabled"); } else { - $("#g-server-add-add-button").enable(false).addClass("ui-state-disabled"); + $("#g-videos-add-button").enable(false).addClass("ui-state-disabled"); } } }); diff --git a/3.1/modules/videos/js/videos_download.js b/3.1/modules/videos/js/videos_download.js new file mode 100644 index 00000000..b0777ec2 --- /dev/null +++ b/3.1/modules/videos/js/videos_download.js @@ -0,0 +1,8 @@ +/** + * rWatcher Edit: This file is one of mine. + * + */ +$("document").ready(function() { + var original_url = document.getElementById('g-videos-full-url'); + $("#g-movie").replaceWith(""); +}); diff --git a/3.1/modules/videos/models/item.php b/3.1/modules/videos/models/item.php new file mode 100644 index 00000000..171d664c --- /dev/null +++ b/3.1/modules/videos/models/item.php @@ -0,0 +1,1030 @@ +loaded()) { + // Set reasonable defaults + $this->created = time(); + $this->rand_key = random::percent(); + $this->thumb_dirty = 1; + $this->resize_dirty = 1; + $this->sort_column = "created"; + $this->sort_order = "ASC"; + $this->owner_id = identity::active_user()->id; + } + } + + /** + * Add a set of restrictions to any following queries to restrict access only to items + * viewable by the active user. + * @chainable + */ + public function viewable() { + return item::viewable($this); + } + + /** + * Is this item an album? + * @return true if it's an album + */ + public function is_album() { + return $this->type == 'album'; + } + + /** + * Is this item a photo? + * @return true if it's a photo + */ + public function is_photo() { + return $this->type == 'photo'; + } + + /** + * Is this item a movie? + * @return true if it's a movie + */ + public function is_movie() { + return $this->type == 'movie'; + } + + public function delete($ignored_id=null) { + if (!$this->loaded()) { + // Concurrent deletes may result in this item already being gone. Ignore it. + return; + } + + if ($this->id == 1) { + $v = new Validation(array("id")); + $v->add_error("id", "cant_delete_root_album"); + ORM_Validation_Exception::handle_validation($this->table_name, $v); + } + + $old = clone $this; + module::event("item_before_delete", $this); + + $parent = $this->parent(); + if ($parent->album_cover_item_id == $this->id) { + item::remove_album_cover($parent); + } + + $path = $this->file_path(); + $resize_path = $this->resize_path(); + $thumb_path = $this->thumb_path(); + + parent::delete(); + if (is_dir($path)) { + // Take some precautions against accidentally deleting way too much + $delete_resize_path = dirname($resize_path); + $delete_thumb_path = dirname($thumb_path); + if ($delete_resize_path == VARPATH . "resizes" || + $delete_thumb_path == VARPATH . "thumbs" || + $path == VARPATH . "albums") { + throw new Exception( + "@todo DELETING_TOO_MUCH ($delete_resize_path, $delete_thumb_path, $path)"); + } + @dir::unlink($path); + @dir::unlink($delete_resize_path); + @dir::unlink($delete_thumb_path); + } else { + @unlink($path); + @unlink($resize_path); + @unlink($thumb_path); + } + + module::event("item_deleted", $old); + } + + /** + * Specify the path to the data file associated with this item. To actually associate it, + * you still have to call save(). + * @chainable + */ + public function set_data_file($data_file) { + $this->data_file = $data_file; + return $this; + } + + /** + * Return the server-relative url to this item, eg: + * /gallery3/index.php/BobsWedding?page=2 + * /gallery3/index.php/BobsWedding/Eating-Cake.jpg + * + * @param string $query the query string (eg "show=3") + */ + public function url($query=null) { + $url = url::site($this->relative_url()); + if ($query) { + $url .= "?$query"; + } + return $url; + } + + /** + * Return the full url to this item, eg: + * http://example.com/gallery3/index.php/BobsWedding?page=2 + * http://example.com/gallery3/index.php/BobsWedding/Eating-Cake.jpg + * + * @param string $query the query string (eg "show=3") + */ + public function abs_url($query=null) { + $url = url::abs_site($this->relative_url()); + if ($query) { + $url .= "?$query"; + } + return $url; + } + + /** + * album: /var/albums/album1/album2 + * photo: /var/albums/album1/album2/photo.jpg + */ + public function file_path() { + return VARPATH . "albums/" . urldecode($this->relative_path()); + } + + /** + * album: http://example.com/gallery3/var/resizes/album1/ + * photo: http://example.com/gallery3/var/albums/album1/photo.jpg + */ + public function file_url($full_uri=false) { + $relative_path = "var/albums/" . $this->relative_path(); + $cache_buster = $this->_cache_buster($this->file_path()); + return ($full_uri ? url::abs_file($relative_path) : url::file($relative_path)) + . $cache_buster; + } + + /** + * album: /var/resizes/album1/.thumb.jpg + * photo: /var/albums/album1/photo.thumb.jpg + */ + public function thumb_path() { + $base = VARPATH . "thumbs/" . urldecode($this->relative_path()); + if ($this->is_photo()) { + return $base; + } else if ($this->is_album()) { + return $base . "/.album.jpg"; + } else if ($this->is_movie()) { + // Replace the extension with jpg + return preg_replace("/...$/", "jpg", $base); + } + } + + /** + * Return true if there is a thumbnail for this item. + */ + public function has_thumb() { + return $this->thumb_width && $this->thumb_height; + } + + /** + * album: http://example.com/gallery3/var/resizes/album1/.thumb.jpg + * photo: http://example.com/gallery3/var/albums/album1/photo.thumb.jpg + */ + public function thumb_url($full_uri=false) { + $cache_buster = $this->_cache_buster($this->thumb_path()); + $relative_path = "var/thumbs/" . $this->relative_path(); + $base = ($full_uri ? url::abs_file($relative_path) : url::file($relative_path)); + if ($this->is_photo()) { + return $base . $cache_buster; + } else if ($this->is_album()) { + return $base . "/.album.jpg" . $cache_buster; + } else if ($this->is_movie()) { + // Replace the extension with jpg + $base = preg_replace("/...$/", "jpg", $base); + return $base . $cache_buster; + } + } + + /** + * album: /var/resizes/album1/.resize.jpg + * photo: /var/albums/album1/photo.resize.jpg + */ + public function resize_path() { + return VARPATH . "resizes/" . urldecode($this->relative_path()) . + ($this->is_album() ? "/.album.jpg" : ""); + } + + /** + * album: http://example.com/gallery3/var/resizes/album1/.resize.jpg + * photo: http://example.com/gallery3/var/albums/album1/photo.resize.jpg + */ + public function resize_url($full_uri=false) { + $relative_path = "var/resizes/" . $this->relative_path(); + $cache_buster = $this->_cache_buster($this->resize_path()); + return ($full_uri ? url::abs_file($relative_path) : url::file($relative_path)) . + ($this->is_album() ? "/.album.jpg" : "") . $cache_buster; + } + + /** + * Rebuild the relative_path_cache and relative_url_cache. + */ + private function _build_relative_caches() { + $names = array(); + $slugs = array(); + foreach (db::build() + ->select(array("name", "slug")) + ->from("items") + ->where("left_ptr", "<=", $this->left_ptr) + ->where("right_ptr", ">=", $this->right_ptr) + ->where("id", "<>", 1) + ->order_by("left_ptr", "ASC") + ->execute() as $row) { + // Don't encode the names segment + $names[] = rawurlencode($row->name); + $slugs[] = rawurlencode($row->slug); + } + $this->relative_path_cache = implode($names, "/"); + $this->relative_url_cache = implode($slugs, "/"); + return $this; + } + + /** + * Return the relative path to this item's file. Note that the components of the path are + * urlencoded so if you want to use this as a filesystem path, you need to call urldecode + * on it. + * @return string + */ + public function relative_path() { + if (!$this->loaded()) { + return; + } + + if (!isset($this->relative_path_cache)) { + $this->_build_relative_caches()->save(); + } + return $this->relative_path_cache; + } + + /** + * Return the relative url to this item's file. + * @return string + */ + public function relative_url() { + if (!$this->loaded()) { + return; + } + + if (!isset($this->relative_url_cache)) { + $this->_build_relative_caches()->save(); + } + return $this->relative_url_cache; + } + + /** + * @see ORM::__get() + */ + public function __get($column) { + if ($column == "owner") { + // This relationship depends on an outside module, which may not be present so handle + // failures gracefully. + try { + return identity::lookup_user($this->owner_id); + } catch (Exception $e) { + return null; + } + } else { + return parent::__get($column); + } + } + + /** + * Handle any business logic necessary to create or modify an item. + * @see ORM::save() + * + * @return ORM Item_Model + */ + public function save() { + $significant_changes = $this->changed; + unset($significant_changes["view_count"]); + unset($significant_changes["relative_url_cache"]); + unset($significant_changes["relative_path_cache"]); + + if ((!empty($this->changed) && $significant_changes) || isset($this->data_file)) { + $this->updated = time(); + if (!$this->loaded()) { + // Create a new item. + module::event("item_before_create", $this); + + // Set a weight if it's missing. We don't do this in the constructor because it's not a + // simple assignment. + if (empty($this->weight)) { + $this->weight = item::get_max_weight(); + } + + // Make an url friendly slug from the name, if necessary + if (empty($this->slug)) { + $tmp = pathinfo($this->name, PATHINFO_FILENAME); + $tmp = preg_replace("/[^A-Za-z0-9-_]+/", "-", $tmp); + $this->slug = trim($tmp, "-"); + + // If the filename is all invalid characters, then the slug may be empty here. Pick a + // random value. + if (empty($this->slug)) { + $this->slug = (string)rand(1000, 9999); + } + } + + // Get the width, height and mime type from our data file for photos and movies. + if ($this->is_photo() || $this->is_movie()) { + if ($this->is_photo()) { + list ($this->width, $this->height, $this->mime_type, $extension) = + photo::get_file_metadata($this->data_file); + } else if ($this->is_movie()) { + list ($this->width, $this->height, $this->mime_type, $extension) = + movie::get_file_metadata($this->data_file); + } + + // Force an extension onto the name if necessary + $pi = pathinfo($this->data_file); + if (empty($pi["extension"])) { + $this->name = "{$this->name}.$extension"; + } + } + + $this->_randomize_name_or_slug_on_conflict(); + + parent::save(); + + // Build our url caches, then save again. We have to do this after it's already been + // saved once because we use only information from the database to build the paths. If we + // could depend on a save happening later we could defer this 2nd save. + $this->_build_relative_caches(); + parent::save(); + + // Take any actions that we can only do once all our paths are set correctly after saving. + switch ($this->type) { + case "album": + mkdir($this->file_path()); + mkdir(dirname($this->thumb_path())); + mkdir(dirname($this->resize_path())); + break; + + case "photo": + case "movie": + // The thumb or resize may already exist in the case where a movie and a photo generate + // a thumbnail of the same name (eg, foo.flv movie and foo.jpg photo will generate + // foo.jpg thumbnail). If that happens, randomize and save again. + if (file_exists($this->resize_path()) || + file_exists($this->thumb_path())) { + $pi = pathinfo($this->name); + $this->name = $pi["filename"] . "-" . random::int() . "." . $pi["extension"]; + parent::save(); + } + + copy($this->data_file, $this->file_path()); + break; + } + + // This will almost definitely trigger another save, so put it at the end so that we're + // tail recursive. Null out the data file variable first, otherwise the next save will + // trigger an item_updated_data_file event. + $this->data_file = null; + module::event("item_created", $this); + } else { + // Update an existing item + module::event("item_before_update", $item); + + // If any significant fields have changed, load up a copy of the original item and + // keep it around. + $original = ORM::factory("item", $this->id); + if (array_intersect($this->changed, array("parent_id", "name", "slug"))) { + $original->_build_relative_caches(); + $this->relative_path_cache = null; + $this->relative_url_cache = null; + } + + $this->_randomize_name_or_slug_on_conflict(); + + parent::save(); + + // Now update the filesystem and any database caches if there were significant value + // changes. If anything past this point fails, then we'll have an inconsistent database + // so this code should be as robust as we can make it. + + // Update the MPTT pointers, if necessary. We have to do this before we generate any + // cached paths! + if ($original->parent_id != $this->parent_id) { + parent::move_to($this->parent()); + } + + if ($original->parent_id != $this->parent_id || $original->name != $this->name) { + // Move all of the items associated data files + @rename($original->file_path(), $this->file_path()); + if ($this->is_album()) { + @rename(dirname($original->resize_path()), dirname($this->resize_path())); + @rename(dirname($original->thumb_path()), dirname($this->thumb_path())); + } else { + @rename($original->resize_path(), $this->resize_path()); + @rename($original->thumb_path(), $this->thumb_path()); + } + + if ($original->parent_id != $this->parent_id) { + // This will result in 2 events since we'll still fire the item_updated event below + module::event("item_moved", $this, $original->parent()); + } + } + + // Changing the name, slug or parent ripples downwards + if ($this->is_album() && + ($original->name != $this->name || + $original->slug != $this->slug || + $original->parent_id != $this->parent_id)) { + db::build() + ->update("items") + ->set("relative_url_cache", null) + ->set("relative_path_cache", null) + ->where("left_ptr", ">", $this->left_ptr) + ->where("right_ptr", "<", $this->right_ptr) + ->execute(); + } + + // Replace the data file, if requested. + // @todo: we don't handle the case where you swap in a file of a different mime type + // should we prevent that in validation? or in set_data_file() + if ($this->data_file && ($this->is_photo() || $this->is_movie())) { + copy($this->data_file, $this->file_path()); + + // Get the width, height and mime type from our data file for photos and movies. + if ($this->is_photo()) { + list ($this->width, $this->height) = photo::get_file_metadata($this->file_path()); + } else if ($this->is_movie()) { + list ($this->width, $this->height) = movie::get_file_metadata($this->file_path()); + } + $this->thumb_dirty = 1; + $this->resize_dirty = 1; + } + + module::event("item_updated", $original, $this); + + if ($this->data_file) { + // Null out the data file variable here, otherwise this event will trigger another + // save() which will think that we're doing another file move. + $this->data_file = null; + module::event("item_updated_data_file", $this); + } + } + } else if (!empty($this->changed)) { + // Insignificant changes only. Don't fire events or do any special checking to try to keep + // this lightweight. + parent::save(); + } + + return $this; + } + + /** + * Check to see if there's another item that occupies the same name or slug that this item + * intends to use, and if so choose a new name/slug while preserving the extension. + * @todo Improve this. Random numbers are not user friendly + */ + private function _randomize_name_or_slug_on_conflict() { + $base_name = pathinfo($this->name, PATHINFO_FILENAME); + $base_ext = pathinfo($this->name, PATHINFO_EXTENSION); + $base_slug = $this->slug; + while (ORM::factory("item") + ->where("parent_id", "=", $this->parent_id) + ->where("id", $this->id ? "<>" : "IS NOT", $this->id) + ->and_open() + ->where("name", "=", $this->name) + ->or_where("slug", "=", $this->slug) + ->close() + ->find()->id) { + $rand = random::int(); + if ($base_ext) { + $this->name = "$base_name-$rand.$base_ext"; + } else { + $this->name = "$base_name-$rand"; + } + $this->slug = "$base_slug-$rand"; + } + } + + /** + * Return the Item_Model representing the cover for this album. + * @return Item_Model or null if there's no cover + */ + public function album_cover() { + if (!$this->is_album()) { + return null; + } + + if (empty($this->album_cover_item_id)) { + return null; + } + + try { + return model_cache::get("item", $this->album_cover_item_id); + } catch (Exception $e) { + // It's possible (unlikely) that the item was deleted, if so keep going. + return null; + } + } + + /** + * Find the position of the given child id in this album. The resulting value is 1-indexed, so + * the first child in the album is at position 1. + * + * This method stands as a backward compatibility for gallery 3.0, and will + * be deprecated in version 3.1. + */ + public function get_position($child, $where=array()) { + return item::get_position($child, $where); + } + + /** + * Return an tag for the thumbnail. + * @param array $extra_attrs Extra attributes to add to the img tag + * @param int (optional) $max Maximum size of the thumbnail (default: null) + * @param boolean (optional) $center_vertically Center vertically (default: false) + * @return string + */ + public function thumb_img($extra_attrs=array(), $max=null, $center_vertically=false) { + list ($height, $width) = $this->scale_dimensions($max); + if ($center_vertically && $max) { + // The constant is divide by 2 to calculate the file and 10 to convert to em + $margin_top = (int)(($max - $height) / 20); + $extra_attrs["style"] = "margin-top: {$margin_top}em"; + $extra_attrs["title"] = $this->title; + } + $attrs = array_merge($extra_attrs, + array( + "src" => $this->thumb_url(), + "alt" => $this->title, + "width" => $width, + "height" => $height) + ); + // html::image forces an absolute url which we don't want + return ""; + } + + /** + * Calculate the largest width/height that fits inside the given maximum, while preserving the + * aspect ratio. Don't upscale. + * @param int $max Maximum size of the largest dimension + * @return array + */ + public function scale_dimensions($max) { + $width = $this->thumb_width; + $height = $this->thumb_height; + + if ($width <= $max && $height <= $max) { + return array($height, $width); + } + + if ($height) { + if (isset($max)) { + if ($width > $height) { + $height = (int)($max * $height / $width); + $width = $max; + } else { + $width = (int)($max * $width / $height); + $height = $max; + } + } + } else { + // Missing thumbnail, can happen on albums with no photos yet. + // @todo we should enforce a placeholder for those albums. + $width = 0; + $height = 0; + } + return array($height, $width); + } + + /** + * Return an tag for the resize. + * @param array $extra_attrs Extra attributes to add to the img tag + * @return string + */ + public function resize_img($extra_attrs) { + $attrs = array_merge($extra_attrs, + array("src" => $this->resize_url(), + "alt" => $this->title, + "width" => $this->resize_width, + "height" => $this->resize_height) + ); + // html::image forces an absolute url which we don't want + return ""; + } + + /** + * Return a flowplayer - diff --git a/3.1/modules/videos/views/videos_tree.html.php b/3.1/modules/videos/views/videos_tree.html.php index 91354329..366d4fb4 100644 --- a/3.1/modules/videos/views/videos_tree.html.php +++ b/3.1/modules/videos/views/videos_tree.html.php @@ -1,4 +1,5 @@ +
  • diff --git a/3.1/modules/videos/views/videos_tree_dialog.html.php b/3.1/modules/videos/views/videos_tree_dialog.html.php index a235ffbf..a0c0f7b7 100644 --- a/3.1/modules/videos/views/videos_tree_dialog.html.php +++ b/3.1/modules/videos/views/videos_tree_dialog.html.php @@ -1,13 +1,14 @@ + -
    -

    html::purify($item->title))) ?>

    +
    +

    html::purify($item->title))) ?>

    -

    +

      parents() as $parent): ?> @@ -17,35 +18,35 @@
    • title) ?>
    -
      +
      - '; - $content .= $this->thumb_bottom($item); - $content .= ''; - - return $content; - } - - // $mode: bit 1 - use mix mode ($mode in [1, 3]), bit 2 - strips bbcode ($mode in [2, 3]) - public function bb2html($text, $mode) { - // Syntax Sample: - // -------------- - // [img]http://elouai.com/images/star.gif[/img] - // [url="http://elouai.com"]eLouai[/url] - // [size="25"]HUGE[/size] - // [color="red"]RED[/color] - // [b]bold[/b] - // [i]italic[/i] - // [u]underline[/u] - // [list][*]item[*]item[*]item[/list] - // [code]value="123";[/code] - // [quote]John said yadda yadda yadda[/quote] - - static $bbcode_mappings = array( - "#\\[b\\](.*?)\\[/b\\]#" => "$1", - "#\\[i\\](.*?)\\[/i\\]#" => "$1", - "#\\[u\\](.*?)\\[/u\\]#" => "$1", - "#\\[s\\](.*?)\\[/s\\]#" => "$1", - "#\\[o\\](.*?)\\[/o\\]#" => "$1", - "#\\[url\\](.*?)\[/url\\]#" => "$1", - "#\\[url=(.*?)\\](.*?)\[/url\\]#" => "$2", - "#\\[mail=(.*?)\\](.*?)\[/mail\\]#" => "$2", - "#\\[img\\](.*?)\\[/img\\]#" => "\"\"", - "#\\[img=(.*?)\\](.*?)\[/img\\]#" => "\"$2\"", - "#\\[quote\\](.*?)\\[/quote\\]#" => "

      $1

      ", - "#\\[code\\](.*?)\\[/code\\]#" => "
      $1
      ", - "#\\[size=([^\\[]*)\\]([^\\[]*)\\[/size\\]#" => "$2", - "#\\[color=([^\\[]*)\\]([^\\[]*)\\[/color\\]#" => "$2", - "#\\[class=([^\\[]*)\\]([^\\[]*)\\[/class\\]#" => "$2", - "#\\[center\\](.*?)\\[/center\\]#" => "
      $1
      ", - "#\\[list\\](.*?)\\[/list\\]#" => "
        $1
      ", - "#\\[ul\\](.*?)\\[/ul\\]#" => "
        $1
      ", - "#\\[li\\](.*?)\\[/li\\]#" => "
    • $1
    • ", - ); - - static $bbcode_strip = '|[[\/\!]*?[^\[\]]*?]|si'; - - // Replace any html brackets with HTML Entities to prevent executing HTML or script - // Don't use strip_tags here because it breaks [url] search by replacing & with amp - if (($mode == 1) or ($mode == 3)): - $newtext = str_replace("<", "<", $text); - $newtext = str_replace(">", ">", $newtext); - $newtext = str_replace(""", "\"", $newtext); - else: - $newtext = str_replace("<", "<", $text); - $newtext = str_replace(">", ">", $newtext); - $newtext = str_replace("&quot;", """, $newtext); - endif; - - // Convert new line chars to html
      tags - $newtext = nl2br($newtext); - - if (strpos($text, "[") !== false): - if (($mode == 2) or ($mode == 3)): - $newtext = preg_replace($bbcode_strip, '', $newtext); - else: - $newtext = preg_replace(array_keys($bbcode_mappings), array_values($bbcode_mappings), $newtext); - endif; - endif; - - return stripslashes($newtext); //stops slashing, useful when pulling from db - } -} - -?> \ No newline at end of file diff --git a/3.1/themes/greydragon/theme.info b/3.1/themes/greydragon/theme.info deleted file mode 100644 index cea1d8d0..00000000 --- a/3.1/themes/greydragon/theme.info +++ /dev/null @@ -1,6 +0,0 @@ -name = "Grey Dragon Theme" -description = "A Crisp flexible theme with support of Color Packs and minimized on JS overhead" -version = 2.3.1 -author = "2010 Serguei Dosyukov" -site = 1 -admin = 0 diff --git a/3.1/themes/greydragon/thumbnail.png b/3.1/themes/greydragon/thumbnail.png deleted file mode 100644 index 4b80ecaf..00000000 Binary files a/3.1/themes/greydragon/thumbnail.png and /dev/null differ diff --git a/3.1/themes/greydragon/views/album.html.php b/3.1/themes/greydragon/views/album.html.php deleted file mode 100644 index 49fa5cf4..00000000 --- a/3.1/themes/greydragon/views/album.html.php +++ /dev/null @@ -1,55 +0,0 @@ - -
      - album_top() ?> -

      bb2html(html::purify($item->title), 1) ?>

      -
      - -add_paginator("top"); ?> - -photo_descmode == "top") and ($item->description)): ?> -
      bb2html(html::purify($item->description), 1) ?>
      - - -
        - - $child): ?> - get_thumb_element($child, TRUE) ?> - - - admin || access::can("add", $item)): ?> - id") ?> -
      • Add some.", - array("attrs" => html::mark_clean("href=\"$addurl\" class=\"g-dialog-link\""))) ?>
      • - -
      • - - -
      -album_bottom() ?> - -photo_descmode == "bottom") and ($item->description)): ?> -
      bb2html(html::purify($item->description), 1) ?>
      - - -add_paginator("bottom"); ?> diff --git a/3.1/themes/greydragon/views/block.html.php b/3.1/themes/greydragon/views/block.html.php deleted file mode 100644 index af29546f..00000000 --- a/3.1/themes/greydragon/views/block.html.php +++ /dev/null @@ -1,33 +0,0 @@ - - - - -
      - is_blockheader_visible): ?> -

      - -
      - -
      -
      diff --git a/3.1/themes/greydragon/views/dynamic.html.php b/3.1/themes/greydragon/views/dynamic.html.php deleted file mode 100644 index 1f787cf3..00000000 --- a/3.1/themes/greydragon/views/dynamic.html.php +++ /dev/null @@ -1,39 +0,0 @@ - -
      -
      - dynamic_top() ?> -
      -

      -
      - -add_paginator("top"); ?> - -
        - $child): ?> - get_thumb_element($child) ?> - -
      -dynamic_bottom() ?> - -add_paginator("bottom"); ?> diff --git a/3.1/themes/greydragon/views/info_block.html.php b/3.1/themes/greydragon/views/info_block.html.php deleted file mode 100644 index d3860584..00000000 --- a/3.1/themes/greydragon/views/info_block.html.php +++ /dev/null @@ -1,24 +0,0 @@ - -
        - owner): ?> -
      • - - owner->url): ?> - owner->display_name()) ?> - - owner->display_name()) ?> - -
      • - - captured): ?> -
      • - - captured)?> -
      • - - description): ?> -
      • - bb2html(html::purify($item->description), 1) ?> -
      • - -
      diff --git a/3.1/themes/greydragon/views/login_ajax.html.php b/3.1/themes/greydragon/views/login_ajax.html.php deleted file mode 100644 index 76028c4e..00000000 --- a/3.1/themes/greydragon/views/login_ajax.html.php +++ /dev/null @@ -1,41 +0,0 @@ - - - -
      - - - - -
      - diff --git a/3.1/themes/greydragon/views/movie.html.php b/3.1/themes/greydragon/views/movie.html.php deleted file mode 100644 index ec870608..00000000 --- a/3.1/themes/greydragon/views/movie.html.php +++ /dev/null @@ -1,43 +0,0 @@ - -
      - photo_top() ?> - -
      -

      bb2html(html::purify($item->title), 1) ?>

      -
      bb2html(html::purify($item->description), 1) ?>
      -
      - - add_paginator("top"); ?> - -
      - resize_top($item) ?> - movie_img(array("class" => "g-movie", "id" => "g-movie-id-{$item->id}")); ?> - context_menu($item, "#g-movie-id-{$item->id}") ?> - resize_bottom($item) ?> -
      - - add_paginator("bottom"); ?> - - photo_bottom() ?> -
      diff --git a/3.1/themes/greydragon/views/no_sidebar.html.php b/3.1/themes/greydragon/views/no_sidebar.html.php deleted file mode 100644 index dd61bb77..00000000 --- a/3.1/themes/greydragon/views/no_sidebar.html.php +++ /dev/null @@ -1,24 +0,0 @@ - - 
    ?> - diff --git a/3.1/themes/greydragon/views/page.html.php b/3.1/themes/greydragon/views/page.html.php deleted file mode 100644 index 13664d65..00000000 --- a/3.1/themes/greydragon/views/page.html.php +++ /dev/null @@ -1,147 +0,0 @@ - - -load_sessioninfo(); ?> - - -enable_pagecache) and ($theme->item())): - // Page will expire in 60 seconds - header('Expires: ' . gmdate('D, d M Y H:i:s', time() + 60).'GMT'); - header("Cache-Control: public"); - header("Cache-Control: post-check=3600, pre-check=43200", false); - header("Content-Type: text/html; charset=UTF-8"); - header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT"); - endif; -?> - - -"; ?> - - - -item()): ?> -item()->is_album()): ?> - $theme->bb2html($theme->item()->title, 2))) ?> -item()->is_photo()): ?> - $theme->bb2html($theme->item()->title, 2))) ?> - - $theme->bb2html($theme->item()->title, 2))) ?> - -tag()): ?> - $theme->bb2html($theme->tag()->name, 2))) ?> - - - - -disable_seosupport): ?> - ' . "\n"; ?> - ' . "\n"; ?> - ' . "\n"; ?> - ' . "\n"; ?> - ' . "\n"; ?> - -" type="image/x-icon" /> -script("jquery.js") ?> -script("jquery.form.js") ?> -script("jquery-ui.js") ?> -page_subtype == "movie"): ?> -script("flowplayer.js") ?> - -script("gallery.ajax.js") ?> -head() ?> -" type="text/css" media="screen,print,projection" /> -color_pack . "/colors.css") ?>" type="text/css" media="screen,print,projection" /> - - - - - - - -page_top() ?> -
    - header_top() ?> - - - - - - -guest) or ($theme->show_guest_menu)): ?> -
    "> - site_menu() ?> -
    - - messages() ?> -header_bottom() ?> - -loginmenu_position == "header"): ?> - user_menu() ?> - - -show_breadcrumbs): ?> - breadcrumb_menu($theme, $parents); ?> - -
    -
    -
    - sidebar_menu($url) ?> -
    "> - - album_menu() ?> - - photo_menu() ?> - - movie_menu() ?> - - tag_menu() ?> - -
    - - sidebarvisible=="left"): ?> - ' ?> - sidebarvisible=="none"): ?> - - ' ?> - - - page_subtype != "login") and ($theme->page_subtype != "reauthenticate") and ($theme->sidebarvisible != "none")): ?> - - - sidebarvisible != "none")? "
    " : null ?> - - sidebarvisible == "left"): ?> - ' ?> - sidebarvisible == "none"): ?> - ' ?> - - ' ?> - - -
    -
    -
  • - -page_bottom() ?> - - diff --git a/3.1/themes/greydragon/views/photo.html.php b/3.1/themes/greydragon/views/photo.html.php deleted file mode 100644 index 884e30a5..00000000 --- a/3.1/themes/greydragon/views/photo.html.php +++ /dev/null @@ -1,79 +0,0 @@ - -desc_allowbbcode): ?> - bb2html($item->description, 1); ?> - - description)); ?> - - -is_photometa_visible): ?> -' . $theme->thumb_info($item) . ''; ?> - - -
    - bb2html(html::purify($item->title), 1); ?> -
    -

    -
    - add_paginator("top"); ?> - photo_top() ?> - photo_descmode == "top") and ($_description)): ?> -
    - -
    - resize_top($item) ?> - - file_url() . '" class="g-sb-preview" '; ?> - - - - resize_width; ?> - parent()->children(); ?> - -
    - rand_key != $item->rand_key)); $i++): - ?> - "> - resize_img(array("id" => "g-photo-id-{$item->id}", "class" => "g-resize", "alt" => $_title)) ?> - - - photo_descmode == "overlay") and ($_description)): ?> - More - - - - - -
    - resize_bottom($item) ?> -
    - photo_descmode == "bottom") and ($_description)): ?> -
    - - add_paginator("bottom"); ?> - photo_bottom() ?> -
    diff --git a/3.1/themes/greydragon/views/rss_block.html.php b/3.1/themes/greydragon/views/rss_block.html.php deleted file mode 100644 index 4d30ce59..00000000 --- a/3.1/themes/greydragon/views/rss_block.html.php +++ /dev/null @@ -1,13 +0,0 @@ - - diff --git a/3.1/themes/greydragon/views/search.html.php b/3.1/themes/greydragon/views/search.html.php deleted file mode 100644 index 94fc170c..00000000 --- a/3.1/themes/greydragon/views/search.html.php +++ /dev/null @@ -1,43 +0,0 @@ - -
    -

    $q)) ?>

    - - - - add_paginator("top"); ?> -
      - - is_album() ? "g-album" : "g-photo" ?> - "> ?> - get_thumb_element($item) ?> - ?> - -
    - add_paginator("bottom"); ?> - -

     

    -

    %term", array("term" => $q)) ?>

    - - -
    \ No newline at end of file diff --git a/3.1/themes/greydragon/views/sidebar.html.php b/3.1/themes/greydragon/views/sidebar.html.php deleted file mode 100644 index 0cad333d..00000000 --- a/3.1/themes/greydragon/views/sidebar.html.php +++ /dev/null @@ -1,8 +0,0 @@ - - -sidebar_top() ?> -
     
    -page_subtype == "album") or ($theme->page_subtype == "photo") or ($theme->page_subtype == "movie") or ($theme->item())): ?> -sidebar_blocks() ?> - -sidebar_bottom() ?> diff --git a/3.1/themes/greydragon/views/tag_block.html.php b/3.1/themes/greydragon/views/tag_block.html.php deleted file mode 100644 index f9bc5886..00000000 --- a/3.1/themes/greydragon/views/tag_block.html.php +++ /dev/null @@ -1,27 +0,0 @@ - - -
    "> - -
    - \ No newline at end of file diff --git a/3.1/themes/greydragon/views/user_profile.html.php b/3.1/themes/greydragon/views/user_profile.html.php deleted file mode 100644 index b7d92f40..00000000 --- a/3.1/themes/greydragon/views/user_profile.html.php +++ /dev/null @@ -1,50 +0,0 @@ - - - -
    -

    $user->display_name())) ?>

    - - - - " - alt="display_name()) ?>" - class="g-avatar g-left" width="40" height="40" /> - - - -
    -

    title) ?>

    -
    - view ?> -
    -
    - -
    diff --git a/3.1/themes/sobriety/theme.info b/3.1/themes/sobriety/theme.info index 545a0815..452fc2f5 100644 --- a/3.1/themes/sobriety/theme.info +++ b/3.1/themes/sobriety/theme.info @@ -6,3 +6,7 @@ site = 1 admin = 0 ;wind commit = 3b05db2685d92ca538d7993c960b06ea32f3a8df ;wind date = Wed Jun 23 11:16:56 2010 -0700 +author_name = "" +author_url = "" +info_url = "http://codex.gallery2.org/Gallery3:Themes:sobriety" +discuss_url = "http://gallery.menalto.com/forum_theme_sobriety" diff --git a/3.1/themes/three_nids/admin/helpers/three_nids_event.php b/3.1/themes/three_nids/admin/helpers/three_nids_event.php index c8a0db51..abb221fc 100644 --- a/3.1/themes/three_nids/admin/helpers/three_nids_event.php +++ b/3.1/themes/three_nids/admin/helpers/three_nids_event.php @@ -1,7 +1,7 @@