diff --git a/LICENSE b/LICENSE new file mode 100644 index 000000000..ef7e7efc0 --- /dev/null +++ b/LICENSE @@ -0,0 +1,674 @@ +GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + {one line to give the program's name and a brief idea of what it does.} + Copyright (C) {year} {name of author} + + 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: + + {project} Copyright (C) {year} {fullname} + 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/README.md b/README.md index 5a89311f8..b36bcc1ff 100644 --- a/README.md +++ b/README.md @@ -7,6 +7,12 @@ RAP通过GUI工具帮助WEB工程师更高效的管理接口文档,同时通 +### Architect +* Hibernate5 + Spring4 + Struts2 +* MySQL +* Redis +* Velocity + ### Why we use RAP? * Enterprise level application. More than 350+ corporations including Alibaba Group are using RAP to manage their important API Docs! * Fast and efficient technical support, continuously update. Go to issues list to find out how lively the community is! @@ -45,12 +51,12 @@ RAP通过GUI工具帮助WEB工程师更高效的管理接口文档,同时通 ## About - @version v0.12.0 + @version v0.13.0 @author @bosn @wangjeaf @director @limu @xinglie @update Oct. 13th 2015 @dependency MockJS(@nuysoft) - @licence GPL + @license GPL ## Contact diff --git a/WebContent/WEB-INF/lib/.DS_Store b/WebContent/WEB-INF/lib/.DS_Store deleted file mode 100644 index 922f6aa64..000000000 Binary files a/WebContent/WEB-INF/lib/.DS_Store and /dev/null differ diff --git a/WebContent/WEB-INF/lib/activation.jar b/WebContent/WEB-INF/lib/activation.jar deleted file mode 100644 index b7a4b4717..000000000 Binary files a/WebContent/WEB-INF/lib/activation.jar and /dev/null differ diff --git a/WebContent/WEB-INF/lib/antlr-2.7.6.jar b/WebContent/WEB-INF/lib/antlr-2.7.6.jar deleted file mode 100644 index 3702b645f..000000000 Binary files a/WebContent/WEB-INF/lib/antlr-2.7.6.jar and /dev/null differ diff --git a/WebContent/WEB-INF/lib/automaton.jar b/WebContent/WEB-INF/lib/automaton.jar deleted file mode 100644 index ba583b3c8..000000000 Binary files a/WebContent/WEB-INF/lib/automaton.jar and /dev/null differ diff --git a/WebContent/WEB-INF/lib/axis.jar b/WebContent/WEB-INF/lib/axis.jar deleted file mode 100644 index 20b09a595..000000000 Binary files a/WebContent/WEB-INF/lib/axis.jar and /dev/null differ diff --git a/WebContent/WEB-INF/lib/c3p0-0.9.1.2.jar b/WebContent/WEB-INF/lib/c3p0-0.9.1.2.jar deleted file mode 100644 index 0f42d60e3..000000000 Binary files a/WebContent/WEB-INF/lib/c3p0-0.9.1.2.jar and /dev/null differ diff --git a/WebContent/WEB-INF/lib/cglib-nodep-2.1_3.jar b/WebContent/WEB-INF/lib/cglib-nodep-2.1_3.jar deleted file mode 100644 index e9b17ebf1..000000000 Binary files a/WebContent/WEB-INF/lib/cglib-nodep-2.1_3.jar and /dev/null differ diff --git a/WebContent/WEB-INF/lib/codehaus.jackson.core-1.5.4.jar b/WebContent/WEB-INF/lib/codehaus.jackson.core-1.5.4.jar deleted file mode 100644 index 61c72dce6..000000000 Binary files a/WebContent/WEB-INF/lib/codehaus.jackson.core-1.5.4.jar and /dev/null differ diff --git a/WebContent/WEB-INF/lib/codehaus.jackson.mapper-1.5.4.jar b/WebContent/WEB-INF/lib/codehaus.jackson.mapper-1.5.4.jar deleted file mode 100644 index 3bc7833b1..000000000 Binary files a/WebContent/WEB-INF/lib/codehaus.jackson.mapper-1.5.4.jar and /dev/null differ diff --git a/WebContent/WEB-INF/lib/commons-beanutils-1.8.0.jar b/WebContent/WEB-INF/lib/commons-beanutils-1.8.0.jar deleted file mode 100644 index caf7ae336..000000000 Binary files a/WebContent/WEB-INF/lib/commons-beanutils-1.8.0.jar and /dev/null differ diff --git a/WebContent/WEB-INF/lib/commons-chain-1.1.jar b/WebContent/WEB-INF/lib/commons-chain-1.1.jar deleted file mode 100644 index 60c027ef3..000000000 Binary files a/WebContent/WEB-INF/lib/commons-chain-1.1.jar and /dev/null differ diff --git a/WebContent/WEB-INF/lib/commons-codec-1.3.jar b/WebContent/WEB-INF/lib/commons-codec-1.3.jar deleted file mode 100644 index 957b6752a..000000000 Binary files a/WebContent/WEB-INF/lib/commons-codec-1.3.jar and /dev/null differ diff --git a/WebContent/WEB-INF/lib/commons-codec-1.6.jar b/WebContent/WEB-INF/lib/commons-codec-1.6.jar deleted file mode 100644 index ee1bc49ac..000000000 Binary files a/WebContent/WEB-INF/lib/commons-codec-1.6.jar and /dev/null differ diff --git a/WebContent/WEB-INF/lib/commons-collections-3.2.jar b/WebContent/WEB-INF/lib/commons-collections-3.2.jar deleted file mode 100644 index 75580be25..000000000 Binary files a/WebContent/WEB-INF/lib/commons-collections-3.2.jar and /dev/null differ diff --git a/WebContent/WEB-INF/lib/commons-digester-2.0.jar b/WebContent/WEB-INF/lib/commons-digester-2.0.jar deleted file mode 100644 index 9c8bd13a2..000000000 Binary files a/WebContent/WEB-INF/lib/commons-digester-2.0.jar and /dev/null differ diff --git a/WebContent/WEB-INF/lib/commons-discovery.jar b/WebContent/WEB-INF/lib/commons-discovery.jar deleted file mode 100644 index b88554847..000000000 Binary files a/WebContent/WEB-INF/lib/commons-discovery.jar and /dev/null differ diff --git a/WebContent/WEB-INF/lib/commons-fileupload-1.3.1.jar b/WebContent/WEB-INF/lib/commons-fileupload-1.3.1.jar deleted file mode 100644 index af0cda226..000000000 Binary files a/WebContent/WEB-INF/lib/commons-fileupload-1.3.1.jar and /dev/null differ diff --git a/WebContent/WEB-INF/lib/commons-httpclient-3.1.jar b/WebContent/WEB-INF/lib/commons-httpclient-3.1.jar deleted file mode 100644 index 7c59774ae..000000000 Binary files a/WebContent/WEB-INF/lib/commons-httpclient-3.1.jar and /dev/null differ diff --git a/WebContent/WEB-INF/lib/commons-io-2.2.jar b/WebContent/WEB-INF/lib/commons-io-2.2.jar deleted file mode 100644 index 84ca56585..000000000 Binary files a/WebContent/WEB-INF/lib/commons-io-2.2.jar and /dev/null differ diff --git a/WebContent/WEB-INF/lib/commons-lang-2.4.jar b/WebContent/WEB-INF/lib/commons-lang-2.4.jar deleted file mode 100644 index 532939eca..000000000 Binary files a/WebContent/WEB-INF/lib/commons-lang-2.4.jar and /dev/null differ diff --git a/WebContent/WEB-INF/lib/commons-lang3-3.2.jar b/WebContent/WEB-INF/lib/commons-lang3-3.2.jar deleted file mode 100644 index a30d272a8..000000000 Binary files a/WebContent/WEB-INF/lib/commons-lang3-3.2.jar and /dev/null differ diff --git a/WebContent/WEB-INF/lib/commons-logging-1.1.3.jar b/WebContent/WEB-INF/lib/commons-logging-1.1.3.jar deleted file mode 100644 index ab5125407..000000000 Binary files a/WebContent/WEB-INF/lib/commons-logging-1.1.3.jar and /dev/null differ diff --git a/WebContent/WEB-INF/lib/commons-net-ftp-2.0.jar b/WebContent/WEB-INF/lib/commons-net-ftp-2.0.jar deleted file mode 100644 index f697534cf..000000000 Binary files a/WebContent/WEB-INF/lib/commons-net-ftp-2.0.jar and /dev/null differ diff --git a/WebContent/WEB-INF/lib/commons-pool-1.5.4.jar b/WebContent/WEB-INF/lib/commons-pool-1.5.4.jar deleted file mode 100644 index 43edf9963..000000000 Binary files a/WebContent/WEB-INF/lib/commons-pool-1.5.4.jar and /dev/null differ diff --git a/WebContent/WEB-INF/lib/commons-validator-1.3.1.jar b/WebContent/WEB-INF/lib/commons-validator-1.3.1.jar deleted file mode 100644 index 55b12b1a9..000000000 Binary files a/WebContent/WEB-INF/lib/commons-validator-1.3.1.jar and /dev/null differ diff --git a/WebContent/WEB-INF/lib/derbyclient.jar b/WebContent/WEB-INF/lib/derbyclient.jar deleted file mode 100644 index 3e8097896..000000000 Binary files a/WebContent/WEB-INF/lib/derbyclient.jar and /dev/null differ diff --git a/WebContent/WEB-INF/lib/dom4j-1.6.1.jar b/WebContent/WEB-INF/lib/dom4j-1.6.1.jar deleted file mode 100644 index c8c4dbb92..000000000 Binary files a/WebContent/WEB-INF/lib/dom4j-1.6.1.jar and /dev/null differ diff --git a/WebContent/WEB-INF/lib/dozer-5.1.jar b/WebContent/WEB-INF/lib/dozer-5.1.jar deleted file mode 100644 index a559a8f04..000000000 Binary files a/WebContent/WEB-INF/lib/dozer-5.1.jar and /dev/null differ diff --git a/WebContent/WEB-INF/lib/dvsl-1.0.jar b/WebContent/WEB-INF/lib/dvsl-1.0.jar deleted file mode 100644 index d9e6f2669..000000000 Binary files a/WebContent/WEB-INF/lib/dvsl-1.0.jar and /dev/null differ diff --git a/WebContent/WEB-INF/lib/ehcache-1.6.0-beta4.jar b/WebContent/WEB-INF/lib/ehcache-1.6.0-beta4.jar deleted file mode 100644 index e8f204af3..000000000 Binary files a/WebContent/WEB-INF/lib/ehcache-1.6.0-beta4.jar and /dev/null differ diff --git a/WebContent/WEB-INF/lib/fluent-hc-4.3.3.jar b/WebContent/WEB-INF/lib/fluent-hc-4.3.3.jar deleted file mode 100644 index 609769160..000000000 Binary files a/WebContent/WEB-INF/lib/fluent-hc-4.3.3.jar and /dev/null differ diff --git a/WebContent/WEB-INF/lib/freemarker-2.3.22.jar b/WebContent/WEB-INF/lib/freemarker-2.3.22.jar deleted file mode 100644 index a67a1c127..000000000 Binary files a/WebContent/WEB-INF/lib/freemarker-2.3.22.jar and /dev/null differ diff --git a/WebContent/WEB-INF/lib/google-collections-1.0.jar b/WebContent/WEB-INF/lib/google-collections-1.0.jar deleted file mode 100644 index 8e394facd..000000000 Binary files a/WebContent/WEB-INF/lib/google-collections-1.0.jar and /dev/null differ diff --git a/WebContent/WEB-INF/lib/gson-1.5-sources.jar b/WebContent/WEB-INF/lib/gson-1.5-sources.jar deleted file mode 100644 index 3977e2085..000000000 Binary files a/WebContent/WEB-INF/lib/gson-1.5-sources.jar and /dev/null differ diff --git a/WebContent/WEB-INF/lib/gson-1.5.jar b/WebContent/WEB-INF/lib/gson-1.5.jar deleted file mode 100644 index e59483bbb..000000000 Binary files a/WebContent/WEB-INF/lib/gson-1.5.jar and /dev/null differ diff --git a/WebContent/WEB-INF/lib/hessian-3.2.1.jar b/WebContent/WEB-INF/lib/hessian-3.2.1.jar deleted file mode 100644 index b7d90bae0..000000000 Binary files a/WebContent/WEB-INF/lib/hessian-3.2.1.jar and /dev/null differ diff --git a/WebContent/WEB-INF/lib/hibernate-tools.jar b/WebContent/WEB-INF/lib/hibernate-tools.jar deleted file mode 100644 index 783947d6c..000000000 Binary files a/WebContent/WEB-INF/lib/hibernate-tools.jar and /dev/null differ diff --git a/WebContent/WEB-INF/lib/hibernate3.jar b/WebContent/WEB-INF/lib/hibernate3.jar deleted file mode 100644 index b87dcb031..000000000 Binary files a/WebContent/WEB-INF/lib/hibernate3.jar and /dev/null differ diff --git a/WebContent/WEB-INF/lib/httpclient-4.3.3.jar b/WebContent/WEB-INF/lib/httpclient-4.3.3.jar deleted file mode 100644 index 6c46bffe4..000000000 Binary files a/WebContent/WEB-INF/lib/httpclient-4.3.3.jar and /dev/null differ diff --git a/WebContent/WEB-INF/lib/httpclient-cache-4.3.3.jar b/WebContent/WEB-INF/lib/httpclient-cache-4.3.3.jar deleted file mode 100644 index 082430d21..000000000 Binary files a/WebContent/WEB-INF/lib/httpclient-cache-4.3.3.jar and /dev/null differ diff --git a/WebContent/WEB-INF/lib/httpcore-4.3.2.jar b/WebContent/WEB-INF/lib/httpcore-4.3.2.jar deleted file mode 100644 index 813ec2348..000000000 Binary files a/WebContent/WEB-INF/lib/httpcore-4.3.2.jar and /dev/null differ diff --git a/WebContent/WEB-INF/lib/httpmime-4.3.3.jar b/WebContent/WEB-INF/lib/httpmime-4.3.3.jar deleted file mode 100644 index f2b1cf7c8..000000000 Binary files a/WebContent/WEB-INF/lib/httpmime-4.3.3.jar and /dev/null differ diff --git a/WebContent/WEB-INF/lib/jackson-asl-0.9.3.jar b/WebContent/WEB-INF/lib/jackson-asl-0.9.3.jar deleted file mode 100644 index 0a5f71f01..000000000 Binary files a/WebContent/WEB-INF/lib/jackson-asl-0.9.3.jar and /dev/null differ diff --git a/WebContent/WEB-INF/lib/jakarta.commons.lang-2.4.jar b/WebContent/WEB-INF/lib/jakarta.commons.lang-2.4.jar deleted file mode 100644 index 532939eca..000000000 Binary files a/WebContent/WEB-INF/lib/jakarta.commons.lang-2.4.jar and /dev/null differ diff --git a/WebContent/WEB-INF/lib/jakarta.log4j-1.2.15.jar b/WebContent/WEB-INF/lib/jakarta.log4j-1.2.15.jar deleted file mode 100644 index c930a6ab4..000000000 Binary files a/WebContent/WEB-INF/lib/jakarta.log4j-1.2.15.jar and /dev/null differ diff --git a/WebContent/WEB-INF/lib/java.servlet-2.5.jar b/WebContent/WEB-INF/lib/java.servlet-2.5.jar deleted file mode 100644 index fb5249346..000000000 Binary files a/WebContent/WEB-INF/lib/java.servlet-2.5.jar and /dev/null differ diff --git a/WebContent/WEB-INF/lib/javassist-3.11.0.GA.jar b/WebContent/WEB-INF/lib/javassist-3.11.0.GA.jar deleted file mode 100644 index b3bfeeb3d..000000000 Binary files a/WebContent/WEB-INF/lib/javassist-3.11.0.GA.jar and /dev/null differ diff --git a/WebContent/WEB-INF/lib/javax.mail.jar b/WebContent/WEB-INF/lib/javax.mail.jar deleted file mode 100644 index ca7eca7d9..000000000 Binary files a/WebContent/WEB-INF/lib/javax.mail.jar and /dev/null differ diff --git a/WebContent/WEB-INF/lib/jaxen-1.1-beta-9.jar b/WebContent/WEB-INF/lib/jaxen-1.1-beta-9.jar deleted file mode 100644 index 6402d3273..000000000 Binary files a/WebContent/WEB-INF/lib/jaxen-1.1-beta-9.jar and /dev/null differ diff --git a/WebContent/WEB-INF/lib/jaxrpc.jar b/WebContent/WEB-INF/lib/jaxrpc.jar deleted file mode 100644 index fe0b047cb..000000000 Binary files a/WebContent/WEB-INF/lib/jaxrpc.jar and /dev/null differ diff --git a/WebContent/WEB-INF/lib/js.jar b/WebContent/WEB-INF/lib/js.jar deleted file mode 100644 index 6f0dafbbc..000000000 Binary files a/WebContent/WEB-INF/lib/js.jar and /dev/null differ diff --git a/WebContent/WEB-INF/lib/json-rpc.jar b/WebContent/WEB-INF/lib/json-rpc.jar deleted file mode 100644 index 7584a94c7..000000000 Binary files a/WebContent/WEB-INF/lib/json-rpc.jar and /dev/null differ diff --git a/WebContent/WEB-INF/lib/jsonplugin-0.30.jar b/WebContent/WEB-INF/lib/jsonplugin-0.30.jar deleted file mode 100644 index a7f06a5c2..000000000 Binary files a/WebContent/WEB-INF/lib/jsonplugin-0.30.jar and /dev/null differ diff --git a/WebContent/WEB-INF/lib/jta.jar b/WebContent/WEB-INF/lib/jta.jar deleted file mode 100644 index 40a2cbdf8..000000000 Binary files a/WebContent/WEB-INF/lib/jta.jar and /dev/null differ diff --git a/WebContent/WEB-INF/lib/junit-4.4.jar b/WebContent/WEB-INF/lib/junit-4.4.jar deleted file mode 100644 index 649b0b327..000000000 Binary files a/WebContent/WEB-INF/lib/junit-4.4.jar and /dev/null differ diff --git a/WebContent/WEB-INF/lib/jxl.jar b/WebContent/WEB-INF/lib/jxl.jar deleted file mode 100644 index c17560d91..000000000 Binary files a/WebContent/WEB-INF/lib/jxl.jar and /dev/null differ diff --git a/WebContent/WEB-INF/lib/log4j-api-2.0.2.jar b/WebContent/WEB-INF/lib/log4j-api-2.0.2.jar deleted file mode 100644 index 35a9a5b60..000000000 Binary files a/WebContent/WEB-INF/lib/log4j-api-2.0.2.jar and /dev/null differ diff --git a/WebContent/WEB-INF/lib/log4j-core-2.0.2.jar b/WebContent/WEB-INF/lib/log4j-core-2.0.2.jar deleted file mode 100644 index 6588c3155..000000000 Binary files a/WebContent/WEB-INF/lib/log4j-core-2.0.2.jar and /dev/null differ diff --git a/WebContent/WEB-INF/lib/mysql-connector-java-5.1.6-bin.jar b/WebContent/WEB-INF/lib/mysql-connector-java-5.1.6-bin.jar deleted file mode 100644 index 0539039f7..000000000 Binary files a/WebContent/WEB-INF/lib/mysql-connector-java-5.1.6-bin.jar and /dev/null differ diff --git a/WebContent/WEB-INF/lib/nekohtml-1.9.13.jar b/WebContent/WEB-INF/lib/nekohtml-1.9.13.jar deleted file mode 100644 index a8081d294..000000000 Binary files a/WebContent/WEB-INF/lib/nekohtml-1.9.13.jar and /dev/null differ diff --git a/WebContent/WEB-INF/lib/ognl-3.0.6.jar b/WebContent/WEB-INF/lib/ognl-3.0.6.jar deleted file mode 100644 index b0838b7af..000000000 Binary files a/WebContent/WEB-INF/lib/ognl-3.0.6.jar and /dev/null differ diff --git a/WebContent/WEB-INF/lib/org.slf4j.slf4j-api-1.5.6.jar b/WebContent/WEB-INF/lib/org.slf4j.slf4j-api-1.5.6.jar deleted file mode 100644 index 9b4221694..000000000 Binary files a/WebContent/WEB-INF/lib/org.slf4j.slf4j-api-1.5.6.jar and /dev/null differ diff --git a/WebContent/WEB-INF/lib/org.slf4j.slf4j-log4j12-1.5.6.jar b/WebContent/WEB-INF/lib/org.slf4j.slf4j-log4j12-1.5.6.jar deleted file mode 100644 index 0c40e9c8b..000000000 Binary files a/WebContent/WEB-INF/lib/org.slf4j.slf4j-log4j12-1.5.6.jar and /dev/null differ diff --git a/WebContent/WEB-INF/lib/oro-2.0.8.jar b/WebContent/WEB-INF/lib/oro-2.0.8.jar deleted file mode 100644 index 23488d260..000000000 Binary files a/WebContent/WEB-INF/lib/oro-2.0.8.jar and /dev/null differ diff --git a/WebContent/WEB-INF/lib/ostermillerutils_1_07_00.jar b/WebContent/WEB-INF/lib/ostermillerutils_1_07_00.jar deleted file mode 100644 index a9931503c..000000000 Binary files a/WebContent/WEB-INF/lib/ostermillerutils_1_07_00.jar and /dev/null differ diff --git a/WebContent/WEB-INF/lib/pinyin4j-2.5.0.jar b/WebContent/WEB-INF/lib/pinyin4j-2.5.0.jar deleted file mode 100644 index e8ede137a..000000000 Binary files a/WebContent/WEB-INF/lib/pinyin4j-2.5.0.jar and /dev/null differ diff --git a/WebContent/WEB-INF/lib/prettytime-3.2.3.Final.jar b/WebContent/WEB-INF/lib/prettytime-3.2.3.Final.jar deleted file mode 100644 index 55a84c387..000000000 Binary files a/WebContent/WEB-INF/lib/prettytime-3.2.3.Final.jar and /dev/null differ diff --git a/WebContent/WEB-INF/lib/quartz-all-1.6.0.jar b/WebContent/WEB-INF/lib/quartz-all-1.6.0.jar deleted file mode 100644 index 14846679a..000000000 Binary files a/WebContent/WEB-INF/lib/quartz-all-1.6.0.jar and /dev/null differ diff --git a/WebContent/WEB-INF/lib/saaj.jar b/WebContent/WEB-INF/lib/saaj.jar deleted file mode 100644 index 4ea696e74..000000000 Binary files a/WebContent/WEB-INF/lib/saaj.jar and /dev/null differ diff --git a/WebContent/WEB-INF/lib/servletapi-2.3.jar b/WebContent/WEB-INF/lib/servletapi-2.3.jar deleted file mode 100644 index cd5b3510b..000000000 Binary files a/WebContent/WEB-INF/lib/servletapi-2.3.jar and /dev/null differ diff --git a/WebContent/WEB-INF/lib/sitemesh-2.2.1.jar b/WebContent/WEB-INF/lib/sitemesh-2.2.1.jar deleted file mode 100644 index 964bc66ac..000000000 Binary files a/WebContent/WEB-INF/lib/sitemesh-2.2.1.jar and /dev/null differ diff --git a/WebContent/WEB-INF/lib/slf4j-api-1.5.8.jar b/WebContent/WEB-INF/lib/slf4j-api-1.5.8.jar deleted file mode 100644 index 35502caae..000000000 Binary files a/WebContent/WEB-INF/lib/slf4j-api-1.5.8.jar and /dev/null differ diff --git a/WebContent/WEB-INF/lib/slf4j-log4j12-1.5.8.jar b/WebContent/WEB-INF/lib/slf4j-log4j12-1.5.8.jar deleted file mode 100644 index b63bcdc74..000000000 Binary files a/WebContent/WEB-INF/lib/slf4j-log4j12-1.5.8.jar and /dev/null differ diff --git a/WebContent/WEB-INF/lib/sourceforge.spring.modules.core-2.5.6.jar b/WebContent/WEB-INF/lib/sourceforge.spring.modules.core-2.5.6.jar deleted file mode 100644 index aafa33609..000000000 Binary files a/WebContent/WEB-INF/lib/sourceforge.spring.modules.core-2.5.6.jar and /dev/null differ diff --git a/WebContent/WEB-INF/lib/spring-modules-cache.jar b/WebContent/WEB-INF/lib/spring-modules-cache.jar deleted file mode 100644 index d692fa9e2..000000000 Binary files a/WebContent/WEB-INF/lib/spring-modules-cache.jar and /dev/null differ diff --git a/WebContent/WEB-INF/lib/spring.jar b/WebContent/WEB-INF/lib/spring.jar deleted file mode 100644 index 4767055eb..000000000 Binary files a/WebContent/WEB-INF/lib/spring.jar and /dev/null differ diff --git a/WebContent/WEB-INF/lib/spy-2.4.jar b/WebContent/WEB-INF/lib/spy-2.4.jar deleted file mode 100644 index 3f037b23f..000000000 Binary files a/WebContent/WEB-INF/lib/spy-2.4.jar and /dev/null differ diff --git a/WebContent/WEB-INF/lib/sslext-1.2-0.jar b/WebContent/WEB-INF/lib/sslext-1.2-0.jar deleted file mode 100644 index 5d7175f75..000000000 Binary files a/WebContent/WEB-INF/lib/sslext-1.2-0.jar and /dev/null differ diff --git a/WebContent/WEB-INF/lib/stringtree-json-2.0.5.jar b/WebContent/WEB-INF/lib/stringtree-json-2.0.5.jar deleted file mode 100644 index 06efba414..000000000 Binary files a/WebContent/WEB-INF/lib/stringtree-json-2.0.5.jar and /dev/null differ diff --git a/WebContent/WEB-INF/lib/struts2-core-2.3.24.jar b/WebContent/WEB-INF/lib/struts2-core-2.3.24.jar deleted file mode 100644 index 0f402080e..000000000 Binary files a/WebContent/WEB-INF/lib/struts2-core-2.3.24.jar and /dev/null differ diff --git a/WebContent/WEB-INF/lib/struts2-jasperreports-plugin-2.3.24.jar b/WebContent/WEB-INF/lib/struts2-jasperreports-plugin-2.3.24.jar deleted file mode 100644 index d48772406..000000000 Binary files a/WebContent/WEB-INF/lib/struts2-jasperreports-plugin-2.3.24.jar and /dev/null differ diff --git a/WebContent/WEB-INF/lib/struts2-jfreechart-plugin-2.3.24.jar b/WebContent/WEB-INF/lib/struts2-jfreechart-plugin-2.3.24.jar deleted file mode 100644 index f5ecf6a72..000000000 Binary files a/WebContent/WEB-INF/lib/struts2-jfreechart-plugin-2.3.24.jar and /dev/null differ diff --git a/WebContent/WEB-INF/lib/struts2-json-plugin-2.3.24.jar b/WebContent/WEB-INF/lib/struts2-json-plugin-2.3.24.jar deleted file mode 100644 index 88ac2aea7..000000000 Binary files a/WebContent/WEB-INF/lib/struts2-json-plugin-2.3.24.jar and /dev/null differ diff --git a/WebContent/WEB-INF/lib/struts2-sitemesh-plugin-2.0.14.jar b/WebContent/WEB-INF/lib/struts2-sitemesh-plugin-2.0.14.jar deleted file mode 100644 index 732008bb7..000000000 Binary files a/WebContent/WEB-INF/lib/struts2-sitemesh-plugin-2.0.14.jar and /dev/null differ diff --git a/WebContent/WEB-INF/lib/struts2-spring-plugin-2.3.24.jar b/WebContent/WEB-INF/lib/struts2-spring-plugin-2.3.24.jar deleted file mode 100644 index 4d95edf61..000000000 Binary files a/WebContent/WEB-INF/lib/struts2-spring-plugin-2.3.24.jar and /dev/null differ diff --git a/WebContent/WEB-INF/lib/struts2-tiles-plugin-2.3.24.jar b/WebContent/WEB-INF/lib/struts2-tiles-plugin-2.3.24.jar deleted file mode 100644 index 45b78d563..000000000 Binary files a/WebContent/WEB-INF/lib/struts2-tiles-plugin-2.3.24.jar and /dev/null differ diff --git a/WebContent/WEB-INF/lib/urlrewritefilter-4.0.3.jar b/WebContent/WEB-INF/lib/urlrewritefilter-4.0.3.jar deleted file mode 100644 index 08f6ba281..000000000 Binary files a/WebContent/WEB-INF/lib/urlrewritefilter-4.0.3.jar and /dev/null differ diff --git a/WebContent/WEB-INF/lib/velocity-1.7-dep.jar b/WebContent/WEB-INF/lib/velocity-1.7-dep.jar deleted file mode 100644 index c99aecff6..000000000 Binary files a/WebContent/WEB-INF/lib/velocity-1.7-dep.jar and /dev/null differ diff --git a/WebContent/WEB-INF/lib/velocity-1.7.jar b/WebContent/WEB-INF/lib/velocity-1.7.jar deleted file mode 100644 index ae936d3d9..000000000 Binary files a/WebContent/WEB-INF/lib/velocity-1.7.jar and /dev/null differ diff --git a/WebContent/WEB-INF/lib/velocity-tools-2.0.jar b/WebContent/WEB-INF/lib/velocity-tools-2.0.jar deleted file mode 100644 index beb7434d5..000000000 Binary files a/WebContent/WEB-INF/lib/velocity-tools-2.0.jar and /dev/null differ diff --git a/WebContent/WEB-INF/lib/velocity-tools-generic-2.0.jar b/WebContent/WEB-INF/lib/velocity-tools-generic-2.0.jar deleted file mode 100644 index a2df49fef..000000000 Binary files a/WebContent/WEB-INF/lib/velocity-tools-generic-2.0.jar and /dev/null differ diff --git a/WebContent/WEB-INF/lib/velocity-tools-view-2.0.jar b/WebContent/WEB-INF/lib/velocity-tools-view-2.0.jar deleted file mode 100644 index 80c1e835d..000000000 Binary files a/WebContent/WEB-INF/lib/velocity-tools-view-2.0.jar and /dev/null differ diff --git a/WebContent/WEB-INF/lib/wddx.jar b/WebContent/WEB-INF/lib/wddx.jar deleted file mode 100644 index 906d65c54..000000000 Binary files a/WebContent/WEB-INF/lib/wddx.jar and /dev/null differ diff --git a/WebContent/WEB-INF/lib/wsdl4j.jar b/WebContent/WEB-INF/lib/wsdl4j.jar deleted file mode 100644 index c6254ee69..000000000 Binary files a/WebContent/WEB-INF/lib/wsdl4j.jar and /dev/null differ diff --git a/WebContent/WEB-INF/lib/xercesImpl-2.6.2.jar b/WebContent/WEB-INF/lib/xercesImpl-2.6.2.jar deleted file mode 100644 index 14c3162c0..000000000 Binary files a/WebContent/WEB-INF/lib/xercesImpl-2.6.2.jar and /dev/null differ diff --git a/WebContent/WEB-INF/lib/xercesImpl.jar b/WebContent/WEB-INF/lib/xercesImpl.jar deleted file mode 100644 index 14c3162c0..000000000 Binary files a/WebContent/WEB-INF/lib/xercesImpl.jar and /dev/null differ diff --git a/WebContent/WEB-INF/lib/xwork-core-2.3.24.jar b/WebContent/WEB-INF/lib/xwork-core-2.3.24.jar deleted file mode 100644 index e24c3109b..000000000 Binary files a/WebContent/WEB-INF/lib/xwork-core-2.3.24.jar and /dev/null differ diff --git a/WebContent/WEB-INF/toolbox.xml b/WebContent/WEB-INF/toolbox.xml deleted file mode 100644 index cd93253f7..000000000 --- a/WebContent/WEB-INF/toolbox.xml +++ /dev/null @@ -1,23 +0,0 @@ - - - - utils - application - com.taobao.rigel.rap.common.StringUtils - - - dateUtils - application - com.taobao.rigel.rap.common.DateUtils - - - consts - application - com.taobao.rigel.rap.common.SystemConstant - - - logger - application - com.taobao.rigel.rap.common.SystemVisitorLog - - diff --git a/WebContent/WEB-INF/urlrewrite.xml b/WebContent/WEB-INF/urlrewrite.xml deleted file mode 100644 index 4aeb4dd1d..000000000 --- a/WebContent/WEB-INF/urlrewrite.xml +++ /dev/null @@ -1,73 +0,0 @@ - - - - - - mock service - - ^/mock/(\d*?)/(.*)$ - /mock/createData.action?__id__=$1&pattern=/${escape:utf8:$2} - * - Origin, X-Requested-With, Content-Type, Accept - - - - mockjs service - - ^/mockjs/(\d*?)/(.*)$ - /mock/createRule.action?__id__=$1&pattern=/${escape:utf8:$2} - * - Origin, X-Requested-With, Content-Type, Accept - - - - mockjs auto service, use mock rules set by Open API - - ^/mockjsauto/(\d*?)/(.*)$ - /mock/createRuleAuto.action?__id__=$1&pattern=/${escape:utf8:$2} - * - Origin, X-Requested-With, Content-Type, Accept - - - - mockjs result service - - ^/mockjsdata/(\d*?)/(.*)$ - /mock/createMockjsData.action?__id__=$1&pattern=/${escape:utf8:$2} - * - Origin, X-Requested-With, Content-Type, Accept - - - - mockjs result service - - ^/mockjsdataauto/(\d*?)/(.*)$ - /mock/createMockjsDataAuto.action?__id__=$1&pattern=/${escape:utf8:$2} - * - Origin, X-Requested-With, Content-Type, Accept - - - - validation API - - ^/validate/(\d*?)/(.*)$ - /mock/validateAPI.action?__id__=$1&pattern=/${escape:utf8:$2} - * - Origin, X-Requested-With, Content-Type, Accept - - - - mockjs plugin generator - - ^/rap.plugin.js(.*)$ - /mock/createPluginScript.action$1 - - - - node doc service - - ^/doc/(\d*)$ - http://localhost:7429/doc/$1.html - - \ No newline at end of file diff --git a/WebContent/account/myAccount.vm b/WebContent/account/myAccount.vm deleted file mode 100644 index c6afc2c91..000000000 --- a/WebContent/account/myAccount.vm +++ /dev/null @@ -1,117 +0,0 @@ - -#parse('/tcom/template.rap.vm') - - - - - Manage Account - #includeNewRapStatic - - - #bodyNewStart -
-
-
- -
-

$!utils.escapeInH($curUser.account)

-
-
-
- -
-

- #if($isEditMode) - - #else - $!utils.escapeInH($curUser.name) - #end -

-
-
-
- -
-

- #if($isEditMode) - - #else - $!utils.escapeInH($curUser.email) - #end -

-
-
- #if($isEditMode) -
- -
-

- * 若无需修改请忽略 -

-
-
-
- -
-

- -

-
-
-
- -
-

- -

-
-
- #end -
- -
-

- $!utils.escapeInH($curUser.createDateStr) -

-
-
-
- -
-

- #if($opSuccess) - 操作成功 - #else - - #end -

-
-
-
- -
-

- #if($isEditMode) - - - #else - - #end -

-
-
-
-
- #bodyEnd - - - diff --git a/WebContent/account/mySetting.vm b/WebContent/account/mySetting.vm deleted file mode 100644 index 9b931ee9f..000000000 --- a/WebContent/account/mySetting.vm +++ /dev/null @@ -1,150 +0,0 @@ - -#parse('/tcom/template.rap.vm') - - - - -Manage Account #includeNewRapStatic - - - - #bodyNewStart - -
-
不要鸡冻,这个功能还木有做完,霍雍和思竹吃饭饭去了
- - - -
-
-
-
- -
- -
-
-
- -
-
- -
-
- -
-
-
- -
- -
-
- -
-
- -
-
-
- -
-
- - -
-
-
-
-
-
- -
- -
- -
-
- -
- -
-
- -
-
- -
-
-
- -
- -
-
- -
-
- -
-
-
- -
-
- - -
-
-
-
-
更多功能,敬请期待~
-
-
- #bodyEnd - - diff --git a/WebContent/account/register.vm b/WebContent/account/register.vm deleted file mode 100644 index dffc0e3ca..000000000 --- a/WebContent/account/register.vm +++ /dev/null @@ -1,81 +0,0 @@ - -#parse('/tcom/template.rap.vm') - - - - 注册新的RAP账户 - #includeNewRapStatic - - - #bodyNewStart -
-
-
- -
- -
-
-
- -
-

- -

-
-
-
- -
-

- -

-
-
-
- -
-

- -

-
-
-
- -
-

- -

-
-
-
- -
-

- -

-
-
-
- -
-

- -

-
-
-
-
- #bodyEnd - - - diff --git a/WebContent/bcom/getModuleHtmlAjax.cb.vm b/WebContent/bcom/getModuleHtmlAjax.cb.vm deleted file mode 100644 index b4e29869b..000000000 --- a/WebContent/bcom/getModuleHtmlAjax.cb.vm +++ /dev/null @@ -1,17 +0,0 @@ -
-
- - #foreach ($page in $module.pageList) -
- - #foreach ($action in $page.actionList) - - #end -
add
-
- #end -
-
-
-
-
diff --git a/WebContent/common/blank.html b/WebContent/common/blank.html deleted file mode 100644 index b1aa3b317..000000000 --- a/WebContent/common/blank.html +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/WebContent/common/redirect.vm b/WebContent/common/redirect.vm deleted file mode 100644 index d85883540..000000000 --- a/WebContent/common/redirect.vm +++ /dev/null @@ -1,14 +0,0 @@ - - - - - RAP - 正在为您跳转 - - - 正在为您跳转... - - - - diff --git a/WebContent/demo/a.js b/WebContent/demo/a.js deleted file mode 100644 index 0e11d983e..000000000 --- a/WebContent/demo/a.js +++ /dev/null @@ -1,13 +0,0 @@ -define(function(require, exports, module) { - var $ = require('jquery'); - exports.go = function() { - $.ajax({ - url : 'data.json', - dataType : 'json', - type : 'get', - success : function(data) { - $('body').html(JSON.stringify(data, null, 4)); - } - }); - } -}) \ No newline at end of file diff --git a/WebContent/demo/mock.plugin/casebox/case1_seajs_jquery_preload.html b/WebContent/demo/mock.plugin/casebox/case1_seajs_jquery_preload.html deleted file mode 100644 index c6f548e8a..000000000 --- a/WebContent/demo/mock.plugin/casebox/case1_seajs_jquery_preload.html +++ /dev/null @@ -1,60 +0,0 @@ - - - - - - - - - -
-
-

- RAP plugin case1: seajs jquery preload issue. -

-

LOG:

-

-
- - - - - \ No newline at end of file diff --git a/WebContent/demo/mock.plugin/data1.js b/WebContent/demo/mock.plugin/data1.js deleted file mode 100644 index 5c9761b84..000000000 --- a/WebContent/demo/mock.plugin/data1.js +++ /dev/null @@ -1 +0,0 @@ -{"a":1, "b":2} \ No newline at end of file diff --git a/WebContent/demo/mock.plugin/jquery-2.0.3.min.js b/WebContent/demo/mock.plugin/jquery-2.0.3.min.js deleted file mode 100644 index 2be209dd2..000000000 --- a/WebContent/demo/mock.plugin/jquery-2.0.3.min.js +++ /dev/null @@ -1,6 +0,0 @@ -/*! jQuery v2.0.3 | (c) 2005, 2013 jQuery Foundation, Inc. | jquery.org/license -//@ sourceMappingURL=jquery-2.0.3.min.map -*/ -(function(e,undefined){var t,n,r=typeof undefined,i=e.location,o=e.document,s=o.documentElement,a=e.jQuery,u=e.$,l={},c=[],p="2.0.3",f=c.concat,h=c.push,d=c.slice,g=c.indexOf,m=l.toString,y=l.hasOwnProperty,v=p.trim,x=function(e,n){return new x.fn.init(e,n,t)},b=/[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source,w=/\S+/g,T=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,C=/^<(\w+)\s*\/?>(?:<\/\1>|)$/,k=/^-ms-/,N=/-([\da-z])/gi,E=function(e,t){return t.toUpperCase()},S=function(){o.removeEventListener("DOMContentLoaded",S,!1),e.removeEventListener("load",S,!1),x.ready()};x.fn=x.prototype={jquery:p,constructor:x,init:function(e,t,n){var r,i;if(!e)return this;if("string"==typeof e){if(r="<"===e.charAt(0)&&">"===e.charAt(e.length-1)&&e.length>=3?[null,e,null]:T.exec(e),!r||!r[1]&&t)return!t||t.jquery?(t||n).find(e):this.constructor(t).find(e);if(r[1]){if(t=t instanceof x?t[0]:t,x.merge(this,x.parseHTML(r[1],t&&t.nodeType?t.ownerDocument||t:o,!0)),C.test(r[1])&&x.isPlainObject(t))for(r in t)x.isFunction(this[r])?this[r](t[r]):this.attr(r,t[r]);return this}return i=o.getElementById(r[2]),i&&i.parentNode&&(this.length=1,this[0]=i),this.context=o,this.selector=e,this}return e.nodeType?(this.context=this[0]=e,this.length=1,this):x.isFunction(e)?n.ready(e):(e.selector!==undefined&&(this.selector=e.selector,this.context=e.context),x.makeArray(e,this))},selector:"",length:0,toArray:function(){return d.call(this)},get:function(e){return null==e?this.toArray():0>e?this[this.length+e]:this[e]},pushStack:function(e){var t=x.merge(this.constructor(),e);return t.prevObject=this,t.context=this.context,t},each:function(e,t){return x.each(this,e,t)},ready:function(e){return x.ready.promise().done(e),this},slice:function(){return this.pushStack(d.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(e){var t=this.length,n=+e+(0>e?t:0);return this.pushStack(n>=0&&t>n?[this[n]]:[])},map:function(e){return this.pushStack(x.map(this,function(t,n){return e.call(t,n,t)}))},end:function(){return this.prevObject||this.constructor(null)},push:h,sort:[].sort,splice:[].splice},x.fn.init.prototype=x.fn,x.extend=x.fn.extend=function(){var e,t,n,r,i,o,s=arguments[0]||{},a=1,u=arguments.length,l=!1;for("boolean"==typeof s&&(l=s,s=arguments[1]||{},a=2),"object"==typeof s||x.isFunction(s)||(s={}),u===a&&(s=this,--a);u>a;a++)if(null!=(e=arguments[a]))for(t in e)n=s[t],r=e[t],s!==r&&(l&&r&&(x.isPlainObject(r)||(i=x.isArray(r)))?(i?(i=!1,o=n&&x.isArray(n)?n:[]):o=n&&x.isPlainObject(n)?n:{},s[t]=x.extend(l,o,r)):r!==undefined&&(s[t]=r));return s},x.extend({expando:"jQuery"+(p+Math.random()).replace(/\D/g,""),noConflict:function(t){return e.$===x&&(e.$=u),t&&e.jQuery===x&&(e.jQuery=a),x},isReady:!1,readyWait:1,holdReady:function(e){e?x.readyWait++:x.ready(!0)},ready:function(e){(e===!0?--x.readyWait:x.isReady)||(x.isReady=!0,e!==!0&&--x.readyWait>0||(n.resolveWith(o,[x]),x.fn.trigger&&x(o).trigger("ready").off("ready")))},isFunction:function(e){return"function"===x.type(e)},isArray:Array.isArray,isWindow:function(e){return null!=e&&e===e.window},isNumeric:function(e){return!isNaN(parseFloat(e))&&isFinite(e)},type:function(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?l[m.call(e)]||"object":typeof e},isPlainObject:function(e){if("object"!==x.type(e)||e.nodeType||x.isWindow(e))return!1;try{if(e.constructor&&!y.call(e.constructor.prototype,"isPrototypeOf"))return!1}catch(t){return!1}return!0},isEmptyObject:function(e){var t;for(t in e)return!1;return!0},error:function(e){throw Error(e)},parseHTML:function(e,t,n){if(!e||"string"!=typeof e)return null;"boolean"==typeof t&&(n=t,t=!1),t=t||o;var r=C.exec(e),i=!n&&[];return r?[t.createElement(r[1])]:(r=x.buildFragment([e],t,i),i&&x(i).remove(),x.merge([],r.childNodes))},parseJSON:JSON.parse,parseXML:function(e){var t,n;if(!e||"string"!=typeof e)return null;try{n=new DOMParser,t=n.parseFromString(e,"text/xml")}catch(r){t=undefined}return(!t||t.getElementsByTagName("parsererror").length)&&x.error("Invalid XML: "+e),t},noop:function(){},globalEval:function(e){var t,n=eval;e=x.trim(e),e&&(1===e.indexOf("use strict")?(t=o.createElement("script"),t.text=e,o.head.appendChild(t).parentNode.removeChild(t)):n(e))},camelCase:function(e){return e.replace(k,"ms-").replace(N,E)},nodeName:function(e,t){return e.nodeName&&e.nodeName.toLowerCase()===t.toLowerCase()},each:function(e,t,n){var r,i=0,o=e.length,s=j(e);if(n){if(s){for(;o>i;i++)if(r=t.apply(e[i],n),r===!1)break}else for(i in e)if(r=t.apply(e[i],n),r===!1)break}else if(s){for(;o>i;i++)if(r=t.call(e[i],i,e[i]),r===!1)break}else for(i in e)if(r=t.call(e[i],i,e[i]),r===!1)break;return e},trim:function(e){return null==e?"":v.call(e)},makeArray:function(e,t){var n=t||[];return null!=e&&(j(Object(e))?x.merge(n,"string"==typeof e?[e]:e):h.call(n,e)),n},inArray:function(e,t,n){return null==t?-1:g.call(t,e,n)},merge:function(e,t){var n=t.length,r=e.length,i=0;if("number"==typeof n)for(;n>i;i++)e[r++]=t[i];else while(t[i]!==undefined)e[r++]=t[i++];return e.length=r,e},grep:function(e,t,n){var r,i=[],o=0,s=e.length;for(n=!!n;s>o;o++)r=!!t(e[o],o),n!==r&&i.push(e[o]);return i},map:function(e,t,n){var r,i=0,o=e.length,s=j(e),a=[];if(s)for(;o>i;i++)r=t(e[i],i,n),null!=r&&(a[a.length]=r);else for(i in e)r=t(e[i],i,n),null!=r&&(a[a.length]=r);return f.apply([],a)},guid:1,proxy:function(e,t){var n,r,i;return"string"==typeof t&&(n=e[t],t=e,e=n),x.isFunction(e)?(r=d.call(arguments,2),i=function(){return e.apply(t||this,r.concat(d.call(arguments)))},i.guid=e.guid=e.guid||x.guid++,i):undefined},access:function(e,t,n,r,i,o,s){var a=0,u=e.length,l=null==n;if("object"===x.type(n)){i=!0;for(a in n)x.access(e,t,a,n[a],!0,o,s)}else if(r!==undefined&&(i=!0,x.isFunction(r)||(s=!0),l&&(s?(t.call(e,r),t=null):(l=t,t=function(e,t,n){return l.call(x(e),n)})),t))for(;u>a;a++)t(e[a],n,s?r:r.call(e[a],a,t(e[a],n)));return i?e:l?t.call(e):u?t(e[0],n):o},now:Date.now,swap:function(e,t,n,r){var i,o,s={};for(o in t)s[o]=e.style[o],e.style[o]=t[o];i=n.apply(e,r||[]);for(o in t)e.style[o]=s[o];return i}}),x.ready.promise=function(t){return n||(n=x.Deferred(),"complete"===o.readyState?setTimeout(x.ready):(o.addEventListener("DOMContentLoaded",S,!1),e.addEventListener("load",S,!1))),n.promise(t)},x.each("Boolean Number String Function Array Date RegExp Object Error".split(" "),function(e,t){l["[object "+t+"]"]=t.toLowerCase()});function j(e){var t=e.length,n=x.type(e);return x.isWindow(e)?!1:1===e.nodeType&&t?!0:"array"===n||"function"!==n&&(0===t||"number"==typeof t&&t>0&&t-1 in e)}t=x(o),function(e,undefined){var t,n,r,i,o,s,a,u,l,c,p,f,h,d,g,m,y,v="sizzle"+-new Date,b=e.document,w=0,T=0,C=st(),k=st(),N=st(),E=!1,S=function(e,t){return e===t?(E=!0,0):0},j=typeof undefined,D=1<<31,A={}.hasOwnProperty,L=[],q=L.pop,H=L.push,O=L.push,F=L.slice,P=L.indexOf||function(e){var t=0,n=this.length;for(;n>t;t++)if(this[t]===e)return t;return-1},R="checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",M="[\\x20\\t\\r\\n\\f]",W="(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",$=W.replace("w","w#"),B="\\["+M+"*("+W+")"+M+"*(?:([*^$|!~]?=)"+M+"*(?:(['\"])((?:\\\\.|[^\\\\])*?)\\3|("+$+")|)|)"+M+"*\\]",I=":("+W+")(?:\\(((['\"])((?:\\\\.|[^\\\\])*?)\\3|((?:\\\\.|[^\\\\()[\\]]|"+B.replace(3,8)+")*)|.*)\\)|)",z=RegExp("^"+M+"+|((?:^|[^\\\\])(?:\\\\.)*)"+M+"+$","g"),_=RegExp("^"+M+"*,"+M+"*"),X=RegExp("^"+M+"*([>+~]|"+M+")"+M+"*"),U=RegExp(M+"*[+~]"),Y=RegExp("="+M+"*([^\\]'\"]*)"+M+"*\\]","g"),V=RegExp(I),G=RegExp("^"+$+"$"),J={ID:RegExp("^#("+W+")"),CLASS:RegExp("^\\.("+W+")"),TAG:RegExp("^("+W.replace("w","w*")+")"),ATTR:RegExp("^"+B),PSEUDO:RegExp("^"+I),CHILD:RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+M+"*(even|odd|(([+-]|)(\\d*)n|)"+M+"*(?:([+-]|)"+M+"*(\\d+)|))"+M+"*\\)|)","i"),bool:RegExp("^(?:"+R+")$","i"),needsContext:RegExp("^"+M+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+M+"*((?:-\\d)?\\d*)"+M+"*\\)|)(?=[^-]|$)","i")},Q=/^[^{]+\{\s*\[native \w/,K=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,Z=/^(?:input|select|textarea|button)$/i,et=/^h\d$/i,tt=/'|\\/g,nt=RegExp("\\\\([\\da-f]{1,6}"+M+"?|("+M+")|.)","ig"),rt=function(e,t,n){var r="0x"+t-65536;return r!==r||n?t:0>r?String.fromCharCode(r+65536):String.fromCharCode(55296|r>>10,56320|1023&r)};try{O.apply(L=F.call(b.childNodes),b.childNodes),L[b.childNodes.length].nodeType}catch(it){O={apply:L.length?function(e,t){H.apply(e,F.call(t))}:function(e,t){var n=e.length,r=0;while(e[n++]=t[r++]);e.length=n-1}}}function ot(e,t,r,i){var o,s,a,u,l,f,g,m,x,w;if((t?t.ownerDocument||t:b)!==p&&c(t),t=t||p,r=r||[],!e||"string"!=typeof e)return r;if(1!==(u=t.nodeType)&&9!==u)return[];if(h&&!i){if(o=K.exec(e))if(a=o[1]){if(9===u){if(s=t.getElementById(a),!s||!s.parentNode)return r;if(s.id===a)return r.push(s),r}else if(t.ownerDocument&&(s=t.ownerDocument.getElementById(a))&&y(t,s)&&s.id===a)return r.push(s),r}else{if(o[2])return O.apply(r,t.getElementsByTagName(e)),r;if((a=o[3])&&n.getElementsByClassName&&t.getElementsByClassName)return O.apply(r,t.getElementsByClassName(a)),r}if(n.qsa&&(!d||!d.test(e))){if(m=g=v,x=t,w=9===u&&e,1===u&&"object"!==t.nodeName.toLowerCase()){f=gt(e),(g=t.getAttribute("id"))?m=g.replace(tt,"\\$&"):t.setAttribute("id",m),m="[id='"+m+"'] ",l=f.length;while(l--)f[l]=m+mt(f[l]);x=U.test(e)&&t.parentNode||t,w=f.join(",")}if(w)try{return O.apply(r,x.querySelectorAll(w)),r}catch(T){}finally{g||t.removeAttribute("id")}}}return kt(e.replace(z,"$1"),t,r,i)}function st(){var e=[];function t(n,r){return e.push(n+=" ")>i.cacheLength&&delete t[e.shift()],t[n]=r}return t}function at(e){return e[v]=!0,e}function ut(e){var t=p.createElement("div");try{return!!e(t)}catch(n){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function lt(e,t){var n=e.split("|"),r=e.length;while(r--)i.attrHandle[n[r]]=t}function ct(e,t){var n=t&&e,r=n&&1===e.nodeType&&1===t.nodeType&&(~t.sourceIndex||D)-(~e.sourceIndex||D);if(r)return r;if(n)while(n=n.nextSibling)if(n===t)return-1;return e?1:-1}function pt(e){return function(t){var n=t.nodeName.toLowerCase();return"input"===n&&t.type===e}}function ft(e){return function(t){var n=t.nodeName.toLowerCase();return("input"===n||"button"===n)&&t.type===e}}function ht(e){return at(function(t){return t=+t,at(function(n,r){var i,o=e([],n.length,t),s=o.length;while(s--)n[i=o[s]]&&(n[i]=!(r[i]=n[i]))})})}s=ot.isXML=function(e){var t=e&&(e.ownerDocument||e).documentElement;return t?"HTML"!==t.nodeName:!1},n=ot.support={},c=ot.setDocument=function(e){var t=e?e.ownerDocument||e:b,r=t.defaultView;return t!==p&&9===t.nodeType&&t.documentElement?(p=t,f=t.documentElement,h=!s(t),r&&r.attachEvent&&r!==r.top&&r.attachEvent("onbeforeunload",function(){c()}),n.attributes=ut(function(e){return e.className="i",!e.getAttribute("className")}),n.getElementsByTagName=ut(function(e){return e.appendChild(t.createComment("")),!e.getElementsByTagName("*").length}),n.getElementsByClassName=ut(function(e){return e.innerHTML="
",e.firstChild.className="i",2===e.getElementsByClassName("i").length}),n.getById=ut(function(e){return f.appendChild(e).id=v,!t.getElementsByName||!t.getElementsByName(v).length}),n.getById?(i.find.ID=function(e,t){if(typeof t.getElementById!==j&&h){var n=t.getElementById(e);return n&&n.parentNode?[n]:[]}},i.filter.ID=function(e){var t=e.replace(nt,rt);return function(e){return e.getAttribute("id")===t}}):(delete i.find.ID,i.filter.ID=function(e){var t=e.replace(nt,rt);return function(e){var n=typeof e.getAttributeNode!==j&&e.getAttributeNode("id");return n&&n.value===t}}),i.find.TAG=n.getElementsByTagName?function(e,t){return typeof t.getElementsByTagName!==j?t.getElementsByTagName(e):undefined}:function(e,t){var n,r=[],i=0,o=t.getElementsByTagName(e);if("*"===e){while(n=o[i++])1===n.nodeType&&r.push(n);return r}return o},i.find.CLASS=n.getElementsByClassName&&function(e,t){return typeof t.getElementsByClassName!==j&&h?t.getElementsByClassName(e):undefined},g=[],d=[],(n.qsa=Q.test(t.querySelectorAll))&&(ut(function(e){e.innerHTML="",e.querySelectorAll("[selected]").length||d.push("\\["+M+"*(?:value|"+R+")"),e.querySelectorAll(":checked").length||d.push(":checked")}),ut(function(e){var n=t.createElement("input");n.setAttribute("type","hidden"),e.appendChild(n).setAttribute("t",""),e.querySelectorAll("[t^='']").length&&d.push("[*^$]="+M+"*(?:''|\"\")"),e.querySelectorAll(":enabled").length||d.push(":enabled",":disabled"),e.querySelectorAll("*,:x"),d.push(",.*:")})),(n.matchesSelector=Q.test(m=f.webkitMatchesSelector||f.mozMatchesSelector||f.oMatchesSelector||f.msMatchesSelector))&&ut(function(e){n.disconnectedMatch=m.call(e,"div"),m.call(e,"[s!='']:x"),g.push("!=",I)}),d=d.length&&RegExp(d.join("|")),g=g.length&&RegExp(g.join("|")),y=Q.test(f.contains)||f.compareDocumentPosition?function(e,t){var n=9===e.nodeType?e.documentElement:e,r=t&&t.parentNode;return e===r||!(!r||1!==r.nodeType||!(n.contains?n.contains(r):e.compareDocumentPosition&&16&e.compareDocumentPosition(r)))}:function(e,t){if(t)while(t=t.parentNode)if(t===e)return!0;return!1},S=f.compareDocumentPosition?function(e,r){if(e===r)return E=!0,0;var i=r.compareDocumentPosition&&e.compareDocumentPosition&&e.compareDocumentPosition(r);return i?1&i||!n.sortDetached&&r.compareDocumentPosition(e)===i?e===t||y(b,e)?-1:r===t||y(b,r)?1:l?P.call(l,e)-P.call(l,r):0:4&i?-1:1:e.compareDocumentPosition?-1:1}:function(e,n){var r,i=0,o=e.parentNode,s=n.parentNode,a=[e],u=[n];if(e===n)return E=!0,0;if(!o||!s)return e===t?-1:n===t?1:o?-1:s?1:l?P.call(l,e)-P.call(l,n):0;if(o===s)return ct(e,n);r=e;while(r=r.parentNode)a.unshift(r);r=n;while(r=r.parentNode)u.unshift(r);while(a[i]===u[i])i++;return i?ct(a[i],u[i]):a[i]===b?-1:u[i]===b?1:0},t):p},ot.matches=function(e,t){return ot(e,null,null,t)},ot.matchesSelector=function(e,t){if((e.ownerDocument||e)!==p&&c(e),t=t.replace(Y,"='$1']"),!(!n.matchesSelector||!h||g&&g.test(t)||d&&d.test(t)))try{var r=m.call(e,t);if(r||n.disconnectedMatch||e.document&&11!==e.document.nodeType)return r}catch(i){}return ot(t,p,null,[e]).length>0},ot.contains=function(e,t){return(e.ownerDocument||e)!==p&&c(e),y(e,t)},ot.attr=function(e,t){(e.ownerDocument||e)!==p&&c(e);var r=i.attrHandle[t.toLowerCase()],o=r&&A.call(i.attrHandle,t.toLowerCase())?r(e,t,!h):undefined;return o===undefined?n.attributes||!h?e.getAttribute(t):(o=e.getAttributeNode(t))&&o.specified?o.value:null:o},ot.error=function(e){throw Error("Syntax error, unrecognized expression: "+e)},ot.uniqueSort=function(e){var t,r=[],i=0,o=0;if(E=!n.detectDuplicates,l=!n.sortStable&&e.slice(0),e.sort(S),E){while(t=e[o++])t===e[o]&&(i=r.push(o));while(i--)e.splice(r[i],1)}return e},o=ot.getText=function(e){var t,n="",r=0,i=e.nodeType;if(i){if(1===i||9===i||11===i){if("string"==typeof e.textContent)return e.textContent;for(e=e.firstChild;e;e=e.nextSibling)n+=o(e)}else if(3===i||4===i)return e.nodeValue}else for(;t=e[r];r++)n+=o(t);return n},i=ot.selectors={cacheLength:50,createPseudo:at,match:J,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(nt,rt),e[3]=(e[4]||e[5]||"").replace(nt,rt),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||ot.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&ot.error(e[0]),e},PSEUDO:function(e){var t,n=!e[5]&&e[2];return J.CHILD.test(e[0])?null:(e[3]&&e[4]!==undefined?e[2]=e[4]:n&&V.test(n)&&(t=gt(n,!0))&&(t=n.indexOf(")",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(nt,rt).toLowerCase();return"*"===e?function(){return!0}:function(e){return e.nodeName&&e.nodeName.toLowerCase()===t}},CLASS:function(e){var t=C[e+" "];return t||(t=RegExp("(^|"+M+")"+e+"("+M+"|$)"))&&C(e,function(e){return t.test("string"==typeof e.className&&e.className||typeof e.getAttribute!==j&&e.getAttribute("class")||"")})},ATTR:function(e,t,n){return function(r){var i=ot.attr(r,e);return null==i?"!="===t:t?(i+="","="===t?i===n:"!="===t?i!==n:"^="===t?n&&0===i.indexOf(n):"*="===t?n&&i.indexOf(n)>-1:"$="===t?n&&i.slice(-n.length)===n:"~="===t?(" "+i+" ").indexOf(n)>-1:"|="===t?i===n||i.slice(0,n.length+1)===n+"-":!1):!0}},CHILD:function(e,t,n,r,i){var o="nth"!==e.slice(0,3),s="last"!==e.slice(-4),a="of-type"===t;return 1===r&&0===i?function(e){return!!e.parentNode}:function(t,n,u){var l,c,p,f,h,d,g=o!==s?"nextSibling":"previousSibling",m=t.parentNode,y=a&&t.nodeName.toLowerCase(),x=!u&&!a;if(m){if(o){while(g){p=t;while(p=p[g])if(a?p.nodeName.toLowerCase()===y:1===p.nodeType)return!1;d=g="only"===e&&!d&&"nextSibling"}return!0}if(d=[s?m.firstChild:m.lastChild],s&&x){c=m[v]||(m[v]={}),l=c[e]||[],h=l[0]===w&&l[1],f=l[0]===w&&l[2],p=h&&m.childNodes[h];while(p=++h&&p&&p[g]||(f=h=0)||d.pop())if(1===p.nodeType&&++f&&p===t){c[e]=[w,h,f];break}}else if(x&&(l=(t[v]||(t[v]={}))[e])&&l[0]===w)f=l[1];else while(p=++h&&p&&p[g]||(f=h=0)||d.pop())if((a?p.nodeName.toLowerCase()===y:1===p.nodeType)&&++f&&(x&&((p[v]||(p[v]={}))[e]=[w,f]),p===t))break;return f-=i,f===r||0===f%r&&f/r>=0}}},PSEUDO:function(e,t){var n,r=i.pseudos[e]||i.setFilters[e.toLowerCase()]||ot.error("unsupported pseudo: "+e);return r[v]?r(t):r.length>1?(n=[e,e,"",t],i.setFilters.hasOwnProperty(e.toLowerCase())?at(function(e,n){var i,o=r(e,t),s=o.length;while(s--)i=P.call(e,o[s]),e[i]=!(n[i]=o[s])}):function(e){return r(e,0,n)}):r}},pseudos:{not:at(function(e){var t=[],n=[],r=a(e.replace(z,"$1"));return r[v]?at(function(e,t,n,i){var o,s=r(e,null,i,[]),a=e.length;while(a--)(o=s[a])&&(e[a]=!(t[a]=o))}):function(e,i,o){return t[0]=e,r(t,null,o,n),!n.pop()}}),has:at(function(e){return function(t){return ot(e,t).length>0}}),contains:at(function(e){return function(t){return(t.textContent||t.innerText||o(t)).indexOf(e)>-1}}),lang:at(function(e){return G.test(e||"")||ot.error("unsupported lang: "+e),e=e.replace(nt,rt).toLowerCase(),function(t){var n;do if(n=h?t.lang:t.getAttribute("xml:lang")||t.getAttribute("lang"))return n=n.toLowerCase(),n===e||0===n.indexOf(e+"-");while((t=t.parentNode)&&1===t.nodeType);return!1}}),target:function(t){var n=e.location&&e.location.hash;return n&&n.slice(1)===t.id},root:function(e){return e===f},focus:function(e){return e===p.activeElement&&(!p.hasFocus||p.hasFocus())&&!!(e.type||e.href||~e.tabIndex)},enabled:function(e){return e.disabled===!1},disabled:function(e){return e.disabled===!0},checked:function(e){var t=e.nodeName.toLowerCase();return"input"===t&&!!e.checked||"option"===t&&!!e.selected},selected:function(e){return e.parentNode&&e.parentNode.selectedIndex,e.selected===!0},empty:function(e){for(e=e.firstChild;e;e=e.nextSibling)if(e.nodeName>"@"||3===e.nodeType||4===e.nodeType)return!1;return!0},parent:function(e){return!i.pseudos.empty(e)},header:function(e){return et.test(e.nodeName)},input:function(e){return Z.test(e.nodeName)},button:function(e){var t=e.nodeName.toLowerCase();return"input"===t&&"button"===e.type||"button"===t},text:function(e){var t;return"input"===e.nodeName.toLowerCase()&&"text"===e.type&&(null==(t=e.getAttribute("type"))||t.toLowerCase()===e.type)},first:ht(function(){return[0]}),last:ht(function(e,t){return[t-1]}),eq:ht(function(e,t,n){return[0>n?n+t:n]}),even:ht(function(e,t){var n=0;for(;t>n;n+=2)e.push(n);return e}),odd:ht(function(e,t){var n=1;for(;t>n;n+=2)e.push(n);return e}),lt:ht(function(e,t,n){var r=0>n?n+t:n;for(;--r>=0;)e.push(r);return e}),gt:ht(function(e,t,n){var r=0>n?n+t:n;for(;t>++r;)e.push(r);return e})}},i.pseudos.nth=i.pseudos.eq;for(t in{radio:!0,checkbox:!0,file:!0,password:!0,image:!0})i.pseudos[t]=pt(t);for(t in{submit:!0,reset:!0})i.pseudos[t]=ft(t);function dt(){}dt.prototype=i.filters=i.pseudos,i.setFilters=new dt;function gt(e,t){var n,r,o,s,a,u,l,c=k[e+" "];if(c)return t?0:c.slice(0);a=e,u=[],l=i.preFilter;while(a){(!n||(r=_.exec(a)))&&(r&&(a=a.slice(r[0].length)||a),u.push(o=[])),n=!1,(r=X.exec(a))&&(n=r.shift(),o.push({value:n,type:r[0].replace(z," ")}),a=a.slice(n.length));for(s in i.filter)!(r=J[s].exec(a))||l[s]&&!(r=l[s](r))||(n=r.shift(),o.push({value:n,type:s,matches:r}),a=a.slice(n.length));if(!n)break}return t?a.length:a?ot.error(e):k(e,u).slice(0)}function mt(e){var t=0,n=e.length,r="";for(;n>t;t++)r+=e[t].value;return r}function yt(e,t,n){var i=t.dir,o=n&&"parentNode"===i,s=T++;return t.first?function(t,n,r){while(t=t[i])if(1===t.nodeType||o)return e(t,n,r)}:function(t,n,a){var u,l,c,p=w+" "+s;if(a){while(t=t[i])if((1===t.nodeType||o)&&e(t,n,a))return!0}else while(t=t[i])if(1===t.nodeType||o)if(c=t[v]||(t[v]={}),(l=c[i])&&l[0]===p){if((u=l[1])===!0||u===r)return u===!0}else if(l=c[i]=[p],l[1]=e(t,n,a)||r,l[1]===!0)return!0}}function vt(e){return e.length>1?function(t,n,r){var i=e.length;while(i--)if(!e[i](t,n,r))return!1;return!0}:e[0]}function xt(e,t,n,r,i){var o,s=[],a=0,u=e.length,l=null!=t;for(;u>a;a++)(o=e[a])&&(!n||n(o,r,i))&&(s.push(o),l&&t.push(a));return s}function bt(e,t,n,r,i,o){return r&&!r[v]&&(r=bt(r)),i&&!i[v]&&(i=bt(i,o)),at(function(o,s,a,u){var l,c,p,f=[],h=[],d=s.length,g=o||Ct(t||"*",a.nodeType?[a]:a,[]),m=!e||!o&&t?g:xt(g,f,e,a,u),y=n?i||(o?e:d||r)?[]:s:m;if(n&&n(m,y,a,u),r){l=xt(y,h),r(l,[],a,u),c=l.length;while(c--)(p=l[c])&&(y[h[c]]=!(m[h[c]]=p))}if(o){if(i||e){if(i){l=[],c=y.length;while(c--)(p=y[c])&&l.push(m[c]=p);i(null,y=[],l,u)}c=y.length;while(c--)(p=y[c])&&(l=i?P.call(o,p):f[c])>-1&&(o[l]=!(s[l]=p))}}else y=xt(y===s?y.splice(d,y.length):y),i?i(null,s,y,u):O.apply(s,y)})}function wt(e){var t,n,r,o=e.length,s=i.relative[e[0].type],a=s||i.relative[" "],l=s?1:0,c=yt(function(e){return e===t},a,!0),p=yt(function(e){return P.call(t,e)>-1},a,!0),f=[function(e,n,r){return!s&&(r||n!==u)||((t=n).nodeType?c(e,n,r):p(e,n,r))}];for(;o>l;l++)if(n=i.relative[e[l].type])f=[yt(vt(f),n)];else{if(n=i.filter[e[l].type].apply(null,e[l].matches),n[v]){for(r=++l;o>r;r++)if(i.relative[e[r].type])break;return bt(l>1&&vt(f),l>1&&mt(e.slice(0,l-1).concat({value:" "===e[l-2].type?"*":""})).replace(z,"$1"),n,r>l&&wt(e.slice(l,r)),o>r&&wt(e=e.slice(r)),o>r&&mt(e))}f.push(n)}return vt(f)}function Tt(e,t){var n=0,o=t.length>0,s=e.length>0,a=function(a,l,c,f,h){var d,g,m,y=[],v=0,x="0",b=a&&[],T=null!=h,C=u,k=a||s&&i.find.TAG("*",h&&l.parentNode||l),N=w+=null==C?1:Math.random()||.1;for(T&&(u=l!==p&&l,r=n);null!=(d=k[x]);x++){if(s&&d){g=0;while(m=e[g++])if(m(d,l,c)){f.push(d);break}T&&(w=N,r=++n)}o&&((d=!m&&d)&&v--,a&&b.push(d))}if(v+=x,o&&x!==v){g=0;while(m=t[g++])m(b,y,l,c);if(a){if(v>0)while(x--)b[x]||y[x]||(y[x]=q.call(f));y=xt(y)}O.apply(f,y),T&&!a&&y.length>0&&v+t.length>1&&ot.uniqueSort(f)}return T&&(w=N,u=C),b};return o?at(a):a}a=ot.compile=function(e,t){var n,r=[],i=[],o=N[e+" "];if(!o){t||(t=gt(e)),n=t.length;while(n--)o=wt(t[n]),o[v]?r.push(o):i.push(o);o=N(e,Tt(i,r))}return o};function Ct(e,t,n){var r=0,i=t.length;for(;i>r;r++)ot(e,t[r],n);return n}function kt(e,t,r,o){var s,u,l,c,p,f=gt(e);if(!o&&1===f.length){if(u=f[0]=f[0].slice(0),u.length>2&&"ID"===(l=u[0]).type&&n.getById&&9===t.nodeType&&h&&i.relative[u[1].type]){if(t=(i.find.ID(l.matches[0].replace(nt,rt),t)||[])[0],!t)return r;e=e.slice(u.shift().value.length)}s=J.needsContext.test(e)?0:u.length;while(s--){if(l=u[s],i.relative[c=l.type])break;if((p=i.find[c])&&(o=p(l.matches[0].replace(nt,rt),U.test(u[0].type)&&t.parentNode||t))){if(u.splice(s,1),e=o.length&&mt(u),!e)return O.apply(r,o),r;break}}}return a(e,f)(o,t,!h,r,U.test(e)),r}n.sortStable=v.split("").sort(S).join("")===v,n.detectDuplicates=E,c(),n.sortDetached=ut(function(e){return 1&e.compareDocumentPosition(p.createElement("div"))}),ut(function(e){return e.innerHTML="","#"===e.firstChild.getAttribute("href")})||lt("type|href|height|width",function(e,t,n){return n?undefined:e.getAttribute(t,"type"===t.toLowerCase()?1:2)}),n.attributes&&ut(function(e){return e.innerHTML="",e.firstChild.setAttribute("value",""),""===e.firstChild.getAttribute("value")})||lt("value",function(e,t,n){return n||"input"!==e.nodeName.toLowerCase()?undefined:e.defaultValue}),ut(function(e){return null==e.getAttribute("disabled")})||lt(R,function(e,t,n){var r;return n?undefined:(r=e.getAttributeNode(t))&&r.specified?r.value:e[t]===!0?t.toLowerCase():null}),x.find=ot,x.expr=ot.selectors,x.expr[":"]=x.expr.pseudos,x.unique=ot.uniqueSort,x.text=ot.getText,x.isXMLDoc=ot.isXML,x.contains=ot.contains}(e);var D={};function A(e){var t=D[e]={};return x.each(e.match(w)||[],function(e,n){t[n]=!0}),t}x.Callbacks=function(e){e="string"==typeof e?D[e]||A(e):x.extend({},e);var t,n,r,i,o,s,a=[],u=!e.once&&[],l=function(p){for(t=e.memory&&p,n=!0,s=i||0,i=0,o=a.length,r=!0;a&&o>s;s++)if(a[s].apply(p[0],p[1])===!1&&e.stopOnFalse){t=!1;break}r=!1,a&&(u?u.length&&l(u.shift()):t?a=[]:c.disable())},c={add:function(){if(a){var n=a.length;(function s(t){x.each(t,function(t,n){var r=x.type(n);"function"===r?e.unique&&c.has(n)||a.push(n):n&&n.length&&"string"!==r&&s(n)})})(arguments),r?o=a.length:t&&(i=n,l(t))}return this},remove:function(){return a&&x.each(arguments,function(e,t){var n;while((n=x.inArray(t,a,n))>-1)a.splice(n,1),r&&(o>=n&&o--,s>=n&&s--)}),this},has:function(e){return e?x.inArray(e,a)>-1:!(!a||!a.length)},empty:function(){return a=[],o=0,this},disable:function(){return a=u=t=undefined,this},disabled:function(){return!a},lock:function(){return u=undefined,t||c.disable(),this},locked:function(){return!u},fireWith:function(e,t){return!a||n&&!u||(t=t||[],t=[e,t.slice?t.slice():t],r?u.push(t):l(t)),this},fire:function(){return c.fireWith(this,arguments),this},fired:function(){return!!n}};return c},x.extend({Deferred:function(e){var t=[["resolve","done",x.Callbacks("once memory"),"resolved"],["reject","fail",x.Callbacks("once memory"),"rejected"],["notify","progress",x.Callbacks("memory")]],n="pending",r={state:function(){return n},always:function(){return i.done(arguments).fail(arguments),this},then:function(){var e=arguments;return x.Deferred(function(n){x.each(t,function(t,o){var s=o[0],a=x.isFunction(e[t])&&e[t];i[o[1]](function(){var e=a&&a.apply(this,arguments);e&&x.isFunction(e.promise)?e.promise().done(n.resolve).fail(n.reject).progress(n.notify):n[s+"With"](this===r?n.promise():this,a?[e]:arguments)})}),e=null}).promise()},promise:function(e){return null!=e?x.extend(e,r):r}},i={};return r.pipe=r.then,x.each(t,function(e,o){var s=o[2],a=o[3];r[o[1]]=s.add,a&&s.add(function(){n=a},t[1^e][2].disable,t[2][2].lock),i[o[0]]=function(){return i[o[0]+"With"](this===i?r:this,arguments),this},i[o[0]+"With"]=s.fireWith}),r.promise(i),e&&e.call(i,i),i},when:function(e){var t=0,n=d.call(arguments),r=n.length,i=1!==r||e&&x.isFunction(e.promise)?r:0,o=1===i?e:x.Deferred(),s=function(e,t,n){return function(r){t[e]=this,n[e]=arguments.length>1?d.call(arguments):r,n===a?o.notifyWith(t,n):--i||o.resolveWith(t,n)}},a,u,l;if(r>1)for(a=Array(r),u=Array(r),l=Array(r);r>t;t++)n[t]&&x.isFunction(n[t].promise)?n[t].promise().done(s(t,l,n)).fail(o.reject).progress(s(t,u,a)):--i;return i||o.resolveWith(l,n),o.promise()}}),x.support=function(t){var n=o.createElement("input"),r=o.createDocumentFragment(),i=o.createElement("div"),s=o.createElement("select"),a=s.appendChild(o.createElement("option"));return n.type?(n.type="checkbox",t.checkOn=""!==n.value,t.optSelected=a.selected,t.reliableMarginRight=!0,t.boxSizingReliable=!0,t.pixelPosition=!1,n.checked=!0,t.noCloneChecked=n.cloneNode(!0).checked,s.disabled=!0,t.optDisabled=!a.disabled,n=o.createElement("input"),n.value="t",n.type="radio",t.radioValue="t"===n.value,n.setAttribute("checked","t"),n.setAttribute("name","t"),r.appendChild(n),t.checkClone=r.cloneNode(!0).cloneNode(!0).lastChild.checked,t.focusinBubbles="onfocusin"in e,i.style.backgroundClip="content-box",i.cloneNode(!0).style.backgroundClip="",t.clearCloneStyle="content-box"===i.style.backgroundClip,x(function(){var n,r,s="padding:0;margin:0;border:0;display:block;-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box",a=o.getElementsByTagName("body")[0];a&&(n=o.createElement("div"),n.style.cssText="border:0;width:0;height:0;position:absolute;top:0;left:-9999px;margin-top:1px",a.appendChild(n).appendChild(i),i.innerHTML="",i.style.cssText="-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;padding:1px;border:1px;display:block;width:4px;margin-top:1%;position:absolute;top:1%",x.swap(a,null!=a.style.zoom?{zoom:1}:{},function(){t.boxSizing=4===i.offsetWidth}),e.getComputedStyle&&(t.pixelPosition="1%"!==(e.getComputedStyle(i,null)||{}).top,t.boxSizingReliable="4px"===(e.getComputedStyle(i,null)||{width:"4px"}).width,r=i.appendChild(o.createElement("div")),r.style.cssText=i.style.cssText=s,r.style.marginRight=r.style.width="0",i.style.width="1px",t.reliableMarginRight=!parseFloat((e.getComputedStyle(r,null)||{}).marginRight)),a.removeChild(n))}),t):t}({});var L,q,H=/(?:\{[\s\S]*\}|\[[\s\S]*\])$/,O=/([A-Z])/g;function F(){Object.defineProperty(this.cache={},0,{get:function(){return{}}}),this.expando=x.expando+Math.random()}F.uid=1,F.accepts=function(e){return e.nodeType?1===e.nodeType||9===e.nodeType:!0},F.prototype={key:function(e){if(!F.accepts(e))return 0;var t={},n=e[this.expando];if(!n){n=F.uid++;try{t[this.expando]={value:n},Object.defineProperties(e,t)}catch(r){t[this.expando]=n,x.extend(e,t)}}return this.cache[n]||(this.cache[n]={}),n},set:function(e,t,n){var r,i=this.key(e),o=this.cache[i];if("string"==typeof t)o[t]=n;else if(x.isEmptyObject(o))x.extend(this.cache[i],t);else for(r in t)o[r]=t[r];return o},get:function(e,t){var n=this.cache[this.key(e)];return t===undefined?n:n[t]},access:function(e,t,n){var r;return t===undefined||t&&"string"==typeof t&&n===undefined?(r=this.get(e,t),r!==undefined?r:this.get(e,x.camelCase(t))):(this.set(e,t,n),n!==undefined?n:t)},remove:function(e,t){var n,r,i,o=this.key(e),s=this.cache[o];if(t===undefined)this.cache[o]={};else{x.isArray(t)?r=t.concat(t.map(x.camelCase)):(i=x.camelCase(t),t in s?r=[t,i]:(r=i,r=r in s?[r]:r.match(w)||[])),n=r.length;while(n--)delete s[r[n]]}},hasData:function(e){return!x.isEmptyObject(this.cache[e[this.expando]]||{})},discard:function(e){e[this.expando]&&delete this.cache[e[this.expando]]}},L=new F,q=new F,x.extend({acceptData:F.accepts,hasData:function(e){return L.hasData(e)||q.hasData(e)},data:function(e,t,n){return L.access(e,t,n)},removeData:function(e,t){L.remove(e,t)},_data:function(e,t,n){return q.access(e,t,n)},_removeData:function(e,t){q.remove(e,t)}}),x.fn.extend({data:function(e,t){var n,r,i=this[0],o=0,s=null;if(e===undefined){if(this.length&&(s=L.get(i),1===i.nodeType&&!q.get(i,"hasDataAttrs"))){for(n=i.attributes;n.length>o;o++)r=n[o].name,0===r.indexOf("data-")&&(r=x.camelCase(r.slice(5)),P(i,r,s[r]));q.set(i,"hasDataAttrs",!0)}return s}return"object"==typeof e?this.each(function(){L.set(this,e)}):x.access(this,function(t){var n,r=x.camelCase(e);if(i&&t===undefined){if(n=L.get(i,e),n!==undefined)return n;if(n=L.get(i,r),n!==undefined)return n;if(n=P(i,r,undefined),n!==undefined)return n}else this.each(function(){var n=L.get(this,r);L.set(this,r,t),-1!==e.indexOf("-")&&n!==undefined&&L.set(this,e,t)})},null,t,arguments.length>1,null,!0)},removeData:function(e){return this.each(function(){L.remove(this,e)})}});function P(e,t,n){var r;if(n===undefined&&1===e.nodeType)if(r="data-"+t.replace(O,"-$1").toLowerCase(),n=e.getAttribute(r),"string"==typeof n){try{n="true"===n?!0:"false"===n?!1:"null"===n?null:+n+""===n?+n:H.test(n)?JSON.parse(n):n}catch(i){}L.set(e,t,n)}else n=undefined;return n}x.extend({queue:function(e,t,n){var r;return e?(t=(t||"fx")+"queue",r=q.get(e,t),n&&(!r||x.isArray(n)?r=q.access(e,t,x.makeArray(n)):r.push(n)),r||[]):undefined},dequeue:function(e,t){t=t||"fx";var n=x.queue(e,t),r=n.length,i=n.shift(),o=x._queueHooks(e,t),s=function(){x.dequeue(e,t) -};"inprogress"===i&&(i=n.shift(),r--),i&&("fx"===t&&n.unshift("inprogress"),delete o.stop,i.call(e,s,o)),!r&&o&&o.empty.fire()},_queueHooks:function(e,t){var n=t+"queueHooks";return q.get(e,n)||q.access(e,n,{empty:x.Callbacks("once memory").add(function(){q.remove(e,[t+"queue",n])})})}}),x.fn.extend({queue:function(e,t){var n=2;return"string"!=typeof e&&(t=e,e="fx",n--),n>arguments.length?x.queue(this[0],e):t===undefined?this:this.each(function(){var n=x.queue(this,e,t);x._queueHooks(this,e),"fx"===e&&"inprogress"!==n[0]&&x.dequeue(this,e)})},dequeue:function(e){return this.each(function(){x.dequeue(this,e)})},delay:function(e,t){return e=x.fx?x.fx.speeds[e]||e:e,t=t||"fx",this.queue(t,function(t,n){var r=setTimeout(t,e);n.stop=function(){clearTimeout(r)}})},clearQueue:function(e){return this.queue(e||"fx",[])},promise:function(e,t){var n,r=1,i=x.Deferred(),o=this,s=this.length,a=function(){--r||i.resolveWith(o,[o])};"string"!=typeof e&&(t=e,e=undefined),e=e||"fx";while(s--)n=q.get(o[s],e+"queueHooks"),n&&n.empty&&(r++,n.empty.add(a));return a(),i.promise(t)}});var R,M,W=/[\t\r\n\f]/g,$=/\r/g,B=/^(?:input|select|textarea|button)$/i;x.fn.extend({attr:function(e,t){return x.access(this,x.attr,e,t,arguments.length>1)},removeAttr:function(e){return this.each(function(){x.removeAttr(this,e)})},prop:function(e,t){return x.access(this,x.prop,e,t,arguments.length>1)},removeProp:function(e){return this.each(function(){delete this[x.propFix[e]||e]})},addClass:function(e){var t,n,r,i,o,s=0,a=this.length,u="string"==typeof e&&e;if(x.isFunction(e))return this.each(function(t){x(this).addClass(e.call(this,t,this.className))});if(u)for(t=(e||"").match(w)||[];a>s;s++)if(n=this[s],r=1===n.nodeType&&(n.className?(" "+n.className+" ").replace(W," "):" ")){o=0;while(i=t[o++])0>r.indexOf(" "+i+" ")&&(r+=i+" ");n.className=x.trim(r)}return this},removeClass:function(e){var t,n,r,i,o,s=0,a=this.length,u=0===arguments.length||"string"==typeof e&&e;if(x.isFunction(e))return this.each(function(t){x(this).removeClass(e.call(this,t,this.className))});if(u)for(t=(e||"").match(w)||[];a>s;s++)if(n=this[s],r=1===n.nodeType&&(n.className?(" "+n.className+" ").replace(W," "):"")){o=0;while(i=t[o++])while(r.indexOf(" "+i+" ")>=0)r=r.replace(" "+i+" "," ");n.className=e?x.trim(r):""}return this},toggleClass:function(e,t){var n=typeof e;return"boolean"==typeof t&&"string"===n?t?this.addClass(e):this.removeClass(e):x.isFunction(e)?this.each(function(n){x(this).toggleClass(e.call(this,n,this.className,t),t)}):this.each(function(){if("string"===n){var t,i=0,o=x(this),s=e.match(w)||[];while(t=s[i++])o.hasClass(t)?o.removeClass(t):o.addClass(t)}else(n===r||"boolean"===n)&&(this.className&&q.set(this,"__className__",this.className),this.className=this.className||e===!1?"":q.get(this,"__className__")||"")})},hasClass:function(e){var t=" "+e+" ",n=0,r=this.length;for(;r>n;n++)if(1===this[n].nodeType&&(" "+this[n].className+" ").replace(W," ").indexOf(t)>=0)return!0;return!1},val:function(e){var t,n,r,i=this[0];{if(arguments.length)return r=x.isFunction(e),this.each(function(n){var i;1===this.nodeType&&(i=r?e.call(this,n,x(this).val()):e,null==i?i="":"number"==typeof i?i+="":x.isArray(i)&&(i=x.map(i,function(e){return null==e?"":e+""})),t=x.valHooks[this.type]||x.valHooks[this.nodeName.toLowerCase()],t&&"set"in t&&t.set(this,i,"value")!==undefined||(this.value=i))});if(i)return t=x.valHooks[i.type]||x.valHooks[i.nodeName.toLowerCase()],t&&"get"in t&&(n=t.get(i,"value"))!==undefined?n:(n=i.value,"string"==typeof n?n.replace($,""):null==n?"":n)}}}),x.extend({valHooks:{option:{get:function(e){var t=e.attributes.value;return!t||t.specified?e.value:e.text}},select:{get:function(e){var t,n,r=e.options,i=e.selectedIndex,o="select-one"===e.type||0>i,s=o?null:[],a=o?i+1:r.length,u=0>i?a:o?i:0;for(;a>u;u++)if(n=r[u],!(!n.selected&&u!==i||(x.support.optDisabled?n.disabled:null!==n.getAttribute("disabled"))||n.parentNode.disabled&&x.nodeName(n.parentNode,"optgroup"))){if(t=x(n).val(),o)return t;s.push(t)}return s},set:function(e,t){var n,r,i=e.options,o=x.makeArray(t),s=i.length;while(s--)r=i[s],(r.selected=x.inArray(x(r).val(),o)>=0)&&(n=!0);return n||(e.selectedIndex=-1),o}}},attr:function(e,t,n){var i,o,s=e.nodeType;if(e&&3!==s&&8!==s&&2!==s)return typeof e.getAttribute===r?x.prop(e,t,n):(1===s&&x.isXMLDoc(e)||(t=t.toLowerCase(),i=x.attrHooks[t]||(x.expr.match.bool.test(t)?M:R)),n===undefined?i&&"get"in i&&null!==(o=i.get(e,t))?o:(o=x.find.attr(e,t),null==o?undefined:o):null!==n?i&&"set"in i&&(o=i.set(e,n,t))!==undefined?o:(e.setAttribute(t,n+""),n):(x.removeAttr(e,t),undefined))},removeAttr:function(e,t){var n,r,i=0,o=t&&t.match(w);if(o&&1===e.nodeType)while(n=o[i++])r=x.propFix[n]||n,x.expr.match.bool.test(n)&&(e[r]=!1),e.removeAttribute(n)},attrHooks:{type:{set:function(e,t){if(!x.support.radioValue&&"radio"===t&&x.nodeName(e,"input")){var n=e.value;return e.setAttribute("type",t),n&&(e.value=n),t}}}},propFix:{"for":"htmlFor","class":"className"},prop:function(e,t,n){var r,i,o,s=e.nodeType;if(e&&3!==s&&8!==s&&2!==s)return o=1!==s||!x.isXMLDoc(e),o&&(t=x.propFix[t]||t,i=x.propHooks[t]),n!==undefined?i&&"set"in i&&(r=i.set(e,n,t))!==undefined?r:e[t]=n:i&&"get"in i&&null!==(r=i.get(e,t))?r:e[t]},propHooks:{tabIndex:{get:function(e){return e.hasAttribute("tabindex")||B.test(e.nodeName)||e.href?e.tabIndex:-1}}}}),M={set:function(e,t,n){return t===!1?x.removeAttr(e,n):e.setAttribute(n,n),n}},x.each(x.expr.match.bool.source.match(/\w+/g),function(e,t){var n=x.expr.attrHandle[t]||x.find.attr;x.expr.attrHandle[t]=function(e,t,r){var i=x.expr.attrHandle[t],o=r?undefined:(x.expr.attrHandle[t]=undefined)!=n(e,t,r)?t.toLowerCase():null;return x.expr.attrHandle[t]=i,o}}),x.support.optSelected||(x.propHooks.selected={get:function(e){var t=e.parentNode;return t&&t.parentNode&&t.parentNode.selectedIndex,null}}),x.each(["tabIndex","readOnly","maxLength","cellSpacing","cellPadding","rowSpan","colSpan","useMap","frameBorder","contentEditable"],function(){x.propFix[this.toLowerCase()]=this}),x.each(["radio","checkbox"],function(){x.valHooks[this]={set:function(e,t){return x.isArray(t)?e.checked=x.inArray(x(e).val(),t)>=0:undefined}},x.support.checkOn||(x.valHooks[this].get=function(e){return null===e.getAttribute("value")?"on":e.value})});var I=/^key/,z=/^(?:mouse|contextmenu)|click/,_=/^(?:focusinfocus|focusoutblur)$/,X=/^([^.]*)(?:\.(.+)|)$/;function U(){return!0}function Y(){return!1}function V(){try{return o.activeElement}catch(e){}}x.event={global:{},add:function(e,t,n,i,o){var s,a,u,l,c,p,f,h,d,g,m,y=q.get(e);if(y){n.handler&&(s=n,n=s.handler,o=s.selector),n.guid||(n.guid=x.guid++),(l=y.events)||(l=y.events={}),(a=y.handle)||(a=y.handle=function(e){return typeof x===r||e&&x.event.triggered===e.type?undefined:x.event.dispatch.apply(a.elem,arguments)},a.elem=e),t=(t||"").match(w)||[""],c=t.length;while(c--)u=X.exec(t[c])||[],d=m=u[1],g=(u[2]||"").split(".").sort(),d&&(f=x.event.special[d]||{},d=(o?f.delegateType:f.bindType)||d,f=x.event.special[d]||{},p=x.extend({type:d,origType:m,data:i,handler:n,guid:n.guid,selector:o,needsContext:o&&x.expr.match.needsContext.test(o),namespace:g.join(".")},s),(h=l[d])||(h=l[d]=[],h.delegateCount=0,f.setup&&f.setup.call(e,i,g,a)!==!1||e.addEventListener&&e.addEventListener(d,a,!1)),f.add&&(f.add.call(e,p),p.handler.guid||(p.handler.guid=n.guid)),o?h.splice(h.delegateCount++,0,p):h.push(p),x.event.global[d]=!0);e=null}},remove:function(e,t,n,r,i){var o,s,a,u,l,c,p,f,h,d,g,m=q.hasData(e)&&q.get(e);if(m&&(u=m.events)){t=(t||"").match(w)||[""],l=t.length;while(l--)if(a=X.exec(t[l])||[],h=g=a[1],d=(a[2]||"").split(".").sort(),h){p=x.event.special[h]||{},h=(r?p.delegateType:p.bindType)||h,f=u[h]||[],a=a[2]&&RegExp("(^|\\.)"+d.join("\\.(?:.*\\.|)")+"(\\.|$)"),s=o=f.length;while(o--)c=f[o],!i&&g!==c.origType||n&&n.guid!==c.guid||a&&!a.test(c.namespace)||r&&r!==c.selector&&("**"!==r||!c.selector)||(f.splice(o,1),c.selector&&f.delegateCount--,p.remove&&p.remove.call(e,c));s&&!f.length&&(p.teardown&&p.teardown.call(e,d,m.handle)!==!1||x.removeEvent(e,h,m.handle),delete u[h])}else for(h in u)x.event.remove(e,h+t[l],n,r,!0);x.isEmptyObject(u)&&(delete m.handle,q.remove(e,"events"))}},trigger:function(t,n,r,i){var s,a,u,l,c,p,f,h=[r||o],d=y.call(t,"type")?t.type:t,g=y.call(t,"namespace")?t.namespace.split("."):[];if(a=u=r=r||o,3!==r.nodeType&&8!==r.nodeType&&!_.test(d+x.event.triggered)&&(d.indexOf(".")>=0&&(g=d.split("."),d=g.shift(),g.sort()),c=0>d.indexOf(":")&&"on"+d,t=t[x.expando]?t:new x.Event(d,"object"==typeof t&&t),t.isTrigger=i?2:3,t.namespace=g.join("."),t.namespace_re=t.namespace?RegExp("(^|\\.)"+g.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,t.result=undefined,t.target||(t.target=r),n=null==n?[t]:x.makeArray(n,[t]),f=x.event.special[d]||{},i||!f.trigger||f.trigger.apply(r,n)!==!1)){if(!i&&!f.noBubble&&!x.isWindow(r)){for(l=f.delegateType||d,_.test(l+d)||(a=a.parentNode);a;a=a.parentNode)h.push(a),u=a;u===(r.ownerDocument||o)&&h.push(u.defaultView||u.parentWindow||e)}s=0;while((a=h[s++])&&!t.isPropagationStopped())t.type=s>1?l:f.bindType||d,p=(q.get(a,"events")||{})[t.type]&&q.get(a,"handle"),p&&p.apply(a,n),p=c&&a[c],p&&x.acceptData(a)&&p.apply&&p.apply(a,n)===!1&&t.preventDefault();return t.type=d,i||t.isDefaultPrevented()||f._default&&f._default.apply(h.pop(),n)!==!1||!x.acceptData(r)||c&&x.isFunction(r[d])&&!x.isWindow(r)&&(u=r[c],u&&(r[c]=null),x.event.triggered=d,r[d](),x.event.triggered=undefined,u&&(r[c]=u)),t.result}},dispatch:function(e){e=x.event.fix(e);var t,n,r,i,o,s=[],a=d.call(arguments),u=(q.get(this,"events")||{})[e.type]||[],l=x.event.special[e.type]||{};if(a[0]=e,e.delegateTarget=this,!l.preDispatch||l.preDispatch.call(this,e)!==!1){s=x.event.handlers.call(this,e,u),t=0;while((i=s[t++])&&!e.isPropagationStopped()){e.currentTarget=i.elem,n=0;while((o=i.handlers[n++])&&!e.isImmediatePropagationStopped())(!e.namespace_re||e.namespace_re.test(o.namespace))&&(e.handleObj=o,e.data=o.data,r=((x.event.special[o.origType]||{}).handle||o.handler).apply(i.elem,a),r!==undefined&&(e.result=r)===!1&&(e.preventDefault(),e.stopPropagation()))}return l.postDispatch&&l.postDispatch.call(this,e),e.result}},handlers:function(e,t){var n,r,i,o,s=[],a=t.delegateCount,u=e.target;if(a&&u.nodeType&&(!e.button||"click"!==e.type))for(;u!==this;u=u.parentNode||this)if(u.disabled!==!0||"click"!==e.type){for(r=[],n=0;a>n;n++)o=t[n],i=o.selector+" ",r[i]===undefined&&(r[i]=o.needsContext?x(i,this).index(u)>=0:x.find(i,this,null,[u]).length),r[i]&&r.push(o);r.length&&s.push({elem:u,handlers:r})}return t.length>a&&s.push({elem:this,handlers:t.slice(a)}),s},props:"altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "),fixHooks:{},keyHooks:{props:"char charCode key keyCode".split(" "),filter:function(e,t){return null==e.which&&(e.which=null!=t.charCode?t.charCode:t.keyCode),e}},mouseHooks:{props:"button buttons clientX clientY offsetX offsetY pageX pageY screenX screenY toElement".split(" "),filter:function(e,t){var n,r,i,s=t.button;return null==e.pageX&&null!=t.clientX&&(n=e.target.ownerDocument||o,r=n.documentElement,i=n.body,e.pageX=t.clientX+(r&&r.scrollLeft||i&&i.scrollLeft||0)-(r&&r.clientLeft||i&&i.clientLeft||0),e.pageY=t.clientY+(r&&r.scrollTop||i&&i.scrollTop||0)-(r&&r.clientTop||i&&i.clientTop||0)),e.which||s===undefined||(e.which=1&s?1:2&s?3:4&s?2:0),e}},fix:function(e){if(e[x.expando])return e;var t,n,r,i=e.type,s=e,a=this.fixHooks[i];a||(this.fixHooks[i]=a=z.test(i)?this.mouseHooks:I.test(i)?this.keyHooks:{}),r=a.props?this.props.concat(a.props):this.props,e=new x.Event(s),t=r.length;while(t--)n=r[t],e[n]=s[n];return e.target||(e.target=o),3===e.target.nodeType&&(e.target=e.target.parentNode),a.filter?a.filter(e,s):e},special:{load:{noBubble:!0},focus:{trigger:function(){return this!==V()&&this.focus?(this.focus(),!1):undefined},delegateType:"focusin"},blur:{trigger:function(){return this===V()&&this.blur?(this.blur(),!1):undefined},delegateType:"focusout"},click:{trigger:function(){return"checkbox"===this.type&&this.click&&x.nodeName(this,"input")?(this.click(),!1):undefined},_default:function(e){return x.nodeName(e.target,"a")}},beforeunload:{postDispatch:function(e){e.result!==undefined&&(e.originalEvent.returnValue=e.result)}}},simulate:function(e,t,n,r){var i=x.extend(new x.Event,n,{type:e,isSimulated:!0,originalEvent:{}});r?x.event.trigger(i,null,t):x.event.dispatch.call(t,i),i.isDefaultPrevented()&&n.preventDefault()}},x.removeEvent=function(e,t,n){e.removeEventListener&&e.removeEventListener(t,n,!1)},x.Event=function(e,t){return this instanceof x.Event?(e&&e.type?(this.originalEvent=e,this.type=e.type,this.isDefaultPrevented=e.defaultPrevented||e.getPreventDefault&&e.getPreventDefault()?U:Y):this.type=e,t&&x.extend(this,t),this.timeStamp=e&&e.timeStamp||x.now(),this[x.expando]=!0,undefined):new x.Event(e,t)},x.Event.prototype={isDefaultPrevented:Y,isPropagationStopped:Y,isImmediatePropagationStopped:Y,preventDefault:function(){var e=this.originalEvent;this.isDefaultPrevented=U,e&&e.preventDefault&&e.preventDefault()},stopPropagation:function(){var e=this.originalEvent;this.isPropagationStopped=U,e&&e.stopPropagation&&e.stopPropagation()},stopImmediatePropagation:function(){this.isImmediatePropagationStopped=U,this.stopPropagation()}},x.each({mouseenter:"mouseover",mouseleave:"mouseout"},function(e,t){x.event.special[e]={delegateType:t,bindType:t,handle:function(e){var n,r=this,i=e.relatedTarget,o=e.handleObj;return(!i||i!==r&&!x.contains(r,i))&&(e.type=o.origType,n=o.handler.apply(this,arguments),e.type=t),n}}}),x.support.focusinBubbles||x.each({focus:"focusin",blur:"focusout"},function(e,t){var n=0,r=function(e){x.event.simulate(t,e.target,x.event.fix(e),!0)};x.event.special[t]={setup:function(){0===n++&&o.addEventListener(e,r,!0)},teardown:function(){0===--n&&o.removeEventListener(e,r,!0)}}}),x.fn.extend({on:function(e,t,n,r,i){var o,s;if("object"==typeof e){"string"!=typeof t&&(n=n||t,t=undefined);for(s in e)this.on(s,t,n,e[s],i);return this}if(null==n&&null==r?(r=t,n=t=undefined):null==r&&("string"==typeof t?(r=n,n=undefined):(r=n,n=t,t=undefined)),r===!1)r=Y;else if(!r)return this;return 1===i&&(o=r,r=function(e){return x().off(e),o.apply(this,arguments)},r.guid=o.guid||(o.guid=x.guid++)),this.each(function(){x.event.add(this,e,r,n,t)})},one:function(e,t,n,r){return this.on(e,t,n,r,1)},off:function(e,t,n){var r,i;if(e&&e.preventDefault&&e.handleObj)return r=e.handleObj,x(e.delegateTarget).off(r.namespace?r.origType+"."+r.namespace:r.origType,r.selector,r.handler),this;if("object"==typeof e){for(i in e)this.off(i,t,e[i]);return this}return(t===!1||"function"==typeof t)&&(n=t,t=undefined),n===!1&&(n=Y),this.each(function(){x.event.remove(this,e,n,t)})},trigger:function(e,t){return this.each(function(){x.event.trigger(e,t,this)})},triggerHandler:function(e,t){var n=this[0];return n?x.event.trigger(e,t,n,!0):undefined}});var G=/^.[^:#\[\.,]*$/,J=/^(?:parents|prev(?:Until|All))/,Q=x.expr.match.needsContext,K={children:!0,contents:!0,next:!0,prev:!0};x.fn.extend({find:function(e){var t,n=[],r=this,i=r.length;if("string"!=typeof e)return this.pushStack(x(e).filter(function(){for(t=0;i>t;t++)if(x.contains(r[t],this))return!0}));for(t=0;i>t;t++)x.find(e,r[t],n);return n=this.pushStack(i>1?x.unique(n):n),n.selector=this.selector?this.selector+" "+e:e,n},has:function(e){var t=x(e,this),n=t.length;return this.filter(function(){var e=0;for(;n>e;e++)if(x.contains(this,t[e]))return!0})},not:function(e){return this.pushStack(et(this,e||[],!0))},filter:function(e){return this.pushStack(et(this,e||[],!1))},is:function(e){return!!et(this,"string"==typeof e&&Q.test(e)?x(e):e||[],!1).length},closest:function(e,t){var n,r=0,i=this.length,o=[],s=Q.test(e)||"string"!=typeof e?x(e,t||this.context):0;for(;i>r;r++)for(n=this[r];n&&n!==t;n=n.parentNode)if(11>n.nodeType&&(s?s.index(n)>-1:1===n.nodeType&&x.find.matchesSelector(n,e))){n=o.push(n);break}return this.pushStack(o.length>1?x.unique(o):o)},index:function(e){return e?"string"==typeof e?g.call(x(e),this[0]):g.call(this,e.jquery?e[0]:e):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(e,t){var n="string"==typeof e?x(e,t):x.makeArray(e&&e.nodeType?[e]:e),r=x.merge(this.get(),n);return this.pushStack(x.unique(r))},addBack:function(e){return this.add(null==e?this.prevObject:this.prevObject.filter(e))}});function Z(e,t){while((e=e[t])&&1!==e.nodeType);return e}x.each({parent:function(e){var t=e.parentNode;return t&&11!==t.nodeType?t:null},parents:function(e){return x.dir(e,"parentNode")},parentsUntil:function(e,t,n){return x.dir(e,"parentNode",n)},next:function(e){return Z(e,"nextSibling")},prev:function(e){return Z(e,"previousSibling")},nextAll:function(e){return x.dir(e,"nextSibling")},prevAll:function(e){return x.dir(e,"previousSibling")},nextUntil:function(e,t,n){return x.dir(e,"nextSibling",n)},prevUntil:function(e,t,n){return x.dir(e,"previousSibling",n)},siblings:function(e){return x.sibling((e.parentNode||{}).firstChild,e)},children:function(e){return x.sibling(e.firstChild)},contents:function(e){return e.contentDocument||x.merge([],e.childNodes)}},function(e,t){x.fn[e]=function(n,r){var i=x.map(this,t,n);return"Until"!==e.slice(-5)&&(r=n),r&&"string"==typeof r&&(i=x.filter(r,i)),this.length>1&&(K[e]||x.unique(i),J.test(e)&&i.reverse()),this.pushStack(i)}}),x.extend({filter:function(e,t,n){var r=t[0];return n&&(e=":not("+e+")"),1===t.length&&1===r.nodeType?x.find.matchesSelector(r,e)?[r]:[]:x.find.matches(e,x.grep(t,function(e){return 1===e.nodeType}))},dir:function(e,t,n){var r=[],i=n!==undefined;while((e=e[t])&&9!==e.nodeType)if(1===e.nodeType){if(i&&x(e).is(n))break;r.push(e)}return r},sibling:function(e,t){var n=[];for(;e;e=e.nextSibling)1===e.nodeType&&e!==t&&n.push(e);return n}});function et(e,t,n){if(x.isFunction(t))return x.grep(e,function(e,r){return!!t.call(e,r,e)!==n});if(t.nodeType)return x.grep(e,function(e){return e===t!==n});if("string"==typeof t){if(G.test(t))return x.filter(t,e,n);t=x.filter(t,e)}return x.grep(e,function(e){return g.call(t,e)>=0!==n})}var tt=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi,nt=/<([\w:]+)/,rt=/<|&#?\w+;/,it=/<(?:script|style|link)/i,ot=/^(?:checkbox|radio)$/i,st=/checked\s*(?:[^=]|=\s*.checked.)/i,at=/^$|\/(?:java|ecma)script/i,ut=/^true\/(.*)/,lt=/^\s*\s*$/g,ct={option:[1,""],thead:[1,"","
"],col:[2,"","
"],tr:[2,"","
"],td:[3,"","
"],_default:[0,"",""]};ct.optgroup=ct.option,ct.tbody=ct.tfoot=ct.colgroup=ct.caption=ct.thead,ct.th=ct.td,x.fn.extend({text:function(e){return x.access(this,function(e){return e===undefined?x.text(this):this.empty().append((this[0]&&this[0].ownerDocument||o).createTextNode(e))},null,e,arguments.length)},append:function(){return this.domManip(arguments,function(e){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var t=pt(this,e);t.appendChild(e)}})},prepend:function(){return this.domManip(arguments,function(e){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var t=pt(this,e);t.insertBefore(e,t.firstChild)}})},before:function(){return this.domManip(arguments,function(e){this.parentNode&&this.parentNode.insertBefore(e,this)})},after:function(){return this.domManip(arguments,function(e){this.parentNode&&this.parentNode.insertBefore(e,this.nextSibling)})},remove:function(e,t){var n,r=e?x.filter(e,this):this,i=0;for(;null!=(n=r[i]);i++)t||1!==n.nodeType||x.cleanData(mt(n)),n.parentNode&&(t&&x.contains(n.ownerDocument,n)&&dt(mt(n,"script")),n.parentNode.removeChild(n));return this},empty:function(){var e,t=0;for(;null!=(e=this[t]);t++)1===e.nodeType&&(x.cleanData(mt(e,!1)),e.textContent="");return this},clone:function(e,t){return e=null==e?!1:e,t=null==t?e:t,this.map(function(){return x.clone(this,e,t)})},html:function(e){return x.access(this,function(e){var t=this[0]||{},n=0,r=this.length;if(e===undefined&&1===t.nodeType)return t.innerHTML;if("string"==typeof e&&!it.test(e)&&!ct[(nt.exec(e)||["",""])[1].toLowerCase()]){e=e.replace(tt,"<$1>");try{for(;r>n;n++)t=this[n]||{},1===t.nodeType&&(x.cleanData(mt(t,!1)),t.innerHTML=e);t=0}catch(i){}}t&&this.empty().append(e)},null,e,arguments.length)},replaceWith:function(){var e=x.map(this,function(e){return[e.nextSibling,e.parentNode]}),t=0;return this.domManip(arguments,function(n){var r=e[t++],i=e[t++];i&&(r&&r.parentNode!==i&&(r=this.nextSibling),x(this).remove(),i.insertBefore(n,r))},!0),t?this:this.remove()},detach:function(e){return this.remove(e,!0)},domManip:function(e,t,n){e=f.apply([],e);var r,i,o,s,a,u,l=0,c=this.length,p=this,h=c-1,d=e[0],g=x.isFunction(d);if(g||!(1>=c||"string"!=typeof d||x.support.checkClone)&&st.test(d))return this.each(function(r){var i=p.eq(r);g&&(e[0]=d.call(this,r,i.html())),i.domManip(e,t,n)});if(c&&(r=x.buildFragment(e,this[0].ownerDocument,!1,!n&&this),i=r.firstChild,1===r.childNodes.length&&(r=i),i)){for(o=x.map(mt(r,"script"),ft),s=o.length;c>l;l++)a=r,l!==h&&(a=x.clone(a,!0,!0),s&&x.merge(o,mt(a,"script"))),t.call(this[l],a,l);if(s)for(u=o[o.length-1].ownerDocument,x.map(o,ht),l=0;s>l;l++)a=o[l],at.test(a.type||"")&&!q.access(a,"globalEval")&&x.contains(u,a)&&(a.src?x._evalUrl(a.src):x.globalEval(a.textContent.replace(lt,"")))}return this}}),x.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(e,t){x.fn[e]=function(e){var n,r=[],i=x(e),o=i.length-1,s=0;for(;o>=s;s++)n=s===o?this:this.clone(!0),x(i[s])[t](n),h.apply(r,n.get());return this.pushStack(r)}}),x.extend({clone:function(e,t,n){var r,i,o,s,a=e.cloneNode(!0),u=x.contains(e.ownerDocument,e);if(!(x.support.noCloneChecked||1!==e.nodeType&&11!==e.nodeType||x.isXMLDoc(e)))for(s=mt(a),o=mt(e),r=0,i=o.length;i>r;r++)yt(o[r],s[r]);if(t)if(n)for(o=o||mt(e),s=s||mt(a),r=0,i=o.length;i>r;r++)gt(o[r],s[r]);else gt(e,a);return s=mt(a,"script"),s.length>0&&dt(s,!u&&mt(e,"script")),a},buildFragment:function(e,t,n,r){var i,o,s,a,u,l,c=0,p=e.length,f=t.createDocumentFragment(),h=[];for(;p>c;c++)if(i=e[c],i||0===i)if("object"===x.type(i))x.merge(h,i.nodeType?[i]:i);else if(rt.test(i)){o=o||f.appendChild(t.createElement("div")),s=(nt.exec(i)||["",""])[1].toLowerCase(),a=ct[s]||ct._default,o.innerHTML=a[1]+i.replace(tt,"<$1>")+a[2],l=a[0];while(l--)o=o.lastChild;x.merge(h,o.childNodes),o=f.firstChild,o.textContent=""}else h.push(t.createTextNode(i));f.textContent="",c=0;while(i=h[c++])if((!r||-1===x.inArray(i,r))&&(u=x.contains(i.ownerDocument,i),o=mt(f.appendChild(i),"script"),u&&dt(o),n)){l=0;while(i=o[l++])at.test(i.type||"")&&n.push(i)}return f},cleanData:function(e){var t,n,r,i,o,s,a=x.event.special,u=0;for(;(n=e[u])!==undefined;u++){if(F.accepts(n)&&(o=n[q.expando],o&&(t=q.cache[o]))){if(r=Object.keys(t.events||{}),r.length)for(s=0;(i=r[s])!==undefined;s++)a[i]?x.event.remove(n,i):x.removeEvent(n,i,t.handle);q.cache[o]&&delete q.cache[o]}delete L.cache[n[L.expando]]}},_evalUrl:function(e){return x.ajax({url:e,type:"GET",dataType:"script",async:!1,global:!1,"throws":!0})}});function pt(e,t){return x.nodeName(e,"table")&&x.nodeName(1===t.nodeType?t:t.firstChild,"tr")?e.getElementsByTagName("tbody")[0]||e.appendChild(e.ownerDocument.createElement("tbody")):e}function ft(e){return e.type=(null!==e.getAttribute("type"))+"/"+e.type,e}function ht(e){var t=ut.exec(e.type);return t?e.type=t[1]:e.removeAttribute("type"),e}function dt(e,t){var n=e.length,r=0;for(;n>r;r++)q.set(e[r],"globalEval",!t||q.get(t[r],"globalEval"))}function gt(e,t){var n,r,i,o,s,a,u,l;if(1===t.nodeType){if(q.hasData(e)&&(o=q.access(e),s=q.set(t,o),l=o.events)){delete s.handle,s.events={};for(i in l)for(n=0,r=l[i].length;r>n;n++)x.event.add(t,i,l[i][n])}L.hasData(e)&&(a=L.access(e),u=x.extend({},a),L.set(t,u))}}function mt(e,t){var n=e.getElementsByTagName?e.getElementsByTagName(t||"*"):e.querySelectorAll?e.querySelectorAll(t||"*"):[];return t===undefined||t&&x.nodeName(e,t)?x.merge([e],n):n}function yt(e,t){var n=t.nodeName.toLowerCase();"input"===n&&ot.test(e.type)?t.checked=e.checked:("input"===n||"textarea"===n)&&(t.defaultValue=e.defaultValue)}x.fn.extend({wrapAll:function(e){var t;return x.isFunction(e)?this.each(function(t){x(this).wrapAll(e.call(this,t))}):(this[0]&&(t=x(e,this[0].ownerDocument).eq(0).clone(!0),this[0].parentNode&&t.insertBefore(this[0]),t.map(function(){var e=this;while(e.firstElementChild)e=e.firstElementChild;return e}).append(this)),this)},wrapInner:function(e){return x.isFunction(e)?this.each(function(t){x(this).wrapInner(e.call(this,t))}):this.each(function(){var t=x(this),n=t.contents();n.length?n.wrapAll(e):t.append(e)})},wrap:function(e){var t=x.isFunction(e);return this.each(function(n){x(this).wrapAll(t?e.call(this,n):e)})},unwrap:function(){return this.parent().each(function(){x.nodeName(this,"body")||x(this).replaceWith(this.childNodes)}).end()}});var vt,xt,bt=/^(none|table(?!-c[ea]).+)/,wt=/^margin/,Tt=RegExp("^("+b+")(.*)$","i"),Ct=RegExp("^("+b+")(?!px)[a-z%]+$","i"),kt=RegExp("^([+-])=("+b+")","i"),Nt={BODY:"block"},Et={position:"absolute",visibility:"hidden",display:"block"},St={letterSpacing:0,fontWeight:400},jt=["Top","Right","Bottom","Left"],Dt=["Webkit","O","Moz","ms"];function At(e,t){if(t in e)return t;var n=t.charAt(0).toUpperCase()+t.slice(1),r=t,i=Dt.length;while(i--)if(t=Dt[i]+n,t in e)return t;return r}function Lt(e,t){return e=t||e,"none"===x.css(e,"display")||!x.contains(e.ownerDocument,e)}function qt(t){return e.getComputedStyle(t,null)}function Ht(e,t){var n,r,i,o=[],s=0,a=e.length;for(;a>s;s++)r=e[s],r.style&&(o[s]=q.get(r,"olddisplay"),n=r.style.display,t?(o[s]||"none"!==n||(r.style.display=""),""===r.style.display&&Lt(r)&&(o[s]=q.access(r,"olddisplay",Rt(r.nodeName)))):o[s]||(i=Lt(r),(n&&"none"!==n||!i)&&q.set(r,"olddisplay",i?n:x.css(r,"display"))));for(s=0;a>s;s++)r=e[s],r.style&&(t&&"none"!==r.style.display&&""!==r.style.display||(r.style.display=t?o[s]||"":"none"));return e}x.fn.extend({css:function(e,t){return x.access(this,function(e,t,n){var r,i,o={},s=0;if(x.isArray(t)){for(r=qt(e),i=t.length;i>s;s++)o[t[s]]=x.css(e,t[s],!1,r);return o}return n!==undefined?x.style(e,t,n):x.css(e,t)},e,t,arguments.length>1)},show:function(){return Ht(this,!0)},hide:function(){return Ht(this)},toggle:function(e){return"boolean"==typeof e?e?this.show():this.hide():this.each(function(){Lt(this)?x(this).show():x(this).hide()})}}),x.extend({cssHooks:{opacity:{get:function(e,t){if(t){var n=vt(e,"opacity");return""===n?"1":n}}}},cssNumber:{columnCount:!0,fillOpacity:!0,fontWeight:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{"float":"cssFloat"},style:function(e,t,n,r){if(e&&3!==e.nodeType&&8!==e.nodeType&&e.style){var i,o,s,a=x.camelCase(t),u=e.style;return t=x.cssProps[a]||(x.cssProps[a]=At(u,a)),s=x.cssHooks[t]||x.cssHooks[a],n===undefined?s&&"get"in s&&(i=s.get(e,!1,r))!==undefined?i:u[t]:(o=typeof n,"string"===o&&(i=kt.exec(n))&&(n=(i[1]+1)*i[2]+parseFloat(x.css(e,t)),o="number"),null==n||"number"===o&&isNaN(n)||("number"!==o||x.cssNumber[a]||(n+="px"),x.support.clearCloneStyle||""!==n||0!==t.indexOf("background")||(u[t]="inherit"),s&&"set"in s&&(n=s.set(e,n,r))===undefined||(u[t]=n)),undefined)}},css:function(e,t,n,r){var i,o,s,a=x.camelCase(t);return t=x.cssProps[a]||(x.cssProps[a]=At(e.style,a)),s=x.cssHooks[t]||x.cssHooks[a],s&&"get"in s&&(i=s.get(e,!0,n)),i===undefined&&(i=vt(e,t,r)),"normal"===i&&t in St&&(i=St[t]),""===n||n?(o=parseFloat(i),n===!0||x.isNumeric(o)?o||0:i):i}}),vt=function(e,t,n){var r,i,o,s=n||qt(e),a=s?s.getPropertyValue(t)||s[t]:undefined,u=e.style;return s&&(""!==a||x.contains(e.ownerDocument,e)||(a=x.style(e,t)),Ct.test(a)&&wt.test(t)&&(r=u.width,i=u.minWidth,o=u.maxWidth,u.minWidth=u.maxWidth=u.width=a,a=s.width,u.width=r,u.minWidth=i,u.maxWidth=o)),a};function Ot(e,t,n){var r=Tt.exec(t);return r?Math.max(0,r[1]-(n||0))+(r[2]||"px"):t}function Ft(e,t,n,r,i){var o=n===(r?"border":"content")?4:"width"===t?1:0,s=0;for(;4>o;o+=2)"margin"===n&&(s+=x.css(e,n+jt[o],!0,i)),r?("content"===n&&(s-=x.css(e,"padding"+jt[o],!0,i)),"margin"!==n&&(s-=x.css(e,"border"+jt[o]+"Width",!0,i))):(s+=x.css(e,"padding"+jt[o],!0,i),"padding"!==n&&(s+=x.css(e,"border"+jt[o]+"Width",!0,i)));return s}function Pt(e,t,n){var r=!0,i="width"===t?e.offsetWidth:e.offsetHeight,o=qt(e),s=x.support.boxSizing&&"border-box"===x.css(e,"boxSizing",!1,o);if(0>=i||null==i){if(i=vt(e,t,o),(0>i||null==i)&&(i=e.style[t]),Ct.test(i))return i;r=s&&(x.support.boxSizingReliable||i===e.style[t]),i=parseFloat(i)||0}return i+Ft(e,t,n||(s?"border":"content"),r,o)+"px"}function Rt(e){var t=o,n=Nt[e];return n||(n=Mt(e,t),"none"!==n&&n||(xt=(xt||x("");C.push("");this._setReadyState(1);this.availableIframe();return C.join("")};A.prototype.availableIframe=function(){var B=document.getElementById("tangram_editor_iframe_"+this.guid);if(B){this.iframe=B;this._setReadyState(3)}else{var C=this;setTimeout(function(){C.availableIframe()},20)}};A.prototype.makeEditable=function(F){var D=this;var B=[baidu.editor.EditorConfig.docType];B.push("");if(baidu.editor.EditorConfig.skinCSS){var C=baidu.editor.EditorConfig.skinCSS+(baidu.ie?"":"?tmp="+new Date().getTime());B.push("")}B.push("");B.push(F||"");B.push("");D.window=D.iframe.contentWindow;var E=D.document=D.window.document;E.open();E.write(B.join(""));E.close();if(baidu.ie){E.body.disabled=true;E.body.contentEditable=true;E.body.removeAttribute("disabled");D._setReadyState(4)}else{setTimeout(function(){try{E.body.spellcheck=false;E.designMode="on";var J=false;try{E.execCommand("styleWithCSS",false,J)}catch(H){E.execCommand("useCSS",false,!J)}var I=false;var G=true;E.execCommand("enableObjectResizing",false,!I);E.execCommand("enableInlineTableEditing",false,!G)}catch(H){}D._setReadyState(4)},1)}};A.prototype.execCommand=function(G,D,E){var C=false,F=true;this.focus();if(this.__hasEnterdExecCommand){F=false}else{this.__hasEnterdExecCommand=true}this.dispatchEvent(new baidu.BaseEvent("onbeforeexeccommand",{command:G,topOpearation:F}));if(typeof G=="string"){var B=baidu.editor._commands;if(typeof B[G]=="function"){C=B[G].apply(null,[this].concat(Array.prototype.slice.call(arguments,1)))}else{C=this.document.execCommand(G,D,E)}}else{if(typeof G=="function"){C=G.apply(null,[this].concat(Array.prototype.slice.call(arguments,1)))}}if(F){this.__hasEnterdExecCommand=false}this.dispatchEvent(new baidu.BaseEvent("onafterexeccommand",{command:G,topOpearation:F}));this.selectionChangeHandler(null,true);return C};A.prototype.queryContextState=function(B){var C=baidu.editor._parser;if(typeof C[B]=="function"){return C[B](this)}};A.prototype.queryCommandState=function(D){var B=baidu.editor._queries;if(typeof B[D]=="function"){return B[D](this)}else{var C=navigator.userAgent;if(/(\d+\.\d)\s+safari/i.test(C)&&!/chrome/i.test(C)&&D.toLowerCase()=="paste"){return false}return this.document.queryCommandEnabled(D)&&this.document.queryCommandState(D)}};A.prototype.getContent=function(B){if(!B){var C=this.document.body.innerHTML;return C}else{var C=baidu.editor.EditorConfig.docType;C+="";C+=this.document.documentElement.innerHTML;C+="";return C}};A.prototype.setContent=function(C){var B=this;this.document.body.innerHTML=C;setTimeout(function(){B.dispatchEvent(new baidu.BaseEvent("onbeforeselectionchange"));B.dispatchEvent(new baidu.BaseEvent("onselectionchange"));B.dispatchEvent(new baidu.BaseEvent("onafterselectionchange"))},0)};A.prototype._bindEvent=function(){var D=this;function E(F){D.selectionChangeHandler(F)}function B(H){H=D.window.event||H;var G=H.keyCode||H.which,F;D.dispatchEvent(F=new baidu.BaseEvent("onbeforekeydown",H));if(F.returnValue==false){return }D.dispatchEvent(F=new baidu.BaseEvent("onkeydown",H));if(F.returnValue==false){return }if(G!=27&&G!=16&&G!=17&&G!=18){clearTimeout(B.timer);B.timer=setTimeout(function(){E()},500)}D.dispatchEvent(new baidu.BaseEvent("onafterkeydown",H))}function C(F){clearTimeout(C.timer);C.timer=setTimeout(function(){E()},20)}baidu.on(D.document,"mouseup",E);baidu.on(D.document,"keydown",B);baidu.on(D.document,"mousemove",C);baidu.on(D.window,"blur",function(){D.dispatchEvent(new baidu.BaseEvent("onblur"));D.isBlur=true});baidu.on(D.window,"focus",function(){D.dispatchEvent(new baidu.BaseEvent("onfocus"));D.isBlur=false});if(baidu.ie){setInterval(function(){if(!D.isBlur){D.ieBakRange=D.document.selection.createRange();D.ieBakRangeType=D.document.selection.type}},20)}this.dispatchEvent(new baidu.BaseEvent("onwysiwygready"))};A.prototype.selectionChangeHandler=function(H){var G=this.temp.scene;var C=this.document.body.innerHTML;if(this.temp.innerHTML!=C){this.temp.innerHTML=C;H=this.window.event||H;if(H&&H.type&&H.type.indexOf("key")>=0){var E=H.srcElement||H.target;if(E){if(E.nodeType==3){E=E.parentNode}var I=E.getElementsByTagName("*").length;if(E.tagName!="HTML"&&E==G.target&&I==G.count){return }G.target=E;G.count=I}}}else{if(window.getSelection){var B=this.window.getSelection().getRangeAt(0);if(B.startContainer==G.startContainer&&B.endContainer==G.endContainer){if(B.collapsed){return }else{if(B.startOffset==G.startOffset&&B.endOffset==G.endOffset){return }}}G.endOffset=B.endOffset;G.startOffset=B.startOffset;G.endContainer=B.endContainer;G.startContainer=B.startContainer}else{if(document.selection){var F=this.document.selection;var B=F.createRange();var D=F.type.toLowerCase();if(G.type==D){if(D=="control"&&B(0)==G.control){return }else{if(G.text==B.text&&G.parentElement==B.parentElement()){return }}}G.type=D;if(D=="control"){G.control=B(0)}else{G.text=B.text;G.parentElement=B.parentElement()}}}}this.dispatchEvent(new baidu.BaseEvent("onbeforeselectionchange"));this.dispatchEvent(new baidu.BaseEvent("onselectionchange"));this.dispatchEvent(new baidu.BaseEvent("onafterselectionchange"))};A.prototype._setReadyState=function(B){this.readyState=B;this.dispatchEvent(new baidu.BaseEvent("onreadystatechange",B))};A.prototype.addToolbarItem=function(B){if(B&&typeof B.initialize=="function"){B.initialize()}};baidu.editor.Editor=A})();baidu.editor.create=function(D,A){var E=new baidu.editor.Editor(D,A);if(typeof D=="string"){D=document.getElementById(D)}var C="";if(D&&D.tagName){if(D.tagName.toLowerCase()=="textarea"){C=D.value}else{C=D.innerHTML}}if(C==""&&A){C=A.content||""}if(!baidu.ie&&C==""){C="
"}var B=baidu.BaseClass.guid();E.addEventListener("onreadystatechange",function(H){var G=H.currentTarget;switch(G.readyState){case 3:G.makeEditable(C);break;case 4:for(var F=baidu.editor._register.length-1;F>=0;F--){baidu.editor._register[F](this)}G.removeEventListener("onreadystatechange",B);G._bindEvent();break}},B);return E};baidu.editor.Editor.prototype.focus=function(){this.window.focus();try{if(baidu.ie&&this.ieBakRange){this.ieBakRange.select()}}catch(A){}};baidu.dom=baidu.dom||{};baidu.isElement=function(A){if(A===undefined||A===null){return false}return A&&A.nodeName&&A.nodeType==1};baidu.isDocument=function(A){if(A===undefined||A===null){return false}return A&&A.nodeType==9};baidu.dom.getWindow=function(A){if(!baidu.isDocument(A)){throw new Error("[baidu.dom.getWindow] param must be Document")}return A.parentWindow?A.parentWindow:(A.defaultView?A.defaultView:null)};baidu.array=baidu.array||{};baidu.array.each=function(F,D){var C,E,B,A=F.length;if("function"==typeof D){for(B=0;B0&&B){B=B.childNodes[A.shift()]}}return B};baidu.dom.element.getName=function(B){var C=B.nodeName.toLowerCase();if(baidu.ie){var A=B.scopeName;if(A!="HTML"){C=A.toLowerCase()+":"+C}}return C};baidu.dom.element.is=function(C){var A=baidu.dom.element.getName(C);for(var B=0;B0){if(I>=V){O=baidu.dom.element.append(O,M.document.createTextNode(""));J=true}else{O=baidu.dom.element.getChild(O,I)}}}if(baidu.isText(Z)){baidu.dom.text.split(Z,T,this.document);if(Z===O){O=baidu.dom.getNext(Z)}}else{if(!T){Z=Z.insertBefore(M.document.createTextNode(""),Z.firstChild);Q=true}else{if(T>=baidu.dom.element.getChildCount(Z)){Z=baidu.dom.element.append(Z,M.document.createTextNode(""));Q=true}else{Z=baidu.dom.getPrevious(baidu.dom.element.getChild(Z,T))}}}var W=baidu.dom.getParents(Z);var E=baidu.dom.getParents(O);var U,a,Y;for(U=0;U0&&!(N===O)){L=baidu.dom.element.append(X,baidu.dom.clone(N))}if(!W[P]||N.parentNode!=W[P].parentNode){G=baidu.dom.getPrevious(N);while(G){if(G===W[P]||G===Z){break}K=baidu.dom.getPrevious(G);if(R==2){X.insertBefore(G.cloneNode(true),X.firstChild)}else{baidu.dom.element.remove(G,C);if(R==1){X.insertBefore(G,X.firstChild)}}G=K}}if(X){X=L}}if(R==2){var D=M.startContainer;if(baidu.isText(D)){D.data+=D.nextSibling.data;D.parentNode.removeChild(D.nextSibling)}var H=M.endContainer;if(baidu.isText(H)&&H.nextSibling){H.data+=H.nextSibling.data;H.parentNode.removeChild(H.nextSibling)}}else{if(a&&Y&&(Z.parentNode!=a.parentNode||O.parentNode!=Y.parentNode)){var F=baidu.dom.getIndex(Y);if(Q&&Y.parentNode==Z.parentNode){F--}M.setStart(baidu.dom.getParent(Y),F)}M.collapse(true)}if(Q){baidu.dom.element.remove(Z,C)}if(J&&O.parentNode){baidu.dom.element.remove(O,C)}};baidu.editor.Range.prototype={deleteContents:function(){var C=this.document.createDocumentFragment();if(this.collapsed){return }A(this,0,C)},cloneContents:function(){var C=this.document.createDocumentFragment();if(!this.collapsed){A(this,2,C)}return C},extractContents:function(){var C=this.document.createDocumentFragment();if(!this.collapsed){A(this,1,C)}return C},clone:function(){var C=new baidu.editor.Range(this.document);C.startContainer=this.startContainer;C.startOffset=this.startOffset;C.endContainer=this.endContainer;C.endOffset=this.endOffset;C.collapsed=this.collapsed;return C},collapse:function(C){if(C){this.endContainer=this.startContainer;this.endOffset=this.startOffset}else{this.startContainer=this.endContainer;this.startOffset=this.endOffset}this.collapsed=true},select:baidu.ie?function(){var G=this.collapsed;var C;var H;var K=this.createBookmark();var E=K.startNode;var I;if(!G){I=K.endNode}var D=this.document.body.createTextRange();D.moveToElementText(E);D.moveStart("character",1);if(I){var J=this.document.body.createTextRange();J.moveToElementText(I);D.setEndPoint("EndToEnd",J);D.moveEnd("character",-1)}else{H=this.document.createElement("span");H.innerHTML="";E.parentNode.insertBefore(H,E);var F=this.document.createTextNode("\ufeff");E.parentNode.insertBefore(F,E)}this.setStartBefore(E);baidu.dom.element.remove(E,this.document);if(G){D.moveStart("character",-1);D.select();this.document.selection.clear();baidu.dom.element.remove(H,this.document)}else{this.setEndBefore(I);baidu.dom.element.remove(I,this.document);D.select()}}:function(){var D=this.startContainer;if(this.collapsed&&baidu.isElement(D)&&!baidu.dom.element.getChildCount(D)){baidu.dom.element.append(D,this.document.createTextNode(""))}var E=this.document.createRange();E.setStart(D,this.startOffset);try{E.setEnd(this.endContainer,this.endOffset)}catch(F){if(F.toString().indexOf("NS_ERROR_ILLEGAL_VALUE")>=0){this.collapse(true);E.setEnd(this.endContainer,this.endOffset)}else{throw (F)}}var C=baidu.dom.getWindow(this.document).getSelection();C.removeAllRanges();C.addRange(E)},createBookmark:function(F){var E,C;var D;var G;E=this.document.createElement("span");baidu.dom.element.setAttr(E,"_BaiduEditor_bm",1);baidu.dom.element.setStyle(E,"display","none");E.innerHTML=" ";if(F){D="_BaiduEditor_bm"+Math.floor(Math.random()*2147483648).toString(36);baidu.dom.element.setAttr(E,"id",D+"S")}if(!this.collapsed){C=baidu.dom.clone(E);C.innerHTML=" ";if(F){baidu.dom.element.setAttr(C,"id",D+"E")}G=this.clone();G.collapse();G.insertNode(C)}G=this.clone();G.collapse(true);G.insertNode(E);if(C){this.setStartAfter(E);this.setEndBefore(C)}else{this.moveToPosition(E,POSITION_AFTER_END)}return{startNode:F?D+"S":E,endNode:F?D+"E":C,serializable:F}},moveToPosition:function(D,C){this.setStartAt(D,C);this.collapse(true)},createBookmark2:function(I){var G=this.startContainer,H=this.endContainer;var C=this.startOffset,E=this.endOffset;var J,F;if(!G||!H){return{start:0,end:0}}if(I){if(baidu.isElement(G)){J=baidu.dom.element.getChild(G,C);if(J&&baidu.isText(J)&&C>0&&baidu.isText(baidu.dom.getPrevious(J))){G=J;C=0}}while(baidu.isText(G)&&(F=baidu.dom.getPrevious(G))&&baidu.isText(F)){G=F;C+=baidu.dom.text.getLength(F)}if(!this.isCollapsed){if(baidu.isElement(H)){J=baidu.dom.element.getChild(H,E);if(J&&baidu.isText(J)&&E>0&&baidu.isText(baidu.dom.getPrevious(J))){H=J;E=0}}while(baidu.isText(H)&&(F=baidu.dom.getPrevious(H))&&baidu.isText(F)){H=F;E+=baidu.dom.text.getLength(F)}}}var D=baidu.dom.getAddress(G,this.document,I);return{start:D,end:this.isCollapsed?D:baidu.dom.getAddress(H,this.document,I),startOffset:C,endOffset:E,normalized:I,is2:true}},moveToBookmark:function(H){if(H.is2){var I=baidu.dom.getByAddress(this.document,H.start,H.normalized),D=H.startOffset;var J=H.end&&baidu.dom.getByAddress(this.document,H.end,H.normalized),F=H.endOffset;this.setStart(I,D);if(J){this.setEnd(J,F)}else{this.collapse(true)}}else{var G=H.serializable,E=G?this.document.getElementById(H.startNode):H.startNode,C=G?this.document.getElementById(H.endNode):H.endNode;this.setStartBefore(E);baidu.dom.element.remove(E,this.document);if(C){this.setEndBefore(C);baidu.dom.element.remove(C,this.document)}else{this.collapse(true)}}},setStart:function(D,C){this.startContainer=D;this.startOffset=C;if(!this.endContainer){this.endContainer=D;this.endOffset=C}B(this)},setEnd:function(C,D){this.endContainer=C;this.endOffset=D;if(!this.startContainer){this.startContainer=C;this.startOffset=D}B(this)},setStartBefore:function(C){this.setStart(baidu.dom.getParent(C),baidu.dom.getIndex(C))},setStartAfter:function(C){this.setStart(baidu.dom.getParent(C),baidu.dom.getIndex(C)+1)},setEndAfter:function(C){this.setEnd(baidu.dom.getParent(C),baidu.dom.getIndex(C)+1)},setEndBefore:function(C){this.setEnd(baidu.dom.getParent(C),baidu.dom.getIndex(C))},setStartAt:function(D,C){switch(C){case POSITION_AFTER_START:this.setStart(D,0);break;case POSITION_BEFORE_END:if(baidu.isText(D)){this.setStart(D,baidu.dom.text.getLength(D))}else{this.setStart(D,baidu.dom.element.getChildCount(D))}break;case POSITION_BEFORE_START:this.setStartBefore(D);break;case POSITION_AFTER_END:this.setStartAfter(D)}B(this)},setEndAt:function(D,C){switch(C){case POSITION_AFTER_START:this.setEnd(D,0);break;case POSITION_BEFORE_END:if(baidu.isText(D)){this.setEnd(D,baidu.dom.text.getLength(D))}else{this.setEnd(D,baidu.dom.element.getChildCount(D))}break;case POSITION_BEFORE_START:this.setEndBefore(D);break;case POSITION_AFTER_END:this.setEndAfter(D)}B(this)},getCommonAncestor:function(D,F){var G=this.startContainer,C=this.endContainer,E;if(G===C){if(D&&baidu.isElement(G)&&this.startOffset==this.endOffset-1){E=baidu.dom.element.getChild(G,this.startOffset)}else{E=G}}else{E=baidu.dom.getCommonAncestor(G,C)}return F&&!baidu.isElement(E)?baidu.dom.getParent(E):E},optimizeBookmark:function(){var D=this.startContainer,C=this.endContainer;if(baidu.isElement(D)&&baidu.dom.element.is(D,"span")&&baidu.dom.element.hasAttribute(D,"_BaiduEditor_bm")){this.setStartAt(D,POSITION_BEFORE_START)}if(C&&baidu.isElement(C)&&baidu.dom.element.is(C,"span")&&baidu.dom.element.hasAttribute(C,"_BaiduEditor_bm")){this.setEndAt(C,POSITION_AFTER_END)}},trim:function(F,I){var G=this.startContainer,C=this.startOffset,J=this.collapsed;if((!F||J)&&G&&baidu.isText(G)){if(!C){C=baidu.dom.getIndex(G);G=baidu.dom.getParent(G)}else{if(C>=baidu.dom.text.getLength(G)){C=baidu.dom.getIndex(G)+1;G=baidu.dom.getParent(G)}else{var E=baidu.dom.text.split(G,C,this.document);C=baidu.dom.getIndex(G)+1;G=baidu.dom.getParent(G);if(!J&&this.startContainer===this.endContainer){this.setEnd(E,this.endOffset-this.startOffset)}}}this.setStart(G,C);if(J){this.collapse(true)}}var H=this.endContainer;var D=this.endOffset;if(!(I||J)&&H&&baidu.isText(H)){if(!D){D=baidu.dom.getIndex(H);H=baidu.dom.getParent(H)}else{if(D>=baidu.dom.text.getLength(H)){D=baidu.dom.getIndex(H)+1;H=baidu.dom.getParent(H)}else{baidu.dom.text.split(H,D,this.document);D=baidu.dom.getIndex(H)+1;H=baidu.dom.getParent(H)}}this.setEnd(H,D)}},insertNode:function(F){this.optimizeBookmark();this.trim(false,true);var E=this.startContainer;var D=this.startOffset;var C=baidu.dom.element.getChild(E,D);if(C){C.parentNode.insertBefore(F,C)}else{E.appendChild(F)}if(baidu.dom.getParent(F)===this.endContainer){this.endOffset++}this.setStartBefore(F)},getTouchedStartNode:function(){var C=this.startContainer;if(this.collapsed||!baidu.isElement(C)){return C}return baidu.dom.element.getChild(C,this.startOffset)||C},getTouchedEndNode:function(){var C=this.endContainer;if(this.collapsed||!baidu.isElement(C)){return C}return baidu.dom.element.getChild(this.endOffset-1)||C},optimize:function(){var C=this.startContainer;var D=this.startOffset;if(!baidu.isElement(C)){if(!D){this.setStartBefore(C)}else{if(D>=baidu.dom.text.getLength(C)){this.setStartAfter(C)}}}C=this.endContainer;D=this.endOffset;if(!baidu.isElement(C)){if(!D){this.setEndBefore(C)}else{if(D>=baidu.dom.text.getLength(C)){this.setEndAfter(C)}}}},walk:function(L){var E=this.startContainer,H=this.startOffset,M=this.endContainer,I=this.endOffset,K=[{n:baidu.firefox&&this.startContainer.nodeName.toUpperCase()=="TR"?baidu.dom.getParent(this.getCommonAncestor(0,1)):this.getCommonAncestor(0,1),i:0}],G,J=false;function D(P,O,N){try{if(J==-1&&!baidu.dom.element.contains(P,E)){J=true}if(!J&&(baidu.dom.getParent(P)==E&&O==H)){J=true}if(baidu.isText(P)&&P==E){if(baidu.dom.text.getLength(P)==H){J=-1}else{if(!J){J=true}}}if(!N){return }if(baidu.isText(P)&&P==M&&I==0){J=false}if(J==true||(J==-2&&P==M)){L(P)}if(baidu.dom.getParent(P)==M&&O+1==I){J=-2}if(baidu.isText(P)&&P==M){J=false}}catch(Q){}}while(G=K.pop()){var C=G.n,F=cri=G.i;D(C,cri,false);while(C.childNodes[cri]!=undefined){K.push({n:C,i:cri});C=C.childNodes[cri];D(C,cri,false);F=cri;cri=0}D(C,F,true);if(K.length){K[K.length-1].i++}}},dispose:function(){for(var C in this){if(typeof this[C]!="function"){delete this[C]}}}}})();var SELECTION_NONE=0;var SELECTION_TEXT=2;var SELECTION_CONTROL=3;var styleObjectElements={img:1,hr:1,li:1,table:1,tr:1,td:1,embed:1,object:1,ol:1,ul:1,a:1,input:1,form:1,select:1,textarea:1,button:1,fieldset:1,th:1,thead:1,tfoot:1};baidu.editor.Editor.prototype.getSelection=function(){var B=this;if(!B.selection){var A=B.document;B.selection={getNative:baidu.ie?function(){return A.selection}:function(){return baidu.dom.getWindow(A).getSelection()},getNativeRange:function(){if(baidu.ie){var C=this.getNative(),D=C.createRange();if(C.type.toUpperCase()!="CONTROL"&&baidu.dom.getDocument(D.parentElement())!=B.document){range=B.ieBakRange;if(range){return range}}return D}else{throw new Error("[baidu.editor.selection.getNativeRange] only support ie now!")}},getType:baidu.ie?function(){var C=SELECTION_NONE;try{var E=this.getNative(),F=E.type;if(E.createRange().parentElement){C=SELECTION_TEXT}if(F.toUpperCase()!="CONTROL"&&baidu.dom.getDocument(E.createRange().parentElement())!=B.document){if(!B.ieBakRange){return SELECTION_NONE}F=B.ieBakRangeType}if(F=="Text"){C=SELECTION_TEXT}if(F=="Control"){C=SELECTION_CONTROL}}catch(D){}return C}:function(){var D=SELECTION_TEXT;var F=this.getNative();if(!F){D=SELECTION_NONE}else{if(F.rangeCount==1){var C=F.getRangeAt(0),E=C.startContainer;if(E==C.endContainer&&E.nodeType==1&&(C.endOffset-C.startOffset)==1&&styleObjectElements[E.childNodes[C.startOffset].nodeName.toLowerCase()]){D=SELECTION_CONTROL}}}return D},getRanges:baidu.ie?(function(){var C=function(I,E){I=I.duplicate();I.collapse(E);var K=I.parentElement();var F=K.firstChild;var G,H=0;while(F){if(F.nodeType==1){G=I.duplicate();G.moveToElementText(F);G.collapse();var L=G.compareEndPoints("StartToStart",I);if(L>0){break}else{if(L===0){return{container:K,offset:H}}}G=null}F=F.nextSibling;H++}if(!G){G=I.duplicate();G.moveToElementText(K);G.collapse(false)}G.setEndPoint("StartToStart",I);var D=G.text.length;var J=K.childNodes;while(D>0&&H--){F=J[H];D-=F.nodeValue?F.nodeValue.length:0}if(D===0){return{container:K,offset:H}}else{if(D>0){return{container:K,offset:0}}else{return{container:J[H],offset:-D}}}};return function(){var F=this.getNative(),K=F&&F.createRange(),L=this.getType(),J;if(!F){return[]}if(L!=SELECTION_CONTROL&&F.createRange().parentElement().ownerDocument!=B.document){K=B.ieBakRange;if(!K){return[]}L=B.ieBakRangeType.toUpperCase()=="CONTROL"?SELECTION_CONTROL:(B.ieBakRangeType.toUpperCase()=="TEXT"?SELECTION_TEXT:SELECTION_NONE)}if(L===SELECTION_TEXT){J=this.createRange();var D=C(K,true);J.setStart(D.container,D.offset);D=C(K);J.setEnd(D.container,D.offset);return[J]}else{if(L==SELECTION_CONTROL){var E=[];for(var H=0;H=0;D--){range.insertNode(F[D])}if(C){range.setStartBefore(F[F.length-1]);range.setEndAfter(F[0]);range.select()}else{E.setCursor(F[F.length-1],4)}},pasteElement:function(E,D){var F=this,C=F.getRanges()[0];C.deleteContents();C.insertNode(E);if(D){B.selection.selectElement(E)}else{F.setCursor(E,4)}},getText:function(C){if(baidu.ie){var D=B.document.selection.createRange(),E=C?D.text:baidu.trim(D.text);return E.replace("\r\n","")}else{var D=B.window.getSelection().getRangeAt(0),E=C?D.toString():baidu.trim(D.toString());return E.replace("\n","")}},getTextNodes:function(){var E=this;var C=E.getRanges();var F=[];for(var D=0;D=0;E--){if(D[E]){F.bookmarks.push(D[E].createBookmark2(true))}else{F.bookmarks.push(false)}}F.content=this.editor.getContent();return F};B.prototype.applyScene=function(G){if(!G){return }this.editor.setContent(G.content);var D=[];for(var F=G.bookmarks.length-1;F>=0;F--){if(G.bookmarks[F]){var E=this.editor.getSelection().createRange();E.moveToBookmark(G.bookmarks[F]);D.push(E)}}this.editor.getSelection().selectRanges(D);this.undoIndex=G.index;this.currentScene=G;this.fireChange()};B.prototype.save=function(E,G,H){var F=this.currentScene;if(!G){G=this.getScene()}if(E&&F&&F.content==G.content){return }this.undoList=this.undoList.slice(0,this.undoIndex+1);this.undoList.push(G);var D=this.undoList.length;if(D>baidu.editor.EditorConfig.maxUndoCount){this.undoList=this.undoList.slice(D-baidu.editor.EditorConfig.maxUndoCount,D)}this.undoIndex=this.undoList.length-1;this.currentScene=G;if(H!==false){this.fireChange()}return true};B.prototype.getNextScene=function(E){var D=this.undoList,G=this.currentScene,H,F;if(G){if(E){for(F=this.undoIndex-1;F>=0;F--){H=D[F];if(G.content!=H.content){H.index=F;return H}}}else{for(F=this.undoIndex+1;F25){E.save(true);E.modifiersCount=1}}else{if(!isReset){E.modifiersCount=0;E.typesCount++;if(E.typesCount>25){E.save(true);E.typesCount=1}}}E.typing=true}F.addEventListener("onkeydown",D,false);F.addEventListener("onbeforeexeccommand",function(G){if(!G.target.topOpearation||G.target.command=="Undo"||G.target.command=="Redo"){return }E.save(false)});F.addEventListener("onafterexeccommand",function(G){if(!G.target.topOpearation||G.target.command=="Undo"||G.target.command=="Redo"){return }E.save(false)});E.save(true)});function C(D){if(!D.undoMan.hasUndo){return }if(D.undoMan.undoIndex==D.undoMan.undoList.length-1){D.undoMan.save(false)}D.undoMan.applyScene(D.undoMan.getNextScene(true))}function A(D){if(!D.undoMan.hasRedo){return }if(D.undoMan.undoIndex==D.undoMan.undoList.length-1){return }D.undoMan.applyScene(D.undoMan.getNextScene(false))}baidu.editor.registCommand("Undo",function(D){C(D)});baidu.editor.registCommand("Redo",function(D){A(D)});baidu.editor.registQuery("Undo",function(D){return D.undoMan.hasUndo});baidu.editor.registQuery("Redo",function(D){return D.undoMan.hasRedo})})();baidu.editor.Editor.prototype.bold=function(){this.execCommand("Bold");this.dispatchEvent(new baidu.BaseEvent("onbold"))};(function(){var J={};var H=1,B=2,G=3,E=4,F=5,I=6;function K(N,M,L){var O=this;O.context=M,O.range=L;O.nodeInRange=function(P){O.context.contains.push(P);var Q=P.lastChild;while(Q){O.context.contains.push(Q);Q=Q.previousSibling}};O.nodePartlyInRange=function(P,Q){O.context.partlyContains.push(P);if(Q){var R=P.lastChild;while(R){if(O.process(R)==E){break}R=R.previousSibling}}else{var R=P.firstChild;while(R){if(O.process(R)==G){break}R=R.nextSibling}}};O.rangeInNode=function(T,U,Q){if(O.context.parents[0]!=T){O.context.parents.unshift(T)}var P=Math.floor((Q+U)/2);while(Q>=U){var S=T.childNodes[P],R=O.compareRangeWithNode(S,L);if(R==G){Q=P-1}else{if(R==E){U=P+1}else{if(R==I){O.rangeInNode(S,0,S.childNodes.length-1);break}else{if(R==F){O.nodeInRange(S);if(U<=P-1){O.rangeInNode(T,U,P-1)}if(P+1<=Q){O.rangeInNode(T,P+1,Q)}break}else{if(R==H){O.nodePartlyInRange(S,true);U=P+1}else{if(R==B){O.nodePartlyInRange(S,false);Q=P-1}}}}}}P=Math.floor((Q+U)/2)}};O.process=function(P){var Q=O.compareRangeWithNode(P,O.range);if(Q==F){O.nodeInRange(P)}else{if(Q==H||Q==B){O.nodePartlyInRange(P,Q==H)}else{if(Q==I){O.rangeInNode(P,0,P.childNodes.length-1)}}}return Q};O.compareRangeWithNode=function(U,Q){if(baidu.ie){var T=N.document.body.createTextRange();if(U.nodeType==1){T.moveToElementText(U)}else{var R=N.document.createElement("a");U.parentNode.insertBefore(R,U);var a=N.document.body.createTextRange();a.moveToElementText(R);R.parentNode.removeChild(R);T.setEndPoint("StartToStart",a);R=N.document.createElement("a");U.parentNode.insertBefore(R,U.nextSibling);var a=N.document.body.createTextRange();a.moveToElementText(R);R.parentNode.removeChild(R);T.setEndPoint("EndToStart",a)}var S=Q.compareEndPoints("StartToStart",T),Y=Q.compareEndPoints("EndToStart",T),P=Q.compareEndPoints("StartToEnd",T),V=Q.compareEndPoints("EndToEnd",T)}else{var Z=N.document.createRange();if(baidu.isText(U)&&U.parentNode.childNodes.length==1){U=U.parentNode}Z.selectNode(U);var X=N.document.createRange();X.selectNodeContents(U);var W;var S=(W=Q.compareBoundaryPoints(Range.START_TO_START,Z))==Q.compareBoundaryPoints(Range.START_TO_START,X)?W:0,P=(W=Q.compareBoundaryPoints(Range.END_TO_START,Z))==Q.compareBoundaryPoints(Range.END_TO_START,X)?W:0,Y=(W=Q.compareBoundaryPoints(Range.START_TO_END,Z))==Q.compareBoundaryPoints(Range.START_TO_END,X)?W:0,V=(W=Q.compareBoundaryPoints(Range.END_TO_END,Z))==Q.compareBoundaryPoints(Range.END_TO_END,X)?W:0}if(S<=0&&V>=0){return F}if(S>=0&&V<=0){return I}if(S*Y==-1){return B}if(P*V==-1){return H}if(S<=0&&Y<=0){return G}if(P>=0&&V>=0){return E}}}J.w3cParser=function(Q){function R(T){if(T.startContainer.nodeType==3&&T.startContainer.nodeValue.length==T.startOffset){T.setStartAfter(T.startContainer)}if(T.endContainer.nodeType==3&&T.endOffset==0){T.setEndBefore(T.endContainer)}return T}var S=new Array(),P=Q.window.getSelection();for(var N=0;N0){var Q=L.pop(),R=Q.lastChild;while(R){L.push(R);R=R.previousSibling}N.contains.push(Q)}return[N]}function A(M,L){var O=new Array();context={collapsed:false,parents:[],contains:[],partlyContains:[]};if(D(L)){context.collapsed=true}O.push(context);var N=L.parentElement();do{context.parents.push(N);N=N.parentNode}while(N.nodeName.toUpperCase()!="HTML");(new K(M,context,L)).process(L.parentElement());return O}function D(M){try{var L=M.duplicate(),O=M.duplicate();L.collapse(true);O.collapse(false);return L.inRange(O)}catch(N){return false}}baidu.editor.Editor.prototype.getContexts=function(){var N=this;if(!N.contextParserInit){function L(){var O;if(baidu.ie){O=J.ieParser(N)}else{O=J.w3cParser(N)}if(O){N.contextsInfo=O}}N.addEventListener("onbeforeselectionchange",function(O){L()});L();N.contextParserInit=true}if(!N.contextsObj){N.contextsObj={containNode:function(U,V){function O(g,a,c){var Y=[],f=-1;for(var Z=a.length-1;Z>=0;Z--){Y=Y.concat(a[Z])}a=Y;if(!a){return f}for(var Z=a.length-1;Z>=0;Z--){var b=a[Z];try{if(b.ownerDocument!=N.document){continue}}catch(d){continue}if(baidu.isText(b)){if(baidu.trim(b.nodeValue)){b=baidu.dom.getParent(b)}}if(!b){continue}if(c.toLowerCase().indexOf(","+b.nodeName.toLowerCase()+",")!=-1){continue}if(g.toLowerCase().indexOf(","+b.nodeName.toLowerCase()+",")==-1){if(f==1){return 2}f=0}else{if(f==0){return 2}f=1}}return f}U=","+U+",";V=","+V+",";var Q=this;var S=false,T=false;for(var R=Q.contains.length-1;R>=0;R--){if(Q.contains[R].length){S=true}if(Q.partlyContains[R].length){T=true}}if(S||T){var X=O(U,Q.contains,V),W=O(U,Q.partlyContains,V);if((W==2)&&(X==-1||X==0)){return 2}if((W!=-1||X!=-1)&&(X==1||X==-1)&&(W==1||W==-1)){return 1}if(W>0||X>0){return 2}}var P=O(U,Q.parents,V);if(P==2||P==1){return 3}return 0},walkTextNode:function(Q){var T=this,O=[];function P(W){for(var V=W.length-1;V>=0;V--){for(var U=W[V].length-1;U>=0;U--){if(baidu.isText(W[V][U])&&baidu.trim(W[V][U].nodeValue)){O.push(W[V][U])}}}}P(T.contains);P(T.partlyContains);for(var R=T.parents.length-1;R>=0;R--){try{if(T.parents[R][0].ownerDocument!=N.document){continue}}catch(S){continue}if(baidu.isText(T.parents[R][0])&&baidu.trim(T.parents[R][0].nodeValue)){O.push(T.parents[R][0])}}for(var R=O.length-1;R>=0;R--){Q(O[R])}}}}N.contextsObj.collapsed=[];N.contextsObj.parents=[];N.contextsObj.contains=[];N.contextsObj.partlyContains=[];for(var M=N.contextsInfo.length-1;M>=0;M--){N.contextsObj.collapsed.push(N.contextsInfo[M].collapsed);N.contextsObj.parents.push(N.contextsInfo[M].parents);N.contextsObj.contains.push(N.contextsInfo[M].contains);N.contextsObj.partlyContains.push(N.contextsInfo[M].partlyContains)}return N.contextsObj}})();baidu.getStyle=function(C,A){if(C=baidu.G(C)){var B=baidu.isString(A);A=B?[A]:A;var G=[];var H=function(M,N){return N.charAt(1).toUpperCase()};var J=function(M){var Q=M.split(",");var P="#",O;for(var N=0;O=Q[N];N++){O=O.replace(/[^\d]/gi,"");O=parseInt(O,10);O=O.toString(16);if(O.length==1){O="0"+O}P+=O}return P.toUpperCase()};for(var F=0,D;F=0?(parseFloat(L.match(/opacity=([^)]*)/)[1])/100)+"":"1"}if(D=C.style[E]){G[F]=D}else{if(C.currentStyle){D=C.currentStyle[E]}else{var I=C.nodeType==9?C:C.ownerDocument||C.document;if(I.defaultView&&I.defaultView.getComputedStyle){var K=I.defaultView.getComputedStyle(C,"");if(K){D=K[E]}}}}if(/color/i.test(E)&&D.indexOf("rgb(")!=-1){D=J(D)}G[F]=D}if(B){G=G[0]}return G}};baidu.editor.registParser("bold",function(A){var B=-1;A.getContexts().walkTextNode(function(C){var D=baidu.getStyle(baidu.dom.getParent(C),"font-weight");if(((parseInt(D)>400||D=="bold")&&(C.parentNode.tagName.indexOf("H")!==0))&&(B==-1||B==1)){B=1}else{B=0}});if(B==-1){B=0}return B});baidu.editor.Editor.prototype.italic=function(){this.execCommand("Italic");this.dispatchEvent(new baidu.BaseEvent("onitalic"))};baidu.editor.registParser("italic",function(A){var B=-1;A.getContexts().walkTextNode(function(C){var D=baidu.getStyle(baidu.dom.getParent(C),"font-style");if(D=="italic"&&(B==-1||B==1)){B=1}else{B=0}});if(B==-1){B=0}return B});baidu.editor.Editor.prototype.underline=function(){this.execCommand("Underline");this.dispatchEvent(new baidu.BaseEvent("onunderline"))};baidu.editor.registParser("underline",function(A){return A.getContexts().containNode("u")});baidu.editor.Editor.prototype.fontname=function(A){this.execCommand("FontName",false,A);this.dispatchEvent(new baidu.BaseEvent("onfontname"))};(function(){baidu.editor.Editor.prototype.queryFontname=function(){var I=this;var B=I.getSelection().getRanges();var H=[];if(B.length==1&&B[0].collapsed){var G=B[0];var F=G.startContainer;while(F.nodeType==3&&F.parentNode){F=F.parentNode}var E=baidu.getStyle(F,"font-family");return A(E)}for(var C=0;C=0){return D[C]}else{if(/^\d+/g.test(C)){return C}else{return B[C]}}}}})();baidu.editor.Editor.prototype.foreColor=function(A){this.execCommand("ForeColor",false,A);this.dispatchEvent(new baidu.BaseEvent("onforecolor"))};(function(){baidu.editor.Editor.prototype.queryForeColor=function(){var H=this,C=H.getSelection(),E=false,F=false,B=C.getRanges(),J=A||function(L){return L};function K(M){var L;while(M.parentNode&&!(L=J(baidu.getStyle(M,"color")))){M=M.parentNode}return L}if(B.length==1&&B[0].collapsed){var D=B[0].startContainer;if(baidu.isText(D)){D=baidu.dom.getParent(D)}E=K(D)}else{var I=C.getTextNodes();for(var G=0;G=H){var D;if(H==10){D=Fe.Dialog.alert("对不起,图片总数限制为"+H+"张:( !",{title:"提示",locked:true})}else{D=Fe.Dialog.alert("对不起,图片总数限制为"+H+"张:( !",{title:"提示",locked:true})}D.onopen=function(){document.body.focus()};D.onclose=function(){A.focus()};return }}var F;if(E){F=E.src}G.dialog=Fe.Dialog.open("../common/uploadRichTextImage.action"+(E!=null?"#imgUrlValue="+encodeURIComponent(F):""),{title:"添加或修改图片",width:"380px",height:"125px",buttonbar:true,buttonAccept:true,buttonCancel:true,locked:true,contentType:"HTMLUrl"});G.dialog.afterUpload=function(J){A.insertImage(J);G.dialog.close();B.uploadNum++};G.dialog.onaccept=function(K){var J=G.dialog.window,J=G.dialog.window=(!J)?G.dialog.getIframe().contentWindow:J,L=J.document;J.startUpload(G);K.returnValue=false};G.dialog.onclose=function(){A.focus()}});A.addEventListener("onselectionchange",function(E){var D=A.queryContextState("image");switch(D){case 0:C=false;break;case 1:C=true;break;case 2:C=false;break;case 3:C=true;break}});A.addEventListener("onbeforeselectionchange",function(D){A.tools.image.enable()});A.addEventListener("onafterselectionchange",function(D){if(C){B.button.highlight()}else{B.button.removeHighlight()}})};(function(){baidu.editor.Editor.prototype.getFilter=function(){var C=this;if(!C._filter){var B=C._filter=new (function(){var E={},F;this.add=function(H,G){G=G||"key_"+(new Date()).getTime();E[G]=H};this.remove=function(G){delete E[G]};var D=this.builder=new A(C);this.filter=function(H){D._process(H);for(var G in E){E[G](H)}};updateTagCount=function(G){F=C.document.getElementsByTagName("*").length};C.addEventListener("onafterexeccommand",updateTagCount);C.addEventListener("onwysiwygready",updateTagCount);C.addEventListener("onselectionchange",function(K){var G=C.document.getElementsByTagName("*").length,J,I,H;if(baidu.ie){J=C.document.selection.createRange()}else{J=C.window.getSelection().getRangeAt(0)}if(G==F){return }else{if(G<=F*0.8||G>=F*1.2){F=G;I=C.document.body}else{F=G;if(!baidu.ie){I=baidu.dom.getCommonAncestor(J.startContainer,J.endContainer)}else{H=C.document.selection;if(H.type.toUpperCase()!="CONTROL"){I=J.parentElement();if(baidu.dom.getDocument(I)!=C.document){I=C.document.body}}else{I=C.document.body}}}}B.filter(I)})})()}return C._filter};var A=function(E){var D={};var B={};var C=[];var G=function(){this.attribute={};this.allow={};this.except={};this.text=false;this.html=false;this.delegates=[]};var F=false;this.element=function(J){F=true;C=[];var I=J.split(",");for(var H=0;H=0;N--){var J=K[N];if(!L.attribute[J.name.toLowerCase()]){M.removeAttribute(J.name)}}if(M.className&&!L.attribute["class"]){M.className=""}var I=M.lastChild;while(I){var Q=I.previousSibling;switch(I.nodeType){case 1:var H=I.tagName.toLowerCase();if(((L.html&&D[H])||L.allow[H])&&!L.except[H]&&!B[H]){arguments.callee(I)}else{if(L.text&&!B[H]){var O=I.innerHTML;for(key in B){O=O.replace(new RegExp("<"+key+"[\\s\\S]*?>[\\s\\S]*?","ig"),"")}O=O.replace(/<[\s\S]*?>/ig,"").replace(/ /g," ").replace(/"/g,'"').replace(/</g,"<").replace(/>/g,">").replace(/&/g,"&");M.insertBefore(E.document.createTextNode(O),I);M.removeChild(I)}else{M.removeChild(I)}}break;case 3:if(!L.text){M.removeChild(I)}break}I=Q}}}})();baidu.editor.register(function(A){A.getFilter().builder.element("body").attribute("contentEditable,style").html().text().element("span").attribute("style").html().text().element("pre").attribute("style").html().text().element("center").attribute("style").html().text().element("ul").attribute("style").html().text().element("ol").attribute("style").html().text().element("li").attribute("style").html().text().element("a").attribute("style, href, target").html().text().element("br").element("div").attribute("style, align").html().text().element("h1, h2, h3, h4, h5, h6").attribute("style, align").html().text().element("table").html("tbody, thead, tfoot, tr").attribute("style, cellpadding, cellspacing, border, align").element("tbody").html("thead, tfoot, tr").attribute("style").element("thead, tfoot").html("tr").attribute("style").element("tr").html("th","td").attribute("style").element("th, td").attribute("style, colspan, rowspan, align").html().text().element("b,strong").attribute("style").html().text().element("i,em").attribute("style").html().text().element("u").attribute("style").html().text().element("font").attribute("face, size, color, style").html().text().element("p").attribute("style,align").html().text().element("img").attribute("src, style, width, height").eliminate("script, style, object, embed, applet, select, input, textarea")});function ce(A){var B=document.createElement(A);B.style.MozUserSelect="none";B.unselectable="on";return B}function stopEvent(A){if(A){A.cancelBubble=true;if(A.stopPropagation){A.stopPropagation()}}}function preventDefault(A){A.returnValue=false;if(A.preventDefault){A.preventDefault()}}function Toolbar(B){var A=this;A.id=B;A.dom=baidu.G(B);A.create()}baidu.extend(Toolbar.prototype,{create:function(){this.dom.style.MozUserSelect="none";this.dom.unselectable="on"},addButton:function(A){if(A&&A.getDomObj){this.dom.appendChild(A.getDomObj())}},addBar:function(){var B=ce("div");var A=ce("span");baidu.addClass(A,"btn_bar");B.appendChild(A);A.style.MozUserSelect="none";A.unselectable="on";B.style.MozUserSelect="none";B.unselectable="on";this.dom.appendChild(B)}});Button.config={hover:"btn_hover",active:"btn_active",disabled:"btn_disabled",highlight:"btn_highlight",defaultClassName:"",textButton:"btn_text btn_default",idPrefix:"toolbar-button-"};var buttonCounter=0;function Button(A){var B=this;buttonCounter++;baidu.BaseClass.call(B);A=A||{};B.id=A.id||Button.config.idPrefix+buttonCounter;B.className=A.className||Button.config.defaultClassName;B._onclick=A.onclick;B.label=A.label;B.title=A.title;B.button=null;B.inner=null;B.isDisabled=false;B.isHighlight=false;B._createWraper()}baidu.inherits(Button,baidu.BaseClass,"Button");baidu.extend(Button.prototype,{_createWraper:function(){var D=this;var C=D.button=ce("div");C.id=D.id;if(D.label){baidu.addClass(C,Button.config.textButton)}var B=ce("div");var A=D.inner=ce("p");C.appendChild(B);B.appendChild(A);B.title=D.title;C.style.MozUserSelect="none";B.style.MozUserSelect="none";A.style.MozUserSelect="none";C.unselectable="on";B.unselectable="on";A.unselectable="on";D.createInner();D.registerHandlers();return D},createInner:function(){var B=this;var A=ce("span");baidu.addClass(A,B.className);A.style.MozUserSelect="none";A.unselectable="on";B.addContent(A);if(B.label){A.innerHTML=B.label}},addContent:function(A){this.inner.appendChild(A)},registerHandlers:function(){var B=this;var A=B.button;baidu.on(A,"mouseover",function(C){if(B.isDisabled){return }baidu.addClass(A,Button.config.hover)});baidu.on(A,"mouseout",function(C){if(B.isDisabled){return }baidu.removeClass(A,Button.config.hover);baidu.removeClass(A,Button.config.active)});baidu.on(A,"mousedown",function(C){if(B.isDisabled){return }baidu.addClass(A,Button.config.active)});baidu.on(A,"mouseup",function(C){if(B.isDisabled){return }baidu.removeClass(A,Button.config.active)});baidu.on(A,"click",function(C){if(B.isDisabled){return }if(B._onclick&&typeof B._onclick=="function"){B._onclick()}else{B.confirm()}})},getDomObj:function(){return this.button},highlight:function(){this.isHighlight=true;baidu.addClass(this.button,Button.config.highlight)},disable:function(){this.isDisabled=true;baidu.removeClass(this.button,Button.config.highlight);baidu.removeClass(this.button,Button.config.hover);baidu.addClass(this.button,Button.config.disabled)},removeHighlight:function(){this.isHighlight=false;baidu.removeClass(this.button,Button.config.highlight)},enable:function(){this.isDisabled=false;baidu.removeClass(this.button,Button.config.disabled)},confirm:function(){this.dispatchEvent(new baidu.BaseEvent("onconfirm"))}});Select.config={select:"editor-toolbar-select",caption:"editor-toolbar-select-caption",dropdown:"editor-toolbar-select-dropdown",inline:"editor-toolbar-select-inline"};var selectListCounter=0;baidu.extend(Select.config,Button.config);function Select(A){var B=this;A=A||{};B.caption=A.caption||"SELECT";B.options=A;if(A.list){B.list=A.list}else{if(A.items){B.list=new List({id:(B.id?"editor-select-list"+B.id:"editor-select-list"+selectListCounter++),items:A.items,listClassName:A.listClassName,itemClassName:A.itemClassName})}else{return false}}B.className=A.className;B._onchange=A.onchange;Button.call(B,A)}baidu.inherits(Select,Button,"Select");baidu.extend(Select.prototype,{createInner:function(){var B=this;baidu.addClass(B.button,Select.config.select);if(B.className){baidu.addClass(B.button,B.className)}var A=B.oCaption=ce("div");baidu.addClass(A,Select.config.inline);baidu.addClass(A,Select.config.caption);A.innerHTML=B.caption;var C=ce("div");baidu.addClass(C,Select.config.inline);baidu.addClass(C,Select.config.dropdown);C.innerHTML=" ";A.unselectable="on";C.unselectable="on";A.MozUserSelect="none";C.MozUserSelect="none";B.addContent(A);B.addContent(C);B._registerHanlders()},_registerHanlders:function(){var A=this;baidu.on(A.button,"mousedown",function(B){if(A.isDisabled){return }var C=baidu.getPosition(A.button);A.list.setPosition({left:C.left,top:(C.top+A.button.offsetHeight)});A.list.toggle();stopEvent(B)});baidu.on(A.button,"mouseup",function(B){if(A.isDisabled){return }stopEvent(B)});A.list._onclick=function(){A.list.hide();var B=A.list.getValue();A._setCaption(B)};A.list.addEventListener("onchange",function(){A.dispatchEvent(new baidu.BaseEvent("onchange"))})},_setCaption:function(B){var A=this;if(!B){return false}if(A.options._setCaption){A.options._setCaption(A.oCaption,B);return false}if(baidu.ie){this.oCaption.innerText=B?B:this.caption}else{this.oCaption.innerHTML=B?B:this.caption}},setValue:function(B,C){var A=this;A.list.setValue(B,C);A._setCaption(B)},getValue:function(){return this.list.getValue()}});List.config={wraper:"editor-toolbar-list",outer:"editor-toolbar-list-item",hover:"editor-toolbar-list-item-hover",selected:"editor-toolbar-list-item-selected",idPrefix:"editor-toolbar-list-"};List.lists=[];List.hideAll=function(){for(var B=0;B=0&&B-1&&/AppleWebKit\/([^\s]*)/.test(navigator.userAgent))?RegExp.$1:0;baidu.isOpera=(window.opera&&/Opera(\s|\/)(\d+(\.\d+)?)/.test(navigator.userAgent))?RegExp.$2:0;baidu.isSafari=(navigator.userAgent.indexOf("Safari")>-1&&/Version\/(\d+(\.\d+)?)/.test(navigator.userAgent))?RegExp.$1:0;baidu.isGecko=(navigator.userAgent.indexOf("Gecko")>-1&&navigator.userAgent.indexOf("KHTML")==-1&&/rv\:(\d+(\.\d+)?)/.test(navigator.userAgent))?RegExp.$1:0;baidu.isStrict=(document.compatMode=="CSS1Compat");baidu.css=function(C,G){if(!C||!G){return null}C=typeof C=="string"?document.getElementById(C):C;var B=!window.opera&&navigator.userAgent.indexOf("MSIE")!=-1;if(G=="float"){G=B?"styleFloat":"cssFloat"}G=G.replace(/(-[a-z])/gi,function(H,I){return I.charAt(1).toUpperCase()});if("opacity"==G&&B){var A=C.style.filter;return A&&A.indexOf("opacity=")>=0?(parseFloat(A.match(/opacity=([^)]*)/)[1])/100)+"":"1"}var F=null;if(F=C.style[G]){return F}if(C.currentStyle){return C.currentStyle[G]}else{var E=C.nodeType==9?C:C.ownerDocument||C.document;if(E.defaultView&&E.defaultView.getComputedStyle){var D=E.defaultView.getComputedStyle(C,"");if(D){return D[G]}}}return null};baidu.dom.getStyle=function(B,A){return baidu.css(B,A)};baidu.dom.getPosition=function(D){D=baidu.G(D);if(!baidu.isElement(D)){throw new Error("[baidu.dom.getPosition] param must be Element")}var G=baidu.dom.getDocument(D);var F=baidu.isGecko>0&&G.getBoxObjectFor&&baidu.dom.getStyle(D,"position")=="absolute"&&(D.style.top===""||D.style.left==="");var H={left:0,top:0};var B=(baidu.isIE&&!baidu.isStrict)?G.body:G.documentElement;if(D==B){return H}var C=null;var E;if(D.getBoundingClientRect){E=D.getBoundingClientRect();H.left=E.left+Math.max(G.documentElement.scrollLeft,G.body.scrollLeft);H.top=E.top+Math.max(G.documentElement.scrollTop,G.body.scrollTop);H.left-=G.documentElement.clientLeft;H.top-=G.documentElement.clientTop;if(baidu.isIE&&!baidu.isStrict){H.left-=2;H.top-=2}}else{if(G.getBoxObjectFor&&!F){E=G.getBoxObjectFor(D);var A=G.getBoxObjectFor(B);H.left=E.screenX-A.screenX;H.top=E.screenY-A.screenY}else{C=D;do{H.left+=C.offsetLeft;H.top+=C.offsetTop;if(baidu.isWebkit>0&&baidu.dom.getStyle(C,"position")=="fixed"){H.left+=G.body.scrollLeft;H.top+=G.body.scrollTop;break}C=C.offsetParent}while(C&&C!=D);if(baidu.isOpera>0||(baidu.isWebkit>0&&baidu.dom.getStyle(D,"position")=="absolute")){H.top-=G.body.offsetTop}C=D.offsetParent;while(C&&C!=G.body){H.left-=C.scrollLeft;if(!baidu.isOpera||C.tagName!="TR"){H.top-=C.scrollTop}C=C.offsetParent}}}return H};MenuButton.config={label:"toolbar-menu-button-label",dropdown:"toolbar-menu-button-dropdown",menubutton:"toolbar-menu-button"};baidu.extend(MenuButton.config,Button.config);function MenuButton(A){var B=this;A=A||{};B.label=A.label||"MenuButton";B.items=[];B.menu=new Menu();Button.call(B,A)}baidu.inherits(MenuButton,Button,"MenuButton");baidu.extend(MenuButton.prototype,{createInner:function(){var B=this;baidu.addClass(B.button,MenuButton.config.textButton);var A=ce("span");baidu.addClass(A,B.className);A.innerHTML=B.label;A.unselectable="on";A.MozUserSelect="none";B.addContent(A);B._registerHandlers()},_registerHandlers:function(){var A=this;baidu.on(A.button,"mousedown",function(B){if(A.isDisabled){return }var C=baidu.dom.getPosition(A.button);A.menu.setPosition({left:C.left,top:(C.top+A.button.offsetHeight)});A.menu.toggle();window.focus();stopEvent(B)});baidu.on(A.button,"mouseup",function(B){if(A.isDisabled){return }stopEvent(B)})},addMenuitem:function(A){this.menu.addMenuitem(A)}});var EditorTools=function(F){this.undo;this.redo;this.bold;this.italic;this.image;var E=new Toolbar(F);this.undo=new Button({className:"btn_undo",title:"撤销"});E.addButton(this.undo);this.redo=new Button({className:"btn_redo",title:"重做"});E.addButton(this.redo);E.addBar();this.bold=new Button({className:"btn_bold",title:"加粗"});E.addButton(this.bold);this.italic=new Button({className:"btn_italic",title:"斜体"});E.addButton(this.italic);this.underline=new Button({className:"btn_underline",title:"下划线"});E.addButton(this.underline);var L=[["黑色","black","000000"],["红色","red","FF0000"],["蓝色","blue","0000FF"],["绿色","green","008000"],["紫色","purple","800080"],["黄色","yellow","FFFF00"],["灰色","gray","808080"],["浅绿色","aqua","00FFFF"],["紫红色","fuchsia","FF00FF"],["褐紫色","maroon","800000"],["藏青色","navy","000080"],["黄褐色","olive","808000"],["银白色","silver","C0C0C0"]];var B={"000000":"黑色",FF0000:"红色","0000FF":"蓝色","008000":"绿色","800080":"紫色",FFFF00:"黄色","808080":"灰色","00FFFF":"浅绿色",FF00FF:"紫红色","800000":"褐紫色","000080":"藏青色","808000":"黄褐色",C0C0C0:"银白色"};var A=[];for(var J in B){var K={};K.value=J;K.content=''+B[J]+"";A.push(K)}this.forecolor=new Select({caption:"字体颜色",title:"字体颜色",className:"editor-toolbar-select-forecolor",items:A,listClassName:"editor-toolbar-forecolor-list",itemClassName:"editor-toolbar-forecolor-item",_setCaption:function(M,O){if(!O){return false}var O=O.replace("#","");O=O=="000"?"000000":O;var N=B[O];N=N||"字体颜色";baidu.ie?M.innerText=N:M.innerHTML=N}});E.addButton(this.forecolor);E.addBar();this.justifyleft=new Button({className:"btn_justifyleft",title:"居左"});E.addButton(this.justifyleft);this.justifycenter=new Button({className:"btn_justifycenter",title:"居中"});E.addButton(this.justifycenter);this.justifyright=new Button({className:"btn_justifyright",title:"居右"});E.addButton(this.justifyright);var H=["sans-serif","宋体","黑体","幼圆","楷体_GB2312","仿宋_GB2312","Arial","Comic Sans MS","Courier New","Tahoma","Times New Roman","Verdana"];var I=[];for(var C=0;C'+H[C]+"";I.push(K)}this.fontname=new Select({caption:"选择字体",title:"字体",className:"editor-toolbar-select-fontfamily",listClassName:"editor-toolbar-fontname-list",itemClassName:"editor-toolbar-fontname-item",items:I});E.addButton(this.fontname);var D={"1":"10","2":"13","3":"16","4":"18","5":"24","6":"32","7":"48"};var G=[];for(var J in D){var K={};K.value=J;K.content=''+D[J]+"";G.push(K)}this.fontsize=new Select({caption:"选择字号",title:"字号",className:"editor-toolbar-select-fontsize",items:G,listClassName:"editor-toolbar-fontsize-list",itemClassName:"editor-toolbar-fontsize-item",_setCaption:function(M,N){if(!N){return false}var O=D[N];O=O||"选择字号";baidu.ie?M.innerText=O:M.innerHTML=O}});E.addButton(this.fontsize);E.addBar();this.image=new Button({className:"btn_image",title:"插入/编辑图片"});E.addButton(this.image);this.buttonDisable()};EditorTools.prototype.buttonEnable=function(){this.bold.enable();this.italic.enable();this.image.enable();this.underline.enable();this.justifyleft.enable();this.justifycenter.enable();this.justifyright.enable();this.fontname.enable();this.fontsize.enable();this.forecolor.enable()};EditorTools.prototype.buttonDisable=function(){this.undo.disable();this.redo.disable();this.bold.disable();this.italic.disable();this.image.disable();this.underline.disable();this.justifyleft.disable();this.justifycenter.disable();this.justifyright.disable();this.fontname.disable();this.fontsize.disable();this.forecolor.disable()};function editorInit(A){var B=A.tools;A.addToolbarItem(new baidu.editor.toolbar.Undo(A,B.undo));A.addToolbarItem(new baidu.editor.toolbar.Redo(A,B.redo));A.addToolbarItem(new baidu.editor.toolbar.Bold(A,B.bold));A.addToolbarItem(new baidu.editor.toolbar.Italic(A,B.italic));A.addToolbarItem(new baidu.editor.toolbar.Underline(A,B.underline));A.addToolbarItem(new baidu.editor.toolbar.JustifyLeft(A,B.justifyleft));A.addToolbarItem(new baidu.editor.toolbar.JustifyCenter(A,B.justifycenter));A.addToolbarItem(new baidu.editor.toolbar.JustifyRight(A,B.justifyright));A.addToolbarItem(new baidu.editor.toolbar.Image(A,B.image));A.addToolbarItem(new baidu.editor.toolbar.FontName(A,B.fontname));A.addToolbarItem(new baidu.editor.toolbar.FontSize(A,B.fontsize));A.addToolbarItem(new baidu.editor.toolbar.ForeColor(A,B.forecolor))}(function(){baidu.getPosition=function(C){return{left:A(C),top:B(C)}};function A(D){var C=0;while(D!=null){C+=D.offsetLeft;D=D.offsetParent}return C}function B(D){var C=0;while(D!=null){C+=D.offsetTop;D=D.offsetParent}return C}})();(function(){baidu.getPointer=function(C){var B=document.documentElement,A=document.body||{scrollLeft:0,scrollTop:0};return{x:C.pageX||(C.clientX+(B.scrollLeft||A.scrollLeft)-(B.clientLeft||0)),y:C.pageY||(C.clientY+(B.scrollTop||A.scrollTop)-(B.clientTop||0))}}})(); \ No newline at end of file diff --git a/WebContent/stat/js/ui/floater/css/floater.css b/WebContent/stat/js/ui/floater/css/floater.css deleted file mode 100644 index fe868f807..000000000 --- a/WebContent/stat/js/ui/floater/css/floater.css +++ /dev/null @@ -1,93 +0,0 @@ -.floaterd { - padding-top: 3px; -} - -.floaterd-top { - background: #3B5C55 -} - -.floaterd-bottom { - display: none -} - -.floater { - position: absolute !important; - border-radius: 6px; - -webkit-box-shadow: 0 5px 15px rgba(0, 0, 0, .5); - box-shadow: 0 5px 15px rgba(0, 0, 0, .5); - background-color: #fff; - background-clip: padding-box; - border: 1px solid rgba(0, 0, 0, .2); - outline: none; - border: none; -} - -.ec-form.floater { - padding-top: 52px; -} - -.floater-title { - cursor: move; - border-radius: 6px 6px 0 0; - position: absolute; - left: 0; - top: 0; - height: 52px; - padding: 4px 10px 0 18px; - font-size: 18px; - color: #333; - min-height: 16.42857143px; - padding: 15px; - border-bottom: 1px solid #e5e5e5; - font-weight: bold; - position: absolute -} - -.floater-close { - position: absolute; - right: 18px; - top: 14px; - font-size: 1px; - font-size: 22px; - font-weight: bold; - line-height: 1; - color: #000; - text-shadow: 0 1px 0 #fff; - opacity: .2; - cursor: pointer; -} - -.floater-close:after { - content: '×'; -} - -.floater-close:hover { - opacity: .4; -} - -.floater-content { - -webkit-box-shadow: 0 5px 15px rgba(0, 0, 0, .5); - box-shadow: 0 5px 15px rgba(0, 0, 0, .5); - background-color: #fff; - background-clip: padding-box; - border-radius: 0 0 6px 6px; - outline: none; -} - -.floater-inner { - overflow-y: auto; - overflow-x: hidden -} - -.floater-corner { - background: #fff -} - -.div-floater-control { - padding: 15px 20px 2px; - margin-top: 20px; - text-align: right; - border-top: 1px solid #e5e5e5; - margin-left: -19px; - margin-right: -19px; -} \ No newline at end of file diff --git a/WebContent/stat/js/ui/foldable/css/foldable.css b/WebContent/stat/js/ui/foldable/css/foldable.css deleted file mode 100644 index dbba70641..000000000 --- a/WebContent/stat/js/ui/foldable/css/foldable.css +++ /dev/null @@ -1,14 +0,0 @@ -/*.ec-foldable {border:solid 1px #000}*/ -.ec-foldable-title {padding:2px 0 4px 20px;cursor:pointer;border-bottom:1px solid #DFF4CD;color:#356502;font-size:14px;} -/*.ec-foldable-title-over {background-color:#EEE}*/ -/*.ec-foldable-title-press {background-color:#CCC}*/ -.ec-foldable-handler {float:right;margin:3px 3px 0 0} -.ec-foldable-title-fold .ec-foldable-handler, .ec-foldable-title-unfold .ec-foldable-handler {width:16px;height:16px} -.ec-foldable-title-fold .ec-foldable-handler {background:url("img/remove.gif") no-repeat scroll 0 0 transparent;} -.ec-foldable-title-unfold .ec-foldable-handler {background:url("img/add.gif") no-repeat scroll 0 0 transparent;} -.icon-a .ec-foldable-title, .icon-b .ec-foldable-title, .icon-c .ec-foldable-title, .icon-d .ec-foldable-title, .icon-e .ec-foldable-title {background:url("img/icon.gif") no-repeat scroll 0 -145px transparent;} -.icon-b .ec-foldable-title {background-position:0 -170px;} -.icon-c .ec-foldable-title {background-position:0 -195px;} -.icon-d .ec-foldable-title {background-position:0 -248px;} -.icon-e .ec-foldable-title {background-position:0 -273px;} -.ec-foldable-content {margin:5px} diff --git a/WebContent/stat/js/ui/foldable/js/ecomui.foldable.js b/WebContent/stat/js/ui/foldable/js/ecomui.foldable.js deleted file mode 100644 index 23f8f5309..000000000 --- a/WebContent/stat/js/ui/foldable/js/ecomui.foldable.js +++ /dev/null @@ -1,66 +0,0 @@ -var ecomui = ecomui || {}; - -(function() { - var lib = baidu, - core = ecui, - dom = core.dom, - ui = core.ui, - util = core.util, - inherits = util.inherits, - copy = util.copy, - - children = dom.children, - createDom = dom.create, - $fastCreate = core.$fastCreate, - setText = dom.setText, - - DOCUMENT = document, - UI_CONTROL = ui.Control, - ECOM_FOLDABLE_CLASS; - - ecomui.Foldable = ui.Foldable = function(el, params) { - var typeClass = params.type, - contentEl = children(el)[0]; - titleEl = createDom(typeClass + "-title"), - handlerEl = createDom(typeClass + "-handler"); - - el.insertBefore(titleEl, contentEl); - setText(titleEl, params.title || ""); - titleEl.insertBefore(handlerEl, titleEl.firstChild); - - params.capture = false; - - UI_CONTROL.call(this, el, params); - - this._uTitle = $fastCreate(UI_CONTROL, titleEl, this); - this._uContent = $fastCreate(UI_CONTROL, contentEl, this, {capture: false}); - this._uHandler = $fastCreate(UI_CONTROL, handlerEl, this._uTitle, {capture: false}); - - this._uTitle["on" + (params.trigger || "click")] = ECOM_FOLDABLE_TITLECLICK; - - ECOM_FOLDABLE_TOGGLECONTENT.call(this._uTitle, params.initFold || false); - }; - - function ECOM_FOLDABLE_TITLECLICK() { - ECOM_FOLDABLE_TOGGLECONTENT.call(this); - } - - function ECOM_FOLDABLE_TOGGLECONTENT(fold) { - var control = this.getParent(), - content = control._uContent, - handler = control._uHandler, - handlerEl = handler.getBase(), - isShow = fold !== undefined ? fold : content.isShow(); - - isShow ? content.hide() : content.show(); - handlerEl.setAttribute("title", isShow ? "点击展开" : "点击折叠"); - - this.$alterClass(isShow ? "unfold" : "fold"); - this.$alterClass(isShow ? "fold" : "unfold", true); - - control.$resize(); - } - - ECOM_FOLDABLE_CLASS = inherits(ui.Foldable, UI_CONTROL); - - })(); diff --git a/WebContent/stat/js/ui/popup/css/popup.css b/WebContent/stat/js/ui/popup/css/popup.css deleted file mode 100644 index 520f5e625..000000000 --- a/WebContent/stat/js/ui/popup/css/popup.css +++ /dev/null @@ -1,28 +0,0 @@ -.popupdtr {padding-top:9px;padding-bottom:9px} -.popupdtr-top {background:url(img/popup_tb.jpg) top left no-repeat;overflow:hidden;font-size:0px} -.popupdtr-bottom {background:url(img/popup_tb.jpg) 0px -9px no-repeat;font-size:0px} - -.ec-popup {padding-right:13px;border-width:auto;border:none;background:url(img/popup_bg.jpg) top left repeat-y;width:267px;overflow-y:auto;overflow-x:hidden} -.ec-popup .ec-item {padding:auto;height:22px;margin-left:3px;margin-right:3px;padding-left:32px;line-height:22px;cursor:default;border-width:auto;border:none} -.ec-popup-item {padding:auto;height:22px;margin-left:3px;margin-right:3px;padding-left:32px;line-height:22px;cursor:default;background:none;border-bottom:none} -.ec-popup-item-over {background:url(img/popup_over.jpg) top left no-repeat} -.ec-popup-item-complex {background:url(img/popup_more.jpg) 245px 7px no-repeat} -.ec-popup-item-complex-over {background:url(img/popup_more_over.jpg) left top no-repeat} - -.ec-scpopup {padding-right:13px;border-width:auto;border:none;background:url(img/popup_bg.jpg) top left repeat-y;width:267px} -.ec-scpopup-layout {width:260px;height:100%;overflow-y:auto;overflow-x:hidden} -.ec-scpopup .ec-item {padding:auto;height:22px;margin-left:3px;margin-right:3px;padding-left:10px;line-height:22px;cursor:default;border-width:auto;border:none} -.ec-scpopup-item {padding:auto;height:22px;margin-left:3px;margin-right:3px;padding-left:10px;line-height:22px;cursor:default;background:none;border-bottom:none} -.ec-scpopup-item-over {background:url(img/popup_over.jpg) top left no-repeat} -.ec-scpopup-item-complex {background:url(img/popup_more.jpg) 244px 7px no-repeat} -.ec-scpopup-item-complex-over {background:url(img/popup_more_over.jpg) left top no-repeat} -.ec-scpopup-layout-overheight .ec-scpopup-item-complex {background:url(img/popup_more.jpg) 227px 7px no-repeat} -.ec-scpopup-layout-overheight .ec-scpopup-item-complex-over {background:url(img/popup_more_over_oh.jpg) left top no-repeat} -.ec-scpopup-layout-overheight .ec-scpopup-item-over {background:url(img/popup_over_oh.jpg) top left no-repeat} - -.ec-ecombox {top:5px;width:120px;height:17px;border:1px solid #CCC;background:#FFF} -.ec-ecombox-button {top:0px;right:0px;width:17px;height:17px;background:url(img/select.jpg) 0px 0px no-repeat} -.ec-ecombox-over .ec-ecombox-button {background:url(img/select.jpg) -17px 0px no-repeat} -.ec-ecombox-press .ec-ecombox-button {background:url(img/select.jpg) -34px 0px no-repeat} - - diff --git a/WebContent/stat/js/ui/popup/js/ecpopup.js b/WebContent/stat/js/ui/popup/js/ecpopup.js deleted file mode 100644 index 00c85c48d..000000000 --- a/WebContent/stat/js/ui/popup/js/ecpopup.js +++ /dev/null @@ -1,245 +0,0 @@ -(function () { - var core = ecui, - dom = core.dom, - ui = core.ui, - util = core.util, - ext = core.ext, - - createControl = core.create, - inherits = util.inherits, - getView = util.getView, - getPosition = dom.getPosition, - first = dom.first, - copy = util.copy, - blank = core.blank, - restore = core.restore, - trim = core.string.trim, - setStyles = dom.setStyles, - insertFloor = dom.insertFloor, - mask = core.mask, - removeDom = dom.remove, - getChild = dom.children, - setText = dom.setText, - getText = dom.getText, - createDom = dom.create, - moveElements = dom.moveElements, - - DOCUMENT = document, - - - UI_EDIT = ui.Edit, - UI_ITEM = ui.Item, - UI_CONTROL = ui.Control, - UI_CONTROL_CLASS = UI_CONTROL.prototype, - UI_EDIT_CLASS = UI_EDIT.prototype, - UI_POPUP = ui.Popup, - UI_POPUP_CLASS = UI_POPUP.prototype; - - var UI_ECOMBOX = ui.Ecombox = function (el, params) { - var me = this, - typeClass = params.type, - items; - - me._uPopup = createControl( - 'Scpopup', - { - 'element' : first(el) - } - ); - me._uPopup.$setParent(me); - items = me._uPopup.getItems(); - - for (var i = 0, item; item = items[i]; i++) { - UI_ECOMBOX_ATTACHHANDLER(item); - } - - - UI_EDIT.call(me, el, params); - - (params.maxlength) && (this.getInput().maxLength = params.maxlength); - this.getInput().style.position = 'absolute'; - - (me._uButton = createControl( - 'Control', - { - 'base' : typeClass + '-button', - 'parent' : me, - 'capture' : false - } - )).getOuter().style.position = 'absolute'; - - el.style.position = 'relative'; - }, - - UI_ECOMBOX_CLASS = inherits(UI_ECOMBOX, UI_EDIT); - - UI_ECOMBOX_CLASS.$click = function (event) { - var target = event.target; - UI_EDIT_CLASS.$click.call(this, event); - if (target.getControl && target.getControl() == this._uButton) { - this.showPopup(); - } - }; - - UI_ECOMBOX_CLASS.setValue = function (text) { - if (this.getInput().value != text) { - UI_EDIT_CLASS.setValue.call(this, text); - return true; - } - else { - return false; - } - }; - - UI_ECOMBOX_CLASS.showPopup = function () { - var pos = getPosition(this.getOuter()), - o = this._uPopup, - popupTop = pos.top + this.getHeight(), - items; - - o.setPosition( - pos.left, - popupTop + o.getHeight() <= getView().bottom ? popupTop : pos.top - o.getHeight() - ); - - items = o.getItems(); - for (var i = 0, item; item = items[i]; i++) { - (item._cPopup) && (item._cPopup.paint()); - } - - mask(0.05); - o.show(); - o.onhide = UI_ECOMBOX_HIDEMASK; - }; - - UI_ECOMBOX_CLASS.$setSize = function (width, height) { - UI_EDIT_CLASS.$setSize.call(this, width, height); - - width = this.getBodyWidth() - height; - this.getInput().style.width = width + 'px' - setStyles(this.getInput(), {'width' : width + 'px', 'height' : height + 'px'}); - }; - - function UI_ECOMBOX_HIDEMASK() { - mask(); - } - - function UI_ECOMBOX_SETVALUE() { - var el = this.getBody(), - value = el.getAttribute('value'), - text = trim(el.getAttribute('title') ? el.getAttribute('title') : el.innerHTML), - con = this; - - while ((con = con.getParent()) && !(con instanceof UI_ECOMBOX)) {} - - if ((con) && (con.setValue(text)) && (con.onpostdata)) { - con.onpostdata(value); - } - - } - - function UI_ECOMBOX_ATTACHHANDLER(item) { - var childs = item.getChildItems(); - if (childs.length == 0) { - return; - } - for (var i = 0, child; child = childs[i]; i++) { - child.onclick = UI_ECOMBOX_SETVALUE; - UI_ECOMBOX_ATTACHHANDLER(child); - } - } - - var UI_SCPOPUP = ui.Scpopup = function (el, params) { - var i = 0, - o; - - UI_CONTROL.call(this, el, params); - - o = createDom(); - moveElements(o, el); - el.appendChild(o); - this._eBody = o; - this._eBody.className = params.type + '-layout'; - - this._nMaxHeight = params.maxheight || 300; - this._nMaxTextLen = params.maxTextLen || 20; - - /* 初始化菜单项 */ - //this.setParent(DOCUMENT.body); - DOCUMENT.body.appendChild(el); - this.$initItems(); - this.$alterItems(); - - el = this.getOuter().style; - el.display = 'none'; - el.position = 'absolute'; - - /* 弹出菜单初始化完成后就不允许改变父对象 */ - this.setParent = blank; - - /* 初始化子弹出菜单 */ - for (el = this.getItems(); o = el[i++]; ) { - o._cPopup && o.setClass(params.base + '-item-complex'); - } - - /* 修正文字长度不能超过限制 */ - for (i=0, el = getChild(this._eBody); o = el[i++];) { - if (first(o) && first(o).tagName.toLowerCase() == 'label') { - o = first(o); - } - if ((getText(o).length) > this._nMaxTextLen) { - o.setAttribute('title', getText(o)); - setText(o, getText(o).substring(0, this._nMaxTextLen - 3) + '...'); - } - } - }, - - UI_SCPOPUP_CLASS = inherits(UI_SCPOPUP, UI_POPUP); - - UI_SCPOPUP_CLASS.$createChild = function (item, el) { - var popup; - if (trim(el.innerHTML) == '') { - removeDom(el); - return false; - } - popup = item._cPopup = createControl( - 'Scpopup', - { - base: item.getParent().getClass(), - element: el - } - ); - - popup.$setParent(item); - return popup; - }; - - UI_SCPOPUP_CLASS.$create = function () { - new ext.TBDecorator(this, 'popupdtr'); - UI_CONTROL_CLASS.$create.call(this); - }; - - UI_SCPOPUP_CLASS.$setSize = function (width, height) { - var el = this._eBody; - if ( height > this._nMaxHeight) { - height = this._nMaxHeight; - if (el.className.indexOf('overheight') < 0) { - el.className = el.className + ' ' + this.getBaseClass() + '-layout-overheight'; - } - } - UI_CONTROL_CLASS.$setSize.call(this, width, height); - }; - - UI_SCPOPUP_CLASS.$forcibly = function (event) { - var con = event.getTarget(), find = false; - while(con) { - if (con == this) { - find = true; - break; - } - con = con.getParent(); - } - (!find) && (UI_POPUP_CLASS.$forcibly.call(this)); - return false; - } -})() diff --git a/WebContent/stat/js/ui/scroll/css/scroll.css b/WebContent/stat/js/ui/scroll/css/scroll.css deleted file mode 100644 index b9ff6824b..000000000 --- a/WebContent/stat/js/ui/scroll/css/scroll.css +++ /dev/null @@ -1,36 +0,0 @@ -.ec-vscroll {background:#F0F0F0;width:auto;padding:15px 0px 15px 0px;font-size:0px} -.ec-hscroll {background:#F0F0F0;height:auto;padding:0px 15px 0px 15px;font-size:0px} -.ec-hscroll-block {background:url(img/hscroll.jpg) -2px -30px repeat-x} -.ec-vscroll-block {background:url(img/scroll.jpg) 0px 0px repeat-y} -.ec-hscroll-block-over {background:url(img/hscroll.jpg) -0px -45px repeat-x} -.ec-hscroll-block-press {background:url(img/hscroll.jpg) -0px -60px repeat-x} -.ec-vscroll-block-over {background:url(img/scroll.jpg) -15px 0px repeat-y} -.ec-vscroll-block-press {background:url(img/scroll.jpg) -30px 0px repeat-y} -.ec-vscroll-prev {background:url(img/scroll.jpg) -45px -40px no-repeat;} -.ec-vscroll-prev-over {background:url(img/scroll.jpg) -75px -40px no-repeat;} -.ec-vscroll-prev-press {background:url(img/scroll.jpg) -60px -40px no-repeat;} -.ec-vscroll-next {background:url(img/scroll.jpg) -45px -55px no-repeat;} -.ec-vscroll-next-over {background:url(img/scroll.jpg) -75px -55px no-repeat;} -.ec-vscroll-next-press {background:url(img/scroll.jpg) -60px -55px no-repeat;} -.ec-hscroll-prev {background:url(img/scroll.jpg) -45px -85px no-repeat;} -.ec-hscroll-prev-over {background:url(img/scroll.jpg) -75px -85px no-repeat;} -.ec-hscroll-prev-press {background:url(img/scroll.jpg) -60px -85px no-repeat;} -.ec-hscroll-next {background:url(img/scroll.jpg) -45px -70px no-repeat;} -.ec-hscroll-next-over {background:url(img/scroll.jpg) -75px -70px no-repeat;} -.ec-hscroll-next-press {background:url(img/scroll.jpg) -60px -70px no-repeat;} - -.vsblockdtr {padding:2px 0px} -.vsblockdtr-top {background:url(img/scroll.jpg) -45px 0px no-repeat} -.vsblockdtr-bottom {background:url(img/scroll.jpg) -45px -18px no-repeat} -.vsblockdtr-over .vsblockdtr-top {background:url(img/scroll.jpg) -45px -20px no-repeat} -.vsblockdtr-over .vsblockdtr-bottom {background:url(img/scroll.jpg) -45px -38px no-repeat} -.vsblockdtr-press .vsblockdtr-top {background:url(img/scroll.jpg) -60px 0px no-repeat} -.vsblockdtr-press .vsblockdtr-bottom {background:url(img/scroll.jpg) -60px -38px no-repeat} - -.hsblockdtr {padding:0px 2px} -.hsblockdtr-left {background:url(img/hscroll.jpg) -60px 0px no-repeat} -.hsblockdtr-right {background:url(img/hscroll.jpg) -18px 0px no-repeat} -.hsblockdtr-over .hsblockdtr-left {background:url(img/hscroll.jpg) -40px -0px no-repeat} -.hsblockdtr-over .hsblockdtr-right {background:url(img/hscroll.jpg) -38px -0px no-repeat} -.hsblockdtr-press .hsblockdtr-left {background:url(img/hscroll.jpg) -40px -15px no-repeat} -.hsblockdtr-press .hsblockdtr-right {background:url(img/hscroll.jpg) -38px -15px no-repeat} diff --git a/WebContent/stat/js/ui/selectbox/css/selectbox.css b/WebContent/stat/js/ui/selectbox/css/selectbox.css deleted file mode 100644 index e4f0fc0b4..000000000 --- a/WebContent/stat/js/ui/selectbox/css/selectbox.css +++ /dev/null @@ -1,16 +0,0 @@ -.ec-panel{z-index:9000;height:100px;width:137px;background:#fff} -.ec-panel-corner {background:#F0F0F0;font-size:1px;} -.ec-panel-layout {border:1px solid #CCC;line-height:20px;padding:3px;} -.select-box .ec-panel-layout{text-align:left;margin-top:1px;background:#fff;} -.select-box .ec-vscroll{border-right:1px #ccc solid;cursor:pointer;cursor:hand;} -.select-box button {margin:5px 0;} -.select-box .ec-edit{padding-right:15px;height:15px;background:#fff url("img/scroll_bg.gif") no-repeat right -15px;border:1px #ccc solid;cursor:pointer;cursor:hand;} - - - -.ec-panel-corner {background:#F0F0F0;font-size:1px;} -.ec-panel-layout {background:#fff; border:1px solid #CCC;line-height:20px;padding:3px;} -.select-box .ec-panel-layout{text-align:left;margin-top:1px;background:#fff;} -.select-box .ec-vscroll{border-right:1px #ccc solid;cursor:pointer;cursor:hand;} -.select-box button {margin:5px 0;} -.sel-edit{z-index:9000;padding-right:13px;background:#fff url("img/scroll_bg.gif") no-repeat right -14px;border:1px #ccc solid;cursor:pointer;cursor:hand;} diff --git a/WebContent/stat/js/ui/selectbox/js/selectbox.js b/WebContent/stat/js/ui/selectbox/js/selectbox.js deleted file mode 100644 index 1227840ed..000000000 --- a/WebContent/stat/js/ui/selectbox/js/selectbox.js +++ /dev/null @@ -1,136 +0,0 @@ -//按钮的点击事件 - function wrapHide(tg){ - var wrap = baidu.dom.getAncestorByClass(tg, "ec-panel"); - wrap = wrap.getControl(); - var selectBox = wrap.getParent(); - var edit = selectBox._uEdit.getInput(); - var allBox = selectBox._uPanel.getOuter().getElementsByTagName("input") - var str = ""; - for(var i=0,j=0; i'; - panelHTML += '
'; - body.innerHTML = panelHTML; - core.init(body); - this.setClass("select-box"); - - this._uHeight = params.pHeight || 30 - this._uCol = params.col || 1; - this._uName = params.name; - this._uEdit = core.get("edit-" + id); - this._uPanel =core.get("panel-" + id); - - //最开始隐藏下拉层 - this._uPanel.hide(); - this.init(); - //绑定事件 - this._uEdit.onclick = SELECT_BOX_CLASS.oneditclick; - } - - //原型继承至基础控件 - SELECT_BOX_CLASS = inherits(ui.SelectBox, UI_CONTROL); - - - //点击输入框弹出下拉层 - SELECT_BOX_CLASS.oneditclick = function(){ - var wrap = this.getParent() - var panelDom = wrap._uPanel.getBase(); - baidu.dom.toggle(panelDom); - - } - - //屏蔽点击事件,返回给控件 - SELECT_BOX_CLASS.$pressend = function(){ - ecui.forcibly(this); - mask(0, 65534); - } - - //重写$forcibly方法 - SELECT_BOX_CLASS.$forcibly = function(){ - var wrap = this.getParent() - var panelDom = wrap._uPanel.getBase(); - baidu.dom.toggle(panelDom); - } - - - //设置下拉面板的可见高度 - SELECT_BOX_CLASS.setPHeight = function(){ - var pHeight = this._uHeight; - var pStyle = this._uPanel.getOuter().style; - pStyle.height = pHeight; - - } - - //控件初始化 - SELECT_BOX_CLASS.init = function(){ - this.setPst(); - this.setPHeight(); - } - - //根据edit定位下拉层 - SELECT_BOX_CLASS.setPst = function(){ - var edit = this._uEdit.getBase(); - var editX = baidu.dom.getPosition(edit).left; - var editY = baidu.dom.getPosition(edit).top; - var pStyle = this._uPanel.getBase(); - pStyle.style.position = "absolute"; - this._uPanel.setPosition(editX,editY+15); - } - - SELECT_BOX_CLASS.updata =function(){ - var allBox = this._uPanel; - alert(allBox) - - - } - - //滚动条不因后面的内容增加而出现 TODO - //设置下拉框中的内容,根据数据构造多个checkbox - SELECT_BOX_CLASS.setData = function(data){ - var sData = data; - var Fname = this._uName; - var Fcol = this._uCol; - var optionHTML = ""; - var checkboxIndex = 1; - var panelContent = this._uPanel.getBody(); - baidu.array.each(sData,function(item,i){ - Schecked = item.isChecked? 'checked="checked"' : ""; - optionHTML += ''; - optionHTML += ''; - if(checkboxIndex%Fcol == 0) optionHTML += '
'; - checkboxIndex++; - }); - optionHTML +='
' - panelContent.innerHTML = optionHTML; - } - - - })() \ No newline at end of file diff --git a/WebContent/stat/js/ui/table/css/table.css b/WebContent/stat/js/ui/table/css/table.css deleted file mode 100644 index 98b842210..000000000 --- a/WebContent/stat/js/ui/table/css/table.css +++ /dev/null @@ -1,136 +0,0 @@ -/* FOR OPERA */ -div{border:0;} - .ec-ecom-table .ec-vscroll {background:#F2F8EE;width:15px;padding:15px 0px 15px 0px;font-size:1px} - .ec-ecom-table .ec-hscroll {background:#F2F8EE;height:15px;padding:0px 15px 0px 15px;font-size:1px} - .ec-ecom-table .ec-hscroll-block {background:url("img/hscroll.gif") -2px -30px repeat-x;border:1px solid #76A258;border-width:0 1px} - .ec-ecom-table .ec-vscroll-block {background:url("img/scroll.gif") 0px 0px repeat-y;border:1px solid #76A258;border-width:1px 0} - .ec-ecom-table .ec-hscroll-block-over {background:url("img/hscroll.gif") -0px -45px repeat-x} - .ec-ecom-table .ec-hscroll-block-press {background:url("img/hscroll.gif") -0px -60px repeat-x} - .ec-ecom-table .ec-vscroll-block-over {background:url("img/scroll.gif") -15px 0px repeat-y} - .ec-ecom-table .ec-vscroll-block-press {background:url("img/scroll.gif") -30px 0px repeat-y} - .ec-ecom-table .ec-vscroll-prev {background:url("img/scroll.gif") -45px -40px no-repeat;} - .ec-ecom-table .ec-vscroll-prev-over {background:url("img/scroll.gif") -75px -40px no-repeat;} - .ec-ecom-table .ec-vscroll-prev-press {background:url("img/scroll.gif") -60px -40px no-repeat;} - .ec-ecom-table .ec-vscroll-next {background:url("img/scroll.gif") -45px -55px no-repeat;} - .ec-ecom-table .ec-vscroll-next-over {background:url("img/scroll.gif") -75px -55px no-repeat;} - .ec-ecom-table .ec-vscroll-next-press {background:url("img/scroll.gif") -60px -55px no-repeat;} - .ec-ecom-table .ec-hscroll-prev {background:url("img/scroll.gif") -45px -85px no-repeat;} - .ec-ecom-table .ec-hscroll-prev-over {background:url("img/scroll.gif") -75px -85px no-repeat;} - .ec-ecom-table .ec-hscroll-prev-press {background:url("img/scroll.gif") -60px -85px no-repeat;} - .ec-ecom-table .ec-hscroll-next {background:url("img/scroll.gif") -45px -70px no-repeat;} - .ec-ecom-table .ec-hscroll-next-over {background:url("img/scroll.gif") -75px -70px no-repeat;} - .ec-ecom-table .ec-hscroll-next-press {background:url("img/scroll.gif") -60px -70px no-repeat;} - .ec-ecom-table .vsblockdtr {padding:2px 0px} - .ec-ecom-table .vsblockdtr-top {background:url("img/scroll.gif") -45px 0px no-repeat} - .ec-ecom-table .vsblockdtr-bottom {background:url("img/scroll.gif") -45px -18px no-repeat} - .ec-ecom-table .vsblockdtr-over .vsblockdtr-top {background:url("img/scroll.gif") -45px -20px no-repeat} - .ec-ecom-table .vsblockdtr-over .vsblockdtr-bottom {background:url("img/scroll.gif") -45px -38px no-repeat} - .ec-ecom-table .vsblockdtr-press .vsblockdtr-top {background:url("img/scroll.gif") -60px 0px no-repeat} - .ec-ecom-table .vsblockdtr-press .vsblockdtr-bottom {background:url("img/scroll.gif") -60px -38px no-repeat} - .ec-ecom-table .ec-panel-disabled .vsblockdtr div {display:none} - .ec-ecom-table .hsblockdtr {padding:0px 2px} - .ec-ecom-table .hsblockdtr-left {background:url("img/hscroll.gif") -60px 0px no-repeat} - .ec-ecom-table .hsblockdtr-right {background:url("img/hscroll.gif") -18px 0px no-repeat} - .ec-ecom-table .hsblockdtr-over .hsblockdtr-left {background:url("img/hscroll.gif") -40px -0px no-repeat} - .ec-ecom-table .hsblockdtr-over .hsblockdtr-right {background:url("img/hscroll.gif") -38px -0px no-repeat} - .ec-ecom-table .hsblockdtr-press .hsblockdtr-left {background:url("img/hscroll.gif") -40px -15px no-repeat} - .ec-ecom-table .hsblockdtr-press .hsblockdtr-right {background:url("img/hscroll.gif") -38px -15px no-repeat} - .ec-ecom-table .ec-panel-disabled .hsblockdtr div {display:none} - .ec-ecom-table {border:1px solid #9CD167;padding-top:23px;background-color:#DCEFD1} - .ec-ecom-table .checkbox {padding-left:0px;padding-right:0px;} - .ec-ecom-table .checkbox-item {padding-left:0px;padding-right:0px;} - .ec-ecom-table .checkbox-disabled {background:url(img/cr.gif) -68px 0px no-repeat;width:17px;height:17px;;margin-right:5px} - .ec-ecom-table table {border-collapse:collapse;border-spacing:0px} - .ec-ecom-table-layout {background:#FFF;color:#333} - .ec-ecom-table-head, .ec-print-table th{ font-weight:normal; color:#326700; padding:6px 5px; padding-right:12px; line-height:15px; border:0; border-left:1px solid #CCE9B9; border-bottom:1px solid #9CD167; overflow:hidden; white-space:nowrap; word-wrap:normal; word-break:keep-all } - .ec-ecom-table-item, .ec-print-table td{ line-height:15px; border:0; padding:5px 5px; padding-right:12px; border-left:1px solid #CCE9B9; word-break:break-all; white-space:normal; word-wrap:break-word; overflow:hidden } - .ec-ecom-table .od td{background-color:#FFF;} - .ec-ecom-table .ev td{background-color:#F2F8EE;} - .ec-ecom-table .od td.dk{background-color:#EAF1E2;} - .ec-ecom-table .ev td.dk{background-color:#DDE9D0;} - .ec-ecom-table-row-focus td.ec-ecom-table-item, - .ec-ecom-table-row-over td.ec-ecom-table-item, - .ec-ecom-table .ec-ecom-table-row-focus td.dk, - .ec-ecom-table .ec-ecom-table-row-over td.dk - {background-color:#FFFCE2} - /* - .ec-ecom-table-row-over .ev .ec-ecom-table-item, - .ec-ecom-table-row-over .ev td.dk, - .ec-ecom-table-row-over .od .ec-ecom-table-item, - .ec-ecom-table-row-over .od td.dk, - .ec-ecom-table-row-focus .ev .ec-ecom-table-item, - .ec-ecom-table-row-focus .ev td.dk, - .ec-ecom-table-row-focus .od .ec-ecom-table-item, - .ec-ecom-table-row-focus .od td.dk, - .ec-ecom-table-row-focus .ec-ecom-table-item, - .ec-ecom-table-row-over .ec-ecom-table-item {background-color:#FFFCE2} - */ - /*排序*/ - .ec-ecom-table-area .sort, .ec-ecom-table-area .sort-over, .ec-ecom-table-area .sort-focus{ text-align:left; cursor:pointer; background:url("img/table.gif") no-repeat 93% -33px; } - .ec-ecom-table-area .sort-over{ background-color:#F6FFB8; } - .ec-ecom-table-area .sort-up, .ec-ecom-table-area .sort-down{ cursor:pointer; /*text-align:right;*/ background:#F6FFB8 url("img/table.gif") no-repeat 93% -33px; } - .ec-ecom-table-area .sort-up { background-position:93% -63px; } - .ec-ecom-table-area .sort-down { background-position:93% -93px; } - .ec-ecom-table-row .op{text-align:center;border:0 none;border-left:1px solid #9CD167} - /*复选框*/ - .ec-checkbox {background:url("img/cr.gif") 0px 0px no-repeat;width:17px;height:15px} - .ec-checkbox-display {background:url("img/cr.gif") -34px 0px no-repeat;} - .ec-checkbox-over {background:url("img/cr.gif") -17px 0px no-repeat;} - .ec-checkbox-checked {background:url("img/cr.gif") -34px 0px no-repeat} - .ec-checkbox-checked-over {background:url("img/cr.gif") -51px 0px no-repeat} - .ec-checkbox-part {background:url("img/cr.gif") -102px 0px no-repeat} - /*展开按钮(上)*/ - .ec-col-toggler,.ec-col-toggler-o{ width:17px; height:20px; position:absolute; top:2px; right:0; background:#DCEFD1 url("img/table.gif") no-repeat 0px 0px; cursor:pointer; } - .ec-col-toggler-o{background-position:-22px 0px} - /*展开按钮(下)*/ - .ec-v-toggler{ width:15px; background:#DDE9D0; position:absolute; right:0; bottom:0; _right:-1px; cursor:pointer; border-left:1px solid #9CD167; /*border-right:1px solid #9CD167;*/ } - .ec-v-toggler div{ width:9px; height:10px; overflow:hidden; background:url("img/table.gif") no-repeat -8px -22px; position:absolute; right:3px; bottom:50%; _padding-top:50%; cursor:pointer; } - .ec-v-toggler-over{background-color:#EAF1E2} - /*验证*/ - .valid-error td.ec-ecom-table-item{ background-color:pink!important; } - /* *分页 *囧, 有同名的list宏,需转义 */ - .ec-page a, .ec-page b{ margin:0; text-indent:0; display:inline-block; *display:inline; zoom:1; height:20px; line-height:20px; background:url("img/table.gif") repeat-x 0 -150px; border:1px solid #9CD167; padding:0 3px; text-decoration:none; color:#326700; } - .ec-page a:hover{ background-position:0 -176px; } - .ec-page .page-n{ /*width:20px;*/ text-align:center; /*padding:0;*/ padding:0 5px; } - .ec-page b{ background-image:none; color:#666; background-color:#EEE; font-weight:normal; } - .ec-page b.page-n{ background-image:none; background-color:#FFF; color:#000; font-weight:bold; } - .ec-page { color:#326700; margin-top: 10px } - .ec-page em{ font-style:normal; color:#000; padding:0 3px; } - .target-page{ width:25px; } - /* 弹出菜单 */ - .ec-popup{ background-color:#DCEFD1; border:1px solid #9CD167; border-width:1px 1px 0 1px; width:70px; } - .ec-popup-item{ background-color:#DCEFD1;/* width:70px; */ height:25px; line-height:25px; border-bottom:1px solid #9CD167; padding-left: 24px; cursor:pointer; vertical-align:bottom; position:relative; } - .ec-popup-item-over{ background-color:#FFFCE2; } - .ec-popup-item .ec-checkbox{ /*float:left;*/ /*margin:4px 4px 0 4px;*/ position:absolute; top:4px; left:4px; border:0 none; /*text-indent: 14px;*/ } - .cb-ctnr{ background:#DCEFD1 url("img/table.gif") 0 -200px; height:14px; margin:0; border:0 none; width:15px; position:absolute; top:7px; cursor:pointer; } - /* 提示信息显示 */ - .tb-msg{ visibility:hidden; margin: 0 0 4px 0; } - .tb-msg .tb-msg-txt{ background:#FFFCE2; color:#D2691E; font-weight:bold; padding:0 4px; display:inline-block; *display:inline; zoom:1; height:20px; line-height:20px; } - .tb-msg .clo-btn{ font-weight:normal; margin: 0 0 0 14px; cursor:pointer; } - - /* 二次屏蔽的提示框 */ - .ectable-modal-tip {background:#FFF;position:absolute;width:200px;height:50px;border:2px solid #CCC} - .ectable-modal-tip-title {position:absolute;height:20px;line-height:20px;text-indent:5px;margin:0;display:block;top:0;left:0;background:#CCC;width:100%} - .ectable-modal-tip-cont {padding:25px 5px 5px 25px;background:transparent url(img/loading.gif) no-repeat scroll 5px 25px} - - /* 打印 */ - @media screen { .ec-print-table{ border:1px solid #9CD167;border-width:1px; border-collapse:collapse; background-color:#DCEFD1 } - .ec-print-table th, .ec-print-table td{ border:1px solid #9CD167; border-width:0 0 1px 1px; } - .ec-print-table td{ background-color:#FFF; } - } - @media print { body{font-family:"微软雅黑","黑体";font-size:10px;} - .strik-info{color:#000;} - .noprint,.nav{display:none;} - .area-v,.area-w{display:none;} - .area{border:1px solid #ddd;margin-top:6px;background:#fff;} - .mess-query .area-inner{background:none;border:0;} - .mess-query .area {border:0;} - .area h5{border:0;} - .area h5 b{background:none;border:0;color:#000;} - .old td{background:#ddd;} - .ec-print-table {border:1px solid #666;border-width:1px 0 1px 1px;border-collapse:collapse} - .ec-print-table th{padding:2px;text-align:center;border-right:1px solid #666; border-color:#666} - .ec-print-table td{padding:2px 6px;border:1px solid #666;border-width:1px 1px 0 0; border-color:#666} - *{word-wrap:break-word;word-break:break-all;} - } - diff --git a/WebContent/stat/js/ui/table/js/ecomui.table.js b/WebContent/stat/js/ui/table/js/ecomui.table.js deleted file mode 100644 index 5f453f99b..000000000 --- a/WebContent/stat/js/ui/table/js/ecomui.table.js +++ /dev/null @@ -1,570 +0,0 @@ -var ecomui = ecomui || {}; - -// IE 6 背景图片缓存 -try { - document.execCommand("BackgroundImageCache", false, true); -} catch(e){} - -(function() { - var lib = baidu, - core = ecui, - dom = core.dom, - ui = core.ui, - util = core.util, - inherits = util.inherits, - copy = util.copy, - toNumber = util.toNumber, - get = core.get, - query = core.query, - setStyles = lib.dom.setStyles, - getPosition = dom.getPosition, - calcHeightRevise = core.calcHeightRevise, - - DOCUMENT = document, - UI_TABLE = ui.LockedTable, - UI_TABLE_CLASS = UI_TABLE.prototype, - UI_CONTROL = ui.Control, - ECOM_TABLE_CLASS; - - ecomui.Table = ui.EcomTable = function(el, params) { - /* - * 计算表格宽度 - */ - var tbEl = el.getElementsByTagName("table")[0]; - if (!tbEl.style.width) { - var colEls = tbEl.rows[0].cells; - var tbOldWidth = tbEl.offsetWidth; - var tbWidth = 0; - - for (var i = 0, len = colEls.length; i < len; i++) { - var o = colEls[i].style.width; - tbWidth += (o !== undefined) ? - (/px$/.test(o) ? parseInt(o, 10) : tbOldWidth * (parseFloat(o) / 100)) : - 130; - } - tbEl.style.width = Math.max(el.offsetWidth * 0.99, tbWidth) + "px"; - } - - //隐藏待渲染的表格, 在vm里定义visibility=hidden - //渲染表格 - UI_TABLE.call(this, el, params); - - //显示渲染好的表格 - this.getOuter().style.visibility = "visible"; - - //记录表格索引 - this._nTbId = params.tbid; - - //是否有选择整列表按钮 - this._bCustom = params.custom; - - var colToggler, verticalBar, showOpColumn, colCount; - - showOpColumn = params.rightLock; - - //如果有操作列 - if (showOpColumn) { - //初始操作列是展开的 - this._bOpColumnUnfolded = true; - - var base = this.getBase(); - - //记住操作列和前一列 - //TODO 倒数第二列不能作为部件, 因为不是表格不可缺少的 - //在使用时取一下 - //colCount = this._aCol.length - 1; - //this._uOpColumn = this.getCol(colCount); - - //收缩按钮 - var el = DOCUMENT.createElement("div"); - el.className = "ec-col-toggler"; - base.appendChild(el); - colToggler = this._uColToggler - = core.$fastCreate( - UI_CONTROL, - el, - this, - {} - ); - - //竖条 - var el = DOCUMENT.createElement("div"); - el.innerHTML = "
"; - el.className = "ec-v-toggler"; - base.appendChild(el); - verticalBar = this._uVerticalBar - = core.$fastCreate( - UI_CONTROL, - el, - this, - {} - ); - verticalBar.hide(); - - //如果有纵向滚动条, 调整收缩按钮的位置 - //FIXME 此时VScroll总是有的 - var vScroll = this.$getSection("VScroll"); - colToggler.getOuter().style.right = 2 + - ((vScroll && vScroll.isShow()) ? vScroll.getWidth() : 0) + "px"; - //绑定事件 - colToggler.onclick = colTogglerClick; - verticalBar.onclick = vBarClick; - verticalBar.show = vBarShow; - - } - - //浮动表头 - if (params.floatthead) { - var self = this; - self._bFloatThead = true; - lib.event.on(window, "scroll", function() { - floatThead(self); - }); - } - - - }; - - ECOM_TABLE_CLASS = inherits(ui.EcomTable, UI_TABLE); - - /* - * 此处获得操作列 - */ - ECOM_TABLE_CLASS.$init = function () { - UI_TABLE_CLASS.$init.call(this); - if (this._nRightLock) { - this._uOpColumn = this.getCol(this._aCol.length - 1); - } - - //整列表选择按钮 - if(this._bCustom) { - var customBtn = core.get("cbCtnr_" + this._nTbId); - customBtn && initCustomBtn(customBtn, this); - } - }; - - /** - * 展开/收起按钮点击 - * @private - */ - function colTogglerClick() { - //this为按钮 - var table = this.getParent(), - vBar = table.$getSection("VerticalBar"); - - if (table._bOpColumnUnfolded) { - //收起操作列 - foldOpColumn(table); - vBar.show(); - this.alterClass("o"); - } else { - //展开操作列 - unfoldOpColumn(table); - vBar.hide(); - this.alterClass("o", true); - } - } - - /** - * 竖条点击 - * @private - */ - function vBarClick() { - //this 为竖条 - var table = this.getParent(); - - //展开操作列 - unfoldOpColumn(table); - - this.hide(); - } - - /** - * 收起操作列 - * @private - */ - function foldOpColumn(table) { - var tableWidth = table.getWidth(), - tableBodyWidth = table.getBody().offsetWidth; - - table._uOpColumn.hide(); - - //设置倒数第二列的宽度 - var col = table.getCol(table.getCols().length - 2); - col.setSize(col.getWidth() + table._uOpColumn.getWidth()); - - table._bOpColumnUnfolded = false; - }; - - /** - * 展开操作列 - * @private - */ - function unfoldOpColumn(table) { - var prevCol = getSndLastCol(table); - - //恢复倒数第二列恢复原来的宽度 - var col = table.getCol(table.getCols().length - 2); - col.setSize(col.getWidth() - table._uOpColumn.getWidth()); - - table._uOpColumn.show(); - - - table._bOpColumnUnfolded = true; - }; - - /** - * 获得倒数第二列 - * @private - */ - function getSndLastCol(table) { - var colCount = table._aCol.length - 1, - ret; - while (colCount--) { - ret = table.getCol(colCount); - if (ret.isShow()) { - break; - } - } - return ret; - } - - /** - * 展开/收缩操作列时设置表格宽度 - * @private - */ - function setTableWidth(table, tableWidth, tableBodyWidth) { - var oldWidth = table._nOldWidth = table.getWidth(); - if (tableWidth > tableBodyWidth) { - table.setSize(oldWidth + table) - } - } - - /** - * 显示竖条 - * @private - */ - function vBarShow() { - UI_CONTROL.prototype.show.call(this); - setVBarPosition(this); - setVBarHeight(this); - } - - /** - * 设置竖条定位 - * @private - */ - function setVBarPosition(vBar) { - var table = vBar.getParent(), - vBarWidth = vBar.getWidth(), - vs = table.$getSection("VScroll"), - style = table.getBase().style, - contentWidth = table.getWidth() - - (toNumber(style.borderLeftWidth) + toNumber(style.borderRightWidth)); - - vBar.getOuter().style.left = contentWidth - vBarWidth - - ((vs && vs.isShow()) ? vs.getWidth() : 0) - + "px"; - } - - - /** - * 在竖条显示时设置其高度 - * @private - */ - function setVBarHeight(vBar) { - var table = vBar.getParent(), - hs = table.$getSection("HScroll"), - th = table.$getSection("Head"), - hscrValue; - - if (hs && hs.isShow()) {//存在水平滚动条 - hs.setValue(hs.getTotal()); - hscrValue = hs.isShow() ? hs.getHeight() : 0; - } - else { - hscrValue = 0; - } - - //TODO -2 用 sumStyle算边框值 - vBar.setSize(0, table.getHeight() - th.getHeight() - 2 - hscrValue); - var style = vBar.getOuter().style; - style.bottom = hscrValue + "px"; - } - - /** - * 表头随浏览器滚动条锁定 - * @private - */ - function floatThead(t) { - var headEl = t._uHead.getOuter(), - lockedHeadEl = t._uLockedHead.getOuter(), - lockedMainEl = t._uLockedMain.getOuter(); - - if (t._uColToggler) { - var colTogglerEl = t._uColToggler.getOuter(); - } - - var outer = t.getOuter(); - - var scrollTop = DOCUMENT.body.scrollTop || DOCUMENT.documentElement.scrollTop, - pos = getPosition(outer), - top = pos.top + 1, - left = pos.left; - - var headHeight = headEl.offsetHeight + calcHeightRevise(headEl), - tbHeightDelta = t.getHeight() - headHeight, - relativeTop = scrollTop - top; - - var floatStyles = { - position: "absolute", - top: relativeTop + "px", - zIndex: 999 - }; - - if (scrollTop - && relativeTop > 0 - && relativeTop < tbHeightDelta) - { - setStyles(headEl, floatStyles); - setStyles(lockedHeadEl, floatStyles); - setStyles(lockedMainEl, {top: headHeight + "px"}); - - //TODO 此处性能优化 - //ecui 1.1.0 fix - setStyles(lockedHeadEl, {width: lockedHeadEl.getElementsByTagName("table")[0].style.width}); - - if (colTogglerEl) { - setStyles(colTogglerEl, {top: 2 + relativeTop + "px", zIndex: 999}); - } - } - - else { - setStyles(headEl, {top: 0, zIndex:0}); - setStyles(lockedHeadEl, {position: "static", zIndex:0}); - setStyles(lockedMainEl, {top: ""}); - - if (colTogglerEl) { - setStyles(colTogglerEl, {top: "", zIndex:0}); - } - } - }; - - /** - * 初始化整列表选择按钮 - */ - function initCustomBtn(customBtn, table) { - var tbId = table._nTbId; - - var popup = core.get("cbPop_" + tbId), - popupItems = core.query({"parent": popup}), - popupItemsLen = popupItems.length; - - var cbCurList = core.get("cball_" + tbId), - cbWholeList = core.get("cbsall_" + tbId), - cbCurInferiors = cbCurList.getInferiors(); - - DOCUMENT.body.appendChild(popup.getOuter()); - - customBtn.onclick = function() { - var containerOuter = this.getOuter(); - containerPos = getPosition(containerOuter); - - popup.setPosition( - containerPos.left + this.getBodyWidth(), - containerPos.top - ); - - popup.show(); - }; - - cbWholeList.onclick = (function() { - var checked = false; - return function(){ - var i = cbCurInferiors.length, - msg = [ - "已选择整列表, 子项目不能取消选择", - "已取消选择整列表" - ]; - - var msgBox = table.setMsg((!checked) ? msg[0] : msg[1]); - - msgBox.parentNode.parentNode.style.visibility = "visible"; - - var hcbsall = lib.dom.g("hcbsall_" + tbId); - while (i--) { - cbCurInferiors[i].setChecked(!checked); - cbCurList.setEnabled(checked); - cbCurInferiors[i].setEnabled(checked); - hcbsall.value = checked ? 0 : 1; - } - - checked = !checked; - } - })(); - - while (popupItemsLen--) { - popupItems[popupItemsLen].onclick = function() { - var cb = core.query({"parent":this})[0]; - cb.click(); - }; - } - } - - /** - * 改写$resize方法 - */ - ECOM_TABLE_CLASS.$resize = function () { - UI_TABLE_CLASS.$resize.call(this); - - //如果存在竖条并且竖条显示, 重设其高度 - var vBar = this._uVerticalBar; - if (vBar && vBar.isShow()) { - setVBarHeight(vBar); - setVBarPosition(vBar); - } - - //修正浮动表头的位置 - if (this._bFloatThead) { - floatThead(this); - } - }; - - /** - * 找出table中被选中行 - * @public - * - * @return {Array} 被选中行 - */ - ECOM_TABLE_CLASS.getChecked = function() { - var ret = []; - try { - var col = this.getCol(0), - cbs = core.get("cball_" + this._nTbId), - cbs = (cbs instanceof core.ui.Checkbox) ? cbs : core.query({"parent": cbs})[0], - cbs = cbs.getInferiors(), - i = cbs.length; - - while (i--) { - if (cbs[i].isChecked()) { - ret.push(cbs[i].getParent()); - } - } - } catch (e) {} - return ret; - }; - - /** - * 找出table中被选中行个数 - * @public - * - * @return {Number} 被选中行的个数 - */ - ECOM_TABLE_CLASS.getCheckedCount = function() { - return this.getChecked().length; - }; - - /** - * 设置消息 - * @public - * - * @return {HTMLElement} 消息div元素 - */ - ECOM_TABLE_CLASS.setMsg = function(msg) { - var msgBox = lib.dom.g("tbMsg_" + this._nTbId); - dom.setText(msgBox, msg); - return msgBox; - }; -})(); - -/* - * 排序 - */ -var defaultSort = (function() { - // 屏蔽二次点击标志 - var dbClickFlag = false; - - return function() { - if (!dbClickFlag) { - window.sortClick(this.getBase().getAttribute('sort')); - dbClickFlag = true; - } - else { - ecTable.showModal("正在排序, 请稍候..."); - } - } -})(); - -/** - * 为兼容以前版本加的补丁 - */ -var ecTable = { - getChecked: function(table) { - return ecomui.Table.prototype.getChecked.call(table, table); - }, - getCheckedCount: function(table) { - return ecomui.Table.prototype.getCheckedCount.call(table, table); - } -}; - -ecui.getChildren = function(control) { - return ecui.query({parent:control}); -}; - -/** - * 整体遮罩, 用于屏蔽二次点击 - */ -var ecTable = ecTable || {}; - -ecTable.showModalTip = function(text) { - var modalCtrl = baidu.dom.g("ecTableModalTip"); - modalCtrl = modalCtrl && modalCtrl.getControl(); - - // 创建提示信息窗体 - if (!modalCtrl) { - modalCtrl = document.createElement("div"); - modalCtrl.id = "ecTableModalTip" - modalCtrl.className = "ectable-modal-tip"; - modalCtrl.style.visibility = "hidden"; - modalCtrl.innerHTML = [ - '', - '
' - ].join(""); - document.body.appendChild(modalCtrl); - - modalCtrl = ecui.$fastCreate( - ecui.ui.Form, - modalCtrl, - null, - {hide:true} - ); - } - - // 给窗体设置文字并显示 - var contEl = modalCtrl.getBody().getElementsByTagName("div")[0]; - ecui.dom.setText(contEl, text); - modalCtrl.getOuter().style.zIndex = 32768; - - - // 窗体居中 - var viewWidth = baidu.page.getViewWidth(), - viewHeight = baidu.page.getViewHeight(), - width = modalCtrl.getWidth(), - height = modalCtrl.getHeight(); - - baidu.setStyles(modalCtrl.getOuter(), { - position: "absolute", - left: Math.max(viewWidth - width, 0) / 2, - top: Math.max(viewHeight - height, 0) / 2 - }); - - modalCtrl.getOuter().style.visibility = ""; - ecui.mask(0.03); - - // 五秒没反应显示刷新链接 - setTimeout(function() { - contEl.innerHTML = '好像没响应? 请刷新'; - }, 5000); - -}; - diff --git a/WebContent/stat/js/ui/table/js/table.js b/WebContent/stat/js/ui/table/js/table.js deleted file mode 100644 index ac5385c76..000000000 --- a/WebContent/stat/js/ui/table/js/table.js +++ /dev/null @@ -1,322 +0,0 @@ -/** - *@file support_table.js - *@description 支持模块使用ecui实现的列表 - * - * 修改记录 - * 2010.01.07 加入当前页或者整列表的选择(样式) - */ - -/* - * IE 6 背景图片缓存 - */ -try { - document.execCommand("BackgroundImageCache", false, true); -} catch(e){} - -/* - *滚动条装饰器 - */ -ecui.ui.VScroll.prototype.$create = function() { - var me = this, - block = this.$getSection('Block'); - new ecui.ext.TBDecorator(block, 'vsblockdtr'); - ecui.ui.Control.prototype.$create.call(this); -}; - -ecui.ui.HScroll.prototype.$create = function() { - var block = this.$getSection('Block'); - new ecui.ext.LRDecorator(block, 'hsblockdtr'); - ecui.ui.Control.prototype.$create.call(this); -}; - - -function initEcuiTable(table) { - var t = table || ecui.get(table), - vs = t.$getSection('VScroll'), - hs = t.$getSection('HScroll'), - th = t.$getSection('Head'), - cCount = t._aCol.length - 1, - col = t.getCol(cCount), - prevCol = t.getCol(cCount - 1); - - //此时重绘,防止火狐下高度异常 - //t.paint(); - - /* - * 展开/收起按钮 - */ - //TODO 判断是否含有操作列 - if (col.getBase().parentNode != prevCol.getBase().parentNode) { - //收缩按钮 - var ct = ecui.create('Control', { - type: 'ec-col-toggler', - parent: t.getBase() - }), - - //竖条 - h = ecui.create('Control', { - type: 'ec-v-toggler', - parent: t.getBase() - }), - - cw = col.getWidth(), - pw = prevCol.getWidth(), - hscrValue; - - h.getBody().innerHTML = '
' - h.hide(); - h.onclick = function() { - ct.click(); - }; - - ct.onclick = function() { - toggleStatus(this); - vs && vs.paint(); - //col.paint(); - }; - ct.onpaint = function(){ - setHbarHeight(h); - //alert("paint col toggler") - } - - //根据是否有滚动条设置按钮位置 - if (vs && vs.isShow()) { - ct.getBase().style.right = vs.getWidth() + "px"; - } - /* - * 设置竖条高度 - */ - var setHbarHeight = function(hbar) { - if (hs) {//存在水平滚动条 - hs.setValue(hs.getTotal()); - hscrValue = hs.isShow() ? hs.getHeight() : 0; - } - else { - hscrValue = 0; - } - hbar.setSize(undefined, t.getHeight() - th.getHeight() - 2 - hscrValue); - var style = hbar.getOuter().style; - if (vs && vs.isShow()) style.right = vs.getWidth() + "px"; - style.bottom = hscrValue + "px"; - } - - /* - * 点击'收起按钮'的回调函数 - */ - var toggleStatus = function(ct) { - - //hack:避免第一次隐藏列后对不齐 - prevCol.setSize(pw); - - if (col.isShow()) { - _autoSize(t, prevCol, pw); - ct.alterClass('o'); - col.hide(); - setHbarHeight(h); - h.show(); - } else { - prevCol.setSize(pw); - ct.alterClass('o', true); - //console.log(hscrValue); - col.show(); - h.hide(); - hs && hs.setValue(hs.getTotal()); - } - - col.paint(); - }; - - /* - * 表格列自适应宽度 - */ - var _autoSize = function(t, c, ow) { - var tw = t.getWidth(), - tcw = t.getBody().offsetWidth; - if (tw > tcw) { - c.setSize(tw - tcw + ow); - } - }; - } - - /* - * 垂直滚动条高度 - - if (vs) { - _setVSHeight = function(vs) { - vs.setSize(undefined, vs.getHeight() - th.getHeight()); - vs.getBase().style.top = ""; - vs.getBase().style.bottom = vs.getWidth() + "px"; - } - vs.onpaint = function() { - this.$paint(); - _setVSHeight(this); - document.body.className = document.body.className; - return false; - } - _setVSHeight(vs); - } - */ - - /* - * 排序-记录水平位置 - - var ectable_xpos = baidu.cookie.getRaw('ectable_xpos'); - if (ectable_xpos) { - hs.setValue(ectable_xpos); - baidu.cookie.remove('ectable_xpos'); - } - */ - - /* - * 排序 - */ - var defaultSort = function() { - window.sortClick(this.getBase().getAttribute('sort')); - baidu.cookie.setRaw('ectable_xpos',hs.getValue()); - }; - - for (var i = 0, cCount = t._aCol.length; i < cCount; i++) { - var col = t.getCol(i); - if (col.getBase().className.match(/\s*sort\s*/)) { - col.onclick = defaultSort; - } - } - - //hack for ie 8 - //document.body.className = document.body.className; - - - /* - * custom checkbox处理 - */ - - var popupContainer = ecui.query({"parent":t.getCol(0)})[0]; - - if (popupContainer) { - var ctrlIdx = popupContainer.getBase().id - .replace(/^s+|s+$/,'') - .match(/cbCtnr_([0-9a-zA-Z_]+)/)[1], - //弹出菜单容器和弹出菜单 - popup = document.getElementById('cbPop_' + ctrlIdx).getControl(), - popupItems = ecui.query({"parent":popup}), - popupItemsLen = popupItems.length, - - //checkbox 控件 - cbCurList = document.getElementById("cbCurList").getControl(), - cbWholeList = document.getElementById("cbWholeList").getControl(), - cbCurInferiors = cbCurList.getInferiors(); - //msgBox = document.getElementById('tbMsg_' + ctrlIdx); - - - popupContainer.onclick = function() { - var containerOuter = this.getOuter(); - containerPos = ecui.dom.getPosition(containerOuter); - - popup.setPosition(containerPos.left + this.getBodyWidth(), containerPos.top); - - popup.show(); - }; - - cbWholeList.onclick = (function() { - var checked = false; - return function(){ - //console.log("xx"); - var i = cbCurInferiors.length, - msg = [ - "已选择整列表, 子项目不能取消选择", - "已取消选择整列表" - ]; - - var msgBox = ecTable.setMsg(t, (!checked) ? msg[0] : msg[1]); - msgBox.style.visibility = "visible"; - - while (i--) { - cbCurInferiors[i].setChecked(!checked); - cbCurList.setEnabled(checked); - cbCurInferiors[i].setEnabled(checked); - } - - checked = !checked; - } - })(); - - while (popupItemsLen--) { - popupItems[popupItemsLen].onclick = function() { - var cb = ecui.query({"parent":this})[0]; - cb.click(); - }; - } - - } -} -var ecTable = { - /** - * 给表格的消息框设置 - * @param {ecTable} table - * @param {String} msg - * @return {String} 消息框 - */ - setMsg: function(table, msg) { - var msgBox = table.getBase(), - first = ecui.dom.first; - - do { - msgBox = msgBox.previousSibling; - } while (msgBox.nodeType != 1) - - first(first(msgBox)).innerHTML = msg; - return msgBox; - }, - - /** - *找出table中被选中条目 - *@param {ecTable} table - *@return {Array} 被选中行 - */ - getChecked: function(table){ - var col = table.getCol(0), - cbs = ecui.query({"parent":col})[0], - cbs = (cbs instanceof ecui.ui.Checkbox) ? cbs : ecui.query({"parent": cbs})[0], - cbs = cbs.getInferiors(), - i = cbs.length, - ret = []; - - while (i--) { - if(cbs[i].isChecked()){ - ret.push(cbs[i].getParent()); - } - } - - return ret; - }, - /** - *获得table中有选中条目个数 - *@param {EcTable} table - *@return {Number} 选中条目个数 - */ - getCheckedCount: function(table) { - return ecTable.getChecked(table).length; - }, - - /** - * 获得当前页面所有table - * @return 包含所有table的数组 - */ - getTables: function() { - return ecui.query({"type": ecui.ui.Table}); - }, - - /** - *初始化当前页所有列表 - */ - init: function() { - var tables = ecTable.getTables(), - len = tables.length; - - while (len--) { - initEcuiTable(tables[len]); - } - } -}; - -ecui.dom.ready(ecTable.init); diff --git a/WebContent/stat/js/ui/wick/js/wick.js b/WebContent/stat/js/ui/wick/js/wick.js deleted file mode 100644 index 26f300d83..000000000 --- a/WebContent/stat/js/ui/wick/js/wick.js +++ /dev/null @@ -1,481 +0,0 @@ -function freezeEvent(e) { - if (e.preventDefault) e.preventDefault(); - e.returnValue = false; - e.cancelBubble = true; - if (e.stopPropagation) e.stopPropagation(); - return false; -}//freezeEvent - -function isWithinNode(e,i,c,t,obj) { - answer = false; - te = e; - while(te && !answer) { - if ((te.id && (te.id == i)) || (te.className && (te.className == i+"Class")) - || (!t && c && te.className && (te.className == c)) - || (!t && c && te.className && (te.className.indexOf(c) != -1)) - || (t && te.tagName && (te.tagName.toLowerCase() == t)) - || (obj && (te == obj)) - ) { - answer = te; - } else { - te = te.parentNode; - } - } - return te; -}//isWithinNode - -function getEvent(event) { - return (event ? event : window.event); -}//getEvent() - -function getEventElement(e) { - return (e.srcElement ? e.srcElement: (e.target ? e.target : e.currentTarget)); -}//getEventElement() - -function findElementPosX(obj) { - curleft = 0; - if (obj.offsetParent) { - while (obj.offsetParent) { - curleft += obj.offsetLeft; - obj = obj.offsetParent; - } - }//if offsetParent exists - else if (obj.x) - curleft += obj.x - return curleft; -}//findElementPosX - -function findElementPosY(obj) { - curtop = 0; - if (obj.offsetParent) { - while (obj.offsetParent) { - curtop += obj.offsetTop; - obj = obj.offsetParent; - } - }//if offsetParent exists - else if (obj.y) - curtop += obj.y - return curtop; -}//findElementPosY - -/* end dhtml building blocks */ - -function handleKeyPress(event) { - e = getEvent(event); - eL = getEventElement(e); - - upEl = isWithinNode(eL,null,"wickEnabled",null,null); - - kc = e["keyCode"]; - - if (siw && ((kc == 13) || (kc == 9))) { - siw.selectingSomething = true; - if (siw.isSafari) siw.inputBox.blur(); //hack to "wake up" safari - siw.inputBox.focus(); - siw.inputBox.value = siw.inputBox.value.replace(/[ \r\n\t\f\s]+$/gi,' '); - hideSmartInputFloater(); - } else if (upEl && (kc != 38) && (kc != 40) && (kc != 37) && (kc != 39) && (kc != 13) && (kc != 27)) { - if (!siw || (siw && !siw.selectingSomething)) { - processSmartInput(upEl); - } - } else if (siw && siw.inputBox) { - siw.inputBox.focus(); //kinda part of the hack. - } - -}//handleKeyPress() - - -function handleKeyDown(event) { - e = getEvent(event); - eL = getEventElement(e); - - if (siw && (kc = e["keyCode"])) { - if (kc == 40) { - siw.selectingSomething = true; - freezeEvent(e); - if (siw.isGecko) siw.inputBox.blur(); /* Gecko hack */ - selectNextSmartInputMatchItem(); - } else if (kc == 38) { - siw.selectingSomething = true; - freezeEvent(e); - if (siw.isGecko) siw.inputBox.blur(); - selectPreviousSmartInputMatchItem(); - } else if ((kc == 13) || (kc == 9)) { - siw.selectingSomething = true; - activateCurrentSmartInputMatch(); - freezeEvent(e); - } else if (kc == 27) { - hideSmartInputFloater(); - freezeEvent(e); - } else { - siw.selectingSomething = false; - } - } - -}//handleKeyDown() - -function handleFocus(event) { - e = getEvent(event); - eL = getEventElement(e); - if (focEl = isWithinNode(eL,null,"wickEnabled",null,null)) { - if (!siw || (siw && !siw.selectingSomething)) processSmartInput(focEl); - } -}//handleFocus() - -function handleBlur(event) { - e = getEvent(event); - eL = getEventElement(e); - if (blurEl = isWithinNode(eL,null,"wickEnabled",null,null)) { - if (siw && !siw.selectingSomething) hideSmartInputFloater(); - } -}//handleBlur() - -function handleClick(event) { - e2 = getEvent(event); - eL2 = getEventElement(e2); - if (siw && siw.selectingSomething) { - selectFromMouseClick(); - } -}//handleClick() - -function handleMouseOver(event) { - e = getEvent(event); - eL = getEventElement(e); - if (siw && (mEl = isWithinNode(eL,null,"matchedSmartInputItem",null,null))) { - siw.selectingSomething = true; - selectFromMouseOver(mEl); - } else if (isWithinNode(eL,null,"siwCredit",null,null)) { - siw.selectingSomething = true; - }else if (siw) { - siw.selectingSomething = false; - } -}//handleMouseOver - -function showSmartInputFloater() { -if (!siw.floater.style.display || (siw.floater.style.display=="none")) { - if (!siw.customFloater) { - x = findElementPosX(siw.inputBox); - y = findElementPosY(siw.inputBox) + siw.inputBox.offsetHeight; - //hack: browser-specific adjustments. - if (!siw.isGecko && !siw.isWinIE) x += 8; - if (!siw.isGecko && !siw.isWinIE) y += 10; - siw.floater.style.left = x; - siw.floater.style.top = y; - } else { - //you may - //do additional things for your custom floater - //beyond setting display and visibility - } - siw.floater.style.display="block"; - siw.floater.style.visibility="visible"; -} -}//showSmartInputFloater() - -function hideSmartInputFloater() { - if (siw) { - siw.floater.style.display="none"; - siw.floater.style.visibility="hidden"; - siw = null; - }//siw exists -}//hideSmartInputFloater - -function processSmartInput(inputBox) { - if (!siw) siw = new smartInputWindow(); - siw.inputBox = inputBox; - - classData = inputBox.className.split(" "); - siwDirectives = null; - for (i=0;(!siwDirectives && classData[i]);i++) { - if (classData[i].indexOf("wickEnabled") != -1) - siwDirectives = classData[i]; - } - - if (siwDirectives && (siwDirectives.indexOf(":") != -1)) { - siw.customFloater = true; - newFloaterId = siwDirectives.split(":")[1]; - siw.floater = document.getElementById(newFloaterId); - siw.floaterContent = siw.floater.getElementsByTagName("div")[0]; - } - - - setSmartInputData(); - if (siw.matchCollection && (siw.matchCollection.length > 0)) selectSmartInputMatchItem(0); - var content = content || null; - content = getSmartInputBoxContent(); - if (content) { - modifySmartInputBoxContent(content); - showSmartInputFloater(); - } else { - hideSmartInputFloater(); - } -}//processSmartInput() - -function smartInputMatch(cleanValue, value) { - this.cleanValue = cleanValue; - this.value = value; - this.isSelected = false; -}//smartInputMatch - -function simplify(s) { - return s.toLowerCase().replace(/^[ \s\f\t\n\r]+/,'').replace(/[ \s\f\t\n\r]+$/,''); -//.replace(/[?,?,?,?,\u00E9,\u00E8,\u00EA,\u00EB]/gi,"e").replace(/[?,?,\u00E0,\u00E2]/gi,"a"). -}//simplify - -function getUserInputToMatch(s) { - a = s; - fields = s.split(","); - if (fields.length > 0) a = fields[fields.length - 1]; - return a; -}//getUserInputToMatch - -function getUserInputBase() { - s = siw.inputBox.value; - a = s; - if ((lastComma = s.lastIndexOf(",")) != -1) { - a = a.replace(/^(.*\,[ \r\n\t\f\s]*).*$/i,'$1'); - } - else { - a = ""; - } - return a; -}//getUserInputBase() - -function runMatchingLogic(userInput, standalone) { - userInput = simplify(userInput); - uifc = userInput.charAt(0).toLowerCase(); - if (uifc == '"') uifc = (n = userInput.charAt(1)) ? n.toLowerCase() : "z"; - if (standalone) userInput = uifc; - if (siw) siw.matchCollection = new Array(); - pointerToCollectionToUse = collection; - if (siw && siw.revisedCollection && (siw.revisedCollection.length > 0) && siw.lastUserInput && (userInput.indexOf(siw.lastUserInput) == 0)) { - pointerToCollectionToUse = siw.revisedCollection; - } else if (collectionIndex[userInput] && (collectionIndex[userInput].length > 0)) { - pointerToCollectionToUse = collectionIndex[userInput]; - } else if (collectionIndex[uifc] && (collectionIndex[uifc].length > 0)) { - pointerToCollectionToUse = collectionIndex[uifc]; - } else if (siw && (userInput.length == 1) && (!collectionIndex[uifc])) { - siw.buildIndex = true; - } else if (siw) { - siw.buildIndex = false; - } - - tempCollection = new Array(); - - re1m = new RegExp("^([ \"\>\<\-]*)("+userInput+")","i"); - re2m = new RegExp("([ \"\>\<\-]+)("+userInput+")","i"); - re1 = new RegExp("^([ \"\}\{\-]*)("+userInput+")","gi"); - re2 = new RegExp("([ \"\}\{\-]+)("+userInput+")","gi"); - - for (i=0,j=0;(i/gi,'\\}').replace(/\< ?/gi,'\\{'); - re = new RegExp("(" + userInput + ")","i"); - if (displayMatches) { - siw.matchCollection[j] = new smartInputMatch(entry, mEntry.replace(/\>/gi,'}').replace(/\< ?/gi,'{').replace(re,"$1")); - } - tempCollection[j] = entry; - j++; - } else if (mEntry.match(re1m) || mEntry.match(re2m)) { - if (!standalone && displayMatches) { - siw.matchCollection[j] = new smartInputMatch(entry, mEntry.replace(/\>/gi,'}').replace(/\$2").replace(re2,"$1$2")); - } - tempCollection[j] = entry; - j++; - } - }//loop thru collection - if (siw) { - siw.lastUserInput = userInput; - siw.revisedCollection = tempCollection.join(",").split(","); - collectionIndex[userInput] = tempCollection.join(",").split(","); - } - if (standalone || siw.buildIndex) { - collectionIndex[uifc] = tempCollection.join(",").split(","); - if (siw) siw.buildIndex = false; - } -}//runMatchingLogic - -function setSmartInputData() { - if (siw) { - orgUserInput = siw.inputBox.value; - orgUserInput = getUserInputToMatch(orgUserInput); - userInput = orgUserInput.toLowerCase().replace(/[\r\n\t\f\s]+/gi,' ').replace(/^ +/gi,'').replace(/ +$/gi,'').replace(/ +/gi,' ').replace(/\\/gi,'').replace(/\[/gi,'').replace(/\(/gi,'').replace(/\./gi,'\.').replace(/\?/gi,''); - if (userInput && (userInput != "") && (userInput != '"')) { - runMatchingLogic(userInput); - }//if userinput not blank and is meaningful - else { - siw.matchCollection = null; - } - }//siw exists ... uhmkaaayyyyy -}//setSmartInputData - -function getSmartInputBoxContent() { - a = null; - if (siw && siw.matchCollection && (siw.matchCollection.length > 0)) { - a = ''; - for (i = 0;i < siw.matchCollection.length; i++) { - selectedString = siw.matchCollection[i].isSelected ? ' selectedSmartInputItem' : ''; - a += '

' + siw.matchCollection[i].value.replace(/\{ */gi,"<").replace(/\} */gi,">") + '

'; - }// - }//siw exists - return a; -}//getSmartInputBoxContent - -function modifySmartInputBoxContent(content) { - //todo: remove credits 'cuz no one gives a shit ;] - done - siw.floaterContent.innerHTML = '
' + content + (siw.showCredit ? ('

Powered By: Chris Holland

') : '') +'
'; - siw.matchListDisplay = document.getElementById("smartInputResults"); -}//modifySmartInputBoxContent() - -function selectFromMouseOver(o) { - currentIndex = getCurrentlySelectedSmartInputItem(); - if (currentIndex != null) deSelectSmartInputMatchItem(currentIndex); - newIndex = getIndexFromElement(o); - selectSmartInputMatchItem(newIndex); - modifySmartInputBoxContent(getSmartInputBoxContent()); -}//selectFromMouseOver - -function selectFromMouseClick() { - activateCurrentSmartInputMatch(); - siw.inputBox.focus(); - hideSmartInputFloater(); -}//selectFromMouseClick - -function getIndexFromElement(o) { - index = 0; - while(o = o.previousSibling) { - index++; - }// - return index; -}//getIndexFromElement - -function getCurrentlySelectedSmartInputItem() { - answer = null; - for (i = 0; ((i < siw.matchCollection.length) && !answer) ; i++) { - if (siw.matchCollection[i].isSelected) - answer = i; - }// - return answer; -}//getCurrentlySelectedSmartInputItem - -function selectSmartInputMatchItem(index) { - siw.matchCollection[index].isSelected = true; -}//selectSmartInputMatchItem() - -function deSelectSmartInputMatchItem(index) { - siw.matchCollection[index].isSelected = false; -}//deSelectSmartInputMatchItem() - -function selectNextSmartInputMatchItem() { - currentIndex = getCurrentlySelectedSmartInputItem(); - if (currentIndex != null) { - deSelectSmartInputMatchItem(currentIndex); - if ((currentIndex + 1) < siw.matchCollection.length) - selectSmartInputMatchItem(currentIndex + 1); - else - selectSmartInputMatchItem(0); - } else { - selectSmartInputMatchItem(0); - } - modifySmartInputBoxContent(getSmartInputBoxContent()); -}//selectNextSmartInputMatchItem - -function selectPreviousSmartInputMatchItem() { - currentIndex = getCurrentlySelectedSmartInputItem(); - if (currentIndex != null) { - deSelectSmartInputMatchItem(currentIndex); - if ((currentIndex - 1) >= 0) - selectSmartInputMatchItem(currentIndex - 1); - else - selectSmartInputMatchItem(siw.matchCollection.length - 1); - } else { - selectSmartInputMatchItem(siw.matchCollection.length - 1); - } - modifySmartInputBoxContent(getSmartInputBoxContent()); -}//selectPreviousSmartInputMatchItem - -function activateCurrentSmartInputMatch() { - baseValue = getUserInputBase(); - if ((selIndex = getCurrentlySelectedSmartInputItem()) != null) { - addedValue = siw.matchCollection[selIndex].cleanValue; - theString = (baseValue ? baseValue : "") + addedValue + ", "; - siw.inputBox.value = theString; - runMatchingLogic(addedValue, true); - } -}//activateCurrentSmartInputMatch - -function smartInputWindow () { - this.customFloater = false; - this.floater = document.getElementById("smartInputFloater"); - this.floaterContent = document.getElementById("smartInputFloaterContent"); - this.selectedSmartInputItem = null; - this.MAX_MATCHES = 15; - this.isGecko = (navigator.userAgent.indexOf("Gecko/200") != -1); - this.isSafari = (navigator.userAgent.indexOf("Safari") != -1); - this.isWinIE = ((navigator.userAgent.indexOf("Win") != -1 ) && (navigator.userAgent.indexOf("MSIE") != -1 )); - this.showCredit = false; -}//smartInputWindow Object - -function registerSmartInputListeners() { - inputs = document.getElementsByTagName("input"); - texts = document.getElementsByTagName("textarea"); - allinputs = new Array(); - z = 0; - y = 0; - while(inputs[z]) { - allinputs[z] = inputs[z]; - z++; - }// - while(texts[y]) { - allinputs[z] = texts[y]; - z++; - y++; - }// - - for (i=0; i < allinputs.length;i++) { - if ((c = allinputs[i].className) && (c == "wickEnabled")) { - allinputs[i].setAttribute("autocomplete","OFF"); - allinputs[i].onfocus = handleFocus; - allinputs[i].onblur = handleBlur; - allinputs[i].onkeydown = handleKeyDown; - allinputs[i].onkeyup = handleKeyPress; - } - }//loop thru inputs - }//registerSmartInputListeners - - siw = null; - - if (document.addEventListener) { - document.addEventListener("keydown", handleKeyDown, false); - document.addEventListener("keyup", handleKeyPress, false); - document.addEventListener("mouseup", handleClick, false); - document.addEventListener("mouseover", handleMouseOver, false); - } else { - document.onkeydown = handleKeyDown; - document.onkeyup = handleKeyPress; - document.onmouseup = handleClick; - document.onmouseover = handleMouseOver; - } - - registerSmartInputListeners(); - - document.write ( - ']","i"),bv=/^(?:checkbox|radio)$/,bw=/checked\s*(?:[^=]|=\s*.checked.)/i,bx=/\/(java|ecma)script/i,by=/^\s*\s*$/g,bz={option:[1,""],legend:[1,"
","
"],thead:[1,"
' - +'<\/td><\/tr><\/table>' - ); - - //note: instruct users to the fact that no commas should be present in entries. - //it would make things insanely messy. - //this is why i'm filtering commas here: - for (x=0;xd;d++)a="0"+a;return a}return{parseDate:function(a){var b={date:null,year:null,month:null,dayOfMonth:null,dayOfWeek:null,time:null};if("number"==typeof a)return this.parseDate(new Date(a));if("function"==typeof a.getFullYear)b.year=String(a.getFullYear()),b.month=String(a.getMonth()+1),b.dayOfMonth=String(a.getDate()),b.time=l(a.toTimeString());else if(-1!=a.search(g))values=a.split(/[T\+-]/),b.year=values[0],b.month=values[1],b.dayOfMonth=values[2],b.time=l(values[3].split(".")[0]);else switch(values=a.split(" "),6===values.length&&isNaN(values[5])&&(values[values.length]="()"),values.length){case 6:b.year=values[5],b.month=k(values[1]),b.dayOfMonth=values[2],b.time=l(values[3]);break;case 2:subValues=values[0].split("-"),b.year=subValues[0],b.month=subValues[1],b.dayOfMonth=subValues[2],b.time=l(values[1]);break;case 7:case 9:case 10:b.year=values[3],b.month=k(values[1]),b.dayOfMonth=values[2],b.time=l(values[4]);break;case 1:subValues=values[0].split(""),b.year=subValues[0]+subValues[1]+subValues[2]+subValues[3],b.month=subValues[5]+subValues[6],b.dayOfMonth=subValues[8]+subValues[9],b.time=l(subValues[13]+subValues[14]+subValues[15]+subValues[16]+subValues[17]+subValues[18]+subValues[19]+subValues[20]);break;default:return null}return b.date=new Date(b.year,b.month-1,b.dayOfMonth),b.dayOfWeek=String(b.date.getDay()),b},date:function(b,c){try{var d=this.parseDate(b);if(null===d)return b;for(var e=(d.date,d.year),f=d.month,g=d.dayOfMonth,k=d.dayOfWeek,l=d.time,n="",o="",p="",q=!1,r=0;r=12?"PM":"AM",n="";break;case"p":o+=l.hour>=12?"p.m.":"a.m.",n="";break;case"E":o+=h(k),n="";break;case"'":n="",q=!0;break;default:o+=s,n=""}}return o+=p}catch(u){return console&&console.log&&console.log(u),b}},prettyDate:function(a){var b,c,d;return("string"==typeof a||"number"==typeof a)&&(b=new Date(a)),"object"==typeof a&&(b=new Date(a.toString())),c=((new Date).getTime()-b.getTime())/1e3,d=Math.floor(c/86400),isNaN(d)||0>d?void 0:60>c?"just now":120>c?"1 minute ago":3600>c?Math.floor(c/60)+" minutes ago":7200>c?"1 hour ago":86400>c?Math.floor(c/3600)+" hours ago":1===d?"Yesterday":7>d?d+" days ago":31>d?Math.ceil(d/7)+" weeks ago":d>=31?"more than 5 weeks ago":void 0},toBrowserTimeZone:function(a,b){return this.date(new Date(a),b||"MM/dd/yyyy HH:mm:ss")}}}()}(DateFormat),function(a){a.format=DateFormat.format}(jQuery); \ No newline at end of file diff --git a/WebContent/stat/js/util/jquery-rapped.js b/WebContent/stat/js/util/jquery-rapped.js deleted file mode 100644 index 3055313bb..000000000 --- a/WebContent/stat/js/util/jquery-rapped.js +++ /dev/null @@ -1,12 +0,0 @@ -define('jquery', [], function(require) { - - /*! jQuery v1.8.2 jquery.com | jquery.org/license */ -(function(a,b){function G(a){var b=F[a]={};return p.each(a.split(s),function(a,c){b[c]=!0}),b}function J(a,c,d){if(d===b&&a.nodeType===1){var e="data-"+c.replace(I,"-$1").toLowerCase();d=a.getAttribute(e);if(typeof d=="string"){try{d=d==="true"?!0:d==="false"?!1:d==="null"?null:+d+""===d?+d:H.test(d)?p.parseJSON(d):d}catch(f){}p.data(a,c,d)}else d=b}return d}function K(a){var b;for(b in a){if(b==="data"&&p.isEmptyObject(a[b]))continue;if(b!=="toJSON")return!1}return!0}function ba(){return!1}function bb(){return!0}function bh(a){return!a||!a.parentNode||a.parentNode.nodeType===11}function bi(a,b){do a=a[b];while(a&&a.nodeType!==1);return a}function bj(a,b,c){b=b||0;if(p.isFunction(b))return p.grep(a,function(a,d){var e=!!b.call(a,d,a);return e===c});if(b.nodeType)return p.grep(a,function(a,d){return a===b===c});if(typeof b=="string"){var d=p.grep(a,function(a){return a.nodeType===1});if(be.test(b))return p.filter(b,d,!c);b=p.filter(b,d)}return p.grep(a,function(a,d){return p.inArray(a,b)>=0===c})}function bk(a){var b=bl.split("|"),c=a.createDocumentFragment();if(c.createElement)while(b.length)c.createElement(b.pop());return c}function bC(a,b){return a.getElementsByTagName(b)[0]||a.appendChild(a.ownerDocument.createElement(b))}function bD(a,b){if(b.nodeType!==1||!p.hasData(a))return;var c,d,e,f=p._data(a),g=p._data(b,f),h=f.events;if(h){delete g.handle,g.events={};for(c in h)for(d=0,e=h[c].length;d").appendTo(e.body),c=b.css("display");b.remove();if(c==="none"||c===""){bI=e.body.appendChild(bI||p.extend(e.createElement("iframe"),{frameBorder:0,width:0,height:0}));if(!bJ||!bI.createElement)bJ=(bI.contentWindow||bI.contentDocument).document,bJ.write(""),bJ.close();b=bJ.body.appendChild(bJ.createElement(a)),c=bH(b,"display"),e.body.removeChild(bI)}return bS[a]=c,c}function ci(a,b,c,d){var e;if(p.isArray(b))p.each(b,function(b,e){c||ce.test(a)?d(a,e):ci(a+"["+(typeof e=="object"?b:"")+"]",e,c,d)});else if(!c&&p.type(b)==="object")for(e in b)ci(a+"["+e+"]",b[e],c,d);else d(a,b)}function cz(a){return function(b,c){typeof b!="string"&&(c=b,b="*");var d,e,f,g=b.toLowerCase().split(s),h=0,i=g.length;if(p.isFunction(c))for(;h)[^>]*$|#([\w\-]*)$)/,v=/^<(\w+)\s*\/?>(?:<\/\1>|)$/,w=/^[\],:{}\s]*$/,x=/(?:^|:|,)(?:\s*\[)+/g,y=/\\(?:["\\\/bfnrt]|u[\da-fA-F]{4})/g,z=/"[^"\\\r\n]*"|true|false|null|-?(?:\d\d*\.|)\d+(?:[eE][\-+]?\d+|)/g,A=/^-ms-/,B=/-([\da-z])/gi,C=function(a,b){return(b+"").toUpperCase()},D=function(){e.addEventListener?(e.removeEventListener("DOMContentLoaded",D,!1),p.ready()):e.readyState==="complete"&&(e.detachEvent("onreadystatechange",D),p.ready())},E={};p.fn=p.prototype={constructor:p,init:function(a,c,d){var f,g,h,i;if(!a)return this;if(a.nodeType)return this.context=this[0]=a,this.length=1,this;if(typeof a=="string"){a.charAt(0)==="<"&&a.charAt(a.length-1)===">"&&a.length>=3?f=[null,a,null]:f=u.exec(a);if(f&&(f[1]||!c)){if(f[1])return c=c instanceof p?c[0]:c,i=c&&c.nodeType?c.ownerDocument||c:e,a=p.parseHTML(f[1],i,!0),v.test(f[1])&&p.isPlainObject(c)&&this.attr.call(a,c,!0),p.merge(this,a);g=e.getElementById(f[2]);if(g&&g.parentNode){if(g.id!==f[2])return d.find(a);this.length=1,this[0]=g}return this.context=e,this.selector=a,this}return!c||c.jquery?(c||d).find(a):this.constructor(c).find(a)}return p.isFunction(a)?d.ready(a):(a.selector!==b&&(this.selector=a.selector,this.context=a.context),p.makeArray(a,this))},selector:"",jquery:"1.8.2",length:0,size:function(){return this.length},toArray:function(){return k.call(this)},get:function(a){return a==null?this.toArray():a<0?this[this.length+a]:this[a]},pushStack:function(a,b,c){var d=p.merge(this.constructor(),a);return d.prevObject=this,d.context=this.context,b==="find"?d.selector=this.selector+(this.selector?" ":"")+c:b&&(d.selector=this.selector+"."+b+"("+c+")"),d},each:function(a,b){return p.each(this,a,b)},ready:function(a){return p.ready.promise().done(a),this},eq:function(a){return a=+a,a===-1?this.slice(a):this.slice(a,a+1)},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},slice:function(){return this.pushStack(k.apply(this,arguments),"slice",k.call(arguments).join(","))},map:function(a){return this.pushStack(p.map(this,function(b,c){return a.call(b,c,b)}))},end:function(){return this.prevObject||this.constructor(null)},push:j,sort:[].sort,splice:[].splice},p.fn.init.prototype=p.fn,p.extend=p.fn.extend=function(){var a,c,d,e,f,g,h=arguments[0]||{},i=1,j=arguments.length,k=!1;typeof h=="boolean"&&(k=h,h=arguments[1]||{},i=2),typeof h!="object"&&!p.isFunction(h)&&(h={}),j===i&&(h=this,--i);for(;i0)return;d.resolveWith(e,[p]),p.fn.trigger&&p(e).trigger("ready").off("ready")},isFunction:function(a){return p.type(a)==="function"},isArray:Array.isArray||function(a){return p.type(a)==="array"},isWindow:function(a){return a!=null&&a==a.window},isNumeric:function(a){return!isNaN(parseFloat(a))&&isFinite(a)},type:function(a){return a==null?String(a):E[m.call(a)]||"object"},isPlainObject:function(a){if(!a||p.type(a)!=="object"||a.nodeType||p.isWindow(a))return!1;try{if(a.constructor&&!n.call(a,"constructor")&&!n.call(a.constructor.prototype,"isPrototypeOf"))return!1}catch(c){return!1}var d;for(d in a);return d===b||n.call(a,d)},isEmptyObject:function(a){var b;for(b in a)return!1;return!0},error:function(a){throw new Error(a)},parseHTML:function(a,b,c){var d;return!a||typeof a!="string"?null:(typeof b=="boolean"&&(c=b,b=0),b=b||e,(d=v.exec(a))?[b.createElement(d[1])]:(d=p.buildFragment([a],b,c?null:[]),p.merge([],(d.cacheable?p.clone(d.fragment):d.fragment).childNodes)))},parseJSON:function(b){if(!b||typeof b!="string")return null;b=p.trim(b);if(a.JSON&&a.JSON.parse)return a.JSON.parse(b);if(w.test(b.replace(y,"@").replace(z,"]").replace(x,"")))return(new Function("return "+b))();p.error("Invalid JSON: "+b)},parseXML:function(c){var d,e;if(!c||typeof c!="string")return null;try{a.DOMParser?(e=new DOMParser,d=e.parseFromString(c,"text/xml")):(d=new ActiveXObject("Microsoft.XMLDOM"),d.async="false",d.loadXML(c))}catch(f){d=b}return(!d||!d.documentElement||d.getElementsByTagName("parsererror").length)&&p.error("Invalid XML: "+c),d},noop:function(){},globalEval:function(b){b&&r.test(b)&&(a.execScript||function(b){a.eval.call(a,b)})(b)},camelCase:function(a){return a.replace(A,"ms-").replace(B,C)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toLowerCase()===b.toLowerCase()},each:function(a,c,d){var e,f=0,g=a.length,h=g===b||p.isFunction(a);if(d){if(h){for(e in a)if(c.apply(a[e],d)===!1)break}else for(;f0&&a[0]&&a[i-1]||i===0||p.isArray(a));if(j)for(;h-1)i.splice(c,1),e&&(c<=g&&g--,c<=h&&h--)}),this},has:function(a){return p.inArray(a,i)>-1},empty:function(){return i=[],this},disable:function(){return i=j=c=b,this},disabled:function(){return!i},lock:function(){return j=b,c||l.disable(),this},locked:function(){return!j},fireWith:function(a,b){return b=b||[],b=[a,b.slice?b.slice():b],i&&(!d||j)&&(e?j.push(b):k(b)),this},fire:function(){return l.fireWith(this,arguments),this},fired:function(){return!!d}};return l},p.extend({Deferred:function(a){var b=[["resolve","done",p.Callbacks("once memory"),"resolved"],["reject","fail",p.Callbacks("once memory"),"rejected"],["notify","progress",p.Callbacks("memory")]],c="pending",d={state:function(){return c},always:function(){return e.done(arguments).fail(arguments),this},then:function(){var a=arguments;return p.Deferred(function(c){p.each(b,function(b,d){var f=d[0],g=a[b];e[d[1]](p.isFunction(g)?function(){var a=g.apply(this,arguments);a&&p.isFunction(a.promise)?a.promise().done(c.resolve).fail(c.reject).progress(c.notify):c[f+"With"](this===e?c:this,[a])}:c[f])}),a=null}).promise()},promise:function(a){return a!=null?p.extend(a,d):d}},e={};return d.pipe=d.then,p.each(b,function(a,f){var g=f[2],h=f[3];d[f[1]]=g.add,h&&g.add(function(){c=h},b[a^1][2].disable,b[2][2].lock),e[f[0]]=g.fire,e[f[0]+"With"]=g.fireWith}),d.promise(e),a&&a.call(e,e),e},when:function(a){var b=0,c=k.call(arguments),d=c.length,e=d!==1||a&&p.isFunction(a.promise)?d:0,f=e===1?a:p.Deferred(),g=function(a,b,c){return function(d){b[a]=this,c[a]=arguments.length>1?k.call(arguments):d,c===h?f.notifyWith(b,c):--e||f.resolveWith(b,c)}},h,i,j;if(d>1){h=new Array(d),i=new Array(d),j=new Array(d);for(;b
a",c=n.getElementsByTagName("*"),d=n.getElementsByTagName("a")[0],d.style.cssText="top:1px;float:left;opacity:.5";if(!c||!c.length)return{};f=e.createElement("select"),g=f.appendChild(e.createElement("option")),h=n.getElementsByTagName("input")[0],b={leadingWhitespace:n.firstChild.nodeType===3,tbody:!n.getElementsByTagName("tbody").length,htmlSerialize:!!n.getElementsByTagName("link").length,style:/top/.test(d.getAttribute("style")),hrefNormalized:d.getAttribute("href")==="/a",opacity:/^0.5/.test(d.style.opacity),cssFloat:!!d.style.cssFloat,checkOn:h.value==="on",optSelected:g.selected,getSetAttribute:n.className!=="t",enctype:!!e.createElement("form").enctype,html5Clone:e.createElement("nav").cloneNode(!0).outerHTML!=="<:nav>",boxModel:e.compatMode==="CSS1Compat",submitBubbles:!0,changeBubbles:!0,focusinBubbles:!1,deleteExpando:!0,noCloneEvent:!0,inlineBlockNeedsLayout:!1,shrinkWrapBlocks:!1,reliableMarginRight:!0,boxSizingReliable:!0,pixelPosition:!1},h.checked=!0,b.noCloneChecked=h.cloneNode(!0).checked,f.disabled=!0,b.optDisabled=!g.disabled;try{delete n.test}catch(o){b.deleteExpando=!1}!n.addEventListener&&n.attachEvent&&n.fireEvent&&(n.attachEvent("onclick",m=function(){b.noCloneEvent=!1}),n.cloneNode(!0).fireEvent("onclick"),n.detachEvent("onclick",m)),h=e.createElement("input"),h.value="t",h.setAttribute("type","radio"),b.radioValue=h.value==="t",h.setAttribute("checked","checked"),h.setAttribute("name","t"),n.appendChild(h),i=e.createDocumentFragment(),i.appendChild(n.lastChild),b.checkClone=i.cloneNode(!0).cloneNode(!0).lastChild.checked,b.appendChecked=h.checked,i.removeChild(h),i.appendChild(n);if(n.attachEvent)for(k in{submit:!0,change:!0,focusin:!0})j="on"+k,l=j in n,l||(n.setAttribute(j,"return;"),l=typeof n[j]=="function"),b[k+"Bubbles"]=l;return p(function(){var c,d,f,g,h="padding:0;margin:0;border:0;display:block;overflow:hidden;",i=e.getElementsByTagName("body")[0];if(!i)return;c=e.createElement("div"),c.style.cssText="visibility:hidden;border:0;width:0;height:0;position:static;top:0;margin-top:1px",i.insertBefore(c,i.firstChild),d=e.createElement("div"),c.appendChild(d),d.innerHTML="
t
",f=d.getElementsByTagName("td"),f[0].style.cssText="padding:0;margin:0;border:0;display:none",l=f[0].offsetHeight===0,f[0].style.display="",f[1].style.display="none",b.reliableHiddenOffsets=l&&f[0].offsetHeight===0,d.innerHTML="",d.style.cssText="box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;padding:1px;border:1px;display:block;width:4px;margin-top:1%;position:absolute;top:1%;",b.boxSizing=d.offsetWidth===4,b.doesNotIncludeMarginInBodyOffset=i.offsetTop!==1,a.getComputedStyle&&(b.pixelPosition=(a.getComputedStyle(d,null)||{}).top!=="1%",b.boxSizingReliable=(a.getComputedStyle(d,null)||{width:"4px"}).width==="4px",g=e.createElement("div"),g.style.cssText=d.style.cssText=h,g.style.marginRight=g.style.width="0",d.style.width="1px",d.appendChild(g),b.reliableMarginRight=!parseFloat((a.getComputedStyle(g,null)||{}).marginRight)),typeof d.style.zoom!="undefined"&&(d.innerHTML="",d.style.cssText=h+"width:1px;padding:1px;display:inline;zoom:1",b.inlineBlockNeedsLayout=d.offsetWidth===3,d.style.display="block",d.style.overflow="visible",d.innerHTML="
",d.firstChild.style.width="5px",b.shrinkWrapBlocks=d.offsetWidth!==3,c.style.zoom=1),i.removeChild(c),c=d=f=g=null}),i.removeChild(n),c=d=f=g=h=i=n=null,b}();var H=/(?:\{[\s\S]*\}|\[[\s\S]*\])$/,I=/([A-Z])/g;p.extend({cache:{},deletedIds:[],uuid:0,expando:"jQuery"+(p.fn.jquery+Math.random()).replace(/\D/g,""),noData:{embed:!0,object:"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000",applet:!0},hasData:function(a){return a=a.nodeType?p.cache[a[p.expando]]:a[p.expando],!!a&&!K(a)},data:function(a,c,d,e){if(!p.acceptData(a))return;var f,g,h=p.expando,i=typeof c=="string",j=a.nodeType,k=j?p.cache:a,l=j?a[h]:a[h]&&h;if((!l||!k[l]||!e&&!k[l].data)&&i&&d===b)return;l||(j?a[h]=l=p.deletedIds.pop()||p.guid++:l=h),k[l]||(k[l]={},j||(k[l].toJSON=p.noop));if(typeof c=="object"||typeof c=="function")e?k[l]=p.extend(k[l],c):k[l].data=p.extend(k[l].data,c);return f=k[l],e||(f.data||(f.data={}),f=f.data),d!==b&&(f[p.camelCase(c)]=d),i?(g=f[c],g==null&&(g=f[p.camelCase(c)])):g=f,g},removeData:function(a,b,c){if(!p.acceptData(a))return;var d,e,f,g=a.nodeType,h=g?p.cache:a,i=g?a[p.expando]:p.expando;if(!h[i])return;if(b){d=c?h[i]:h[i].data;if(d){p.isArray(b)||(b in d?b=[b]:(b=p.camelCase(b),b in d?b=[b]:b=b.split(" ")));for(e=0,f=b.length;e1,null,!1))},removeData:function(a){return this.each(function(){p.removeData(this,a)})}}),p.extend({queue:function(a,b,c){var d;if(a)return b=(b||"fx")+"queue",d=p._data(a,b),c&&(!d||p.isArray(c)?d=p._data(a,b,p.makeArray(c)):d.push(c)),d||[]},dequeue:function(a,b){b=b||"fx";var c=p.queue(a,b),d=c.length,e=c.shift(),f=p._queueHooks(a,b),g=function(){p.dequeue(a,b)};e==="inprogress"&&(e=c.shift(),d--),e&&(b==="fx"&&c.unshift("inprogress"),delete f.stop,e.call(a,g,f)),!d&&f&&f.empty.fire()},_queueHooks:function(a,b){var c=b+"queueHooks";return p._data(a,c)||p._data(a,c,{empty:p.Callbacks("once memory").add(function(){p.removeData(a,b+"queue",!0),p.removeData(a,c,!0)})})}}),p.fn.extend({queue:function(a,c){var d=2;return typeof a!="string"&&(c=a,a="fx",d--),arguments.length1)},removeAttr:function(a){return this.each(function(){p.removeAttr(this,a)})},prop:function(a,b){return p.access(this,p.prop,a,b,arguments.length>1)},removeProp:function(a){return a=p.propFix[a]||a,this.each(function(){try{this[a]=b,delete this[a]}catch(c){}})},addClass:function(a){var b,c,d,e,f,g,h;if(p.isFunction(a))return this.each(function(b){p(this).addClass(a.call(this,b,this.className))});if(a&&typeof a=="string"){b=a.split(s);for(c=0,d=this.length;c=0)d=d.replace(" "+c[f]+" "," ");e.className=a?p.trim(d):""}}}return this},toggleClass:function(a,b){var c=typeof a,d=typeof b=="boolean";return p.isFunction(a)?this.each(function(c){p(this).toggleClass(a.call(this,c,this.className,b),b)}):this.each(function(){if(c==="string"){var e,f=0,g=p(this),h=b,i=a.split(s);while(e=i[f++])h=d?h:!g.hasClass(e),g[h?"addClass":"removeClass"](e)}else if(c==="undefined"||c==="boolean")this.className&&p._data(this,"__className__",this.className),this.className=this.className||a===!1?"":p._data(this,"__className__")||""})},hasClass:function(a){var b=" "+a+" ",c=0,d=this.length;for(;c=0)return!0;return!1},val:function(a){var c,d,e,f=this[0];if(!arguments.length){if(f)return c=p.valHooks[f.type]||p.valHooks[f.nodeName.toLowerCase()],c&&"get"in c&&(d=c.get(f,"value"))!==b?d:(d=f.value,typeof d=="string"?d.replace(P,""):d==null?"":d);return}return e=p.isFunction(a),this.each(function(d){var f,g=p(this);if(this.nodeType!==1)return;e?f=a.call(this,d,g.val()):f=a,f==null?f="":typeof f=="number"?f+="":p.isArray(f)&&(f=p.map(f,function(a){return a==null?"":a+""})),c=p.valHooks[this.type]||p.valHooks[this.nodeName.toLowerCase()];if(!c||!("set"in c)||c.set(this,f,"value")===b)this.value=f})}}),p.extend({valHooks:{option:{get:function(a){var b=a.attributes.value;return!b||b.specified?a.value:a.text}},select:{get:function(a){var b,c,d,e,f=a.selectedIndex,g=[],h=a.options,i=a.type==="select-one";if(f<0)return null;c=i?f:0,d=i?f+1:h.length;for(;c=0}),c.length||(a.selectedIndex=-1),c}}},attrFn:{},attr:function(a,c,d,e){var f,g,h,i=a.nodeType;if(!a||i===3||i===8||i===2)return;if(e&&p.isFunction(p.fn[c]))return p(a)[c](d);if(typeof a.getAttribute=="undefined")return p.prop(a,c,d);h=i!==1||!p.isXMLDoc(a),h&&(c=c.toLowerCase(),g=p.attrHooks[c]||(T.test(c)?M:L));if(d!==b){if(d===null){p.removeAttr(a,c);return}return g&&"set"in g&&h&&(f=g.set(a,d,c))!==b?f:(a.setAttribute(c,d+""),d)}return g&&"get"in g&&h&&(f=g.get(a,c))!==null?f:(f=a.getAttribute(c),f===null?b:f)},removeAttr:function(a,b){var c,d,e,f,g=0;if(b&&a.nodeType===1){d=b.split(s);for(;g=0}})});var V=/^(?:textarea|input|select)$/i,W=/^([^\.]*|)(?:\.(.+)|)$/,X=/(?:^|\s)hover(\.\S+|)\b/,Y=/^key/,Z=/^(?:mouse|contextmenu)|click/,$=/^(?:focusinfocus|focusoutblur)$/,_=function(a){return p.event.special.hover?a:a.replace(X,"mouseenter$1 mouseleave$1")};p.event={add:function(a,c,d,e,f){var g,h,i,j,k,l,m,n,o,q,r;if(a.nodeType===3||a.nodeType===8||!c||!d||!(g=p._data(a)))return;d.handler&&(o=d,d=o.handler,f=o.selector),d.guid||(d.guid=p.guid++),i=g.events,i||(g.events=i={}),h=g.handle,h||(g.handle=h=function(a){return typeof p!="undefined"&&(!a||p.event.triggered!==a.type)?p.event.dispatch.apply(h.elem,arguments):b},h.elem=a),c=p.trim(_(c)).split(" ");for(j=0;j=0&&(s=s.slice(0,-1),i=!0),s.indexOf(".")>=0&&(t=s.split("."),s=t.shift(),t.sort());if((!f||p.event.customEvent[s])&&!p.event.global[s])return;c=typeof c=="object"?c[p.expando]?c:new p.Event(s,c):new p.Event(s),c.type=s,c.isTrigger=!0,c.exclusive=i,c.namespace=t.join("."),c.namespace_re=c.namespace?new RegExp("(^|\\.)"+t.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,m=s.indexOf(":")<0?"on"+s:"";if(!f){h=p.cache;for(j in h)h[j].events&&h[j].events[s]&&p.event.trigger(c,d,h[j].handle.elem,!0);return}c.result=b,c.target||(c.target=f),d=d!=null?p.makeArray(d):[],d.unshift(c),n=p.event.special[s]||{};if(n.trigger&&n.trigger.apply(f,d)===!1)return;q=[[f,n.bindType||s]];if(!g&&!n.noBubble&&!p.isWindow(f)){r=n.delegateType||s,k=$.test(r+s)?f:f.parentNode;for(l=f;k;k=k.parentNode)q.push([k,r]),l=k;l===(f.ownerDocument||e)&&q.push([l.defaultView||l.parentWindow||a,r])}for(j=0;j=0:p.find(m,this,null,[f]).length),h[m]&&j.push(l);j.length&&u.push({elem:f,matches:j})}o.length>q&&u.push({elem:this,matches:o.slice(q)});for(d=0;d0?this.on(b,null,a,c):this.trigger(b)},Y.test(b)&&(p.event.fixHooks[b]=p.event.keyHooks),Z.test(b)&&(p.event.fixHooks[b]=p.event.mouseHooks)}),function(a,b){function bc(a,b,c,d){c=c||[],b=b||r;var e,f,i,j,k=b.nodeType;if(!a||typeof a!="string")return c;if(k!==1&&k!==9)return[];i=g(b);if(!i&&!d)if(e=P.exec(a))if(j=e[1]){if(k===9){f=b.getElementById(j);if(!f||!f.parentNode)return c;if(f.id===j)return c.push(f),c}else if(b.ownerDocument&&(f=b.ownerDocument.getElementById(j))&&h(b,f)&&f.id===j)return c.push(f),c}else{if(e[2])return w.apply(c,x.call(b.getElementsByTagName(a),0)),c;if((j=e[3])&&_&&b.getElementsByClassName)return w.apply(c,x.call(b.getElementsByClassName(j),0)),c}return bp(a.replace(L,"$1"),b,c,d,i)}function bd(a){return function(b){var c=b.nodeName.toLowerCase();return c==="input"&&b.type===a}}function be(a){return function(b){var c=b.nodeName.toLowerCase();return(c==="input"||c==="button")&&b.type===a}}function bf(a){return z(function(b){return b=+b,z(function(c,d){var e,f=a([],c.length,b),g=f.length;while(g--)c[e=f[g]]&&(c[e]=!(d[e]=c[e]))})})}function bg(a,b,c){if(a===b)return c;var d=a.nextSibling;while(d){if(d===b)return-1;d=d.nextSibling}return 1}function bh(a,b){var c,d,f,g,h,i,j,k=C[o][a];if(k)return b?0:k.slice(0);h=a,i=[],j=e.preFilter;while(h){if(!c||(d=M.exec(h)))d&&(h=h.slice(d[0].length)),i.push(f=[]);c=!1;if(d=N.exec(h))f.push(c=new q(d.shift())),h=h.slice(c.length),c.type=d[0].replace(L," ");for(g in e.filter)(d=W[g].exec(h))&&(!j[g]||(d=j[g](d,r,!0)))&&(f.push(c=new q(d.shift())),h=h.slice(c.length),c.type=g,c.matches=d);if(!c)break}return b?h.length:h?bc.error(a):C(a,i).slice(0)}function bi(a,b,d){var e=b.dir,f=d&&b.dir==="parentNode",g=u++;return b.first?function(b,c,d){while(b=b[e])if(f||b.nodeType===1)return a(b,c,d)}:function(b,d,h){if(!h){var i,j=t+" "+g+" ",k=j+c;while(b=b[e])if(f||b.nodeType===1){if((i=b[o])===k)return b.sizset;if(typeof i=="string"&&i.indexOf(j)===0){if(b.sizset)return b}else{b[o]=k;if(a(b,d,h))return b.sizset=!0,b;b.sizset=!1}}}else while(b=b[e])if(f||b.nodeType===1)if(a(b,d,h))return b}}function bj(a){return a.length>1?function(b,c,d){var e=a.length;while(e--)if(!a[e](b,c,d))return!1;return!0}:a[0]}function bk(a,b,c,d,e){var f,g=[],h=0,i=a.length,j=b!=null;for(;h-1},h,!0),m=[function(a,c,d){return!g&&(d||c!==l)||((b=c).nodeType?j(a,c,d):k(a,c,d))}];for(;i1&&bj(m),i>1&&a.slice(0,i-1).join("").replace(L,"$1"),c,i0,f=a.length>0,g=function(h,i,j,k,m){var n,o,p,q=[],s=0,u="0",x=h&&[],y=m!=null,z=l,A=h||f&&e.find.TAG("*",m&&i.parentNode||i),B=t+=z==null?1:Math.E;y&&(l=i!==r&&i,c=g.el);for(;(n=A[u])!=null;u++){if(f&&n){for(o=0;p=a[o];o++)if(p(n,i,j)){k.push(n);break}y&&(t=B,c=++g.el)}d&&((n=!p&&n)&&s--,h&&x.push(n))}s+=u;if(d&&u!==s){for(o=0;p=b[o];o++)p(x,q,i,j);if(h){if(s>0)while(u--)!x[u]&&!q[u]&&(q[u]=v.call(k));q=bk(q)}w.apply(k,q),y&&!h&&q.length>0&&s+b.length>1&&bc.uniqueSort(k)}return y&&(t=B,l=z),x};return g.el=0,d?z(g):g}function bo(a,b,c,d){var e=0,f=b.length;for(;e2&&(j=h[0]).type==="ID"&&b.nodeType===9&&!f&&e.relative[h[1].type]){b=e.find.ID(j.matches[0].replace(V,""),b,f)[0];if(!b)return c;a=a.slice(h.shift().length)}for(g=W.POS.test(a)?-1:h.length-1;g>=0;g--){j=h[g];if(e.relative[k=j.type])break;if(l=e.find[k])if(d=l(j.matches[0].replace(V,""),R.test(h[0].type)&&b.parentNode||b,f)){h.splice(g,1),a=d.length&&h.join("");if(!a)return w.apply(c,x.call(d,0)),c;break}}}return i(a,m)(d,b,f,c,R.test(a)),c}function bq(){}var c,d,e,f,g,h,i,j,k,l,m=!0,n="undefined",o=("sizcache"+Math.random()).replace(".",""),q=String,r=a.document,s=r.documentElement,t=0,u=0,v=[].pop,w=[].push,x=[].slice,y=[].indexOf||function(a){var b=0,c=this.length;for(;be.cacheLength&&delete a[b.shift()],a[c]=d},a)},B=A(),C=A(),D=A(),E="[\\x20\\t\\r\\n\\f]",F="(?:\\\\.|[-\\w]|[^\\x00-\\xa0])+",G=F.replace("w","w#"),H="([*^$|!~]?=)",I="\\["+E+"*("+F+")"+E+"*(?:"+H+E+"*(?:(['\"])((?:\\\\.|[^\\\\])*?)\\3|("+G+")|)|)"+E+"*\\]",J=":("+F+")(?:\\((?:(['\"])((?:\\\\.|[^\\\\])*?)\\2|([^()[\\]]*|(?:(?:"+I+")|[^:]|\\\\.)*|.*))\\)|)",K=":(even|odd|eq|gt|lt|nth|first|last)(?:\\("+E+"*((?:-\\d)?\\d*)"+E+"*\\)|)(?=[^-]|$)",L=new RegExp("^"+E+"+|((?:^|[^\\\\])(?:\\\\.)*)"+E+"+$","g"),M=new RegExp("^"+E+"*,"+E+"*"),N=new RegExp("^"+E+"*([\\x20\\t\\r\\n\\f>+~])"+E+"*"),O=new RegExp(J),P=/^(?:#([\w\-]+)|(\w+)|\.([\w\-]+))$/,Q=/^:not/,R=/[\x20\t\r\n\f]*[+~]/,S=/:not\($/,T=/h\d/i,U=/input|select|textarea|button/i,V=/\\(?!\\)/g,W={ID:new RegExp("^#("+F+")"),CLASS:new RegExp("^\\.("+F+")"),NAME:new RegExp("^\\[name=['\"]?("+F+")['\"]?\\]"),TAG:new RegExp("^("+F.replace("w","w*")+")"),ATTR:new RegExp("^"+I),PSEUDO:new RegExp("^"+J),POS:new RegExp(K,"i"),CHILD:new RegExp("^:(only|nth|first|last)-child(?:\\("+E+"*(even|odd|(([+-]|)(\\d*)n|)"+E+"*(?:([+-]|)"+E+"*(\\d+)|))"+E+"*\\)|)","i"),needsContext:new RegExp("^"+E+"*[>+~]|"+K,"i")},X=function(a){var b=r.createElement("div");try{return a(b)}catch(c){return!1}finally{b=null}},Y=X(function(a){return a.appendChild(r.createComment("")),!a.getElementsByTagName("*").length}),Z=X(function(a){return a.innerHTML="",a.firstChild&&typeof a.firstChild.getAttribute!==n&&a.firstChild.getAttribute("href")==="#"}),$=X(function(a){a.innerHTML="";var b=typeof a.lastChild.getAttribute("multiple");return b!=="boolean"&&b!=="string"}),_=X(function(a){return a.innerHTML="",!a.getElementsByClassName||!a.getElementsByClassName("e").length?!1:(a.lastChild.className="e",a.getElementsByClassName("e").length===2)}),ba=X(function(a){a.id=o+0,a.innerHTML="
",s.insertBefore(a,s.firstChild);var b=r.getElementsByName&&r.getElementsByName(o).length===2+r.getElementsByName(o+0).length;return d=!r.getElementById(o),s.removeChild(a),b});try{x.call(s.childNodes,0)[0].nodeType}catch(bb){x=function(a){var b,c=[];for(;b=this[a];a++)c.push(b);return c}}bc.matches=function(a,b){return bc(a,null,null,b)},bc.matchesSelector=function(a,b){return bc(b,null,null,[a]).length>0},f=bc.getText=function(a){var b,c="",d=0,e=a.nodeType;if(e){if(e===1||e===9||e===11){if(typeof a.textContent=="string")return a.textContent;for(a=a.firstChild;a;a=a.nextSibling)c+=f(a)}else if(e===3||e===4)return a.nodeValue}else for(;b=a[d];d++)c+=f(b);return c},g=bc.isXML=function(a){var b=a&&(a.ownerDocument||a).documentElement;return b?b.nodeName!=="HTML":!1},h=bc.contains=s.contains?function(a,b){var c=a.nodeType===9?a.documentElement:a,d=b&&b.parentNode;return a===d||!!(d&&d.nodeType===1&&c.contains&&c.contains(d))}:s.compareDocumentPosition?function(a,b){return b&&!!(a.compareDocumentPosition(b)&16)}:function(a,b){while(b=b.parentNode)if(b===a)return!0;return!1},bc.attr=function(a,b){var c,d=g(a);return d||(b=b.toLowerCase()),(c=e.attrHandle[b])?c(a):d||$?a.getAttribute(b):(c=a.getAttributeNode(b),c?typeof a[b]=="boolean"?a[b]?b:null:c.specified?c.value:null:null)},e=bc.selectors={cacheLength:50,createPseudo:z,match:W,attrHandle:Z?{}:{href:function(a){return a.getAttribute("href",2)},type:function(a){return a.getAttribute("type")}},find:{ID:d?function(a,b,c){if(typeof b.getElementById!==n&&!c){var d=b.getElementById(a);return d&&d.parentNode?[d]:[]}}:function(a,c,d){if(typeof c.getElementById!==n&&!d){var e=c.getElementById(a);return e?e.id===a||typeof e.getAttributeNode!==n&&e.getAttributeNode("id").value===a?[e]:b:[]}},TAG:Y?function(a,b){if(typeof b.getElementsByTagName!==n)return b.getElementsByTagName(a)}:function(a,b){var c=b.getElementsByTagName(a);if(a==="*"){var d,e=[],f=0;for(;d=c[f];f++)d.nodeType===1&&e.push(d);return e}return c},NAME:ba&&function(a,b){if(typeof b.getElementsByName!==n)return b.getElementsByName(name)},CLASS:_&&function(a,b,c){if(typeof b.getElementsByClassName!==n&&!c)return b.getElementsByClassName(a)}},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(a){return a[1]=a[1].replace(V,""),a[3]=(a[4]||a[5]||"").replace(V,""),a[2]==="~="&&(a[3]=" "+a[3]+" "),a.slice(0,4)},CHILD:function(a){return a[1]=a[1].toLowerCase(),a[1]==="nth"?(a[2]||bc.error(a[0]),a[3]=+(a[3]?a[4]+(a[5]||1):2*(a[2]==="even"||a[2]==="odd")),a[4]=+(a[6]+a[7]||a[2]==="odd")):a[2]&&bc.error(a[0]),a},PSEUDO:function(a){var b,c;if(W.CHILD.test(a[0]))return null;if(a[3])a[2]=a[3];else if(b=a[4])O.test(b)&&(c=bh(b,!0))&&(c=b.indexOf(")",b.length-c)-b.length)&&(b=b.slice(0,c),a[0]=a[0].slice(0,c)),a[2]=b;return a.slice(0,3)}},filter:{ID:d?function(a){return a=a.replace(V,""),function(b){return b.getAttribute("id")===a}}:function(a){return a=a.replace(V,""),function(b){var c=typeof b.getAttributeNode!==n&&b.getAttributeNode("id");return c&&c.value===a}},TAG:function(a){return a==="*"?function(){return!0}:(a=a.replace(V,"").toLowerCase(),function(b){return b.nodeName&&b.nodeName.toLowerCase()===a})},CLASS:function(a){var b=B[o][a];return b||(b=B(a,new RegExp("(^|"+E+")"+a+"("+E+"|$)"))),function(a){return b.test(a.className||typeof a.getAttribute!==n&&a.getAttribute("class")||"")}},ATTR:function(a,b,c){return function(d,e){var f=bc.attr(d,a);return f==null?b==="!=":b?(f+="",b==="="?f===c:b==="!="?f!==c:b==="^="?c&&f.indexOf(c)===0:b==="*="?c&&f.indexOf(c)>-1:b==="$="?c&&f.substr(f.length-c.length)===c:b==="~="?(" "+f+" ").indexOf(c)>-1:b==="|="?f===c||f.substr(0,c.length+1)===c+"-":!1):!0}},CHILD:function(a,b,c,d){return a==="nth"?function(a){var b,e,f=a.parentNode;if(c===1&&d===0)return!0;if(f){e=0;for(b=f.firstChild;b;b=b.nextSibling)if(b.nodeType===1){e++;if(a===b)break}}return e-=d,e===c||e%c===0&&e/c>=0}:function(b){var c=b;switch(a){case"only":case"first":while(c=c.previousSibling)if(c.nodeType===1)return!1;if(a==="first")return!0;c=b;case"last":while(c=c.nextSibling)if(c.nodeType===1)return!1;return!0}}},PSEUDO:function(a,b){var c,d=e.pseudos[a]||e.setFilters[a.toLowerCase()]||bc.error("unsupported pseudo: "+a);return d[o]?d(b):d.length>1?(c=[a,a,"",b],e.setFilters.hasOwnProperty(a.toLowerCase())?z(function(a,c){var e,f=d(a,b),g=f.length;while(g--)e=y.call(a,f[g]),a[e]=!(c[e]=f[g])}):function(a){return d(a,0,c)}):d}},pseudos:{not:z(function(a){var b=[],c=[],d=i(a.replace(L,"$1"));return d[o]?z(function(a,b,c,e){var f,g=d(a,null,e,[]),h=a.length;while(h--)if(f=g[h])a[h]=!(b[h]=f)}):function(a,e,f){return b[0]=a,d(b,null,f,c),!c.pop()}}),has:z(function(a){return function(b){return bc(a,b).length>0}}),contains:z(function(a){return function(b){return(b.textContent||b.innerText||f(b)).indexOf(a)>-1}}),enabled:function(a){return a.disabled===!1},disabled:function(a){return a.disabled===!0},checked:function(a){var b=a.nodeName.toLowerCase();return b==="input"&&!!a.checked||b==="option"&&!!a.selected},selected:function(a){return a.parentNode&&a.parentNode.selectedIndex,a.selected===!0},parent:function(a){return!e.pseudos.empty(a)},empty:function(a){var b;a=a.firstChild;while(a){if(a.nodeName>"@"||(b=a.nodeType)===3||b===4)return!1;a=a.nextSibling}return!0},header:function(a){return T.test(a.nodeName)},text:function(a){var b,c;return a.nodeName.toLowerCase()==="input"&&(b=a.type)==="text"&&((c=a.getAttribute("type"))==null||c.toLowerCase()===b)},radio:bd("radio"),checkbox:bd("checkbox"),file:bd("file"),password:bd("password"),image:bd("image"),submit:be("submit"),reset:be("reset"),button:function(a){var b=a.nodeName.toLowerCase();return b==="input"&&a.type==="button"||b==="button"},input:function(a){return U.test(a.nodeName)},focus:function(a){var b=a.ownerDocument;return a===b.activeElement&&(!b.hasFocus||b.hasFocus())&&(!!a.type||!!a.href)},active:function(a){return a===a.ownerDocument.activeElement},first:bf(function(a,b,c){return[0]}),last:bf(function(a,b,c){return[b-1]}),eq:bf(function(a,b,c){return[c<0?c+b:c]}),even:bf(function(a,b,c){for(var d=0;d=0;)a.push(d);return a}),gt:bf(function(a,b,c){for(var d=c<0?c+b:c;++d",a.querySelectorAll("[selected]").length||e.push("\\["+E+"*(?:checked|disabled|ismap|multiple|readonly|selected|value)"),a.querySelectorAll(":checked").length||e.push(":checked")}),X(function(a){a.innerHTML="

",a.querySelectorAll("[test^='']").length&&e.push("[*^$]="+E+"*(?:\"\"|'')"),a.innerHTML="",a.querySelectorAll(":enabled").length||e.push(":enabled",":disabled")}),e=new RegExp(e.join("|")),bp=function(a,d,f,g,h){if(!g&&!h&&(!e||!e.test(a))){var i,j,k=!0,l=o,m=d,n=d.nodeType===9&&a;if(d.nodeType===1&&d.nodeName.toLowerCase()!=="object"){i=bh(a),(k=d.getAttribute("id"))?l=k.replace(c,"\\$&"):d.setAttribute("id",l),l="[id='"+l+"'] ",j=i.length;while(j--)i[j]=l+i[j].join("");m=R.test(a)&&d.parentNode||d,n=i.join(",")}if(n)try{return w.apply(f,x.call(m.querySelectorAll(n),0)),f}catch(p){}finally{k||d.removeAttribute("id")}}return b(a,d,f,g,h)},h&&(X(function(b){a=h.call(b,"div");try{h.call(b,"[test!='']:sizzle"),f.push("!=",J)}catch(c){}}),f=new RegExp(f.join("|")),bc.matchesSelector=function(b,c){c=c.replace(d,"='$1']");if(!g(b)&&!f.test(c)&&(!e||!e.test(c)))try{var i=h.call(b,c);if(i||a||b.document&&b.document.nodeType!==11)return i}catch(j){}return bc(c,null,null,[b]).length>0})}(),e.pseudos.nth=e.pseudos.eq,e.filters=bq.prototype=e.pseudos,e.setFilters=new bq,bc.attr=p.attr,p.find=bc,p.expr=bc.selectors,p.expr[":"]=p.expr.pseudos,p.unique=bc.uniqueSort,p.text=bc.getText,p.isXMLDoc=bc.isXML,p.contains=bc.contains}(a);var bc=/Until$/,bd=/^(?:parents|prev(?:Until|All))/,be=/^.[^:#\[\.,]*$/,bf=p.expr.match.needsContext,bg={children:!0,contents:!0,next:!0,prev:!0};p.fn.extend({find:function(a){var b,c,d,e,f,g,h=this;if(typeof a!="string")return p(a).filter(function(){for(b=0,c=h.length;b0)for(e=d;e=0:p.filter(a,this).length>0:this.filter(a).length>0)},closest:function(a,b){var c,d=0,e=this.length,f=[],g=bf.test(a)||typeof a!="string"?p(a,b||this.context):0;for(;d-1:p.find.matchesSelector(c,a)){f.push(c);break}c=c.parentNode}}return f=f.length>1?p.unique(f):f,this.pushStack(f,"closest",a)},index:function(a){return a?typeof a=="string"?p.inArray(this[0],p(a)):p.inArray(a.jquery?a[0]:a,this):this[0]&&this[0].parentNode?this.prevAll().length:-1},add:function(a,b){var c=typeof a=="string"?p(a,b):p.makeArray(a&&a.nodeType?[a]:a),d=p.merge(this.get(),c);return this.pushStack(bh(c[0])||bh(d[0])?d:p.unique(d))},addBack:function(a){return this.add(a==null?this.prevObject:this.prevObject.filter(a))}}),p.fn.andSelf=p.fn.addBack,p.each({parent:function(a){var b=a.parentNode;return b&&b.nodeType!==11?b:null},parents:function(a){return p.dir(a,"parentNode")},parentsUntil:function(a,b,c){return p.dir(a,"parentNode",c)},next:function(a){return bi(a,"nextSibling")},prev:function(a){return bi(a,"previousSibling")},nextAll:function(a){return p.dir(a,"nextSibling")},prevAll:function(a){return p.dir(a,"previousSibling")},nextUntil:function(a,b,c){return p.dir(a,"nextSibling",c)},prevUntil:function(a,b,c){return p.dir(a,"previousSibling",c)},siblings:function(a){return p.sibling((a.parentNode||{}).firstChild,a)},children:function(a){return p.sibling(a.firstChild)},contents:function(a){return p.nodeName(a,"iframe")?a.contentDocument||a.contentWindow.document:p.merge([],a.childNodes)}},function(a,b){p.fn[a]=function(c,d){var e=p.map(this,b,c);return bc.test(a)||(d=c),d&&typeof d=="string"&&(e=p.filter(d,e)),e=this.length>1&&!bg[a]?p.unique(e):e,this.length>1&&bd.test(a)&&(e=e.reverse()),this.pushStack(e,a,k.call(arguments).join(","))}}),p.extend({filter:function(a,b,c){return c&&(a=":not("+a+")"),b.length===1?p.find.matchesSelector(b[0],a)?[b[0]]:[]:p.find.matches(a,b)},dir:function(a,c,d){var e=[],f=a[c];while(f&&f.nodeType!==9&&(d===b||f.nodeType!==1||!p(f).is(d)))f.nodeType===1&&e.push(f),f=f[c];return e},sibling:function(a,b){var c=[];for(;a;a=a.nextSibling)a.nodeType===1&&a!==b&&c.push(a);return c}});var bl="abbr|article|aside|audio|bdi|canvas|data|datalist|details|figcaption|figure|footer|header|hgroup|mark|meter|nav|output|progress|section|summary|time|video",bm=/ jQuery\d+="(?:null|\d+)"/g,bn=/^\s+/,bo=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi,bp=/<([\w:]+)/,bq=/
","
"],tr:[2,"","
"],td:[3,"","
"],col:[2,"","
"],area:[1,"",""],_default:[0,"",""]},bA=bk(e),bB=bA.appendChild(e.createElement("div"));bz.optgroup=bz.option,bz.tbody=bz.tfoot=bz.colgroup=bz.caption=bz.thead,bz.th=bz.td,p.support.htmlSerialize||(bz._default=[1,"X
","
"]),p.fn.extend({text:function(a){return p.access(this,function(a){return a===b?p.text(this):this.empty().append((this[0]&&this[0].ownerDocument||e).createTextNode(a))},null,a,arguments.length)},wrapAll:function(a){if(p.isFunction(a))return this.each(function(b){p(this).wrapAll(a.call(this,b))});if(this[0]){var b=p(a,this[0].ownerDocument).eq(0).clone(!0);this[0].parentNode&&b.insertBefore(this[0]),b.map(function(){var a=this;while(a.firstChild&&a.firstChild.nodeType===1)a=a.firstChild;return a}).append(this)}return this},wrapInner:function(a){return p.isFunction(a)?this.each(function(b){p(this).wrapInner(a.call(this,b))}):this.each(function(){var b=p(this),c=b.contents();c.length?c.wrapAll(a):b.append(a)})},wrap:function(a){var b=p.isFunction(a);return this.each(function(c){p(this).wrapAll(b?a.call(this,c):a)})},unwrap:function(){return this.parent().each(function(){p.nodeName(this,"body")||p(this).replaceWith(this.childNodes)}).end()},append:function(){return this.domManip(arguments,!0,function(a){(this.nodeType===1||this.nodeType===11)&&this.appendChild(a)})},prepend:function(){return this.domManip(arguments,!0,function(a){(this.nodeType===1||this.nodeType===11)&&this.insertBefore(a,this.firstChild)})},before:function(){if(!bh(this[0]))return this.domManip(arguments,!1,function(a){this.parentNode.insertBefore(a,this)});if(arguments.length){var a=p.clean(arguments);return this.pushStack(p.merge(a,this),"before",this.selector)}},after:function(){if(!bh(this[0]))return this.domManip(arguments,!1,function(a){this.parentNode.insertBefore(a,this.nextSibling)});if(arguments.length){var a=p.clean(arguments);return this.pushStack(p.merge(this,a),"after",this.selector)}},remove:function(a,b){var c,d=0;for(;(c=this[d])!=null;d++)if(!a||p.filter(a,[c]).length)!b&&c.nodeType===1&&(p.cleanData(c.getElementsByTagName("*")),p.cleanData([c])),c.parentNode&&c.parentNode.removeChild(c);return this},empty:function(){var a,b=0;for(;(a=this[b])!=null;b++){a.nodeType===1&&p.cleanData(a.getElementsByTagName("*"));while(a.firstChild)a.removeChild(a.firstChild)}return this},clone:function(a,b){return a=a==null?!1:a,b=b==null?a:b,this.map(function(){return p.clone(this,a,b)})},html:function(a){return p.access(this,function(a){var c=this[0]||{},d=0,e=this.length;if(a===b)return c.nodeType===1?c.innerHTML.replace(bm,""):b;if(typeof a=="string"&&!bs.test(a)&&(p.support.htmlSerialize||!bu.test(a))&&(p.support.leadingWhitespace||!bn.test(a))&&!bz[(bp.exec(a)||["",""])[1].toLowerCase()]){a=a.replace(bo,"<$1>");try{for(;d1&&typeof j=="string"&&bw.test(j))return this.each(function(){p(this).domManip(a,c,d)});if(p.isFunction(j))return this.each(function(e){var f=p(this);a[0]=j.call(this,e,c?f.html():b),f.domManip(a,c,d)});if(this[0]){e=p.buildFragment(a,this,k),g=e.fragment,f=g.firstChild,g.childNodes.length===1&&(g=f);if(f){c=c&&p.nodeName(f,"tr");for(h=e.cacheable||l-1;i0?this.clone(!0):this).get(),p(g[e])[b](d),f=f.concat(d);return this.pushStack(f,a,g.selector)}}),p.extend({clone:function(a,b,c){var d,e,f,g;p.support.html5Clone||p.isXMLDoc(a)||!bu.test("<"+a.nodeName+">")?g=a.cloneNode(!0):(bB.innerHTML=a.outerHTML,bB.removeChild(g=bB.firstChild));if((!p.support.noCloneEvent||!p.support.noCloneChecked)&&(a.nodeType===1||a.nodeType===11)&&!p.isXMLDoc(a)){bE(a,g),d=bF(a),e=bF(g);for(f=0;d[f];++f)e[f]&&bE(d[f],e[f])}if(b){bD(a,g);if(c){d=bF(a),e=bF(g);for(f=0;d[f];++f)bD(d[f],e[f])}}return d=e=null,g},clean:function(a,b,c,d){var f,g,h,i,j,k,l,m,n,o,q,r,s=b===e&&bA,t=[];if(!b||typeof b.createDocumentFragment=="undefined")b=e;for(f=0;(h=a[f])!=null;f++){typeof h=="number"&&(h+="");if(!h)continue;if(typeof h=="string")if(!br.test(h))h=b.createTextNode(h);else{s=s||bk(b),l=b.createElement("div"),s.appendChild(l),h=h.replace(bo,"<$1>"),i=(bp.exec(h)||["",""])[1].toLowerCase(),j=bz[i]||bz._default,k=j[0],l.innerHTML=j[1]+h+j[2];while(k--)l=l.lastChild;if(!p.support.tbody){m=bq.test(h),n=i==="table"&&!m?l.firstChild&&l.firstChild.childNodes:j[1]===""&&!m?l.childNodes:[];for(g=n.length-1;g>=0;--g)p.nodeName(n[g],"tbody")&&!n[g].childNodes.length&&n[g].parentNode.removeChild(n[g])}!p.support.leadingWhitespace&&bn.test(h)&&l.insertBefore(b.createTextNode(bn.exec(h)[0]),l.firstChild),h=l.childNodes,l.parentNode.removeChild(l)}h.nodeType?t.push(h):p.merge(t,h)}l&&(h=l=s=null);if(!p.support.appendChecked)for(f=0;(h=t[f])!=null;f++)p.nodeName(h,"input")?bG(h):typeof h.getElementsByTagName!="undefined"&&p.grep(h.getElementsByTagName("input"),bG);if(c){q=function(a){if(!a.type||bx.test(a.type))return d?d.push(a.parentNode?a.parentNode.removeChild(a):a):c.appendChild(a)};for(f=0;(h=t[f])!=null;f++)if(!p.nodeName(h,"script")||!q(h))c.appendChild(h),typeof h.getElementsByTagName!="undefined"&&(r=p.grep(p.merge([],h.getElementsByTagName("script")),q),t.splice.apply(t,[f+1,0].concat(r)),f+=r.length)}return t},cleanData:function(a,b){var c,d,e,f,g=0,h=p.expando,i=p.cache,j=p.support.deleteExpando,k=p.event.special;for(;(e=a[g])!=null;g++)if(b||p.acceptData(e)){d=e[h],c=d&&i[d];if(c){if(c.events)for(f in c.events)k[f]?p.event.remove(e,f):p.removeEvent(e,f,c.handle);i[d]&&(delete i[d],j?delete e[h]:e.removeAttribute?e.removeAttribute(h):e[h]=null,p.deletedIds.push(d))}}}}),function(){var a,b;p.uaMatch=function(a){a=a.toLowerCase();var b=/(chrome)[ \/]([\w.]+)/.exec(a)||/(webkit)[ \/]([\w.]+)/.exec(a)||/(opera)(?:.*version|)[ \/]([\w.]+)/.exec(a)||/(msie) ([\w.]+)/.exec(a)||a.indexOf("compatible")<0&&/(mozilla)(?:.*? rv:([\w.]+)|)/.exec(a)||[];return{browser:b[1]||"",version:b[2]||"0"}},a=p.uaMatch(g.userAgent),b={},a.browser&&(b[a.browser]=!0,b.version=a.version),b.chrome?b.webkit=!0:b.webkit&&(b.safari=!0),p.browser=b,p.sub=function(){function a(b,c){return new a.fn.init(b,c)}p.extend(!0,a,this),a.superclass=this,a.fn=a.prototype=this(),a.fn.constructor=a,a.sub=this.sub,a.fn.init=function c(c,d){return d&&d instanceof p&&!(d instanceof a)&&(d=a(d)),p.fn.init.call(this,c,d,b)},a.fn.init.prototype=a.fn;var b=a(e);return a}}();var bH,bI,bJ,bK=/alpha\([^)]*\)/i,bL=/opacity=([^)]*)/,bM=/^(top|right|bottom|left)$/,bN=/^(none|table(?!-c[ea]).+)/,bO=/^margin/,bP=new RegExp("^("+q+")(.*)$","i"),bQ=new RegExp("^("+q+")(?!px)[a-z%]+$","i"),bR=new RegExp("^([-+])=("+q+")","i"),bS={},bT={position:"absolute",visibility:"hidden",display:"block"},bU={letterSpacing:0,fontWeight:400},bV=["Top","Right","Bottom","Left"],bW=["Webkit","O","Moz","ms"],bX=p.fn.toggle;p.fn.extend({css:function(a,c){return p.access(this,function(a,c,d){return d!==b?p.style(a,c,d):p.css(a,c)},a,c,arguments.length>1)},show:function(){return b$(this,!0)},hide:function(){return b$(this)},toggle:function(a,b){var c=typeof a=="boolean";return p.isFunction(a)&&p.isFunction(b)?bX.apply(this,arguments):this.each(function(){(c?a:bZ(this))?p(this).show():p(this).hide()})}}),p.extend({cssHooks:{opacity:{get:function(a,b){if(b){var c=bH(a,"opacity");return c===""?"1":c}}}},cssNumber:{fillOpacity:!0,fontWeight:!0,lineHeight:!0,opacity:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{"float":p.support.cssFloat?"cssFloat":"styleFloat"},style:function(a,c,d,e){if(!a||a.nodeType===3||a.nodeType===8||!a.style)return;var f,g,h,i=p.camelCase(c),j=a.style;c=p.cssProps[i]||(p.cssProps[i]=bY(j,i)),h=p.cssHooks[c]||p.cssHooks[i];if(d===b)return h&&"get"in h&&(f=h.get(a,!1,e))!==b?f:j[c];g=typeof d,g==="string"&&(f=bR.exec(d))&&(d=(f[1]+1)*f[2]+parseFloat(p.css(a,c)),g="number");if(d==null||g==="number"&&isNaN(d))return;g==="number"&&!p.cssNumber[i]&&(d+="px");if(!h||!("set"in h)||(d=h.set(a,d,e))!==b)try{j[c]=d}catch(k){}},css:function(a,c,d,e){var f,g,h,i=p.camelCase(c);return c=p.cssProps[i]||(p.cssProps[i]=bY(a.style,i)),h=p.cssHooks[c]||p.cssHooks[i],h&&"get"in h&&(f=h.get(a,!0,e)),f===b&&(f=bH(a,c)),f==="normal"&&c in bU&&(f=bU[c]),d||e!==b?(g=parseFloat(f),d||p.isNumeric(g)?g||0:f):f},swap:function(a,b,c){var d,e,f={};for(e in b)f[e]=a.style[e],a.style[e]=b[e];d=c.call(a);for(e in b)a.style[e]=f[e];return d}}),a.getComputedStyle?bH=function(b,c){var d,e,f,g,h=a.getComputedStyle(b,null),i=b.style;return h&&(d=h[c],d===""&&!p.contains(b.ownerDocument,b)&&(d=p.style(b,c)),bQ.test(d)&&bO.test(c)&&(e=i.width,f=i.minWidth,g=i.maxWidth,i.minWidth=i.maxWidth=i.width=d,d=h.width,i.width=e,i.minWidth=f,i.maxWidth=g)),d}:e.documentElement.currentStyle&&(bH=function(a,b){var c,d,e=a.currentStyle&&a.currentStyle[b],f=a.style;return e==null&&f&&f[b]&&(e=f[b]),bQ.test(e)&&!bM.test(b)&&(c=f.left,d=a.runtimeStyle&&a.runtimeStyle.left,d&&(a.runtimeStyle.left=a.currentStyle.left),f.left=b==="fontSize"?"1em":e,e=f.pixelLeft+"px",f.left=c,d&&(a.runtimeStyle.left=d)),e===""?"auto":e}),p.each(["height","width"],function(a,b){p.cssHooks[b]={get:function(a,c,d){if(c)return a.offsetWidth===0&&bN.test(bH(a,"display"))?p.swap(a,bT,function(){return cb(a,b,d)}):cb(a,b,d)},set:function(a,c,d){return b_(a,c,d?ca(a,b,d,p.support.boxSizing&&p.css(a,"boxSizing")==="border-box"):0)}}}),p.support.opacity||(p.cssHooks.opacity={get:function(a,b){return bL.test((b&&a.currentStyle?a.currentStyle.filter:a.style.filter)||"")?.01*parseFloat(RegExp.$1)+"":b?"1":""},set:function(a,b){var c=a.style,d=a.currentStyle,e=p.isNumeric(b)?"alpha(opacity="+b*100+")":"",f=d&&d.filter||c.filter||"";c.zoom=1;if(b>=1&&p.trim(f.replace(bK,""))===""&&c.removeAttribute){c.removeAttribute("filter");if(d&&!d.filter)return}c.filter=bK.test(f)?f.replace(bK,e):f+" "+e}}),p(function(){p.support.reliableMarginRight||(p.cssHooks.marginRight={get:function(a,b){return p.swap(a,{display:"inline-block"},function(){if(b)return bH(a,"marginRight")})}}),!p.support.pixelPosition&&p.fn.position&&p.each(["top","left"],function(a,b){p.cssHooks[b]={get:function(a,c){if(c){var d=bH(a,b);return bQ.test(d)?p(a).position()[b]+"px":d}}}})}),p.expr&&p.expr.filters&&(p.expr.filters.hidden=function(a){return a.offsetWidth===0&&a.offsetHeight===0||!p.support.reliableHiddenOffsets&&(a.style&&a.style.display||bH(a,"display"))==="none"},p.expr.filters.visible=function(a){return!p.expr.filters.hidden(a)}),p.each({margin:"",padding:"",border:"Width"},function(a,b){p.cssHooks[a+b]={expand:function(c){var d,e=typeof c=="string"?c.split(" "):[c],f={};for(d=0;d<4;d++)f[a+bV[d]+b]=e[d]||e[d-2]||e[0];return f}},bO.test(a)||(p.cssHooks[a+b].set=b_)});var cd=/%20/g,ce=/\[\]$/,cf=/\r?\n/g,cg=/^(?:color|date|datetime|datetime-local|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i,ch=/^(?:select|textarea)/i;p.fn.extend({serialize:function(){return p.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?p.makeArray(this.elements):this}).filter(function(){return this.name&&!this.disabled&&(this.checked||ch.test(this.nodeName)||cg.test(this.type))}).map(function(a,b){var c=p(this).val();return c==null?null:p.isArray(c)?p.map(c,function(a,c){return{name:b.name,value:a.replace(cf,"\r\n")}}):{name:b.name,value:c.replace(cf,"\r\n")}}).get()}}),p.param=function(a,c){var d,e=[],f=function(a,b){b=p.isFunction(b)?b():b==null?"":b,e[e.length]=encodeURIComponent(a)+"="+encodeURIComponent(b)};c===b&&(c=p.ajaxSettings&&p.ajaxSettings.traditional);if(p.isArray(a)||a.jquery&&!p.isPlainObject(a))p.each(a,function(){f(this.name,this.value)});else for(d in a)ci(d,a[d],c,f);return e.join("&").replace(cd,"+")};var cj,ck,cl=/#.*$/,cm=/^(.*?):[ \t]*([^\r\n]*)\r?$/mg,cn=/^(?:about|app|app\-storage|.+\-extension|file|res|widget):$/,co=/^(?:GET|HEAD)$/,cp=/^\/\//,cq=/\?/,cr=/)<[^<]*)*<\/script>/gi,cs=/([?&])_=[^&]*/,ct=/^([\w\+\.\-]+:)(?:\/\/([^\/?#:]*)(?::(\d+)|)|)/,cu=p.fn.load,cv={},cw={},cx=["*/"]+["*"];try{ck=f.href}catch(cy){ck=e.createElement("a"),ck.href="",ck=ck.href}cj=ct.exec(ck.toLowerCase())||[],p.fn.load=function(a,c,d){if(typeof a!="string"&&cu)return cu.apply(this,arguments);if(!this.length)return this;var e,f,g,h=this,i=a.indexOf(" ");return i>=0&&(e=a.slice(i,a.length),a=a.slice(0,i)),p.isFunction(c)?(d=c,c=b):c&&typeof c=="object"&&(f="POST"),p.ajax({url:a,type:f,dataType:"html",data:c,complete:function(a,b){d&&h.each(d,g||[a.responseText,b,a])}}).done(function(a){g=arguments,h.html(e?p("
").append(a.replace(cr,"")).find(e):a)}),this},p.each("ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "),function(a,b){p.fn[b]=function(a){return this.on(b,a)}}),p.each(["get","post"],function(a,c){p[c]=function(a,d,e,f){return p.isFunction(d)&&(f=f||e,e=d,d=b),p.ajax({type:c,url:a,data:d,success:e,dataType:f})}}),p.extend({getScript:function(a,c){return p.get(a,b,c,"script")},getJSON:function(a,b,c){return p.get(a,b,c,"json")},ajaxSetup:function(a,b){return b?cB(a,p.ajaxSettings):(b=a,a=p.ajaxSettings),cB(a,b),a},ajaxSettings:{url:ck,isLocal:cn.test(cj[1]),global:!0,type:"GET",contentType:"application/x-www-form-urlencoded; charset=UTF-8",processData:!0,async:!0,accepts:{xml:"application/xml, text/xml",html:"text/html",text:"text/plain",json:"application/json, text/javascript","*":cx},contents:{xml:/xml/,html:/html/,json:/json/},responseFields:{xml:"responseXML",text:"responseText"},converters:{"* text":a.String,"text html":!0,"text json":p.parseJSON,"text xml":p.parseXML},flatOptions:{context:!0,url:!0}},ajaxPrefilter:cz(cv),ajaxTransport:cz(cw),ajax:function(a,c){function y(a,c,f,i){var k,s,t,u,w,y=c;if(v===2)return;v=2,h&&clearTimeout(h),g=b,e=i||"",x.readyState=a>0?4:0,f&&(u=cC(l,x,f));if(a>=200&&a<300||a===304)l.ifModified&&(w=x.getResponseHeader("Last-Modified"),w&&(p.lastModified[d]=w),w=x.getResponseHeader("Etag"),w&&(p.etag[d]=w)),a===304?(y="notmodified",k=!0):(k=cD(l,u),y=k.state,s=k.data,t=k.error,k=!t);else{t=y;if(!y||a)y="error",a<0&&(a=0)}x.status=a,x.statusText=(c||y)+"",k?o.resolveWith(m,[s,y,x]):o.rejectWith(m,[x,y,t]),x.statusCode(r),r=b,j&&n.trigger("ajax"+(k?"Success":"Error"),[x,l,k?s:t]),q.fireWith(m,[x,y]),j&&(n.trigger("ajaxComplete",[x,l]),--p.active||p.event.trigger("ajaxStop"))}typeof a=="object"&&(c=a,a=b),c=c||{};var d,e,f,g,h,i,j,k,l=p.ajaxSetup({},c),m=l.context||l,n=m!==l&&(m.nodeType||m instanceof p)?p(m):p.event,o=p.Deferred(),q=p.Callbacks("once memory"),r=l.statusCode||{},t={},u={},v=0,w="canceled",x={readyState:0,setRequestHeader:function(a,b){if(!v){var c=a.toLowerCase();a=u[c]=u[c]||a,t[a]=b}return this},getAllResponseHeaders:function(){return v===2?e:null},getResponseHeader:function(a){var c;if(v===2){if(!f){f={};while(c=cm.exec(e))f[c[1].toLowerCase()]=c[2]}c=f[a.toLowerCase()]}return c===b?null:c},overrideMimeType:function(a){return v||(l.mimeType=a),this},abort:function(a){return a=a||w,g&&g.abort(a),y(0,a),this}};o.promise(x),x.success=x.done,x.error=x.fail,x.complete=q.add,x.statusCode=function(a){if(a){var b;if(v<2)for(b in a)r[b]=[r[b],a[b]];else b=a[x.status],x.always(b)}return this},l.url=((a||l.url)+"").replace(cl,"").replace(cp,cj[1]+"//"),l.dataTypes=p.trim(l.dataType||"*").toLowerCase().split(s),l.crossDomain==null&&(i=ct.exec(l.url.toLowerCase())||!1,l.crossDomain=i&&i.join(":")+(i[3]?"":i[1]==="http:"?80:443)!==cj.join(":")+(cj[3]?"":cj[1]==="http:"?80:443)),l.data&&l.processData&&typeof l.data!="string"&&(l.data=p.param(l.data,l.traditional)),cA(cv,l,c,x);if(v===2)return x;j=l.global,l.type=l.type.toUpperCase(),l.hasContent=!co.test(l.type),j&&p.active++===0&&p.event.trigger("ajaxStart");if(!l.hasContent){l.data&&(l.url+=(cq.test(l.url)?"&":"?")+l.data,delete l.data),d=l.url;if(l.cache===!1){var z=p.now(),A=l.url.replace(cs,"$1_="+z);l.url=A+(A===l.url?(cq.test(l.url)?"&":"?")+"_="+z:"")}}(l.data&&l.hasContent&&l.contentType!==!1||c.contentType)&&x.setRequestHeader("Content-Type",l.contentType),l.ifModified&&(d=d||l.url,p.lastModified[d]&&x.setRequestHeader("If-Modified-Since",p.lastModified[d]),p.etag[d]&&x.setRequestHeader("If-None-Match",p.etag[d])),x.setRequestHeader("Accept",l.dataTypes[0]&&l.accepts[l.dataTypes[0]]?l.accepts[l.dataTypes[0]]+(l.dataTypes[0]!=="*"?", "+cx+"; q=0.01":""):l.accepts["*"]);for(k in l.headers)x.setRequestHeader(k,l.headers[k]);if(!l.beforeSend||l.beforeSend.call(m,x,l)!==!1&&v!==2){w="abort";for(k in{success:1,error:1,complete:1})x[k](l[k]);g=cA(cw,l,c,x);if(!g)y(-1,"No Transport");else{x.readyState=1,j&&n.trigger("ajaxSend",[x,l]),l.async&&l.timeout>0&&(h=setTimeout(function(){x.abort("timeout")},l.timeout));try{v=1,g.send(t,y)}catch(B){if(v<2)y(-1,B);else throw B}}return x}return x.abort()},active:0,lastModified:{},etag:{}});var cE=[],cF=/\?/,cG=/(=)\?(?=&|$)|\?\?/,cH=p.now();p.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var a=cE.pop()||p.expando+"_"+cH++;return this[a]=!0,a}}),p.ajaxPrefilter("json jsonp",function(c,d,e){var f,g,h,i=c.data,j=c.url,k=c.jsonp!==!1,l=k&&cG.test(j),m=k&&!l&&typeof i=="string"&&!(c.contentType||"").indexOf("application/x-www-form-urlencoded")&&cG.test(i);if(c.dataTypes[0]==="jsonp"||l||m)return f=c.jsonpCallback=p.isFunction(c.jsonpCallback)?c.jsonpCallback():c.jsonpCallback,g=a[f],l?c.url=j.replace(cG,"$1"+f):m?c.data=i.replace(cG,"$1"+f):k&&(c.url+=(cF.test(j)?"&":"?")+c.jsonp+"="+f),c.converters["script json"]=function(){return h||p.error(f+" was not called"),h[0]},c.dataTypes[0]="json",a[f]=function(){h=arguments},e.always(function(){a[f]=g,c[f]&&(c.jsonpCallback=d.jsonpCallback,cE.push(f)),h&&p.isFunction(g)&&g(h[0]),h=g=b}),"script"}),p.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/javascript|ecmascript/},converters:{"text script":function(a){return p.globalEval(a),a}}}),p.ajaxPrefilter("script",function(a){a.cache===b&&(a.cache=!1),a.crossDomain&&(a.type="GET",a.global=!1)}),p.ajaxTransport("script",function(a){if(a.crossDomain){var c,d=e.head||e.getElementsByTagName("head")[0]||e.documentElement;return{send:function(f,g){c=e.createElement("script"),c.async="async",a.scriptCharset&&(c.charset=a.scriptCharset),c.src=a.url,c.onload=c.onreadystatechange=function(a,e){if(e||!c.readyState||/loaded|complete/.test(c.readyState))c.onload=c.onreadystatechange=null,d&&c.parentNode&&d.removeChild(c),c=b,e||g(200,"success")},d.insertBefore(c,d.firstChild)},abort:function(){c&&c.onload(0,1)}}}});var cI,cJ=a.ActiveXObject?function(){for(var a in cI)cI[a](0,1)}:!1,cK=0;p.ajaxSettings.xhr=a.ActiveXObject?function(){return!this.isLocal&&cL()||cM()}:cL,function(a){p.extend(p.support,{ajax:!!a,cors:!!a&&"withCredentials"in a})}(p.ajaxSettings.xhr()),p.support.ajax&&p.ajaxTransport(function(c){if(!c.crossDomain||p.support.cors){var d;return{send:function(e,f){var g,h,i=c.xhr();c.username?i.open(c.type,c.url,c.async,c.username,c.password):i.open(c.type,c.url,c.async);if(c.xhrFields)for(h in c.xhrFields)i[h]=c.xhrFields[h];c.mimeType&&i.overrideMimeType&&i.overrideMimeType(c.mimeType),!c.crossDomain&&!e["X-Requested-With"]&&(e["X-Requested-With"]="XMLHttpRequest");try{for(h in e)i.setRequestHeader(h,e[h])}catch(j){}i.send(c.hasContent&&c.data||null),d=function(a,e){var h,j,k,l,m;try{if(d&&(e||i.readyState===4)){d=b,g&&(i.onreadystatechange=p.noop,cJ&&delete cI[g]);if(e)i.readyState!==4&&i.abort();else{h=i.status,k=i.getAllResponseHeaders(),l={},m=i.responseXML,m&&m.documentElement&&(l.xml=m);try{l.text=i.responseText}catch(a){}try{j=i.statusText}catch(n){j=""}!h&&c.isLocal&&!c.crossDomain?h=l.text?200:404:h===1223&&(h=204)}}}catch(o){e||f(-1,o)}l&&f(h,j,l,k)},c.async?i.readyState===4?setTimeout(d,0):(g=++cK,cJ&&(cI||(cI={},p(a).unload(cJ)),cI[g]=d),i.onreadystatechange=d):d()},abort:function(){d&&d(0,1)}}}});var cN,cO,cP=/^(?:toggle|show|hide)$/,cQ=new RegExp("^(?:([-+])=|)("+q+")([a-z%]*)$","i"),cR=/queueHooks$/,cS=[cY],cT={"*":[function(a,b){var c,d,e=this.createTween(a,b),f=cQ.exec(b),g=e.cur(),h=+g||0,i=1,j=20;if(f){c=+f[2],d=f[3]||(p.cssNumber[a]?"":"px");if(d!=="px"&&h){h=p.css(e.elem,a,!0)||c||1;do i=i||".5",h=h/i,p.style(e.elem,a,h+d);while(i!==(i=e.cur()/g)&&i!==1&&--j)}e.unit=d,e.start=h,e.end=f[1]?h+(f[1]+1)*c:c}return e}]};p.Animation=p.extend(cW,{tweener:function(a,b){p.isFunction(a)?(b=a,a=["*"]):a=a.split(" ");var c,d=0,e=a.length;for(;d-1,j={},k={},l,m;i?(k=e.position(),l=k.top,m=k.left):(l=parseFloat(g)||0,m=parseFloat(h)||0),p.isFunction(b)&&(b=b.call(a,c,f)),b.top!=null&&(j.top=b.top-f.top+l),b.left!=null&&(j.left=b.left-f.left+m),"using"in b?b.using.call(a,j):e.css(j)}},p.fn.extend({position:function(){if(!this[0])return;var a=this[0],b=this.offsetParent(),c=this.offset(),d=c_.test(b[0].nodeName)?{top:0,left:0}:b.offset();return c.top-=parseFloat(p.css(a,"marginTop"))||0,c.left-=parseFloat(p.css(a,"marginLeft"))||0,d.top+=parseFloat(p.css(b[0],"borderTopWidth"))||0,d.left+=parseFloat(p.css(b[0],"borderLeftWidth"))||0,{top:c.top-d.top,left:c.left-d.left}},offsetParent:function(){return this.map(function(){var a=this.offsetParent||e.body;while(a&&!c_.test(a.nodeName)&&p.css(a,"position")==="static")a=a.offsetParent;return a||e.body})}}),p.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(a,c){var d=/Y/.test(c);p.fn[a]=function(e){return p.access(this,function(a,e,f){var g=da(a);if(f===b)return g?c in g?g[c]:g.document.documentElement[e]:a[e];g?g.scrollTo(d?p(g).scrollLeft():f,d?f:p(g).scrollTop()):a[e]=f},a,e,arguments.length,null)}}),p.each({Height:"height",Width:"width"},function(a,c){p.each({padding:"inner"+a,content:c,"":"outer"+a},function(d,e){p.fn[e]=function(e,f){var g=arguments.length&&(d||typeof e!="boolean"),h=d||(e===!0||f===!0?"margin":"border");return p.access(this,function(c,d,e){var f;return p.isWindow(c)?c.document.documentElement["client"+a]:c.nodeType===9?(f=c.documentElement,Math.max(c.body["scroll"+a],f["scroll"+a],c.body["offset"+a],f["offset"+a],f["client"+a])):e===b?p.css(c,d,e,h):p.style(c,d,e,h)},c,g?e:b,g,null)}})}),a.jQuery=a.$=p,typeof define=="function"&&define.amd&&define.amd.jQuery&&define("jquery",[],function(){return p})})(window); - - // wrap for RAP - if (window.wrapJQueryForRAP) { - window.wrapJQueryForRAP($); - } - $.providedByRAP = true; - return $.noConflict(true); -}); \ No newline at end of file diff --git a/WebContent/stat/js/util/jsformat.js b/WebContent/stat/js/util/jsformat.js deleted file mode 100644 index ec6f7643d..000000000 --- a/WebContent/stat/js/util/jsformat.js +++ /dev/null @@ -1 +0,0 @@ -String.prototype.toHtml=function(){return this.replace(/\&/g,'&').replace(/\/g,'>').replace(/\x20/g,' ').replace(/(\r\n|\r|\n)/g,'
')};String.prototype.formatJS=function(){var s=this;var index=0,brch=0;var keywords=['abstract','boolean','break','byte','case','catch','char','class','const','continue','default','delete','do','double','else','extends','false','final','finally','float','for','function','goto','if','implements','import','in','instanceof','int','interface','long','native','new','null','package','private','protected','public','return','short','static','super','switch','synchronized','this','throw','throws','transient','true','try','typeof','var','void','while','with'];var objects=['Anchor','anchors','Applet','applets','Area','Array','arguments','Button','Checkbox','Date','document','FileUpload','Form','forms','Frame','frames','Function','Hidden','history','Image','images','Link','links','Area','location','Math','MimeType','mimeTypes','navigator','options','Password','Plugin','plugins','Radio','Reset','RegExp','Select','String','Submit','Text','Textarea','window'];var specials=['prototype','callee','caller','apply','call','encodeURIComponent','decodeURIComponent','parseInt','parseFloat','__defineGetter__','__defineSetter__'];var blocks=[];var indent="",indent_fix="";s=s.replace(/\t/g,' ').replace(/\r\n|\r/g,"\n").replace(/(\/\/[^\n]*(\n|$)|\/\*(\*(?!\/)|[^\*])*\*+\/|\"(\\\"|\\\\|[^\"\n])*\"|\'(\\\'|\\\\|[^\'\n])*\'|([=!\(\:\{\[\;&|^]\s*)\/(\\.|[^\/\n])+\/[igm]*)/g,function($0){var color="#CCCCCC",ret="'";var kkk=$0;if(kkk.charAt(0)=='"')color="#FF00FF";else if(kkk.charAt(0)=="'")color="#9900FF";else if(kkk.match(/^(?:[=!\(\:\{\[&|^]\s*)(\/(\\.|[^\/\n])+\/[igm]*$)/)){ret=kkk.replace(/^([=!\(\:\{\[&|^]\s*)(\/(\\.|[^\/\n])+\/[igm]*$)/,"$1'");kkk=kkk.replace(/^([=!\(\:\{\[&|^]\s*)(\/(\\.|[^\/\n])+\/[igm]*$)/,"$2");color="#6666CC"}blocks[blocks.length]=""+kkk.toHtml()+"";return ret}).replace(/(\}?[\n ]*;[\n ]*)/g,function($0,$1){return $1.replace(/[\n ]/g,'')+"\n"}).replace(/\b(else)\b/g,"$1\n").replace(/\b((case|default)[^:]*\:)/g,"$1\n").replace(/(\{[\n ]*)((([A-Za-z\$\_][0-9A-Za-z\$\_]*|`)[\n ]*\:[\n ]*[^,\}]+,?)+)([\n ]*\})/g,function($0,$1,$2,$3,$4,$5){return $1+$2.replace(/[\n ]+/g,' ').replace(/(([A-Za-z\$\_][0-9A-Za-z\$\_]*|`)\:[^,\}]+,?)/g,"$1\n")+$5}).replace(/[\n ]*(\{|\};?)[\n ]*/g,function($0,$1){if($1.charAt(0)=='}')brch--;var ss="\n";for(var i=0;i/g,'>').replace(/\x20/g,' ').replace(eval('/\\b('+keywords.join('|')+')\\b/g'),'$1').replace(eval('/\\b('+objects.join('|')+')\\b/g'),'$1').replace(eval('/\\b('+specials.join('|')+')\\b/g'),'$1').replace(/\n/g,'
').replace(/\'/g,function($0){return blocks[index++]});return s} diff --git a/WebContent/stat/qunit/qunit.css b/WebContent/stat/qunit/qunit.css deleted file mode 100644 index c28d0ffe3..000000000 --- a/WebContent/stat/qunit/qunit.css +++ /dev/null @@ -1,237 +0,0 @@ -/*! - * QUnit 1.14.1pre - * http://qunitjs.com/ - * - * Copyright 2014 jQuery Foundation and other contributors - * Released under the MIT license - * http://jquery.org/license - * - * Date: 2014-03-12T10:25Z - */ - -/** Font Family and Sizes */ - -#qunit-tests, #qunit-header, #qunit-banner, #qunit-testrunner-toolbar, #qunit-userAgent, #qunit-testresult { - font-family: "Helvetica Neue Light", "HelveticaNeue-Light", "Helvetica Neue", Calibri, Helvetica, Arial, sans-serif; -} - -#qunit-testrunner-toolbar, #qunit-userAgent, #qunit-testresult, #qunit-tests li { font-size: small; } -#qunit-tests { font-size: smaller; } - - -/** Resets */ - -#qunit-tests, #qunit-header, #qunit-banner, #qunit-userAgent, #qunit-testresult, #qunit-modulefilter { - margin: 0; - padding: 0; -} - - -/** Header */ - -#qunit-header { - padding: 0.5em 0 0.5em 1em; - - color: #8699A4; - background-color: #0D3349; - - font-size: 1.5em; - line-height: 1em; - font-weight: 400; - - border-radius: 5px 5px 0 0; -} - -#qunit-header a { - text-decoration: none; - color: #C2CCD1; -} - -#qunit-header a:hover, -#qunit-header a:focus { - color: #FFF; -} - -#qunit-testrunner-toolbar label { - display: inline-block; - padding: 0 0.5em 0 0.1em; -} - -#qunit-banner { - height: 5px; -} - -#qunit-testrunner-toolbar { - padding: 0.5em 1em 0.5em 1em; - color: #5E740B; - background-color: #EEE; - overflow: hidden; -} - -#qunit-userAgent { - padding: 0.5em 1em 0.5em 1em; - background-color: #2B81AF; - color: #FFF; - text-shadow: rgba(0, 0, 0, 0.5) 2px 2px 1px; -} - -#qunit-modulefilter-container { - float: right; -} - -/** Tests: Pass/Fail */ - -#qunit-tests { - list-style-position: inside; -} - -#qunit-tests li { - padding: 0.4em 1em 0.4em 1em; - border-bottom: 1px solid #FFF; - list-style-position: inside; -} - -#qunit-tests.hidepass li.pass, #qunit-tests.hidepass li.running { - display: none; -} - -#qunit-tests li strong { - cursor: pointer; -} - -#qunit-tests li a { - padding: 0.5em; - color: #C2CCD1; - text-decoration: none; -} -#qunit-tests li a:hover, -#qunit-tests li a:focus { - color: #000; -} - -#qunit-tests li .runtime { - float: right; - font-size: smaller; -} - -.qunit-assert-list { - margin-top: 0.5em; - padding: 0.5em; - - background-color: #FFF; - - border-radius: 5px; -} - -.qunit-collapsed { - display: none; -} - -#qunit-tests table { - border-collapse: collapse; - margin-top: 0.2em; -} - -#qunit-tests th { - text-align: right; - vertical-align: top; - padding: 0 0.5em 0 0; -} - -#qunit-tests td { - vertical-align: top; -} - -#qunit-tests pre { - margin: 0; - white-space: pre-wrap; - word-wrap: break-word; -} - -#qunit-tests del { - background-color: #E0F2BE; - color: #374E0C; - text-decoration: none; -} - -#qunit-tests ins { - background-color: #FFCACA; - color: #500; - text-decoration: none; -} - -/*** Test Counts */ - -#qunit-tests b.counts { color: #000; } -#qunit-tests b.passed { color: #5E740B; } -#qunit-tests b.failed { color: #710909; } - -#qunit-tests li li { - padding: 5px; - background-color: #FFF; - border-bottom: none; - list-style-position: inside; -} - -/*** Passing Styles */ - -#qunit-tests li li.pass { - color: #3C510C; - background-color: #FFF; - border-left: 10px solid #C6E746; -} - -#qunit-tests .pass { color: #528CE0; background-color: #D2E0E6; } -#qunit-tests .pass .test-name { color: #366097; } - -#qunit-tests .pass .test-actual, -#qunit-tests .pass .test-expected { color: #999; } - -#qunit-banner.qunit-pass { background-color: #C6E746; } - -/*** Failing Styles */ - -#qunit-tests li li.fail { - color: #710909; - background-color: #FFF; - border-left: 10px solid #EE5757; - white-space: pre; -} - -#qunit-tests > li:last-child { - border-radius: 0 0 5px 5px; -} - -#qunit-tests .fail { color: #000; background-color: #EE5757; } -#qunit-tests .fail .test-name, -#qunit-tests .fail .module-name { color: #000; } - -#qunit-tests .fail .test-actual { color: #EE5757; } -#qunit-tests .fail .test-expected { color: #008000; } - -#qunit-banner.qunit-fail { background-color: #EE5757; } - - -/** Result */ - -#qunit-testresult { - padding: 0.5em 1em 0.5em 1em; - - color: #2B81AF; - background-color: #D2E0E6; - - border-bottom: 1px solid #FFF; -} -#qunit-testresult .module-name { - font-weight: 700; -} - -/** Fixture */ - -#qunit-fixture { - position: absolute; - top: -10000px; - left: -10000px; - width: 1000px; - height: 1000px; -} \ No newline at end of file diff --git a/WebContent/stat/qunit/qunit.js b/WebContent/stat/qunit/qunit.js deleted file mode 100644 index 049b57a2d..000000000 --- a/WebContent/stat/qunit/qunit.js +++ /dev/null @@ -1,2289 +0,0 @@ -/*! - * QUnit 1.14.1pre - * http://qunitjs.com/ - * - * Copyright 2014 jQuery Foundation and other contributors - * Released under the MIT license - * http://jquery.org/license - * - * Date: 2014-03-12T10:25Z - */ - - -(function( window ) { - -var QUnit, - assert, - config, - onErrorFnPrev, - testId = 0, - fileName = (sourceFromStacktrace( 0 ) || "" ).replace(/(:\d+)+\)?/, "").replace(/.+\//, ""), - toString = Object.prototype.toString, - hasOwn = Object.prototype.hasOwnProperty, - // Keep a local reference to Date (GH-283) - Date = window.Date, - setTimeout = window.setTimeout, - clearTimeout = window.clearTimeout, - defined = { - document: typeof window.document !== "undefined", - setTimeout: typeof window.setTimeout !== "undefined", - sessionStorage: (function() { - var x = "qunit-test-string"; - try { - sessionStorage.setItem( x, x ); - sessionStorage.removeItem( x ); - return true; - } catch( e ) { - return false; - } - }()) - }, - /** - * Provides a normalized error string, correcting an issue - * with IE 7 (and prior) where Error.prototype.toString is - * not properly implemented - * - * Based on http://es5.github.com/#x15.11.4.4 - * - * @param {String|Error} error - * @return {String} error message - */ - errorString = function( error ) { - var name, message, - errorString = error.toString(); - if ( errorString.substring( 0, 7 ) === "[object" ) { - name = error.name ? error.name.toString() : "Error"; - message = error.message ? error.message.toString() : ""; - if ( name && message ) { - return name + ": " + message; - } else if ( name ) { - return name; - } else if ( message ) { - return message; - } else { - return "Error"; - } - } else { - return errorString; - } - }, - /** - * Makes a clone of an object using only Array or Object as base, - * and copies over the own enumerable properties. - * - * @param {Object} obj - * @return {Object} New object with only the own properties (recursively). - */ - objectValues = function( obj ) { - // Grunt 0.3.x uses an older version of jshint that still has jshint/jshint#392. - /*jshint newcap: false */ - var key, val, - vals = QUnit.is( "array", obj ) ? [] : {}; - for ( key in obj ) { - if ( hasOwn.call( obj, key ) ) { - val = obj[key]; - vals[key] = val === Object(val) ? objectValues(val) : val; - } - } - return vals; - }; - - -// Root QUnit object. -// `QUnit` initialized at top of scope -QUnit = { - - // call on start of module test to prepend name to all tests - module: function( name, testEnvironment ) { - config.currentModule = name; - config.currentModuleTestEnvironment = testEnvironment; - config.modules[name] = true; - }, - - asyncTest: function( testName, expected, callback ) { - if ( arguments.length === 2 ) { - callback = expected; - expected = null; - } - - QUnit.test( testName, expected, callback, true ); - }, - - test: function( testName, expected, callback, async ) { - var test, - nameHtml = "" + escapeText( testName ) + ""; - - if ( arguments.length === 2 ) { - callback = expected; - expected = null; - } - - if ( config.currentModule ) { - nameHtml = "" + escapeText( config.currentModule ) + ": " + nameHtml; - } - - test = new Test({ - nameHtml: nameHtml, - testName: testName, - expected: expected, - async: async, - callback: callback, - module: config.currentModule, - moduleTestEnvironment: config.currentModuleTestEnvironment, - stack: sourceFromStacktrace( 2 ) - }); - - if ( !validTest( test ) ) { - return; - } - - test.queue(); - }, - - // Specify the number of expected assertions to guarantee that failed test (no assertions are run at all) don't slip through. - expect: function( asserts ) { - if (arguments.length === 1) { - config.current.expected = asserts; - } else { - return config.current.expected; - } - }, - - start: function( count ) { - // QUnit hasn't been initialized yet. - // Note: RequireJS (et al) may delay onLoad - if ( config.semaphore === undefined ) { - QUnit.begin(function() { - // This is triggered at the top of QUnit.load, push start() to the event loop, to allow QUnit.load to finish first - setTimeout(function() { - QUnit.start( count ); - }); - }); - return; - } - - config.semaphore -= count || 1; - // don't start until equal number of stop-calls - if ( config.semaphore > 0 ) { - return; - } - // ignore if start is called more often then stop - if ( config.semaphore < 0 ) { - config.semaphore = 0; - QUnit.pushFailure( "Called start() while already started (QUnit.config.semaphore was 0 already)", null, sourceFromStacktrace(2) ); - return; - } - // A slight delay, to avoid any current callbacks - if ( defined.setTimeout ) { - setTimeout(function() { - if ( config.semaphore > 0 ) { - return; - } - if ( config.timeout ) { - clearTimeout( config.timeout ); - } - - config.blocking = false; - process( true ); - }, 13); - } else { - config.blocking = false; - process( true ); - } - }, - - stop: function( count ) { - config.semaphore += count || 1; - config.blocking = true; - - if ( config.testTimeout && defined.setTimeout ) { - clearTimeout( config.timeout ); - config.timeout = setTimeout(function() { - QUnit.ok( false, "Test timed out" ); - config.semaphore = 1; - QUnit.start(); - }, config.testTimeout ); - } - } -}; - -// We use the prototype to distinguish between properties that should -// be exposed as globals (and in exports) and those that shouldn't -(function() { - function F() {} - F.prototype = QUnit; - QUnit = new F(); - // Make F QUnit's constructor so that we can add to the prototype later - QUnit.constructor = F; -}()); - -/** - * Config object: Maintain internal state - * Later exposed as QUnit.config - * `config` initialized at top of scope - */ -config = { - // The queue of tests to run - queue: [], - - // block until document ready - blocking: true, - - // when enabled, show only failing tests - // gets persisted through sessionStorage and can be changed in UI via checkbox - hidepassed: false, - - // by default, run previously failed tests first - // very useful in combination with "Hide passed tests" checked - reorder: true, - - // by default, modify document.title when suite is done - altertitle: true, - - // by default, scroll to top of the page when suite is done - scrolltop: true, - - // when enabled, all tests must call expect() - requireExpects: false, - - // add checkboxes that are persisted in the query-string - // when enabled, the id is set to `true` as a `QUnit.config` property - urlConfig: [ - { - id: "noglobals", - label: "Check for Globals", - tooltip: "Enabling this will test if any test introduces new properties on the `window` object. Stored as query-strings." - }, - { - id: "notrycatch", - label: "No try-catch", - tooltip: "Enabling this will run tests outside of a try-catch block. Makes debugging exceptions in IE reasonable. Stored as query-strings." - } - ], - - // Set of all modules. - modules: {}, - - // logging callback queues - begin: [], - done: [], - log: [], - testStart: [], - testDone: [], - moduleStart: [], - moduleDone: [] -}; - -// Initialize more QUnit.config and QUnit.urlParams -(function() { - var i, current, - location = window.location || { search: "", protocol: "file:" }, - params = location.search.slice( 1 ).split( "&" ), - length = params.length, - urlParams = {}; - - if ( params[ 0 ] ) { - for ( i = 0; i < length; i++ ) { - current = params[ i ].split( "=" ); - current[ 0 ] = decodeURIComponent( current[ 0 ] ); - - // allow just a key to turn on a flag, e.g., test.html?noglobals - current[ 1 ] = current[ 1 ] ? decodeURIComponent( current[ 1 ] ) : true; - if ( urlParams[ current[ 0 ] ] ) { - urlParams[ current[ 0 ] ] = [].concat( urlParams[ current[ 0 ] ], current[ 1 ] ); - } else { - urlParams[ current[ 0 ] ] = current[ 1 ]; - } - } - } - - QUnit.urlParams = urlParams; - - // String search anywhere in moduleName+testName - config.filter = urlParams.filter; - - // Exact match of the module name - config.module = urlParams.module; - - config.testNumber = []; - if ( urlParams.testNumber ) { - - // Ensure that urlParams.testNumber is an array - urlParams.testNumber = [].concat( urlParams.testNumber ); - for ( i = 0; i < urlParams.testNumber.length; i++ ) { - current = urlParams.testNumber[ i ]; - config.testNumber.push( parseInt( current, 10 ) ); - } - } - - // Figure out if we're running the tests from a server or not - QUnit.isLocal = location.protocol === "file:"; -}()); - -extend( QUnit, { - - config: config, - - // Initialize the configuration options - init: function() { - extend( config, { - stats: { all: 0, bad: 0 }, - moduleStats: { all: 0, bad: 0 }, - started: +new Date(), - updateRate: 1000, - blocking: false, - autostart: true, - autorun: false, - filter: "", - queue: [], - semaphore: 1 - }); - - var tests, banner, result, - qunit = id( "qunit" ); - - if ( qunit ) { - qunit.innerHTML = - "

" + escapeText( document.title ) + "

" + - "

" + - "
" + - "

" + - "
    "; - } - - tests = id( "qunit-tests" ); - banner = id( "qunit-banner" ); - result = id( "qunit-testresult" ); - - if ( tests ) { - tests.innerHTML = ""; - } - - if ( banner ) { - banner.className = ""; - } - - if ( result ) { - result.parentNode.removeChild( result ); - } - - if ( tests ) { - result = document.createElement( "p" ); - result.id = "qunit-testresult"; - result.className = "result"; - tests.parentNode.insertBefore( result, tests ); - result.innerHTML = "Running...
     "; - } - }, - - // Resets the test setup. Useful for tests that modify the DOM. - /* - DEPRECATED: Use multiple tests instead of resetting inside a test. - Use testStart or testDone for custom cleanup. - This method will throw an error in 2.0, and will be removed in 2.1 - */ - reset: function() { - var fixture = id( "qunit-fixture" ); - if ( fixture ) { - fixture.innerHTML = config.fixture; - } - }, - - // Safe object type checking - is: function( type, obj ) { - return QUnit.objectType( obj ) === type; - }, - - objectType: function( obj ) { - if ( typeof obj === "undefined" ) { - return "undefined"; - } - - // Consider: typeof null === object - if ( obj === null ) { - return "null"; - } - - var match = toString.call( obj ).match(/^\[object\s(.*)\]$/), - type = match && match[1] || ""; - - switch ( type ) { - case "Number": - if ( isNaN(obj) ) { - return "nan"; - } - return "number"; - case "String": - case "Boolean": - case "Array": - case "Date": - case "RegExp": - case "Function": - return type.toLowerCase(); - } - if ( typeof obj === "object" ) { - return "object"; - } - return undefined; - }, - - push: function( result, actual, expected, message ) { - if ( !config.current ) { - throw new Error( "assertion outside test context, was " + sourceFromStacktrace() ); - } - - var output, source, - details = { - module: config.current.module, - name: config.current.testName, - result: result, - message: message, - actual: actual, - expected: expected - }; - - message = escapeText( message ) || ( result ? "okay" : "failed" ); - message = "" + message + ""; - output = message; - - if ( !result ) { - expected = escapeText( QUnit.jsDump.parse(expected) ); - actual = escapeText( QUnit.jsDump.parse(actual) ); - output += "
    "; - - if ( actual !== expected ) { - output += ""; - output += ""; - } - - source = sourceFromStacktrace(); - - if ( source ) { - details.source = source; - output += ""; - } - - output += "
    Expected:
    " + expected + "
    Result:
    " + actual + "
    Diff:
    " + QUnit.diff( expected, actual ) + "
    Source:
    " + escapeText( source ) + "
    "; - } - - runLoggingCallbacks( "log", QUnit, details ); - - config.current.assertions.push({ - result: !!result, - message: output - }); - }, - - pushFailure: function( message, source, actual ) { - if ( !config.current ) { - throw new Error( "pushFailure() assertion outside test context, was " + sourceFromStacktrace(2) ); - } - - var output, - details = { - module: config.current.module, - name: config.current.testName, - result: false, - message: message - }; - - message = escapeText( message ) || "error"; - message = "" + message + ""; - output = message; - - output += ""; - - if ( actual ) { - output += ""; - } - - if ( source ) { - details.source = source; - output += ""; - } - - output += "
    Result:
    " + escapeText( actual ) + "
    Source:
    " + escapeText( source ) + "
    "; - - runLoggingCallbacks( "log", QUnit, details ); - - config.current.assertions.push({ - result: false, - message: output - }); - }, - - url: function( params ) { - params = extend( extend( {}, QUnit.urlParams ), params ); - var key, - querystring = "?"; - - for ( key in params ) { - if ( hasOwn.call( params, key ) ) { - querystring += encodeURIComponent( key ) + "=" + - encodeURIComponent( params[ key ] ) + "&"; - } - } - return window.location.protocol + "//" + window.location.host + - window.location.pathname + querystring.slice( 0, -1 ); - }, - - extend: extend, - id: id, - addEvent: addEvent, - addClass: addClass, - hasClass: hasClass, - removeClass: removeClass - // load, equiv, jsDump, diff: Attached later -}); - -/** - * @deprecated: Created for backwards compatibility with test runner that set the hook function - * into QUnit.{hook}, instead of invoking it and passing the hook function. - * QUnit.constructor is set to the empty F() above so that we can add to it's prototype here. - * Doing this allows us to tell if the following methods have been overwritten on the actual - * QUnit object. - */ -extend( QUnit.constructor.prototype, { - - // Logging callbacks; all receive a single argument with the listed properties - // run test/logs.html for any related changes - begin: registerLoggingCallback( "begin" ), - - // done: { failed, passed, total, runtime } - done: registerLoggingCallback( "done" ), - - // log: { result, actual, expected, message } - log: registerLoggingCallback( "log" ), - - // testStart: { name } - testStart: registerLoggingCallback( "testStart" ), - - // testDone: { name, failed, passed, total, runtime } - testDone: registerLoggingCallback( "testDone" ), - - // moduleStart: { name } - moduleStart: registerLoggingCallback( "moduleStart" ), - - // moduleDone: { name, failed, passed, total } - moduleDone: registerLoggingCallback( "moduleDone" ) -}); - -if ( !defined.document || document.readyState === "complete" ) { - config.autorun = true; -} - -QUnit.load = function() { - runLoggingCallbacks( "begin", QUnit, {} ); - - // Initialize the config, saving the execution queue - var banner, filter, i, j, label, len, main, ol, toolbar, val, selection, - urlConfigContainer, moduleFilter, userAgent, - numModules = 0, - moduleNames = [], - moduleFilterHtml = "", - urlConfigHtml = "", - oldconfig = extend( {}, config ); - - QUnit.init(); - extend(config, oldconfig); - - config.blocking = false; - - len = config.urlConfig.length; - - for ( i = 0; i < len; i++ ) { - val = config.urlConfig[i]; - if ( typeof val === "string" ) { - val = { - id: val, - label: val - }; - } - config[ val.id ] = QUnit.urlParams[ val.id ]; - if ( !val.value || typeof val.value === "string" ) { - urlConfigHtml += ""; - } else { - urlConfigHtml += ""; - } - } - for ( i in config.modules ) { - if ( config.modules.hasOwnProperty( i ) ) { - moduleNames.push(i); - } - } - numModules = moduleNames.length; - moduleNames.sort( function( a, b ) { - return a.localeCompare( b ); - }); - moduleFilterHtml += ""; - - // `userAgent` initialized at top of scope - userAgent = id( "qunit-userAgent" ); - if ( userAgent ) { - userAgent.innerHTML = navigator.userAgent; - } - - // `banner` initialized at top of scope - banner = id( "qunit-header" ); - if ( banner ) { - banner.innerHTML = "" + banner.innerHTML + " "; - } - - // `toolbar` initialized at top of scope - toolbar = id( "qunit-testrunner-toolbar" ); - if ( toolbar ) { - // `filter` initialized at top of scope - filter = document.createElement( "input" ); - filter.type = "checkbox"; - filter.id = "qunit-filter-pass"; - - addEvent( filter, "click", function() { - var tmp, - ol = id( "qunit-tests" ); - - if ( filter.checked ) { - ol.className = ol.className + " hidepass"; - } else { - tmp = " " + ol.className.replace( /[\n\t\r]/g, " " ) + " "; - ol.className = tmp.replace( / hidepass /, " " ); - } - if ( defined.sessionStorage ) { - if (filter.checked) { - sessionStorage.setItem( "qunit-filter-passed-tests", "true" ); - } else { - sessionStorage.removeItem( "qunit-filter-passed-tests" ); - } - } - }); - - if ( config.hidepassed || defined.sessionStorage && sessionStorage.getItem( "qunit-filter-passed-tests" ) ) { - filter.checked = true; - // `ol` initialized at top of scope - ol = id( "qunit-tests" ); - ol.className = ol.className + " hidepass"; - } - toolbar.appendChild( filter ); - - // `label` initialized at top of scope - label = document.createElement( "label" ); - label.setAttribute( "for", "qunit-filter-pass" ); - label.setAttribute( "title", "Only show tests and assertions that fail. Stored in sessionStorage." ); - label.innerHTML = "Hide passed tests"; - toolbar.appendChild( label ); - - urlConfigContainer = document.createElement("span"); - urlConfigContainer.innerHTML = urlConfigHtml; - // For oldIE support: - // * Add handlers to the individual elements instead of the container - // * Use "click" instead of "change" for checkboxes - // * Fallback from event.target to event.srcElement - addEvents( urlConfigContainer.getElementsByTagName("input"), "click", function( event ) { - var params = {}, - target = event.target || event.srcElement; - params[ target.name ] = target.checked ? - target.defaultValue || true : - undefined; - window.location = QUnit.url( params ); - }); - addEvents( urlConfigContainer.getElementsByTagName("select"), "change", function( event ) { - var params = {}, - target = event.target || event.srcElement; - params[ target.name ] = target.options[ target.selectedIndex ].value || undefined; - window.location = QUnit.url( params ); - }); - toolbar.appendChild( urlConfigContainer ); - - if (numModules > 1) { - moduleFilter = document.createElement( "span" ); - moduleFilter.setAttribute( "id", "qunit-modulefilter-container" ); - moduleFilter.innerHTML = moduleFilterHtml; - addEvent( moduleFilter.lastChild, "change", function() { - var selectBox = moduleFilter.getElementsByTagName("select")[0], - selectedModule = decodeURIComponent(selectBox.options[selectBox.selectedIndex].value); - - window.location = QUnit.url({ - module: ( selectedModule === "" ) ? undefined : selectedModule, - // Remove any existing filters - filter: undefined, - testNumber: undefined - }); - }); - toolbar.appendChild(moduleFilter); - } - } - - // `main` initialized at top of scope - main = id( "qunit-fixture" ); - if ( main ) { - config.fixture = main.innerHTML; - } - - if ( config.autostart ) { - QUnit.start(); - } -}; - -if ( defined.document ) { - addEvent( window, "load", QUnit.load ); -} - -// `onErrorFnPrev` initialized at top of scope -// Preserve other handlers -onErrorFnPrev = window.onerror; - -// Cover uncaught exceptions -// Returning true will suppress the default browser handler, -// returning false will let it run. -window.onerror = function ( error, filePath, linerNr ) { - var ret = false; - if ( onErrorFnPrev ) { - ret = onErrorFnPrev( error, filePath, linerNr ); - } - - // Treat return value as window.onerror itself does, - // Only do our handling if not suppressed. - if ( ret !== true ) { - if ( QUnit.config.current ) { - if ( QUnit.config.current.ignoreGlobalErrors ) { - return true; - } - QUnit.pushFailure( error, filePath + ":" + linerNr ); - } else { - QUnit.test( "global failure", extend( function() { - QUnit.pushFailure( error, filePath + ":" + linerNr ); - }, { validTest: validTest } ) ); - } - return false; - } - - return ret; -}; - -function done() { - config.autorun = true; - - // Log the last module results - if ( config.previousModule ) { - runLoggingCallbacks( "moduleDone", QUnit, { - name: config.previousModule, - failed: config.moduleStats.bad, - passed: config.moduleStats.all - config.moduleStats.bad, - total: config.moduleStats.all - }); - } - delete config.previousModule; - - var i, key, - banner = id( "qunit-banner" ), - tests = id( "qunit-tests" ), - runtime = +new Date() - config.started, - passed = config.stats.all - config.stats.bad, - html = [ - "Tests completed in ", - runtime, - " milliseconds.
    ", - "", - passed, - " assertions of ", - config.stats.all, - " passed, ", - config.stats.bad, - " failed." - ].join( "" ); - - if ( banner ) { - banner.className = ( config.stats.bad ? "qunit-fail" : "qunit-pass" ); - } - - if ( tests ) { - id( "qunit-testresult" ).innerHTML = html; - } - - if ( config.altertitle && defined.document && document.title ) { - // show ✖ for good, ✔ for bad suite result in title - // use escape sequences in case file gets loaded with non-utf-8-charset - document.title = [ - ( config.stats.bad ? "\u2716" : "\u2714" ), - document.title.replace( /^[\u2714\u2716] /i, "" ) - ].join( " " ); - } - - // clear own sessionStorage items if all tests passed - if ( config.reorder && defined.sessionStorage && config.stats.bad === 0 ) { - // `key` & `i` initialized at top of scope - for ( i = 0; i < sessionStorage.length; i++ ) { - key = sessionStorage.key( i++ ); - if ( key.indexOf( "qunit-test-" ) === 0 ) { - sessionStorage.removeItem( key ); - } - } - } - - // scroll back to top to show results - if ( config.scrolltop && window.scrollTo ) { - window.scrollTo(0, 0); - } - - runLoggingCallbacks( "done", QUnit, { - failed: config.stats.bad, - passed: passed, - total: config.stats.all, - runtime: runtime - }); -} - -/** @return Boolean: true if this test should be ran */ -function validTest( test ) { - var include, - filter = config.filter && config.filter.toLowerCase(), - module = config.module && config.module.toLowerCase(), - fullName = ( test.module + ": " + test.testName ).toLowerCase(); - - // Internally-generated tests are always valid - if ( test.callback && test.callback.validTest === validTest ) { - delete test.callback.validTest; - return true; - } - - if ( config.testNumber.length > 0 ) { - if ( inArray( test.testNumber, config.testNumber ) < 0 ) { - return false; - } - } - - if ( module && ( !test.module || test.module.toLowerCase() !== module ) ) { - return false; - } - - if ( !filter ) { - return true; - } - - include = filter.charAt( 0 ) !== "!"; - if ( !include ) { - filter = filter.slice( 1 ); - } - - // If the filter matches, we need to honour include - if ( fullName.indexOf( filter ) !== -1 ) { - return include; - } - - // Otherwise, do the opposite - return !include; -} - -// so far supports only Firefox, Chrome and Opera (buggy), Safari (for real exceptions) -// Later Safari and IE10 are supposed to support error.stack as well -// See also https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error/Stack -function extractStacktrace( e, offset ) { - offset = offset === undefined ? 3 : offset; - - var stack, include, i; - - if ( e.stacktrace ) { - // Opera - return e.stacktrace.split( "\n" )[ offset + 3 ]; - } else if ( e.stack ) { - // Firefox, Chrome - stack = e.stack.split( "\n" ); - if (/^error$/i.test( stack[0] ) ) { - stack.shift(); - } - if ( fileName ) { - include = []; - for ( i = offset; i < stack.length; i++ ) { - if ( stack[ i ].indexOf( fileName ) !== -1 ) { - break; - } - include.push( stack[ i ] ); - } - if ( include.length ) { - return include.join( "\n" ); - } - } - return stack[ offset ]; - } else if ( e.sourceURL ) { - // Safari, PhantomJS - // hopefully one day Safari provides actual stacktraces - // exclude useless self-reference for generated Error objects - if ( /qunit.js$/.test( e.sourceURL ) ) { - return; - } - // for actual exceptions, this is useful - return e.sourceURL + ":" + e.line; - } -} -function sourceFromStacktrace( offset ) { - try { - throw new Error(); - } catch ( e ) { - return extractStacktrace( e, offset ); - } -} - -/** - * Escape text for attribute or text content. - */ -function escapeText( s ) { - if ( !s ) { - return ""; - } - s = s + ""; - // Both single quotes and double quotes (for attributes) - return s.replace( /['"<>&]/g, function( s ) { - switch( s ) { - case "'": - return "'"; - case "\"": - return """; - case "<": - return "<"; - case ">": - return ">"; - case "&": - return "&"; - } - }); -} - -function synchronize( callback, last ) { - config.queue.push( callback ); - - if ( config.autorun && !config.blocking ) { - process( last ); - } -} - -function process( last ) { - function next() { - process( last ); - } - var start = new Date().getTime(); - config.depth = config.depth ? config.depth + 1 : 1; - - while ( config.queue.length && !config.blocking ) { - if ( !defined.setTimeout || config.updateRate <= 0 || ( ( new Date().getTime() - start ) < config.updateRate ) ) { - config.queue.shift()(); - } else { - setTimeout( next, 13 ); - break; - } - } - config.depth--; - if ( last && !config.blocking && !config.queue.length && config.depth === 0 ) { - done(); - } -} - -function saveGlobal() { - config.pollution = []; - - if ( config.noglobals ) { - for ( var key in window ) { - if ( hasOwn.call( window, key ) ) { - // in Opera sometimes DOM element ids show up here, ignore them - if ( /^qunit-test-output/.test( key ) ) { - continue; - } - config.pollution.push( key ); - } - } - } -} - -function checkPollution() { - var newGlobals, - deletedGlobals, - old = config.pollution; - - saveGlobal(); - - newGlobals = diff( config.pollution, old ); - if ( newGlobals.length > 0 ) { - QUnit.pushFailure( "Introduced global variable(s): " + newGlobals.join(", ") ); - } - - deletedGlobals = diff( old, config.pollution ); - if ( deletedGlobals.length > 0 ) { - QUnit.pushFailure( "Deleted global variable(s): " + deletedGlobals.join(", ") ); - } -} - -// returns a new Array with the elements that are in a but not in b -function diff( a, b ) { - var i, j, - result = a.slice(); - - for ( i = 0; i < result.length; i++ ) { - for ( j = 0; j < b.length; j++ ) { - if ( result[i] === b[j] ) { - result.splice( i, 1 ); - i--; - break; - } - } - } - return result; -} - -function extend( a, b ) { - for ( var prop in b ) { - if ( hasOwn.call( b, prop ) ) { - // Avoid "Member not found" error in IE8 caused by messing with window.constructor - if ( !( prop === "constructor" && a === window ) ) { - if ( b[ prop ] === undefined ) { - delete a[ prop ]; - } else { - a[ prop ] = b[ prop ]; - } - } - } - } - - return a; -} - -/** - * @param {HTMLElement} elem - * @param {string} type - * @param {Function} fn - */ -function addEvent( elem, type, fn ) { - if ( elem.addEventListener ) { - - // Standards-based browsers - elem.addEventListener( type, fn, false ); - } else if ( elem.attachEvent ) { - - // support: IE <9 - elem.attachEvent( "on" + type, fn ); - } else { - - // Caller must ensure support for event listeners is present - throw new Error( "addEvent() was called in a context without event listener support" ); - } -} - -/** - * @param {Array|NodeList} elems - * @param {string} type - * @param {Function} fn - */ -function addEvents( elems, type, fn ) { - var i = elems.length; - while ( i-- ) { - addEvent( elems[i], type, fn ); - } -} - -function hasClass( elem, name ) { - return (" " + elem.className + " ").indexOf(" " + name + " ") > -1; -} - -function addClass( elem, name ) { - if ( !hasClass( elem, name ) ) { - elem.className += (elem.className ? " " : "") + name; - } -} - -function removeClass( elem, name ) { - var set = " " + elem.className + " "; - // Class name may appear multiple times - while ( set.indexOf(" " + name + " ") > -1 ) { - set = set.replace(" " + name + " " , " "); - } - // If possible, trim it for prettiness, but not necessarily - elem.className = typeof set.trim === "function" ? set.trim() : set.replace(/^\s+|\s+$/g, ""); -} - -function id( name ) { - return defined.document && document.getElementById && document.getElementById( name ); -} - -function registerLoggingCallback( key ) { - return function( callback ) { - config[key].push( callback ); - }; -} - -// Supports deprecated method of completely overwriting logging callbacks -function runLoggingCallbacks( key, scope, args ) { - var i, callbacks; - if ( QUnit.hasOwnProperty( key ) ) { - QUnit[ key ].call(scope, args ); - } else { - callbacks = config[ key ]; - for ( i = 0; i < callbacks.length; i++ ) { - callbacks[ i ].call( scope, args ); - } - } -} - -// from jquery.js -function inArray( elem, array ) { - if ( array.indexOf ) { - return array.indexOf( elem ); - } - - for ( var i = 0, length = array.length; i < length; i++ ) { - if ( array[ i ] === elem ) { - return i; - } - } - - return -1; -} - -function Test( settings ) { - extend( this, settings ); - this.assertions = []; - this.testNumber = ++Test.count; -} - -Test.count = 0; - -Test.prototype = { - init: function() { - var a, b, li, - tests = id( "qunit-tests" ); - - if ( tests ) { - b = document.createElement( "strong" ); - b.innerHTML = this.nameHtml; - - // `a` initialized at top of scope - a = document.createElement( "a" ); - a.innerHTML = "Rerun"; - a.href = QUnit.url({ testNumber: this.testNumber }); - - li = document.createElement( "li" ); - li.appendChild( b ); - li.appendChild( a ); - li.className = "running"; - li.id = this.id = "qunit-test-output" + testId++; - - tests.appendChild( li ); - } - }, - setup: function() { - if ( - // Emit moduleStart when we're switching from one module to another - this.module !== config.previousModule || - // They could be equal (both undefined) but if the previousModule property doesn't - // yet exist it means this is the first test in a suite that isn't wrapped in a - // module, in which case we'll just emit a moduleStart event for 'undefined'. - // Without this, reporters can get testStart before moduleStart which is a problem. - !hasOwn.call( config, "previousModule" ) - ) { - if ( hasOwn.call( config, "previousModule" ) ) { - runLoggingCallbacks( "moduleDone", QUnit, { - name: config.previousModule, - failed: config.moduleStats.bad, - passed: config.moduleStats.all - config.moduleStats.bad, - total: config.moduleStats.all - }); - } - config.previousModule = this.module; - config.moduleStats = { all: 0, bad: 0 }; - runLoggingCallbacks( "moduleStart", QUnit, { - name: this.module - }); - } - - config.current = this; - - this.testEnvironment = extend({ - setup: function() {}, - teardown: function() {} - }, this.moduleTestEnvironment ); - - this.started = +new Date(); - runLoggingCallbacks( "testStart", QUnit, { - name: this.testName, - module: this.module - }); - - /*jshint camelcase:false */ - - - /** - * Expose the current test environment. - * - * @deprecated since 1.12.0: Use QUnit.config.current.testEnvironment instead. - */ - QUnit.current_testEnvironment = this.testEnvironment; - - /*jshint camelcase:true */ - - if ( !config.pollution ) { - saveGlobal(); - } - if ( config.notrycatch ) { - this.testEnvironment.setup.call( this.testEnvironment, QUnit.assert ); - return; - } - try { - this.testEnvironment.setup.call( this.testEnvironment, QUnit.assert ); - } catch( e ) { - QUnit.pushFailure( "Setup failed on " + this.testName + ": " + ( e.message || e ), extractStacktrace( e, 1 ) ); - } - }, - run: function() { - config.current = this; - - var running = id( "qunit-testresult" ); - - if ( running ) { - running.innerHTML = "Running:
    " + this.nameHtml; - } - - if ( this.async ) { - QUnit.stop(); - } - - this.callbackStarted = +new Date(); - - if ( config.notrycatch ) { - this.callback.call( this.testEnvironment, QUnit.assert ); - this.callbackRuntime = +new Date() - this.callbackStarted; - return; - } - - try { - this.callback.call( this.testEnvironment, QUnit.assert ); - this.callbackRuntime = +new Date() - this.callbackStarted; - } catch( e ) { - this.callbackRuntime = +new Date() - this.callbackStarted; - - QUnit.pushFailure( "Died on test #" + (this.assertions.length + 1) + " " + this.stack + ": " + ( e.message || e ), extractStacktrace( e, 0 ) ); - // else next test will carry the responsibility - saveGlobal(); - - // Restart the tests if they're blocking - if ( config.blocking ) { - QUnit.start(); - } - } - }, - teardown: function() { - config.current = this; - if ( config.notrycatch ) { - if ( typeof this.callbackRuntime === "undefined" ) { - this.callbackRuntime = +new Date() - this.callbackStarted; - } - this.testEnvironment.teardown.call( this.testEnvironment, QUnit.assert ); - return; - } else { - try { - this.testEnvironment.teardown.call( this.testEnvironment, QUnit.assert ); - } catch( e ) { - QUnit.pushFailure( "Teardown failed on " + this.testName + ": " + ( e.message || e ), extractStacktrace( e, 1 ) ); - } - } - checkPollution(); - }, - finish: function() { - config.current = this; - if ( config.requireExpects && this.expected === null ) { - QUnit.pushFailure( "Expected number of assertions to be defined, but expect() was not called.", this.stack ); - } else if ( this.expected !== null && this.expected !== this.assertions.length ) { - QUnit.pushFailure( "Expected " + this.expected + " assertions, but " + this.assertions.length + " were run", this.stack ); - } else if ( this.expected === null && !this.assertions.length ) { - QUnit.pushFailure( "Expected at least one assertion, but none were run - call expect(0) to accept zero assertions.", this.stack ); - } - - var i, assertion, a, b, time, li, ol, - test = this, - good = 0, - bad = 0, - tests = id( "qunit-tests" ); - - this.runtime = +new Date() - this.started; - config.stats.all += this.assertions.length; - config.moduleStats.all += this.assertions.length; - - if ( tests ) { - ol = document.createElement( "ol" ); - ol.className = "qunit-assert-list"; - - for ( i = 0; i < this.assertions.length; i++ ) { - assertion = this.assertions[i]; - - li = document.createElement( "li" ); - li.className = assertion.result ? "pass" : "fail"; - li.innerHTML = assertion.message || ( assertion.result ? "okay" : "failed" ); - ol.appendChild( li ); - - if ( assertion.result ) { - good++; - } else { - bad++; - config.stats.bad++; - config.moduleStats.bad++; - } - } - - // store result when possible - if ( QUnit.config.reorder && defined.sessionStorage ) { - if ( bad ) { - sessionStorage.setItem( "qunit-test-" + this.module + "-" + this.testName, bad ); - } else { - sessionStorage.removeItem( "qunit-test-" + this.module + "-" + this.testName ); - } - } - - if ( bad === 0 ) { - addClass( ol, "qunit-collapsed" ); - } - - // `b` initialized at top of scope - b = document.createElement( "strong" ); - b.innerHTML = this.nameHtml + " (" + bad + ", " + good + ", " + this.assertions.length + ")"; - - addEvent(b, "click", function() { - var next = b.parentNode.lastChild, - collapsed = hasClass( next, "qunit-collapsed" ); - ( collapsed ? removeClass : addClass )( next, "qunit-collapsed" ); - }); - - addEvent(b, "dblclick", function( e ) { - var target = e && e.target ? e.target : window.event.srcElement; - if ( target.nodeName.toLowerCase() === "span" || target.nodeName.toLowerCase() === "b" ) { - target = target.parentNode; - } - if ( window.location && target.nodeName.toLowerCase() === "strong" ) { - window.location = QUnit.url({ testNumber: test.testNumber }); - } - }); - - // `time` initialized at top of scope - time = document.createElement( "span" ); - time.className = "runtime"; - time.innerHTML = this.runtime + " ms"; - - // `li` initialized at top of scope - li = id( this.id ); - li.className = bad ? "fail" : "pass"; - li.removeChild( li.firstChild ); - a = li.firstChild; - li.appendChild( b ); - li.appendChild( a ); - li.appendChild( time ); - li.appendChild( ol ); - - } else { - for ( i = 0; i < this.assertions.length; i++ ) { - if ( !this.assertions[i].result ) { - bad++; - config.stats.bad++; - config.moduleStats.bad++; - } - } - } - - runLoggingCallbacks( "testDone", QUnit, { - name: this.testName, - module: this.module, - failed: bad, - passed: this.assertions.length - bad, - total: this.assertions.length, - runtime: this.runtime, - // DEPRECATED: this property will be removed in 2.0.0, use runtime instead - duration: this.runtime - }); - - QUnit.reset(); - - config.current = undefined; - }, - - queue: function() { - var bad, - test = this; - - synchronize(function() { - test.init(); - }); - function run() { - // each of these can by async - synchronize(function() { - test.setup(); - }); - synchronize(function() { - test.run(); - }); - synchronize(function() { - test.teardown(); - }); - synchronize(function() { - test.finish(); - }); - } - - // `bad` initialized at top of scope - // defer when previous test run passed, if storage is available - bad = QUnit.config.reorder && defined.sessionStorage && - +sessionStorage.getItem( "qunit-test-" + this.module + "-" + this.testName ); - - if ( bad ) { - run(); - } else { - synchronize( run, true ); - } - } -}; - -// `assert` initialized at top of scope -// Assert helpers -// All of these must either call QUnit.push() or manually do: -// - runLoggingCallbacks( "log", .. ); -// - config.current.assertions.push({ .. }); -assert = QUnit.assert = { - /** - * Asserts rough true-ish result. - * @name ok - * @function - * @example ok( "asdfasdf".length > 5, "There must be at least 5 chars" ); - */ - ok: function( result, msg ) { - if ( !config.current ) { - throw new Error( "ok() assertion outside test context, was " + sourceFromStacktrace(2) ); - } - result = !!result; - msg = msg || ( result ? "okay" : "failed" ); - - var source, - details = { - module: config.current.module, - name: config.current.testName, - result: result, - message: msg - }; - - msg = "" + escapeText( msg ) + ""; - - if ( !result ) { - source = sourceFromStacktrace( 2 ); - if ( source ) { - details.source = source; - msg += "
    Source:
    " +
    -					escapeText( source ) +
    -					"
    "; - } - } - runLoggingCallbacks( "log", QUnit, details ); - config.current.assertions.push({ - result: result, - message: msg - }); - }, - - /** - * Assert that the first two arguments are equal, with an optional message. - * Prints out both actual and expected values. - * @name equal - * @function - * @example equal( format( "Received {0} bytes.", 2), "Received 2 bytes.", "format() replaces {0} with next argument" ); - */ - equal: function( actual, expected, message ) { - /*jshint eqeqeq:false */ - QUnit.push( expected == actual, actual, expected, message ); - }, - - /** - * @name notEqual - * @function - */ - notEqual: function( actual, expected, message ) { - /*jshint eqeqeq:false */ - QUnit.push( expected != actual, actual, expected, message ); - }, - - /** - * @name propEqual - * @function - */ - propEqual: function( actual, expected, message ) { - actual = objectValues(actual); - expected = objectValues(expected); - QUnit.push( QUnit.equiv(actual, expected), actual, expected, message ); - }, - - /** - * @name notPropEqual - * @function - */ - notPropEqual: function( actual, expected, message ) { - actual = objectValues(actual); - expected = objectValues(expected); - QUnit.push( !QUnit.equiv(actual, expected), actual, expected, message ); - }, - - /** - * @name deepEqual - * @function - */ - deepEqual: function( actual, expected, message ) { - QUnit.push( QUnit.equiv(actual, expected), actual, expected, message ); - }, - - /** - * @name notDeepEqual - * @function - */ - notDeepEqual: function( actual, expected, message ) { - QUnit.push( !QUnit.equiv(actual, expected), actual, expected, message ); - }, - - /** - * @name strictEqual - * @function - */ - strictEqual: function( actual, expected, message ) { - QUnit.push( expected === actual, actual, expected, message ); - }, - - /** - * @name notStrictEqual - * @function - */ - notStrictEqual: function( actual, expected, message ) { - QUnit.push( expected !== actual, actual, expected, message ); - }, - - "throws": function( block, expected, message ) { - var actual, - expectedOutput = expected, - ok = false; - - // 'expected' is optional - if ( !message && typeof expected === "string" ) { - message = expected; - expected = null; - } - - config.current.ignoreGlobalErrors = true; - try { - block.call( config.current.testEnvironment ); - } catch (e) { - actual = e; - } - config.current.ignoreGlobalErrors = false; - - if ( actual ) { - - // we don't want to validate thrown error - if ( !expected ) { - ok = true; - expectedOutput = null; - - // expected is an Error object - } else if ( expected instanceof Error ) { - ok = actual instanceof Error && - actual.name === expected.name && - actual.message === expected.message; - - // expected is a regexp - } else if ( QUnit.objectType( expected ) === "regexp" ) { - ok = expected.test( errorString( actual ) ); - - // expected is a string - } else if ( QUnit.objectType( expected ) === "string" ) { - ok = expected === errorString( actual ); - - // expected is a constructor - } else if ( actual instanceof expected ) { - ok = true; - - // expected is a validation function which returns true is validation passed - } else if ( expected.call( {}, actual ) === true ) { - expectedOutput = null; - ok = true; - } - - QUnit.push( ok, actual, expectedOutput, message ); - } else { - QUnit.pushFailure( message, null, "No exception was thrown." ); - } - } -}; - -/** - * @deprecated since 1.8.0 - * Kept assertion helpers in root for backwards compatibility. - */ -extend( QUnit.constructor.prototype, assert ); - -/** - * @deprecated since 1.9.0 - * Kept to avoid TypeErrors for undefined methods. - */ -QUnit.constructor.prototype.raises = function() { - QUnit.push( false, false, false, "QUnit.raises has been deprecated since 2012 (fad3c1ea), use QUnit.throws instead" ); -}; - -/** - * @deprecated since 1.0.0, replaced with error pushes since 1.3.0 - * Kept to avoid TypeErrors for undefined methods. - */ -QUnit.constructor.prototype.equals = function() { - QUnit.push( false, false, false, "QUnit.equals has been deprecated since 2009 (e88049a0), use QUnit.equal instead" ); -}; -QUnit.constructor.prototype.same = function() { - QUnit.push( false, false, false, "QUnit.same has been deprecated since 2009 (e88049a0), use QUnit.deepEqual instead" ); -}; - -// Test for equality any JavaScript type. -// Author: Philippe Rathé -QUnit.equiv = (function() { - - // Call the o related callback with the given arguments. - function bindCallbacks( o, callbacks, args ) { - var prop = QUnit.objectType( o ); - if ( prop ) { - if ( QUnit.objectType( callbacks[ prop ] ) === "function" ) { - return callbacks[ prop ].apply( callbacks, args ); - } else { - return callbacks[ prop ]; // or undefined - } - } - } - - // the real equiv function - var innerEquiv, - // stack to decide between skip/abort functions - callers = [], - // stack to avoiding loops from circular referencing - parents = [], - parentsB = [], - - getProto = Object.getPrototypeOf || function ( obj ) { - /* jshint camelcase: false, proto: true */ - return obj.__proto__; - }, - callbacks = (function () { - - // for string, boolean, number and null - function useStrictEquality( b, a ) { - /*jshint eqeqeq:false */ - if ( b instanceof a.constructor || a instanceof b.constructor ) { - // to catch short annotation VS 'new' annotation of a - // declaration - // e.g. var i = 1; - // var j = new Number(1); - return a == b; - } else { - return a === b; - } - } - - return { - "string": useStrictEquality, - "boolean": useStrictEquality, - "number": useStrictEquality, - "null": useStrictEquality, - "undefined": useStrictEquality, - - "nan": function( b ) { - return isNaN( b ); - }, - - "date": function( b, a ) { - return QUnit.objectType( b ) === "date" && a.valueOf() === b.valueOf(); - }, - - "regexp": function( b, a ) { - return QUnit.objectType( b ) === "regexp" && - // the regex itself - a.source === b.source && - // and its modifiers - a.global === b.global && - // (gmi) ... - a.ignoreCase === b.ignoreCase && - a.multiline === b.multiline && - a.sticky === b.sticky; - }, - - // - skip when the property is a method of an instance (OOP) - // - abort otherwise, - // initial === would have catch identical references anyway - "function": function() { - var caller = callers[callers.length - 1]; - return caller !== Object && typeof caller !== "undefined"; - }, - - "array": function( b, a ) { - var i, j, len, loop, aCircular, bCircular; - - // b could be an object literal here - if ( QUnit.objectType( b ) !== "array" ) { - return false; - } - - len = a.length; - if ( len !== b.length ) { - // safe and faster - return false; - } - - // track reference to avoid circular references - parents.push( a ); - parentsB.push( b ); - for ( i = 0; i < len; i++ ) { - loop = false; - for ( j = 0; j < parents.length; j++ ) { - aCircular = parents[j] === a[i]; - bCircular = parentsB[j] === b[i]; - if ( aCircular || bCircular ) { - if ( a[i] === b[i] || aCircular && bCircular ) { - loop = true; - } else { - parents.pop(); - parentsB.pop(); - return false; - } - } - } - if ( !loop && !innerEquiv(a[i], b[i]) ) { - parents.pop(); - parentsB.pop(); - return false; - } - } - parents.pop(); - parentsB.pop(); - return true; - }, - - "object": function( b, a ) { - /*jshint forin:false */ - var i, j, loop, aCircular, bCircular, - // Default to true - eq = true, - aProperties = [], - bProperties = []; - - // comparing constructors is more strict than using - // instanceof - if ( a.constructor !== b.constructor ) { - // Allow objects with no prototype to be equivalent to - // objects with Object as their constructor. - if ( !(( getProto(a) === null && getProto(b) === Object.prototype ) || - ( getProto(b) === null && getProto(a) === Object.prototype ) ) ) { - return false; - } - } - - // stack constructor before traversing properties - callers.push( a.constructor ); - - // track reference to avoid circular references - parents.push( a ); - parentsB.push( b ); - - // be strict: don't ensure hasOwnProperty and go deep - for ( i in a ) { - loop = false; - for ( j = 0; j < parents.length; j++ ) { - aCircular = parents[j] === a[i]; - bCircular = parentsB[j] === b[i]; - if ( aCircular || bCircular ) { - if ( a[i] === b[i] || aCircular && bCircular ) { - loop = true; - } else { - eq = false; - break; - } - } - } - aProperties.push(i); - if ( !loop && !innerEquiv(a[i], b[i]) ) { - eq = false; - break; - } - } - - parents.pop(); - parentsB.pop(); - callers.pop(); // unstack, we are done - - for ( i in b ) { - bProperties.push( i ); // collect b's properties - } - - // Ensures identical properties name - return eq && innerEquiv( aProperties.sort(), bProperties.sort() ); - } - }; - }()); - - innerEquiv = function() { // can take multiple arguments - var args = [].slice.apply( arguments ); - if ( args.length < 2 ) { - return true; // end transition - } - - return (function( a, b ) { - if ( a === b ) { - return true; // catch the most you can - } else if ( a === null || b === null || typeof a === "undefined" || - typeof b === "undefined" || - QUnit.objectType(a) !== QUnit.objectType(b) ) { - return false; // don't lose time with error prone cases - } else { - return bindCallbacks(a, callbacks, [ b, a ]); - } - - // apply transition with (1..n) arguments - }( args[0], args[1] ) && innerEquiv.apply( this, args.splice(1, args.length - 1 )) ); - }; - - return innerEquiv; -}()); - -/** - * jsDump Copyright (c) 2008 Ariel Flesler - aflesler(at)gmail(dot)com | - * http://flesler.blogspot.com Licensed under BSD - * (http://www.opensource.org/licenses/bsd-license.php) Date: 5/15/2008 - * - * @projectDescription Advanced and extensible data dumping for Javascript. - * @version 1.0.0 - * @author Ariel Flesler - * @link {http://flesler.blogspot.com/2008/05/jsdump-pretty-dump-of-any-javascript.html} - */ -QUnit.jsDump = (function() { - function quote( str ) { - return "\"" + str.toString().replace( /"/g, "\\\"" ) + "\""; - } - function literal( o ) { - return o + ""; - } - function join( pre, arr, post ) { - var s = jsDump.separator(), - base = jsDump.indent(), - inner = jsDump.indent(1); - if ( arr.join ) { - arr = arr.join( "," + s + inner ); - } - if ( !arr ) { - return pre + post; - } - return [ pre, inner + arr, base + post ].join(s); - } - function array( arr, stack ) { - var i = arr.length, ret = new Array(i); - this.up(); - while ( i-- ) { - ret[i] = this.parse( arr[i] , undefined , stack); - } - this.down(); - return join( "[", ret, "]" ); - } - - var reName = /^function (\w+)/, - jsDump = { - // type is used mostly internally, you can fix a (custom)type in advance - parse: function( obj, type, stack ) { - stack = stack || [ ]; - var inStack, res, - parser = this.parsers[ type || this.typeOf(obj) ]; - - type = typeof parser; - inStack = inArray( obj, stack ); - - if ( inStack !== -1 ) { - return "recursion(" + (inStack - stack.length) + ")"; - } - if ( type === "function" ) { - stack.push( obj ); - res = parser.call( this, obj, stack ); - stack.pop(); - return res; - } - return ( type === "string" ) ? parser : this.parsers.error; - }, - typeOf: function( obj ) { - var type; - if ( obj === null ) { - type = "null"; - } else if ( typeof obj === "undefined" ) { - type = "undefined"; - } else if ( QUnit.is( "regexp", obj) ) { - type = "regexp"; - } else if ( QUnit.is( "date", obj) ) { - type = "date"; - } else if ( QUnit.is( "function", obj) ) { - type = "function"; - } else if ( typeof obj.setInterval !== undefined && typeof obj.document !== "undefined" && typeof obj.nodeType === "undefined" ) { - type = "window"; - } else if ( obj.nodeType === 9 ) { - type = "document"; - } else if ( obj.nodeType ) { - type = "node"; - } else if ( - // native arrays - toString.call( obj ) === "[object Array]" || - // NodeList objects - ( typeof obj.length === "number" && typeof obj.item !== "undefined" && ( obj.length ? obj.item(0) === obj[0] : ( obj.item( 0 ) === null && typeof obj[0] === "undefined" ) ) ) - ) { - type = "array"; - } else if ( obj.constructor === Error.prototype.constructor ) { - type = "error"; - } else { - type = typeof obj; - } - return type; - }, - separator: function() { - return this.multiline ? this.HTML ? "
    " : "\n" : this.HTML ? " " : " "; - }, - // extra can be a number, shortcut for increasing-calling-decreasing - indent: function( extra ) { - if ( !this.multiline ) { - return ""; - } - var chr = this.indentChar; - if ( this.HTML ) { - chr = chr.replace( /\t/g, " " ).replace( / /g, " " ); - } - return new Array( this.depth + ( extra || 0 ) ).join(chr); - }, - up: function( a ) { - this.depth += a || 1; - }, - down: function( a ) { - this.depth -= a || 1; - }, - setParser: function( name, parser ) { - this.parsers[name] = parser; - }, - // The next 3 are exposed so you can use them - quote: quote, - literal: literal, - join: join, - // - depth: 1, - // This is the list of parsers, to modify them, use jsDump.setParser - parsers: { - window: "[Window]", - document: "[Document]", - error: function(error) { - return "Error(\"" + error.message + "\")"; - }, - unknown: "[Unknown]", - "null": "null", - "undefined": "undefined", - "function": function( fn ) { - var ret = "function", - // functions never have name in IE - name = "name" in fn ? fn.name : (reName.exec(fn) || [])[1]; - - if ( name ) { - ret += " " + name; - } - ret += "( "; - - ret = [ ret, QUnit.jsDump.parse( fn, "functionArgs" ), "){" ].join( "" ); - return join( ret, QUnit.jsDump.parse(fn,"functionCode" ), "}" ); - }, - array: array, - nodelist: array, - "arguments": array, - object: function( map, stack ) { - /*jshint forin:false */ - var ret = [ ], keys, key, val, i; - QUnit.jsDump.up(); - keys = []; - for ( key in map ) { - keys.push( key ); - } - keys.sort(); - for ( i = 0; i < keys.length; i++ ) { - key = keys[ i ]; - val = map[ key ]; - ret.push( QUnit.jsDump.parse( key, "key" ) + ": " + QUnit.jsDump.parse( val, undefined, stack ) ); - } - QUnit.jsDump.down(); - return join( "{", ret, "}" ); - }, - node: function( node ) { - var len, i, val, - open = QUnit.jsDump.HTML ? "<" : "<", - close = QUnit.jsDump.HTML ? ">" : ">", - tag = node.nodeName.toLowerCase(), - ret = open + tag, - attrs = node.attributes; - - if ( attrs ) { - for ( i = 0, len = attrs.length; i < len; i++ ) { - val = attrs[i].nodeValue; - // IE6 includes all attributes in .attributes, even ones not explicitly set. - // Those have values like undefined, null, 0, false, "" or "inherit". - if ( val && val !== "inherit" ) { - ret += " " + attrs[i].nodeName + "=" + QUnit.jsDump.parse( val, "attribute" ); - } - } - } - ret += close; - - // Show content of TextNode or CDATASection - if ( node.nodeType === 3 || node.nodeType === 4 ) { - ret += node.nodeValue; - } - - return ret + open + "/" + tag + close; - }, - // function calls it internally, it's the arguments part of the function - functionArgs: function( fn ) { - var args, - l = fn.length; - - if ( !l ) { - return ""; - } - - args = new Array(l); - while ( l-- ) { - // 97 is 'a' - args[l] = String.fromCharCode(97+l); - } - return " " + args.join( ", " ) + " "; - }, - // object calls it internally, the key part of an item in a map - key: quote, - // function calls it internally, it's the content of the function - functionCode: "[code]", - // node calls it internally, it's an html attribute value - attribute: quote, - string: quote, - date: quote, - regexp: literal, - number: literal, - "boolean": literal - }, - // if true, entities are escaped ( <, >, \t, space and \n ) - HTML: false, - // indentation unit - indentChar: " ", - // if true, items in a collection, are separated by a \n, else just a space. - multiline: true - }; - - return jsDump; -}()); - -/* - * Javascript Diff Algorithm - * By John Resig (http://ejohn.org/) - * Modified by Chu Alan "sprite" - * - * Released under the MIT license. - * - * More Info: - * http://ejohn.org/projects/javascript-diff-algorithm/ - * - * Usage: QUnit.diff(expected, actual) - * - * QUnit.diff( "the quick brown fox jumped over", "the quick fox jumps over" ) == "the quick brown fox jumped jumps over" - */ -QUnit.diff = (function() { - /*jshint eqeqeq:false, eqnull:true */ - function diff( o, n ) { - var i, - ns = {}, - os = {}; - - for ( i = 0; i < n.length; i++ ) { - if ( !hasOwn.call( ns, n[i] ) ) { - ns[ n[i] ] = { - rows: [], - o: null - }; - } - ns[ n[i] ].rows.push( i ); - } - - for ( i = 0; i < o.length; i++ ) { - if ( !hasOwn.call( os, o[i] ) ) { - os[ o[i] ] = { - rows: [], - n: null - }; - } - os[ o[i] ].rows.push( i ); - } - - for ( i in ns ) { - if ( hasOwn.call( ns, i ) ) { - if ( ns[i].rows.length === 1 && hasOwn.call( os, i ) && os[i].rows.length === 1 ) { - n[ ns[i].rows[0] ] = { - text: n[ ns[i].rows[0] ], - row: os[i].rows[0] - }; - o[ os[i].rows[0] ] = { - text: o[ os[i].rows[0] ], - row: ns[i].rows[0] - }; - } - } - } - - for ( i = 0; i < n.length - 1; i++ ) { - if ( n[i].text != null && n[ i + 1 ].text == null && n[i].row + 1 < o.length && o[ n[i].row + 1 ].text == null && - n[ i + 1 ] == o[ n[i].row + 1 ] ) { - - n[ i + 1 ] = { - text: n[ i + 1 ], - row: n[i].row + 1 - }; - o[ n[i].row + 1 ] = { - text: o[ n[i].row + 1 ], - row: i + 1 - }; - } - } - - for ( i = n.length - 1; i > 0; i-- ) { - if ( n[i].text != null && n[ i - 1 ].text == null && n[i].row > 0 && o[ n[i].row - 1 ].text == null && - n[ i - 1 ] == o[ n[i].row - 1 ]) { - - n[ i - 1 ] = { - text: n[ i - 1 ], - row: n[i].row - 1 - }; - o[ n[i].row - 1 ] = { - text: o[ n[i].row - 1 ], - row: i - 1 - }; - } - } - - return { - o: o, - n: n - }; - } - - return function( o, n ) { - o = o.replace( /\s+$/, "" ); - n = n.replace( /\s+$/, "" ); - - var i, pre, - str = "", - out = diff( o === "" ? [] : o.split(/\s+/), n === "" ? [] : n.split(/\s+/) ), - oSpace = o.match(/\s+/g), - nSpace = n.match(/\s+/g); - - if ( oSpace == null ) { - oSpace = [ " " ]; - } - else { - oSpace.push( " " ); - } - - if ( nSpace == null ) { - nSpace = [ " " ]; - } - else { - nSpace.push( " " ); - } - - if ( out.n.length === 0 ) { - for ( i = 0; i < out.o.length; i++ ) { - str += "" + out.o[i] + oSpace[i] + ""; - } - } - else { - if ( out.n[0].text == null ) { - for ( n = 0; n < out.o.length && out.o[n].text == null; n++ ) { - str += "" + out.o[n] + oSpace[n] + ""; - } - } - - for ( i = 0; i < out.n.length; i++ ) { - if (out.n[i].text == null) { - str += "" + out.n[i] + nSpace[i] + ""; - } - else { - // `pre` initialized at top of scope - pre = ""; - - for ( n = out.n[i].row + 1; n < out.o.length && out.o[n].text == null; n++ ) { - pre += "" + out.o[n] + oSpace[n] + ""; - } - str += " " + out.n[i].text + nSpace[i] + pre; - } - } - } - - return str; - }; -}()); - -// For browser, export only select globals -if ( typeof window !== "undefined" ) { - extend( window, QUnit.constructor.prototype ); - window.QUnit = QUnit; -} - -// For CommonJS environments, export everything -if ( typeof module !== "undefined" && module.exports ) { - module.exports = QUnit; -} - - -// Get a reference to the global object, like window in browsers -}( (function() { - return this; -})() )); \ No newline at end of file diff --git a/WebContent/tcom/mod.macro.vm b/WebContent/tcom/mod.macro.vm deleted file mode 100644 index 0a6baa79b..000000000 --- a/WebContent/tcom/mod.macro.vm +++ /dev/null @@ -1,54 +0,0 @@ -#macro (includeEditorStatic) - - - - -#end - -#macro (createEditor $suffix $textareaName $editorWidth $editorHeight $selfInit) - #set($editorAreaWidth = $editorWidth - 10) -
    - -
    -
    -
    -
    - - - -
    -#end \ No newline at end of file diff --git a/WebContent/tcom/table.css.vm b/WebContent/tcom/table.css.vm deleted file mode 100644 index 698323aa3..000000000 --- a/WebContent/tcom/table.css.vm +++ /dev/null @@ -1,368 +0,0 @@ -#set($imgRoot = "${staticRoot}/js/ui/table/css/img") -#set($tbCss = { - "default":{ - "hs_img": "$imgRoot/hscroll.gif", - "s_img": "$imgRoot/scroll.gif", - "cr_img": "$imgRoot/cr.gif", - "t_img": "$imgRoot/table.gif", - "th_font": "#326700", - "th_bg": "#DCEFD1", - "bdr_dk": "#9CD167", - "bdr_lt": "#CCE9B9", - "r_ev": "#F2F8EE", - "r_od": "#FFF", - "r_ev_dk": "#DDE9D0", - "r_od_dk": "#EAF1E2", - "hl_bg": "#FFFCE2" - }, - "blue":{ - "hs_img": "$imgRoot/hscroll_blue.gif", - "s_img": "$imgRoot/scroll_blue.gif", - "cr_img": "$imgRoot/cr.gif", - "t_img": "$imgRoot/table_blue.gif", - "th_font": "#2C7AAA", - "th_bg": "#C2E2F6", - "bdr_dk": "#2C7AAA", - "bdr_lt": "#AEDCF9", - "r_ev": "#F1F9FF", - "r_od": "#FFF", - "r_ev_dk": "#E4F2FA", - "r_od_dk": "#F1F9FF", - "hl_bg": "#FFFCE2" - }, - "blueGray":{ - "hs_img": "$imgRoot/hscroll_bluegray.gif", - "s_img": "$imgRoot/scroll_bluegray.gif", - "cr_img": "$imgRoot/cr.gif", - "t_img": "$imgRoot/table_bluegray.gif", - "th_font": "#346665", - "th_bg": "#D9E5E1", - "bdr_dk": "#BCBCBC", - "bdr_lt": "#DDD", - "r_ev": "#FFF", - "r_od": "#FFF", - "r_ev_dk": "#FFF", - "r_od_dk": "#FFF", - "hl_bg": "#FFFCE2", - "th_bold": true, - "td_bdr_btm": true, - "scr_bdr": "#4099C5" - } -}) - -#if(!$tbSkin) - #set($cssMap = $tbCss.get("blueGray")) -#else - #set($cssMap = $tbCss.get($tbSkin)) -#end - - - -/* - * XXXXXXXXXXXXXX - * $tbSkin - * XXXXXXXXXXXXXX - */ - /* FOR OPERA */ - div{border:0;} - -.ec-ecom-table .ec-vscroll {background:$cssMap.r_ev;width:15px;padding:15px 0px 15px 0px;font-size:1px} -.ec-ecom-table .ec-hscroll {background:$cssMap.r_ev;height:15px;padding:0px 15px 0px 15px;font-size:1px} -.ec-ecom-table .ec-hscroll-block {background:url("$cssMap.hs_img") -2px -30px repeat-x;border:1px solid $cssMap.scr_bdr;border-width:0 1px} -.ec-ecom-table .ec-vscroll-block {background:url("$cssMap.s_img") 0px 0px repeat-y;border:1px solid $cssMap.scr_bdr;border-width:1px 0} -.ec-ecom-table .ec-hscroll-block-over {background:url("$cssMap.hs_img") -0px -45px repeat-x} -.ec-ecom-table .ec-hscroll-block-press {background:url("$cssMap.hs_img") -0px -60px repeat-x} -.ec-ecom-table .ec-vscroll-block-over {background:url("$cssMap.s_img") -15px 0px repeat-y} -.ec-ecom-table .ec-vscroll-block-press {background:url("$cssMap.s_img") -30px 0px repeat-y} -.ec-ecom-table .ec-vscroll-prev {background:url("$cssMap.s_img") -45px -40px no-repeat;} -.ec-ecom-table .ec-vscroll-prev-over {background:url("$cssMap.s_img") -75px -40px no-repeat;} -.ec-ecom-table .ec-vscroll-prev-press {background:url("$cssMap.s_img") -60px -40px no-repeat;} -.ec-ecom-table .ec-vscroll-next {background:url("$cssMap.s_img") -45px -55px no-repeat;} -.ec-ecom-table .ec-vscroll-next-over {background:url("$cssMap.s_img") -75px -55px no-repeat;} -.ec-ecom-table .ec-vscroll-next-press {background:url("$cssMap.s_img") -60px -55px no-repeat;} -.ec-ecom-table .ec-hscroll-prev {background:url("$cssMap.s_img") -45px -85px no-repeat;} -.ec-ecom-table .ec-hscroll-prev-over {background:url("$cssMap.s_img") -75px -85px no-repeat;} -.ec-ecom-table .ec-hscroll-prev-press {background:url("$cssMap.s_img") -60px -85px no-repeat;} -.ec-ecom-table .ec-hscroll-next {background:url("$cssMap.s_img") -45px -70px no-repeat;} -.ec-ecom-table .ec-hscroll-next-over {background:url("$cssMap.s_img") -75px -70px no-repeat;} -.ec-ecom-table .ec-hscroll-next-press {background:url("$cssMap.s_img") -60px -70px no-repeat;} - -.ec-ecom-table .vsblockdtr {padding:2px 0px} -.ec-ecom-table .vsblockdtr-top {background:url("$cssMap.s_img") -45px 0px no-repeat} -.ec-ecom-table .vsblockdtr-bottom {background:url("$cssMap.s_img") -45px -18px no-repeat} -.ec-ecom-table .vsblockdtr-over .vsblockdtr-top {background:url("$cssMap.s_img") -45px -20px no-repeat} -.ec-ecom-table .vsblockdtr-over .vsblockdtr-bottom {background:url("$cssMap.s_img") -45px -38px no-repeat} -.ec-ecom-table .vsblockdtr-press .vsblockdtr-top {background:url("$cssMap.s_img") -60px 0px no-repeat} -.ec-ecom-table .vsblockdtr-press .vsblockdtr-bottom {background:url("$cssMap.s_img") -60px -38px no-repeat} -.ec-ecom-table .ec-panel-disabled .vsblockdtr div {display:none} - -.ec-ecom-table .hsblockdtr {padding:0px 2px} -.ec-ecom-table .hsblockdtr-left {background:url("$cssMap.hs_img") -60px 0px no-repeat} -.ec-ecom-table .hsblockdtr-right {background:url("$cssMap.hs_img") -18px 0px no-repeat} -.ec-ecom-table .hsblockdtr-over .hsblockdtr-left {background:url("$cssMap.hs_img") -40px -0px no-repeat} -.ec-ecom-table .hsblockdtr-over .hsblockdtr-right {background:url("$cssMap.hs_img") -38px -0px no-repeat} -.ec-ecom-table .hsblockdtr-press .hsblockdtr-left {background:url("$cssMap.hs_img") -40px -15px no-repeat} -.ec-ecom-table .hsblockdtr-press .hsblockdtr-right {background:url("$cssMap.hs_img") -38px -15px no-repeat} -.ec-ecom-table .ec-panel-disabled .hsblockdtr div {display:none} - - .ec-ecom-table {border:1px solid $cssMap.bdr_dk;padding-top:23px;background-color:$cssMap.th_bg} - .ec-ecom-table .checkbox {padding-left:0px;padding-right:0px;} - .ec-ecom-table .checkbox-item {padding-left:0px;padding-right:0px;} - .ec-ecom-table table {border-collapse:collapse;border-spacing:0px} - .ec-ecom-table-layout {background:#FFF;color:#333} - .ec-ecom-table-head, - .ec-print-table th{ - font-weight:#if($cssMap.th_bold)bold#{else}normal#end; - color:$cssMap.th_font; - padding:6px 5px; padding-right:12px; - line-height:15px; - border:0; - border-left:1px solid $cssMap.bdr_lt; border-bottom:1px solid $cssMap.bdr_dk; - overflow:hidden; - white-space:nowrap; - word-wrap:normal; - word-break:keep-all - } - .ec-ecom-table-item, - .ec-print-table td{ - line-height:15px; - border:0; - padding:5px 5px; padding-right:12px; - border-left:1px solid $cssMap.bdr_lt; - #if($cssMap.td_bdr_btm)border-bottom:1px solid $cssMap.bdr_lt;#end - word-break:break-all; - white-space:normal; - word-wrap:break-word; - overflow:hidden - } - - .ec-ecom-table-row .od td{background-color:$cssMap.r_od;} - .ec-ecom-table-row .ev td{background-color:$cssMap.r_ev;} - .ec-ecom-table-row .od td.dk{background-color:$cssMap.r_od_dk;} - .ec-ecom-table-row .ev td.dk{background-color:$cssMap.r_ev_dk;} - - .ec-ecom-table-row-over .ev .ec-ecom-table-item,.ec-ecom-table-row-over .ev td.dk, - .ec-ecom-table-row-over .od .ec-ecom-table-item,.ec-ecom-table-row-over .od td.dk, - .ec-ecom-table-row-focus .ev .ec-ecom-table-item,.ec-ecom-table-row-focus .ev td.dk, - .ec-ecom-table-row-focus .od .ec-ecom-table-item,.ec-ecom-table-row-focus .od td.dk, - .ec-ecom-table-row-focus .ec-ecom-table-item, - .ec-ecom-table-row-over .ec-ecom-table-item - {background-color:$cssMap.hl_bg} - - .ec-ecom-table-row .first, - .ec-ecom-table-area .first{ - border-left:0 none; - } - - /*排序*/ - .ec-ecom-table-area .sort, - .ec-ecom-table-area .sort-over, - .ec-ecom-table-area .sort-focus{ - text-align:left; - cursor:pointer; - background:url("$cssMap.t_img") no-repeat 93% -33px; - } - .ec-ecom-table-area .sort-over{ - background-color:#F6FFB8; - } - .ec-ecom-table-area .sort-up, - .ec-ecom-table-area .sort-down{ - cursor:pointer; - /*text-align:right;*/ - background:#F6FFB8 url("$cssMap.t_img") no-repeat 93% -33px; - } - - .ec-ecom-table-area .sort-up { - background-position:93% -63px; - } - .ec-ecom-table-area .sort-down { - background-position:93% -93px; - } - - .ec-ecom-table-row .op{text-align:center;border:0 none;border-left:1px solid $cssMap.bdr_dk} - - /*复选框*/ - .ec-checkbox {background:url("$cssMap.cr_img") 0px 0px no-repeat;width:17px;height:15px} - .ec-checkbox-disabled {background:url("$cssMap.cr_img") -68px 0px no-repeat;} - .ec-checkbox-over {background:url("$cssMap.cr_img") -17px 0px no-repeat;} - .ec-checkbox-checked {background:url("$cssMap.cr_img") -34px 0px no-repeat} - .ec-checkbox-checked-over {background:url("$cssMap.cr_img") -51px 0px no-repeat} - .ec-checkbox-part {background:url("$cssMap.cr_img") -102px 0px no-repeat} - - /*展开按钮(上)*/ - .ec-col-toggler,.ec-col-toggler-o{ - width:17px; height:20px; - position:absolute; top:2px; right:0; - background:$cssMap.th_bg url("$cssMap.t_img") no-repeat 0px 0px; - cursor:pointer; - } - .ec-col-toggler-o{background-position:-22px 0px} - - /*展开按钮(下)*/ - .ec-v-toggler{ - width:15px; background:$cssMap.r_ev_dk; - position:absolute; right:0; bottom:0; _right:-1px; - cursor:pointer; - border-left:1px solid $cssMap.bdr_dk; - /*border-right:1px solid $cssMap.bdr_dk;*/ - } - .ec-v-toggler div{ - width:9px; height:10px; - overflow:hidden; - background:url("$cssMap.t_img") no-repeat -8px -22px; - position:absolute; right:3px; bottom:50%; - _padding-top:50%; - cursor:pointer; - } - .ec-v-toggler-over{background-color:$cssMap.r_od_dk} - - /*验证*/ - .valid-error .ev td.ec-ecom-table-item, - .valid-error .od td.ec-ecom-table-item{ - background-color:pink; - } - /* - *分页 - *囧, 有同名的list宏,需转义 - */ - .list-page a, - .list-page b{ - margin:0; - text-indent:0; - display:inline-block; - *display:inline; - zoom:1; - height:20px; - line-height:20px; - background:url("$cssMap.t_img") repeat-x 0 -150px; - border:1px solid $cssMap.bdr_dk; - padding:0 3px; - text-decoration:none; - color:$cssMap.th_font; - } - .list-page a:hover{ - background-position:0 -176px; - } - .list-page .page-n{ - /*width:20px;*/ - text-align:center; - /*padding:0;*/ - padding:0 5px; - } - .list-page b{ - background-image:none; - color:#666; - background-color:#EEE; - font-weight:normal; - } - .list-page b.page-n{ - background-image:none; - background-color:#FFF; - color:#000; - font-weight:bold; - } - .list-page { - color:$cssMap.th_font; - margin-top: 10px - } - .list-page em{ - font-style:normal; - color:#000; - padding:0 3px; - } - .target-page{ - width:25px; - } - /*弹出菜单*/ - .ec-popup{ - background-color:$cssMap.th_bg; - border:1px solid $cssMap.bdr_dk; - border-width:1px 1px 0 1px; - width:70px; - } - .ec-popup-item{ - background-color:$cssMap.th_bg; - width:70px; height:25px; line-height:25px; - border-bottom:1px solid $cssMap.bdr_dk; - padding-left: 24px; - cursor:pointer; - vertical-align:bottom; - position:relative; - } - .ec-popup-item-over{ - background-color:$cssMap.hl_bg; - } - .ec-popup-item .ec-checkbox{ - /*float:left;*/ - /*margin:4px 4px 0 4px;*/ - position:absolute; top:4px; left:4px; - border:0 none; - /*text-indent: 14px;*/ - } - .cb-ctnr{ - background:$cssMap.th_bg url("$cssMap.t_img") 0 -200px; - height:14px; - margin:0; - border:0 none; - width:15px; - position:absolute; - top:7px; - cursor:pointer; - } - - /* - * 提示信息显示 - */ - .tb-msg{ - visibility:hidden; - display:none; - margin: 0 0 4px 0; - } - .tb-msg .tb-msg-txt{ - background:$cssMap.hl_bg; - color:#D2691E; - font-weight:bold; - padding:0 4px; - display:inline-block; *display:inline; - zoom:1; - height:20px; line-height:20px; - } - .tb-msg .clo-btn{ - font-weight:normal; - margin: 0 0 0 14px; - cursor:pointer; - } - - /* - * 打印 - */ - @media screen { - .ec-print-table{ - border:1px solid $cssMap.bdr_dk;border-width:1px; - border-collapse:collapse; background-color:$cssMap.th_bg - } - .ec-print-table th, - .ec-print-table td{ - border:1px solid $cssMap.bdr_dk; - border-width:0 0 1px 1px; - } - .ec-print-table td{ - background-color:#FFF; - } - } - @media print { - body{font-family:"微软雅黑","黑体";font-size:10px;} - .strik-info{color:#000;} - .noprint,.nav{display:none;} - .area-v,.area-w{display:none;} - .area{border:1px solid #ddd;margin-top:6px;background:#fff;} - .mess-query .area-inner{background:none;border:0;} - .mess-query .area {border:0;} - .area h5{border:0;} - .area h5 b{background:none;border:0;color:#000;} - .old td{background:#ddd;} - .ec-print-table {border:1px solid #666;border-width:1px 0 1px 1px;border-collapse:collapse} - .ec-print-table th{padding:2px;text-align:center;border-right:1px solid #666; border-color:#666} - .ec-print-table td{padding:2px 6px;border:1px solid #666;border-width:1px 1px 0 0; border-color:#666} - *{word-wrap:break-word;word-break:break-all;} - } \ No newline at end of file diff --git a/WebContent/tcom/utils.macro.vm b/WebContent/tcom/utils.macro.vm deleted file mode 100644 index 2baa3dbef..000000000 --- a/WebContent/tcom/utils.macro.vm +++ /dev/null @@ -1,539 +0,0 @@ -#parse('/tcom/const.inc.vm') - - -## 权限字符串 - -#macro (getRoleStr $roleId)#if($roleId==1)超级管理员#elseif($roleId==2)管理员#else 普通用户 #end #end - -## 分页 -#macro (pager $curPagerNum $pagerSize $totalNum $url) -

    - #set($totalPage = ($totalNum - 1) / $pagerSize + 1) - - #set($currentPager = $curPagerNum) - - #set($pagerStart = 1) - #set($pagerEnd = $totalPage) - - #if($currentPager >= $totalPage) - #set($currentPager = $totalPage) - #set($pagerEnd = $totalPage) - #end - - #if($currentPager < 1) - #set($currentPager = 1) - #end - - #if($currentPager > 1) - 首页 - «上一页 - #else - 首页 - «上一页 - #end - - #if($totalPage > 11) - #if($currentPager > 5) - #set($pagerStart = $currentPager - 5) - #set($pagerEnd = $currentPager + 5) - #else - #set($pagerEnd = 10) - #end - #if($pagerEnd > $totalPage) - #set($pagerStart = $totalPage - 9) - #set($pagerEnd = $totalPage) - #end - #end - - #foreach($item in [${pageStart}..${pageEnd}]) - #if($item == $currentPager) - $item - #else - $item - #end - #end - - #if($currentPager < $totalPage) - 下一页» - 尾页 - #else - 下一页» - 尾页 - #end - 跳转 -       共$!totalPage页,$!totalNum条记录   -

    - #if($totalNum == 0) - - #end -#end -#macro (table $lstConfigs $data $options) -#* - * 表格控件 - * - * @params {List} $lstConfigs [必填]列表表头数据,列样式(宽度,自定义属性等) - * @params {List} $data [必填]表格内容数据 - * @params {List} $options 表格其他参数 - * lstTitles {list} [选填]表头, 可以由RD设置, 一般情况下就取${lstConfigs}的值 - * checkbox {String} [选填]用户自行选择的checkbox的name值 - * checkboxVal {String} [选填]用户自行选择的checkbox的id值 - * hasOp {Boolean} [选填]参数为true, 表示有操作列 - * custom {Boolean} [选填]全选是否可以针对整表,依赖于选项checkbox - * style {String} [选填]表格采用的样式, 默认为"default" - * url {String} [选填]分页请求的URL, 默认为"" - * id {String} [选填]列表的id, 命名建议[0-9a-zA-Z_]+ - * needPrint {Boolean} [选填]是否需要打印, 默认不需要打印 - * page {list} [选填]每页记录数 - * @todo 修改id - 固定 - *# -#if($options.id) - #set($tbId = $options.id) -#else - #if($tbId) - #set($tbId = $tbId + 1) - #else - #set($tbId = 0) - #end -#end - -#set($tbNoData = false) -#if(!$data || $data.size() == 0) - #set($tbNoData = true) -#end - - - - #if ($pager || $options.pager) -
    - #if($options.pager) - #pager($options.pager.curPagerNum - $options.pager.pagerSize - $options.pager.totalRecNum - $options.url) - #else - #pager($pager.curPagerNum - $pager.pagerSize - $pager.totalRecNum - $options.url) - #end - - #end - -#end -#** - * @desc : 适用于数据确定的下拉列表、单选组、多选组,数据类型为List型 - * @param {String} name 表单项name属性值 - * @param {List} data 填充表单项value和label属性的值 - * @param {String} curVal 当前选中值 - * @param {String} flag 哪个类型的表单项(radio/select/checkbox) - * @param {String} attrs 表单项其它的属性 - *# -#set($fieldIndex = 0) -#macro (list $name $data $curVal $flag $attrs) - #if($flag == "select") - - #elseif($flag == "checkbox") - #foreach($item in $data) - - #set($fieldIndex = $fieldIndex + 1) - #end - #elseif($flag == "radio") - #foreach($item in $data) - - #set($fieldIndex = $fieldIndex + 1) - #end - #end -#end -#** - * @desc : 层级下拉框 - * @param {String} fName 下拉框fName属性值 - * @param {List} fData 填充下拉框value和label属性及层级关系的值 - * @param {String} fCurVal 当前选中值 - * @param {String} fAttrs 表单项其它的属性 - *# -#macro (levelSelect $fName $fData $fCurVal $fAttrs) - -#end -#** - * @desc : 层级下拉框(数据源无序) - * @param {String} fName 下拉框fName属性值 - * @param {List} fData 填充下拉框value和label属性及层级关系的值 - * @param {String} fCurVal 当前选中值 - * @param {String} fAttrs 表单项其它的属性 - *# -#macro (levelSelect2 $fName $fData $fCurVal $fAttrs) - - -#end -#** - * @desc : 统一引入错误提示 - *# -#macro (globalMsg) - #if($errors && $errors.globalMsg) -
    -
    -
    -
    $!errors.globalMsg
    -
    -
    -
    - #end -#end -#** - * @desc : 单日历 - * @param {String} name 表单项name属性值 - * @param {String} value 默认时间 - * @param {list} options 可选项 支持的参数有 range设定可操作范围 ecid设置ecid - * @demo #singleCal("cal-demo" "2012-01-12") - *# -#macro (singleCal $name $value $options) - - #end -#** - * @desc : 双日历 - * @param {String} name 表单项name属性值 - * @param {String} value 默认时间 - * @param {list} options 可选项 支持的参数有 range设定可操作范围 ecid设置ecid - * @demo #rangeCal("2012-01-11" "2012-02-23") - *# -#macro (rangeCal $bVal $eVal $options) - -#end -#** -* @desc : 浮动层开头部分代码 -* @param {String} ecId ecui控件Id,在ecFloater.show(ecId)调用使用 -* @param {String} title 浮动层标题名称 -* @param {Number} width 浮动层的宽度值 -* @param {Number} height 浮动层的高度值 -* @demo -* #startFloater("floater1" "标题" 500 300) -* 浮动层里面的HTML代码 -* #endFloater -*# -#macro (startFloater $ecId $title $width $height) - -#end -#** -* @desc : 初始本地存储模块 -* @param {String} ecId 可选,默认为localStorage。ecui控件Id,用户获取ecui本地存储控件。 -* @demo #storageInit() 或 #storageInit("myLocalStorage") -*# -#macro (storageInit $ecId) - #if(!$ecId) - #set($ecId = "localStorage") - #end -
    -#end -#** -* @desc : 提交查询表单时本地保存内容 -* @param {String} ecId 可选,默认为localStorage。ecui控件Id,用户获取ecui本地存储控件。 -* @demo #storageSave() 或 #storageSave("myLocalStorage") -*# -#macro (storageSave $ecId) - #if(!$ecId) - #set($ecId = "localStorage") - #end - this.localDataId.value = ecui.get('$!ecId').save(this); -#end -#** - * @desc : navBar 方案制作导航条 - *# -#macro (navBar $curTab $curCTab) -#set($commURL = "$common.stepController?type=current&schemeId=$!schemeId¤tStep=") - - - -#end -#** - * @desc : includeNewRapStatic 新版统一引入静态资源 - *# -#macro (includeNewRapStatic) - - - - - - - - - - - - - - - - - - - - - -#end \ No newline at end of file diff --git a/WebContent/unit-tests/errors/bugfix-list.js b/WebContent/unit-tests/errors/bugfix-list.js deleted file mode 100644 index 6c9561cfd..000000000 --- a/WebContent/unit-tests/errors/bugfix-list.js +++ /dev/null @@ -1,114 +0,0 @@ -module('bugfix-BOSN', { - setup: function() { - this.oldProjectId = RAP.getProjectId(), - this.oldMode = RAP.getMode(); - // 项目ID设置为“Bosn修复BUG专用”的ID - RAP.setProjectId(189); - // 拦截所有请求 - RAP.setMode(1); - }, - teardown: function() { - RAP.setProjectId(this.oldProjectId); - RAP.setMode(this.oldMode); - } -}); - -test('dataTypeBug fix', function() { - stop(); - KISSY.use('io', function(S, IO) { - IO({ - url: 'dataTypeBug.do', - dataType:'json', - success: function(data) { - ok(KISSY.isArray(data.numberArray), 'numberArray is array'); - ok(KISSY.isNumber(data.numberArray[0]), 'numberArray[0] is number'); - ok(KISSY.isArray(data.stringArray), 'stringArray is array'); - ok(KISSY.isString(data.stringArray[0]), 'stringArray[0] is string'); - start(); - } - }) - }) -}) - - -test('paramMockJsTemplate fix', function() { - stop(2); - KISSY.use('io', function(S, IO) { - IO({ - url: 'paramMockJsTemplate.do', - dataType:'json', - success: function(data) { - console.log(data); - equal(data.result, 'page is 1008, num is okokok', 'data origin: page is 1008, num is okokok'); - equal(data.result2, '', 'data origin: 1') - start(1); - - IO({ - url: 'paramMockJsTemplate.do', - data: { - num: 111, - page: 222 - }, - dataType:'json', - success: function(data) { - equal(data.result, 'page is 222, num is 111', 'data changed: page is 222, num is 111'); - equal(data.result2, 222, 'data changed: 222') - start(1); - } - }) - } - }) - }) -}) - - -test('unicode fix', function() { - stop(); - KISSY.use('io', function(S, IO) { - IO({ - url: 'unicode.do', - dataType:'json', - success: function(data) { - ok(KISSY.isString(data.string1), 'params are string'); - ok(KISSY.isString(data.string2), 'params are string'); - ok(KISSY.isString(data.string3), 'params are string'); - equal(data.string1, '1233打发打发..*(&(@#*&@(*#&*(', 'string1 is ok'); - equal(data.string2, '9832749802374098324782937flakdsjfldaskjf啊死了都快放假啊老师的看风景阿斯蒂芬(*&(*&', 'string2 is ok'); - equal(data.string3, '哈哈深度开发回家啊说的发来了空间啊说的饭卡上的减肥快乐的撒娇放假', 'string3 is ok'); - start(); - } - }) - }) -}) - - -test('copyFunc fix', function() { - stop(); - KISSY.use('io', function(S, IO) { - IO({ - url: 'copyFunc', - dataType:'json', - success: function(data) { - console.log(data); - ok(KISSY.isArray(data.obj), 'data.obj is array'); - ok(KISSY.isArray(data.objCopy), 'data.objCopy is array'); - var a = data.obj[0], b = data.objCopy[0]; - for(var prop in a) { - ok(prop in b, 'b has ' + prop + ' too'); - } - for(var prop in b) { - ok(prop in a, 'a has ' + prop + ' too'); - } - for(var prop in a.item) { - ok(prop in b.item, 'b.item has ' + prop + ' too'); - equal(typeof a.item[prop], typeof b.item[prop], 'value type is the same.') - } - for(var prop in b.item) { - ok(prop in a.item, 'a.item has ' + prop + ' too'); - equal(typeof a.item[prop], typeof b.item[prop], 'value type is the same.') - } - start(); - } - }) - }) -}) diff --git a/WebContent/unit-tests/errors/rap-plugin-error.js b/WebContent/unit-tests/errors/rap-plugin-error.js deleted file mode 100644 index 175c5506f..000000000 --- a/WebContent/unit-tests/errors/rap-plugin-error.js +++ /dev/null @@ -1,46 +0,0 @@ -module('bugfix'); - -test('without io: KISSY.use("node", function(S, A) {})', function() { - stop(4); - KISSY.use('node', function(S, Node) { - start(1); - ok(S.config, 'still has S.config'); - }); - - KISSY.use('node, io', function(S, Node) { - start(1); - ok(S.config, 'still has S.config'); - }); - - KISSY.use('node, io', function(S, Node, IO) { - start(1); - ok(S.config, 'still has S.config'); - }); - - KISSY.use('node, io, node', function(S, Node, IO, Node) { - start(1); - ok(S.config, 'still has S.config'); - }); -}) - -test('KISSY.add using IO', function() { - stop(); - KISSY.add('tester/module', function(S, Node, IO) { - ok(KISSY.io != undefined, 'got KISSY.io'); - ok(KISSY.ajax != undefined, 'got KISSY.ajax'); - ok(KISSY.IO != undefined, 'got KISSY.IO'); - - IO({ - url: '/base', - dataType:'json', - success: function(data) { - equal(typeof data.a, 'number', 'get data ok'); - start(); - } - }) - }, {requires: ['node', 'io']}) - - KISSY.use('tester/module', function(S, A) { - - }) -}) \ No newline at end of file diff --git a/WebContent/unit-tests/getrule/base.js b/WebContent/unit-tests/getrule/base.js deleted file mode 100644 index 82d120832..000000000 --- a/WebContent/unit-tests/getrule/base.js +++ /dev/null @@ -1,39 +0,0 @@ -module('get-mockjs-rule'); - -test('jQuery - getMockjsRule - /mockjs/projectId/action', function() { - stop(); - $.ajax({ - type : "get", - url : "/mockjs/114/mockjs/base", - dataType : "jsonp", - jsonp: "callback", - success : function(data){ - start(); - ok('a|1-10' in data, 'mockjs rule: a|1-10 is in data'); - ok(KISSY.isNumber(data['a|1-10']), 'and dataType is number'); - }, - error:function(){ - } - }); -}); - - -test('KISSY - getMockjsRule - /mockjs/projectId/action', function() { - stop(); - var base = '/mockjs/114/mockjs/base'; - KISSY.oldUse('io', function(S, IO) { - IO({ - type : "get", - url : base, - dataType : "jsonp", - jsonp: "callback", - success : function(data){ - start(); - ok('a|1-10' in data, 'mockjs rule: a|1-10 is in data'); - ok(KISSY.isNumber(data['a|1-10']), 'and dataType is number'); - }, - error:function(){ - } - }) - }); -}); \ No newline at end of file diff --git a/WebContent/unit-tests/getruledata/base.js b/WebContent/unit-tests/getruledata/base.js deleted file mode 100644 index 55a23cd9b..000000000 --- a/WebContent/unit-tests/getruledata/base.js +++ /dev/null @@ -1,127 +0,0 @@ -module('get-mockjs-data'); - -test('jQuery.ajax[ORIGIN] - getMockjsData - get /mockjsdata/projectId/action', function() { - stop(); - $.ajax({ - type : "get", - url : "/mockjsdata/114/mockjs/base", - dataType : "jsonp", - jsonp: "callback", - success : function(data){ - start(); - ok('a' in data, 'property exists'); - ok(KISSY.isNumber(data.a), 'a is number'); - ok(data.a >= 1 && data.a <= 10, 'a between 1 and 10'); - }, - error:function(){ - } - }); -}); - - -test('jQuery.ajax[RAPPED] - getMockjsData - Action : /mockjs/base', function() { - stop(); - equal(RAP.getPrefix(), '/mockjs/', 'PREFIX is /mockjs/'); - $.rapAjax({ - type : "get", - url : "/mockjs/base", - dataType : "jsonp", - jsonp: "callback", - success : function(data){ - start(); - ok('a' in data, 'mockjs : a is in data'); - ok(KISSY.isNumber(data['a']), 'and dataType is number'); - }, - error:function(){ - } - }); -}); - - -test('jQuery.ajax[RAPPED] - getMockjsData - Prefix: /mockjsdata/, Action:/mockjs/base', function() { - stop(); - equal(RAP.getPrefix(), '/mockjs/', 'PREFIX is /mockjs/'); - var old = RAP.getPrefix(); - RAP.setPrefix('/mockjsdata/') - $.rapAjax({ - type : "get", - url : "/mockjs/base", - dataType : "jsonp", - jsonp: "callback", - success : function(data){ - RAP.setPrefix(old); - start(); - ok('a' in data, 'mockjs : a is in data'); - ok(KISSY.isNumber(data['a']), 'and dataType is number'); - }, - error:function(){ - } - }); -}); - - -test('KISSY[ORIGIN] - getMockjsData - get /mockjsdata/projectId/action', function() { - stop(); - KISSY.oldUse('io', function(S, IO) { - IO({ - type : "get", - url : "/mockjsdata/114/mockjs/base", - dataType : "jsonp", - jsonp: "callback", - success : function(data){ - start(); - ok('a' in data, 'property exists'); - ok(KISSY.isNumber(data.a), 'a is number'); - ok(data.a >= 1 && data.a <= 10, 'a between 1 and 10'); - }, - error:function(){ - } - }) - }); -}); - - -test('KISSY[RAPPED] - getMockjsData - Action: /mockjs/base', function() { - stop(); - var base = '/mockjs/base'; - KISSY.use('io', function(S, IO) { - IO({ - type : "get", - url : base, - dataType : "jsonp", - jsonp: "callback", - success : function(data){ - start(); - ok('a' in data, 'property exists'); - ok(KISSY.isNumber(data.a), 'a is number'); - ok(data.a >= 1 && data.a <= 10, 'a between 1 and 10'); - }, - error:function(){ - } - }) - }); -}); - -test('KISSY[RAPPED] - getMockjsData - Prefix: /mockjsdata/, Action: /mockjs/base', function() { - stop(); - var base = '/mockjs/base'; - KISSY.use('io', function(S, IO) { - var old = RAP.getPrefix(); - RAP.setPrefix('/mockjsdata/'); - IO({ - type : "get", - url : base, - dataType : "jsonp", - jsonp: "callback", - success : function(data){ - start(); - ok('a' in data, 'property exists'); - ok(KISSY.isNumber(data.a), 'a is number'); - ok(data.a >= 1 && data.a <= 10, 'a between 1 and 10'); - }, - error:function(){ - } - }) - RAP.setPrefix(old); - }); -}); \ No newline at end of file diff --git a/WebContent/unit-tests/getruledata/datatypes.js b/WebContent/unit-tests/getruledata/datatypes.js deleted file mode 100644 index 3d8b5dac4..000000000 --- a/WebContent/unit-tests/getruledata/datatypes.js +++ /dev/null @@ -1,147 +0,0 @@ -module('mockjs-data-validation'); - -test('DATA_TYPES: exist and type', function() { - stop(); - var base = '/datatypes'; - KISSY.use('io', function(S, IO) { - IO({ - type : "get", - url : base, - dataType : "jsonp", - jsonp: "callback", - success : function(data){ - start(); - - ok('boolean' in data, 'boolean in data'); - ok('string' in data, 'string in data'); - ok('object' in data, 'object in data'); - ok('number' in data, 'number in data'); - - ok(KISSY.isNumber(data.number), 'number is number'); - ok(KISSY.isObject(data.object), 'object is object'); - ok(KISSY.isString(data.string), 'string is string'); - ok(KISSY.isBoolean(data.boolean), 'boolean is boolean'); - var obj = data.object; - ok('d' in obj, 'sub prop'); - - ok(KISSY.isNumber(obj.a), 'sub prop is number'); - ok(KISSY.isString(obj.b), 'sub prop is string'); - ok(KISSY.isBoolean(obj.c), 'sub prop is boolean'); - ok(KISSY.isObject(obj.d), 'sub prop is object'); - - ok(obj.d.d1, 'd1 in obj.d'); - ok(KISSY.isNumber(obj.d.d1), 'obj.d.d1 is number'); - - ok('array_boolean' in data, 'array boolean in data'); - ok('array_string' in data, 'array string in data'); - ok('array_number' in data, 'array number in data'); - ok('array_object' in data, 'array object in data'); - - ok(KISSY.isBoolean(data.array_boolean[0]), 'booleans[0] is boolean'); - ok(KISSY.isString(data.array_string[0]), 'strings[0] is string'); - ok(KISSY.isNumber(data.array_number[0]), 'numbers[0] is number'); - ok(KISSY.isObject(data.array_object[0]), 'objects[0] is object'); - - var obj = data.array_object[0]; - ok('d' in obj, 'sub prop exist'); - ok(KISSY.isObject(obj.d), 'is object!'); - ok('d1' in obj.d, 'sub sub prop exist'); - ok(KISSY.isNumber(obj.d.d1), 'is number'); - }, - error:function(){ - } - }) - }); -}); - - -test('DATA_TYPES: values', function() { - stop(); - var base = '/datatypes'; - KISSY.use('io', function(S, IO) { - IO({ - type : "get", - url : base, - dataType : "jsonp", - jsonp: "callback", - success : function(data){ - start(); - - ok(data.number >= 1 && data.number <= 20, 'number|1-20'); - ok(data.boolean === true || data.boolean === false, 'boolean is true or false'); - ok(/^B{1,5}$/.test(data.string), 'string is B{1-5}'); - - var obj = data.object; - ok('d' in obj, 'sub prop'); - - ok(obj.a >=1 && obj.a <= 10, 'a|1-10'); - ok(/^A{3,5}$/.test(obj.b), 'string is A{3-5}'); - ok(obj.c === true || obj.c === false, 'sub prop is boolean'); - - ok(obj.d.d1 >=3 && obj.d.d1 <=10, 'obj.d.d1|3-10'); - - var arr = data.array_boolean; - ok(arr[0] === true, 'a[0] = true'); - ok(arr[1] === false, 'a[1] = false'); - - var arr = data.array_string; - ok(arr[0] == 'a', 'b[0] = a'); - ok(arr[1] == 'b', 'b[1] = b'); - ok(arr[2] == 'c', 'b[2] = c'); - - var arr = data.array_number; - ok(arr[0] == 1, 'b[0] = 1'); - ok(arr[1] == 2, 'b[1] = 2'); - ok(arr[2] == 3, 'b[2] = 3'); - - var arr = data.array_object; - ok(arr.length == 3, 'object length is 3'); - - var obj = data.array_object[0]; - ok(obj.a >= 3 && obj.a <= 7, 'a|3-7'); - ok(/^A{4}$/.test(obj.b), 'b is AAAA'); - ok(obj.c === true || obj.c === false, 'c is true or false'); - ok(obj.d.d1 >= 3 && obj.d.d1 <= 7, 'd.d1|3-7'); - }, - error:function(){ - } - }) - }); -}); - -function propsIn(props, obj, name) { - for(var i = 0; i < props.length; i++) { - ok(props[i] in obj, props[i] + ' in ' + name); - } -} -test('DATA_TYPES: demo data from mockjs.com(import by JSON, Cool~)', function() { - stop(); - var base = '/mockjs/demo/from/site'; - KISSY.use('io', function(S, IO) { - IO({ - type : "get", - url : base, - dataType : "jsonp", - jsonp: "callback", - success : function(data){ - start(); - ok(data.data, 'data exists'); - ok(KISSY.isArray(data.data), 'data is array'); - ok(data.data.length >= 1 && data.data.length <= 10, 'data|1-10'); - var pick = data.data[0]; - propsIn(['cn', 'date', 'datetime', 'dummyimage', 'email', 'float1', 'float2', 'float3', - 'float4', 'grade1', 'grade2', 'img1', 'img2', 'method', 'param', 'published', 'repeat', 'size', - 'star', 'time'], pick, 'data[0]'); - equal(pick.id, 1, 'id is 1'); - if (data.data.length > 1) { - equal(data.data[1].id, 2, 'id increment'); - } - } - }) - }); -}); - -// TODO -// @mock=@value@prop test -// 各种mockjs的规则编辑测试 -// @mock=和直接写的测试 diff --git a/WebContent/unit-tests/prepare.js b/WebContent/unit-tests/prepare.js deleted file mode 100644 index f5ec3200e..000000000 --- a/WebContent/unit-tests/prepare.js +++ /dev/null @@ -1,22 +0,0 @@ -var root = /unit-tests/; -RAP.setHost(window.location.host); - -function loadScript(s, callback) { - $.getScript(root + s + '?' + (+new Date)).done(callback); -} - - -function loadScripts(scripts, callback) { - // keep in order - var i = 0; - loadScript(scripts[i], function() { - i++; - if (i == scripts.length) { - callback(); - return; - } - else { - loadScript(scripts[i], arguments.callee); - } - }); -} \ No newline at end of file diff --git a/WebContent/unit-tests/rap-plugin/base.js b/WebContent/unit-tests/rap-plugin/base.js deleted file mode 100644 index 3e2ce1487..000000000 --- a/WebContent/unit-tests/rap-plugin/base.js +++ /dev/null @@ -1,128 +0,0 @@ -module('rap-plugin-base'); - -test('KISSY.use("rap_io"), to see KISSY.io|KISSY.IO|KISSY.ajax', function() { - stop(); - action = '/base'; - KISSY.use('rap_io', function(S, IO) { - ok(KISSY.io != undefined, 'got KISSY.io'); - ok(KISSY.ajax != undefined, 'got KISSY.ajax'); - ok(KISSY.IO != undefined, 'got KISSY.IO'); - - ok(KISSY.io == IO, 'KISSY.io is rap_io'); - ok(KISSY.ajax == IO, 'KISSY.io is rap_io'); - ok(KISSY.IO == IO, 'KISSY.io is rap_io'); - - IO({ - url: action, - dataType:'json', - success: function(data) { - equal(typeof data.a, 'number', 'get data ok by KISSY.use("io")'); - start(); - } - }) - }) -}) - - -test('get data from KISSY.use("io")', function() { - stop(); - action = '/base'; - KISSY.use('io', function(S, IO) { - ok(KISSY.io != undefined, 'got KISSY.io'); - ok(KISSY.ajax != undefined, 'got KISSY.ajax'); - ok(KISSY.IO != undefined, 'got KISSY.IO'); - IO({ - url: action, - dataType:'json', - success: function(data) { - equal(typeof data.a, 'number', 'get data ok by KISSY.use("io")'); - start(); - } - }) - }) -}); - -test('get data from KISSY.use("ajax")', function() { - stop(); - action = '/base'; - KISSY.use('ajax', function(S, IO) { - IO({ - url: action, - dataType:'json', - success: function(data) { - equal(typeof data.a, 'number', 'get data ok by KISSY.use("ajax")'); - start(); - } - }) - }) -}); - -test('get Data from KISSY.io', function() { - action = '/base'; - stop(); - KISSY.io({ - url: action, - dataType:'json', - success: function(data) { - equal(typeof data.a, 'number', 'KISSY.io get data ok: a'); - equal(typeof data.b, 'string', 'KISSY.io get data ok: b'); - ok(KISSY.isObject(data.c), 'c is object'); - start(); - } - }); -}); - - -test('get Data from KISSY.ajax', function() { - action = '/base'; - stop(); - KISSY.io({ - url: action, - dataType:'json', - success: function(data) { - equal(typeof data.a, 'number', 'KISSY.ajax get data ok: a'); - equal(typeof data.b, 'string', 'KISSY.ajax get data ok: b'); - ok(KISSY.isObject(data.c), 'c is object'); - start(); - } - }); -}); - -test('KISSY.use("io", {success: function(S, IO) {}})', function() { - action = '/base'; - stop(); - KISSY.use("io", {success: function(S, IO) { - ok(KISSY.io != undefined, 'got KISSY.io'); - ok(KISSY.ajax != undefined, 'got KISSY.ajax'); - ok(KISSY.IO != undefined, 'got KISSY.IO'); - - IO({ - url: action, - dataType:'json', - success: function(data) { - equal(typeof data.a, 'number', 'get data ok'); - start(); - } - }) - }}) -}); - - -test('KISSY.use("ajax", {success: function(S, IO) {}})', function() { - action = '/base'; - stop(); - KISSY.use("ajax", {success: function(S, IO) { - ok(KISSY.io != undefined, 'got KISSY.io'); - ok(KISSY.ajax != undefined, 'got KISSY.ajax'); - ok(KISSY.IO != undefined, 'got KISSY.IO'); - - IO({ - url: action, - dataType:'json', - success: function(data) { - equal(typeof data.a, 'number', 'get data ok'); - start(); - } - }) - }}) -}); \ No newline at end of file diff --git a/WebContent/unit-tests/rap-plugin/for-seajs.js b/WebContent/unit-tests/rap-plugin/for-seajs.js deleted file mode 100644 index ca1f07aad..000000000 --- a/WebContent/unit-tests/rap-plugin/for-seajs.js +++ /dev/null @@ -1,64 +0,0 @@ -module('Seajs-jQuery-RAP'); - -test('Seajs+jQuery: basic check', function() { - stop(4); - ok(window.wrapJQueryForRAP, 'wrap method exists'); - define('a', function(require) { - start(1); - var jq = require('jquery'); - ok(jq.providedByRAP, 'provided by rap'); - ok(jq._rap_wrapped, 'ajax wrapped') - ok(jq('body')[0] == document.body, 'jquery is loaded by seajs'); - }) - - define('b', function(require) { - start(1); - var jq = require('jQuery'); - ok(jq.providedByRAP, 'provided by rap'); - ok(jq._rap_wrapped, 'ajax wrapped') - ok(jq('body')[0] == document.body, 'jQuery is loaded by seajs'); - }) - - define('c', function(require) { - start(1); - var jq = require('jq'); - ok(jq.providedByRAP, 'provided by rap'); - ok(jq._rap_wrapped, 'ajax wrapped') - ok(jq('body')[0] == document.body, 'jq is loaded by seajs'); - }) - - define('d', function(require) { - start(1); - var jq = require('jQ'); - ok(jq.providedByRAP, 'provided by rap'); - ok(jq._rap_wrapped, 'ajax wrapped') - ok(jq('body')[0] == document.body, 'jQ is loaded by seajs'); - }) - - seajs.use(['a','b','c','d'], function(a,b,c,d){}); -}); - - -test('Seajs+jQuery: get rap data', function() { - stop() - var action = '/base'; - define('e', function(require) { - var $ = require('jquery'); - equal(RAP.getPrefix(), '/mockjs/', 'PREFIX is /mockjs/'); - $.ajax({ - type : "get", - url : "/mockjs/base", - dataType : "jsonp", - jsonp: "callback", - success : function(data){ - start(); - ok('a' in data, 'mockjs : a is in data'); - ok(KISSY.isNumber(data['a']), 'and dataType is number'); - }, - error:function(){ - } - }); - }) - - seajs.use('e', function() {}); -}) \ No newline at end of file diff --git a/WebContent/unit-tests/rap-plugin/modes.js b/WebContent/unit-tests/rap-plugin/modes.js deleted file mode 100644 index 571a5b5ee..000000000 --- a/WebContent/unit-tests/rap-plugin/modes.js +++ /dev/null @@ -1,200 +0,0 @@ -module('rap-plugin-modes'); - -//mode 0:不走rap,应该404 -test('setMode 0 - 404 [KISSY]', function() { - var old = RAP.getMode(); - RAP.setMode(0); - - stop(); - var action = '/base'; - KISSY.use('io', function(S, IO) { - IO({ - url: action, - dataType:'json', - success: function(data) { - start(); - ok(0, 'in here, is not right in this case'); - RAP.setMode(old); - }, - error: function(data) { - start(); - ok(1, 'in here, 404 is right in this case'); - RAP.setMode(old); - } - }) - }) -}); - -//mode 0:不走rap,应该404 -test('setMode 0 - 404 [jQuery]', function() { - var old = RAP.getMode(); - RAP.setMode(0); - - stop(); - var action = '/base'; - $.rapAjax({ - type : "get", - url : action, - dataType : "jsonp", - jsonp: "callback", - success : function(data){ - start(); - ok(0, 'in here, is not right in this case'); - RAP.setMode(old); - }, - error:function(){ - start(); - ok(1, 'in here, 404 is right in this case'); - RAP.setMode(old); - } - }); -}); - - -//mode 0:放行 -test('setMode 0 - 200 [KISSY]', function() { - var old = RAP.getMode(); - RAP.setMode(0); - - stop(); - var action = '/mockjsdata/114/mockjs/base'; - KISSY.use('io', function(S, IO) { - IO({ - url: action, - dataType:'jsonp', - jsonp: 'callback', - success: function(data) { - start(); - ok(1, 'in here, is not right in this case'); - RAP.setMode(old); - }, - error: function(data) { - start(); - ok(0, 'in here, 404 is right in this case'); - RAP.setMode(old); - } - }) - }) -}); - -//mode 0:放行 -test('setMode 0 - 200 [jQuery]', function() { - var old = RAP.getMode(); - RAP.setMode(0); - - stop(); - var action = '/mockjsdata/114/mockjs/base'; - $.rapAjax({ - type : "get", - url : action, - dataType : "jsonp", - jsonp: "callback", - success : function(data){ - start(); - ok(1, 'in here, is not right in this case'); - RAP.setMode(old); - }, - error:function(){ - start(); - ok(0, 'in here, 404 is right in this case'); - RAP.setMode(old); - } - }); -}); - -//mode 1:拦截所有请求 -test('setMode 1 - 200 [KISSY]', function() { - var old = RAP.getMode(); - RAP.setMode(1); - - stop(); - var action = '/base'; - KISSY.use('io', function(S, IO) { - IO({ - url: action, - dataType:'json', - success: function(data) { - start(); - ok(1, 'in here, is right in this case'); - RAP.setMode(old); - }, - error: function(data) { - start(); - ok(0, 'in here, 404 is not right in this case'); - RAP.setMode(old); - } - }) - }) -}) - -// mode 1:拦截所有请求 -test('setMode 1 - 200 [jQuery]', function() { - var old = RAP.getMode(); - RAP.setMode(1); - - stop(); - var action = '/base'; - $.rapAjax({ - type : "get", - url : action, - dataType : "jsonp", - jsonp: "callback", - success : function(data){ - start(); - ok(1, 'in here, is right in this case'); - RAP.setMode(old); - }, - error:function(){ - start(); - ok(0, 'in here, 404 is not right in this case'); - RAP.setMode(old); - } - }); -}) - - -//mode 1:拦截所有请求 -test('setMode 1 - 404 [KISSY]', function() { - var old = RAP.getMode(); - RAP.setMode(1); - - stop(); - var action = '/mockjsdata/114/mockjs/base'; - KISSY.use('io', function(S, IO) { - IO({ - url: action, - dataType:'json', - success: function(data) { - start(); - ok(data.isOk === false, 'no matched action'); - equal(data.errMsg, 'no matched action', 'no matched action'); - RAP.setMode(old); - }, - error: function(data) { - } - }) - }) -}) - -// mode 1:拦截所有请求 -test('setMode 1 - 404 [jQuery]', function() { - var old = RAP.getMode(); - RAP.setMode(1); - - stop(); - var action = '/mockjsdata/114/mockjs/base'; - $.rapAjax({ - type : "get", - url : action, - dataType : "jsonp", - jsonp: "callback", - success : function(data){ - start(); - ok(data.isOk === false, 'no matched action'); - equal(data.errMsg, 'no matched action', 'no matched action'); - RAP.setMode(old); - }, - error:function(){ - } - }); -}) \ No newline at end of file diff --git a/WebContent/unit-tests/rap-plugin/whiteblack.js b/WebContent/unit-tests/rap-plugin/whiteblack.js deleted file mode 100644 index 79996e6fb..000000000 --- a/WebContent/unit-tests/rap-plugin/whiteblack.js +++ /dev/null @@ -1,245 +0,0 @@ -module('rap-plugin-whiteList'); - -test('setWhiteList[ok] in mode 3', function() { - var old = RAP.getMode(); - RAP.setMode(3); - var white = RAP.getWhiteList(); - RAP.setWhiteList(['/base']); - - stop(2); - var action = '/base'; - var counter = 0; - KISSY.use('io', function(S, IO) { - IO({ - url: action, - dataType:'json', - success: function(data) { - counter ++; - start(1); - ok(1, 'in here, is right in this case'); - if (counter == 2) { - RAP.setMode(old); - RAP.setWhiteList(white); - } - }, - error: function(data) { - counter ++; - start(1); - ok(0, 'in here, 404 is not right in this case'); - if (counter == 2) { - RAP.setMode(old); - RAP.setWhiteList(white); - } - } - }) - }) - - $.rapAjax({ - type : "get", - url : action, - dataType : "jsonp", - jsonp: "callback", - success : function(data){ - counter ++; - start(1); - ok(1, 'in here, is right in this case'); - if (counter == 2) { - RAP.setMode(old); - RAP.setWhiteList(white); - } - }, - error:function(){ - counter ++; - start(1); - ok(0, 'in here, 404 is not right in this case'); - if (counter == 2) { - RAP.setMode(old); - RAP.setWhiteList(white); - } - } - }); -}) - -test('setWhiteList[not ok] in mode 3', function() { - var old = RAP.getMode(); - RAP.setMode(3); - - var white = RAP.getWhiteList(); - RAP.setWhiteList(['/notExistsAction']); - - stop(2); - var action = '/base'; - var counter = 0; - KISSY.use('io', function(S, IO) { - IO({ - url: action, - dataType:'json', - success: function(data) { - counter ++; - start(1); - ok(0, 'whiteList mode, url node in list, should not 200'); - if (counter == 2) { - RAP.setMode(old); - RAP.setWhiteList(white); - } - }, - error: function(data) { - counter ++; - start(1); - ok(1, 'whiteList mode, url node in list, should 404'); - if (counter == 2) { - RAP.setMode(old); - RAP.setWhiteList(white); - } - } - }) - }) - - $.rapAjax({ - type : "get", - url : action, - dataType : "jsonp", - jsonp: "callback", - success : function(data){ - counter ++; - start(1); - ok(0, 'whiteList mode, url node in list, should not 200'); - if (counter == 2) { - RAP.setMode(old); - RAP.setWhiteList(white); - } - }, - error:function(){ - counter ++; - start(1); - ok(1, 'whiteList mode, url node in list, should 404'); - if (counter == 2) { - RAP.setMode(old); - RAP.setWhiteList(white); - } - } - }); -}) - - -module('rap-plugin-blackList'); - -test('setBlackList[not ok] in mode 2', function() { - var old = RAP.getMode(); - RAP.setMode(2); - - var black = RAP.getBlackList(); - RAP.setBlackList(['/notExistsAction']); - - stop(2); - var action = '/base'; - var counter = 0; - KISSY.use('io', function(S, IO) { - IO({ - url: action, - dataType:'json', - success: function(data) { - counter ++; - start(1); - ok(1, 'in here, is right in this case'); - if (counter == 2) { - RAP.setMode(old); - RAP.setBlackList(black); - } - }, - error: function(data) { - counter ++; - start(1); - ok(0, 'in here, 404 is not right in this case'); - if (counter == 2) { - RAP.setMode(old); - RAP.setBlackList(black); - } - } - }) - }) - - $.rapAjax({ - type : "get", - url : action, - dataType : "jsonp", - jsonp: "callback", - success : function(data){ - counter ++; - start(1); - ok(1, 'in here, is right in this case'); - if (counter == 2) { - RAP.setMode(old); - RAP.setBlackList(black); - } - }, - error:function(){ - counter ++; - start(1); - ok(0, 'in here, 404 is not right in this case'); - if (counter == 2) { - RAP.setMode(old); - RAP.setBlackList(black); - } - } - }); -}) - -test('setWhiteList[ok] in mode 2', function() { - var old = RAP.getMode(); - RAP.setMode(2); - - var black = RAP.getBlackList(); - RAP.setBlackList(['/base']); - - stop(2); - var action = '/base'; - var counter = 0; - KISSY.use('io', function(S, IO) { - IO({ - url: action, - dataType:'json', - success: function(data) { - counter ++; - start(1); - ok(0, 'whiteList mode, url node in list, should not 200'); - if (counter == 2) { - RAP.setMode(old); - RAP.setBlackList(black); - } - }, - error: function(data) { - counter ++; - start(1); - ok(1, 'whiteList mode, url node in list, should 404'); - if (counter == 2) { - RAP.setMode(old); - RAP.setBlackList(black); - } - } - }) - }) - - $.rapAjax({ - type : "get", - url : action, - dataType : "jsonp", - jsonp: "callback", - success : function(data){ - counter ++; - start(1); - ok(0, 'whiteList mode, url node in list, should not 200'); - if (counter == 2) { - RAP.setMode(old); - } - }, - error:function(){ - counter ++; - start(1); - ok(1, 'whiteList mode, url node in list, should 404'); - if (counter == 2) { - RAP.setMode(old); - } - } - }); -}) \ No newline at end of file diff --git a/WebContent/unit-tests/utility/structureValidator.js b/WebContent/unit-tests/utility/structureValidator.js deleted file mode 100644 index 5063c096c..000000000 --- a/WebContent/unit-tests/utility/structureValidator.js +++ /dev/null @@ -1,28 +0,0 @@ -module ('utility-structureValidator'); - - -test('Utility: StructureValidator functions test', function() { - var o1 = { - p1 : 1, - p2 : 2, - p3 : 3, - obj : [{ - op3 : 3, - op6 : 6, - op7 : 7 - }] - }; - var o2 = { - p1 : 1, - p3 : 3, - p4 : 4, - obj : [] - }; - - var validator = new StructureValidator(o1, o2); - - var correctData = {"left":[{"type":"LOST","property":"p4","namespace":"obj"}],"right":[{"type":"LOST","property":"p2","namespace":"obj"},{"type":"EMPTY_ARRAY","property":"obj","namespace":"obj"}]}; - var realData = validator.getResult(); - - deepEqual(correctData, realData, 'strcuture check complete'); -}); diff --git a/WebContent/workspace/myWorkspace.vm b/WebContent/workspace/myWorkspace.vm deleted file mode 100644 index 83965f757..000000000 --- a/WebContent/workspace/myWorkspace.vm +++ /dev/null @@ -1,531 +0,0 @@ - -#parse('/tcom/template.rap.vm') - - - - $!utils.escapeInH($workspace.project.name) - 文档编辑 - - #includeNewRapStatic - - - - - - - #bodyNewStart -
    -
    - -
    - - - - - #if($accessable) - - - - #end - - - - #if($accessable) - - #end -
    - - -
    -
    - -
    -
    -
    - -
    -
    - -
    -
    -
    -
    -
    - #bodyEnd - - - ## [todo] mode case - #if (1 == 1) - #startFloater("saveVSSFloater" "" 500 380) -
    - -
    - - - - - - - - - - - - - - - - - -
    推进版本 - - - - - - - - -
    变化预览:
    提交描述:
    - - -
    -
    -
    - #endFloater - #elseif ($workspace.modeInt == 2) - #startFloater("checkinFloater" "Check In" 600 400) -
    - -
    -
    -
    - -
    -
    - #endFloater - - #startFloater("checkoutFloater" "Check Out" 600 400) -
    - -
    -
    -
    - -
    -
    - #endFloater - #startFloater("validateFloater" "Validating" 600 400) -
    -
    推广分析[Module]->网民分析[Page]->行业ID[Parameter] has no length validator.
    -
    - #endFloater - - #startFloater("saveFloater" "Save/Load Workspace" 600 400) -
    - -
    -
    -
    -     -     -     - -
    -
    - #endFloater - #end - - #startFloater("versionFloater" "" 600 400) -
    - -
    -
    -
    - -     -     - -
    -
    - #endFloater - - #startFloater("editAFloater" "编辑接口" 600 300) -
    -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    名称 - -
    请求类型 - - - - - - - - -
    请求链接 - -
    回跳模板 - -
    说明 - -
    返回格式 - - - - -
    - -
    -
    - - -
    -
    -
    - #endFloater - #startFloater("editPFloater" "编辑页面" 600 400) -
    -
    - - - - - - - - - - - - -
    名称 - -
    说明 - -
    -
    - - -
    -
    -
    - #endFloater - #startFloater("importJSONFloater" "JSON导入" 600 350) -
    - -
    - - - - -
    - -
    -
    - - -
    -
    -
    - #endFloater - #startFloater("exportRAPDataFloater" "JSON导入" 600 350) -
    -
    - - - - -
    - -
    -
    - -
    -
    -
    - #endFloater - #startFloater("pluginCodeFloater" "FE工具箱" 600 230) -
    -
    -
    插件代码
    -
    - -
    -
    项目路由
    -
    - -
    -
    - - -
    -
    -
    - -
    -
    - #endFloater - #startFloater("actionUrlFloater" "请求链接" 600 180) -
    -
    -
    - -
    -
    - -
    -
    -
    - #endFloater - - #startFloater("mockDataPreviewFloater" "Mock数据预览" 600 600) -
    -
    -
    Mock规则 - -
    - -
    -
    -
    Mock数据 - - - -
    - -
    -
    - -
    -
    - #endFloater - - #startFloater("actionOpFloater" "文档操作" 600 230) -
    -
    -
    - -
    - - - -
    -
    -
    - -
      -
    • - -
    • -
    • - -
    • -
    -
    -
    - - -
    -
    -
    - #endFloater - - - diff --git a/lab/rap.plugin.xinglie.js b/lab/rap.plugin.xinglie.js index 93569a6a5..7bf9f8e11 100644 --- a/lab/rap.plugin.xinglie.js +++ b/lab/rap.plugin.xinglie.js @@ -1,5 +1,5 @@ /*! rap.plugin May.30th 2014 by 行列 */ -(function() { +(function () { var node = null; var blackList = []; var whiteList = ["/api/dspfilter/zonesizes", "/api/dspfilter/distypes", "/api/dspfilter/screens", "/api/dspfilter/sitetypes", "/api/dspfilter/pagelist", "/api/dspfilter/urls", "/api/dspsettle/account/balance", "/api/dspsettle/account/list", "/api/log", "/api/dspsettle/account/anotice"]; @@ -23,10 +23,14 @@ // console handler if (typeof window.console === 'undefined') { window.console = { - log: function() {}, - warn: function() {}, - info: function() {}, - dir: function() {} + log: function () { + }, + warn: function () { + }, + info: function () { + }, + dir: function () { + } }; } @@ -59,77 +63,77 @@ } /*function wrapJQuery(jQuery) { - if (jQuery._rap_wrapped) { - return; - } - jQuery._rap_wrapped = true; - - var ajax = jQuery.ajax; - jQuery.ajax = function() { - var oOptions = arguments[0]; - var url = oOptions.url; - if (route(url) && projectId) { - rapUrlConverterJQuery(oOptions); - var oldSuccess1 = oOptions.success; - oldSuccess1 && (oOptions.success = function(data) { - if (PREFIX == '/mockjs/') { - data = Mock.mock(data); - console.log('请求' + url + '返回的Mock数据:'); - console.dir(data); - - } - oldSuccess1.apply(this, arguments); - }); - - var oldComplete = oOptions.complete; - oldComplete && (oOptions.complete = function(data) { - if (PREFIX == '/mockjs/') { - data = Mock.mock(data); - console.log('请求' + url + '返回的Mock数据:'); - console.dir(data); - - } - oldComplete.apply(this, arguments); - }); - } else if (isInWhiteList(url) && !oOptions.RAP_NOT_TRACK) { - var checkerOptions = { - url: oOptions.url - }; - rapUrlConverterJQuery(checkerOptions); - checkerOptions.RAP_NOT_TRACK = true; - checkerOptions.success = checkerHandler; - // real data checking - var oldSuccess2 = oOptions.success; - oOptions.success = function() { - var realData = arguments[0]; - checkerOptions.context = { - data: realData, - url: oOptions.url - }; - // perform real data check - ajax.apply(jQuery, [checkerOptions]); - oldSuccess2.apply(this, arguments); - }; - } - ajax.apply(this, arguments); - }; - } - - window.wrapJQueryForRAP = wrapJQuery;*/ + if (jQuery._rap_wrapped) { + return; + } + jQuery._rap_wrapped = true; + + var ajax = jQuery.ajax; + jQuery.ajax = function() { + var oOptions = arguments[0]; + var url = oOptions.url; + if (route(url) && projectId) { + rapUrlConverterJQuery(oOptions); + var oldSuccess1 = oOptions.success; + oldSuccess1 && (oOptions.success = function(data) { + if (PREFIX == '/mockjs/') { + data = Mock.mock(data); + console.log('请求' + url + '返回的Mock数据:'); + console.dir(data); + + } + oldSuccess1.apply(this, arguments); + }); + + var oldComplete = oOptions.complete; + oldComplete && (oOptions.complete = function(data) { + if (PREFIX == '/mockjs/') { + data = Mock.mock(data); + console.log('请求' + url + '返回的Mock数据:'); + console.dir(data); + + } + oldComplete.apply(this, arguments); + }); + } else if (isInWhiteList(url) && !oOptions.RAP_NOT_TRACK) { + var checkerOptions = { + url: oOptions.url + }; + rapUrlConverterJQuery(checkerOptions); + checkerOptions.RAP_NOT_TRACK = true; + checkerOptions.success = checkerHandler; + // real data checking + var oldSuccess2 = oOptions.success; + oOptions.success = function() { + var realData = arguments[0]; + checkerOptions.context = { + data: realData, + url: oOptions.url + }; + // perform real data check + ajax.apply(jQuery, [checkerOptions]); + oldSuccess2.apply(this, arguments); + }; + } + ajax.apply(this, arguments); + }; + } + + window.wrapJQueryForRAP = wrapJQuery;*/ // ************************************************************************************************ var guid = +new Date(); - var JSONP = function(url, callback) { + var JSONP = function (url, callback) { var me = this; var script = document.createElement('script'); var key = 'jsonp' + guid++; var success; - window[key] = function(data) { + window[key] = function (data) { callback(data); delete window[key]; success = true; }; - script.onload = script.onreadystatechange = script.onerror = function() { - setTimeout(function() { + script.onload = script.onreadystatechange = script.onerror = function () { + setTimeout(function () { script.parentNode.removeChild(script); if (!success) { callback('script error'); @@ -140,10 +144,10 @@ script.src = url + '&_c=' + key; document.body.appendChild(script); }; - var isFunction = function(f) { + var isFunction = function (f) { return Object.prototype.toString.call(f) == '[object Function]'; }; - var parseURLParamsArray = function(url) { + var parseURLParamsArray = function (url) { var q = url ? url.indexOf("?") : -1; if (q == -1) return []; @@ -156,7 +160,7 @@ return parseURLEncodedTextArray(search); }; - var parseURLEncodedTextArray = function(text) { + var parseURLEncodedTextArray = function (text) { var maxValueLength = 25000; var params = []; @@ -185,7 +189,7 @@ } } - params.sort(function(a, b) { + params.sort(function (a, b) { return a.name <= b.name ? -1 : 1; }); @@ -196,7 +200,7 @@ // ************************************************************************************************ // XMLHttpRequestWrapper - var XMLHttpRequestWrapper = function(activeXObject) { + var XMLHttpRequestWrapper = function (activeXObject) { // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // XMLHttpRequestWrapper internal variables @@ -225,7 +229,7 @@ setRequestHeader: 1 }; - var updateSelfProperties = function() { + var updateSelfProperties = function () { if (supportsXHRIterator) { for (var propName in xhrRequest) { if (propName in updateSelfPropertiesIgnore) continue; @@ -261,7 +265,7 @@ upload: 1 }; - var updateXHRProperties = function() { + var updateXHRProperties = function () { for (var propName in self) { if (propName in updateXHRPropertiesIgnore) continue; @@ -278,7 +282,7 @@ }; - var handleStateChange = function() { + var handleStateChange = function () { //Firebug.Console.log(["onreadystatechange", xhrRequest.readyState, xhrRequest.readyState == 4 && xhrRequest.status]); self.readyState = xhrRequest.readyState; @@ -286,7 +290,8 @@ if (xhrRequest.readyState == 4) { updateSelfProperties(); - xhrRequest.onreadystatechange = function() {}; + xhrRequest.onreadystatechange = function () { + }; } //Firebug.Console.log(spy.url + ": " + xhrRequest.readyState); @@ -299,12 +304,13 @@ this.readyState = 0; - this.onreadystatechange = function() {}; + this.onreadystatechange = function () { + }; // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // XMLHttpRequestWrapper public methods - this.open = function(method, url, async, user, password) { + this.open = function (method, url, async, user, password) { //Firebug.Console.log("xhrRequest open"); updateSelfProperties(); @@ -321,7 +327,8 @@ // xhrRequest.open.apply may not be available in IE if (supportsApply) xhrRequest.open.apply(xhrRequest, arguments); else xhrRequest.open(method, url, async, user, password); - } catch (e) {} + } catch (e) { + } xhrRequest.onreadystatechange = handleStateChange; @@ -329,10 +336,10 @@ // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * - this.send = function(data) { + this.send = function (data) { if (this.$useJSONP) { var me = this; - JSONP(me.$url, function(data) { + JSONP(me.$url, function (data) { console.log(data); if (data !== 'script error') { data = JSON.stringify(Mock.mock(data)); @@ -362,7 +369,7 @@ // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * - this.setRequestHeader = function(header, value) { + this.setRequestHeader = function (header, value) { if (this.$useJSONP) return; return xhrRequest.setRequestHeader(header, value); }; @@ -370,7 +377,7 @@ // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * - this.abort = function() { + this.abort = function () { if (this.$useJSONP) return; xhrRequest.abort(); updateSelfProperties(); @@ -378,13 +385,13 @@ // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * - this.getResponseHeader = function(header) { + this.getResponseHeader = function (header) { return xhrRequest.getResponseHeader(header); }; // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * - this.getAllResponseHeaders = function() { + this.getAllResponseHeaders = function () { return xhrRequest.getAllResponseHeaders(); }; @@ -407,14 +414,14 @@ if (isFunction(propValue)) { if (typeof self[propName] == "undefined") { - this[propName] = (function(name, xhr) { + this[propName] = (function (name, xhr) { return supportsApply ? - // if the browser supports apply + // if the browser supports apply - function() { - return xhr[name].apply(xhr, arguments); - } : function(a, b, c, d, e) { + function () { + return xhr[name].apply(xhr, arguments); + } : function (a, b, c, d, e) { return xhr[name](a, b, c, d, e); }; @@ -445,7 +452,7 @@ var xhrObjects = " MSXML2.XMLHTTP.5.0 MSXML2.XMLHTTP.4.0 MSXML2.XMLHTTP.3.0 MSXML2.XMLHTTP Microsoft.XMLHTTP "; - window.ActiveXObject = function(name) { + window.ActiveXObject = function (name) { var error = null; try { @@ -466,7 +473,7 @@ // Register the XMLHttpRequestWrapper for non-IE6 browsers if (!isIE6) { var _XMLHttpRequest = XMLHttpRequest; - window.XMLHttpRequest = function() { + window.XMLHttpRequest = function () { return new XMLHttpRequestWrapper(); }; } @@ -478,135 +485,135 @@ * jQuery override */ /*if (window.jQuery) { - wrapJQuery(window.jQuery); - }*/ + wrapJQuery(window.jQuery); + }*/ /** * kissy override */ /*if (window.KISSY) { - KISSY.oldUse = KISSY.use; - KISSY.oldAdd = KISSY.add; - - KISSY.add('rap_io', function(S, IO) { - var oldIO = IO; - var key; - var fn = KISSY.io = KISSY.IO = KISSY.ajax = function(options) { - var oOptions, url; - if (arguments[0]) { - oOptions = arguments[0]; - url = oOptions.url; - if (route(url) && !oOptions.RAP_NOT_TRACK) { - rapUrlConverterKissy(oOptions); - var oldSuccess1 = oOptions.success; - oldSuccess1 && (oOptions.success = function(data) { - if (PREFIX == '/mockjs/') { - data = Mock.mock(data); - console.log('请求' + url + '返回的Mock数据:'); - console.dir(data); - } - oldSuccess1.apply(this, arguments); - }); - var oldComplete = oOptions.complete; - oldComplete && (oOptions.complete = function(data) { - if (PREFIX == '/mockjs/') { - data = Mock.mock(data); - console.log('请求' + url + '返回的Mock数据:'); - console.dir(data); - - } - oldComplete.apply(this, arguments); - }); - } else if (isInWhiteList(url) && !oOptions.RAP_NOT_TRACK) { - var checkerOptions = { - url: oOptions.url - }; - rapUrlConverterKissy(checkerOptions); - checkerOptions.RAP_NOT_TRACK = true; - checkerOptions.success = checkerHandler; - // real data checking - var oldSuccess2 = oOptions.success; - oOptions.success = function() { - var realData = arguments[0]; - checkerOptions.context = { - data: realData, - url: oOptions.url - }; - // perform real data check - IO(checkerOptions); - oldSuccess2.apply(this, arguments); - }; - - } - } - IO.apply(this, arguments); - }; - - for (key in oldIO) { - if (oldIO.hasOwnProperty(key)) { - fn[key] = oldIO[key]; - } - } - - return fn; - }, { - requires: ['ajax'] - }); - - - KISSY.use = function(modules, callback) { - var args = arguments; - if (modules instanceof Array || typeof modules === 'string') { - args[0] = replace(modules); - } - KISSY.oldUse.apply(this, args); - }; - - KISSY.add = function(name, fn, options) { - if (options && options.requires) { - - for (var i = 0, l = options.requires.length; i < l; i++) { - var current = options.requires[i].toLowerCase(); - - if (current == 'io' || current == 'ajax') { - options.requires[i] = 'rap_io'; - } - } - } - - KISSY.oldAdd.apply(this, arguments); - }; - - if (KISSY.IO || KISSY.io || KISSY.ajax) { - KISSY.use('rap_io', function() {}); - } - - }*/ + KISSY.oldUse = KISSY.use; + KISSY.oldAdd = KISSY.add; + + KISSY.add('rap_io', function(S, IO) { + var oldIO = IO; + var key; + var fn = KISSY.io = KISSY.IO = KISSY.ajax = function(options) { + var oOptions, url; + if (arguments[0]) { + oOptions = arguments[0]; + url = oOptions.url; + if (route(url) && !oOptions.RAP_NOT_TRACK) { + rapUrlConverterKissy(oOptions); + var oldSuccess1 = oOptions.success; + oldSuccess1 && (oOptions.success = function(data) { + if (PREFIX == '/mockjs/') { + data = Mock.mock(data); + console.log('请求' + url + '返回的Mock数据:'); + console.dir(data); + } + oldSuccess1.apply(this, arguments); + }); + var oldComplete = oOptions.complete; + oldComplete && (oOptions.complete = function(data) { + if (PREFIX == '/mockjs/') { + data = Mock.mock(data); + console.log('请求' + url + '返回的Mock数据:'); + console.dir(data); + + } + oldComplete.apply(this, arguments); + }); + } else if (isInWhiteList(url) && !oOptions.RAP_NOT_TRACK) { + var checkerOptions = { + url: oOptions.url + }; + rapUrlConverterKissy(checkerOptions); + checkerOptions.RAP_NOT_TRACK = true; + checkerOptions.success = checkerHandler; + // real data checking + var oldSuccess2 = oOptions.success; + oOptions.success = function() { + var realData = arguments[0]; + checkerOptions.context = { + data: realData, + url: oOptions.url + }; + // perform real data check + IO(checkerOptions); + oldSuccess2.apply(this, arguments); + }; + + } + } + IO.apply(this, arguments); + }; + + for (key in oldIO) { + if (oldIO.hasOwnProperty(key)) { + fn[key] = oldIO[key]; + } + } + + return fn; + }, { + requires: ['ajax'] + }); + + + KISSY.use = function(modules, callback) { + var args = arguments; + if (modules instanceof Array || typeof modules === 'string') { + args[0] = replace(modules); + } + KISSY.oldUse.apply(this, args); + }; + + KISSY.add = function(name, fn, options) { + if (options && options.requires) { + + for (var i = 0, l = options.requires.length; i < l; i++) { + var current = options.requires[i].toLowerCase(); + + if (current == 'io' || current == 'ajax') { + options.requires[i] = 'rap_io'; + } + } + } + + KISSY.oldAdd.apply(this, arguments); + }; + + if (KISSY.IO || KISSY.io || KISSY.ajax) { + KISSY.use('rap_io', function() {}); + } + + }*/ } /*if (window.define && window.define.cmd) { - var data = seajs.config().data; - data.alias = data.alias || {}; - var path = 'http://' + ROOT + '/stat/js/util/jquery-rapped.js'; - data.alias.jquery = data.alias.jQuery = data.alias.jq = data.alias.jQ = data.alias.$ = path; - } - - function replace(modules) { - var splited = modules; - if (KISSY.isString(modules)) { - splited = modules.split(','); - } - var index = -1; - for (var i = 0, l = splited.length; i < l; i++) { - var name = KISSY.trim(splited[i]).toLowerCase(); - if (name === 'ajax' || name === 'io') { - splited[i] = 'rap_io'; - } - } - return splited.join(','); - } -*/ + var data = seajs.config().data; + data.alias = data.alias || {}; + var path = 'http://' + ROOT + '/stat/js/util/jquery-rapped.js'; + data.alias.jquery = data.alias.jQuery = data.alias.jq = data.alias.jQ = data.alias.$ = path; + } + + function replace(modules) { + var splited = modules; + if (KISSY.isString(modules)) { + splited = modules.split(','); + } + var index = -1; + for (var i = 0, l = splited.length; i < l; i++) { + var name = KISSY.trim(splited[i]).toLowerCase(); + if (name === 'ajax' || name === 'io') { + splited[i] = 'rap_io'; + } + } + return splited.join(','); + } + */ function checkerHandler(mockData) { if (PREFIX == '/mockjs/') { @@ -791,7 +798,7 @@ } window.RAP = { - initList: function(list) { + initList: function (list) { var PARAM_REG = /\/:[^\/]*/g; var i, n = list.length, item; @@ -810,26 +817,26 @@ } return list; }, - setBlackList: function(arr) { + setBlackList: function (arr) { if (arr && arr instanceof Array) { blackList = this.initList(arr); } }, - setWhiteList: function(arr) { + setWhiteList: function (arr) { if (arr && arr instanceof Array) { whiteList = this.initList(arr); } }, - getBlackList: function() { + getBlackList: function () { return blackList; }, - getWhiteList: function() { + getWhiteList: function () { return whiteList; }, - getMode: function() { + getMode: function () { return mode; }, - setMode: function(m) { + setMode: function (m) { m = +m; if (m in modeList) { mode = m; @@ -838,22 +845,22 @@ console.warn('Illegal mode id. Please check.'); } }, - setHost: function(h) { + setHost: function (h) { ROOT = h; }, - getHost: function() { + getHost: function () { return ROOT; }, - setPrefix: function(p) { + setPrefix: function (p) { PREFIX = p; }, - getPrefix: function(p) { + getPrefix: function (p) { return PREFIX; }, - setProjectId: function(id) { + setProjectId: function (id) { projectId = id; }, - getProjectId: function() { + getProjectId: function () { return projectId; } }; diff --git a/lab/rapActionSample.js b/lab/rapActionSample.js index 9208a589c..20e9fce35 100644 --- a/lab/rapActionSample.js +++ b/lab/rapActionSample.js @@ -3,16 +3,30 @@ */ { - "id": 627, // 请求ID - "name": "报表数据", // 请求名称 - "description": "获取报表数据", // 请求描述 - "requestType": "1", // 请求类型(GET/POST) - "requestUrl": "/snsADGroup/listSNSADGroup.htm", // 请求链接 - "responseTemplate": "", + "id" +: + 627, // 请求ID + "name" +: + "报表数据", // 请求名称 + "description" +: + "获取报表数据", // 请求描述 + "requestType" +: + "1", // 请求类型(GET/POST) + "requestUrl" +: + "/snsADGroup/listSNSADGroup.htm", // 请求链接 + "responseTemplate" +: + "", /** * 请求参数列表 */ - "requestParameterList": [{ + "requestParameterList" +: + [{ "id": 11819, // 参数ID "identifier": "queryVO", // 参数标识符 "name": "请求对象", // 参数名称 @@ -82,8 +96,10 @@ * * 结构与请求参数列表相同 */ - "responseParameterList": [{ - "id": 11635, + "responseParameterList" +: + [{ + "id": 11635, "identifier": "result", "name": "", "remark": "", diff --git a/pom.xml b/pom.xml new file mode 100644 index 000000000..534119cdf --- /dev/null +++ b/pom.xml @@ -0,0 +1,208 @@ + + + 4.0.0 + + groupId + RAP + 0.13.0-SNAPSHOT + war + + + + redis.clients + jedis + 2.7.2 + jar + compile + + + org.codehaus.jackson + jackson-mapper-asl + 1.8.8 + + + org.apache.struts + struts2-core + 2.3.24.1 + + + javassist + javassist + + + + + org.springframework + spring-orm + 4.2.4.RELEASE + + + dk.brics.automaton + automaton + 1.11-8 + + + org.apache.velocity + velocity + 1.7 + + + org.springframework + spring-context + 4.2.4.RELEASE + + + + org.springframework + spring-context-support + 4.2.4.RELEASE + + + org.springframework + spring-web + 4.2.4.RELEASE + + + org.apache.velocity + velocity-tools + 2.0 + + + javax.servlet.jsp + javax.servlet.jsp-api + 2.3.1 + + + org.apache.struts + struts2-spring-plugin + 2.3.24.1 + + + com.google.code.gson + gson + 2.3.1 + + + org.tuckey + urlrewritefilter + 4.0.4 + + + javax.transaction + jta + 1.1 + + + c3p0 + c3p0 + 0.9.1.2 + + + mysql + mysql-connector-java + 5.1.6 + + + dom4j + dom4j + 1.6.1 + + + javax.mail + javax.mail-api + 1.5.5 + + + org.apache.logging.log4j + log4j-api + 2.5 + + + org.apache.logging.log4j + log4j-core + 2.5 + + + com.belerweb + pinyin4j + 2.5.0 + + + org.slf4j + slf4j-log4j12 + 1.5.6 + + + org.ocpsoft.prettytime + prettytime + 3.2.3.Final + + + org.hibernate + hibernate-core + 5.0.6.Final + + + org.mozilla + rhino + 1.7.7 + + + nl.flotsam + xeger + 1.0.0-SNAPSHOT + system + ${basedir}/src/main/webapp/WEB-INF/lib/xeger-1.0-SNAPSHOT.jar + + + com.alibaba + buc.sso.common + 0.4.4 + system + ${basedir}/src/main/webapp/WEB-INF/lib/buc.sso.common-0.4.4.jar + + + com.alibaba + buc.sso.client + 0.4.4 + system + ${basedir}/src/main/webapp/WEB-INF/lib/buc.sso.client-0.4.4.jar + + + javax.servlet + javax.servlet-api + 3.1.0 + provided + + + antlr + antlr + 2.7.7 + + + + + + org.codehaus.cargo + cargo-maven2-plugin + 1.4.17 + + tomcat8x + http://apache.dataguru.cn/tomcat/tomcat-8/v8.0.30/bin/apache-tomcat-8.0.30.tar.gz + + + ${project.groupId} + ${project.artifactId} + war + + / + + + + + + + + diff --git a/src/Tester.java b/src/Tester.java deleted file mode 100644 index 226b6fc21..000000000 --- a/src/Tester.java +++ /dev/null @@ -1,13 +0,0 @@ -import com.taobao.rigel.rap.account.service.impl.AccountMgrImpl; -import com.taobao.rigel.rap.common.Patterns; -import com.taobao.rigel.rap.common.StringUtils; - -/** - * Created by Bosn on 2014/8/16. - */ -public class Tester { - public static void main(String[] args) { - - System.out.println(StringUtils.getDoubleMD5("123456")); - } -} diff --git a/src/applicationContext.xml b/src/applicationContext.xml deleted file mode 100644 index 271312adf..000000000 --- a/src/applicationContext.xml +++ /dev/null @@ -1,125 +0,0 @@ - - - - - - - - - *Mgr - *Service - *Proxy - - - - - - transactionInterceptor - - - - - - - - - - - - - - - classpath:/mysql.local.properties - - - - - - ${jdbc.driverClassName} - - - ${jdbc.url} - - - ${jdbc.username} - - - ${jdbc.password} - - - ${jdbc.maxPoolSize} - - - ${jdbc.minPoolSize} - - - ${jdbc.idleConnectionTestPeriod} - - - - ${jdbc.maxIdleTime} - - - - - - - - - - com/taobao/rigel/rap/project/mapping/Project.hbm.xml - com/taobao/rigel/rap/project/mapping/Module.hbm.xml - com/taobao/rigel/rap/project/mapping/Page.hbm.xml - com/taobao/rigel/rap/project/mapping/Action.hbm.xml - com/taobao/rigel/rap/project/mapping/Parameter.hbm.xml - com/taobao/rigel/rap/account/mapping/User.hbm.xml - com/taobao/rigel/rap/account/mapping/Role.hbm.xml - com/taobao/rigel/rap/account/mapping/Notification.hbm.xml - com/taobao/rigel/rap/workspace/mapping/Workspace.hbm.xml - com/taobao/rigel/rap/workspace/mapping/Save.hbm.xml - com/taobao/rigel/rap/workspace/mapping/CheckIn.hbm.xml - com/taobao/rigel/rap/organization/mapping/Corporation.hbm.xml - com/taobao/rigel/rap/organization/mapping/Group.hbm.xml - com/taobao/rigel/rap/organization/mapping/ProductionLine.hbm.xml - com/taobao/rigel/rap/mock/mapping/Rule.hbm.xml - - - - - org.hibernate.dialect.MySQLDialect - false - - - - - - - - - - - - - - - - - - - PROPAGATION_REQUIRED - - - - - diff --git a/src/com/taobao/rigel/rap/account/applicationContext.xml b/src/com/taobao/rigel/rap/account/applicationContext.xml deleted file mode 100644 index 85c000603..000000000 --- a/src/com/taobao/rigel/rap/account/applicationContext.xml +++ /dev/null @@ -1,17 +0,0 @@ - - - - - - - - - - - - - \ No newline at end of file diff --git a/src/com/taobao/rigel/rap/account/bo/Notification.java b/src/com/taobao/rigel/rap/account/bo/Notification.java deleted file mode 100644 index de3466751..000000000 --- a/src/com/taobao/rigel/rap/account/bo/Notification.java +++ /dev/null @@ -1,120 +0,0 @@ -package com.taobao.rigel.rap.account.bo; - -import java.util.Date; -import java.util.Locale; - -import org.ocpsoft.prettytime.PrettyTime; - -public class Notification { - private long id; - private long userId; - private long targetUserId; - public long getTargetUserId() { - return targetUserId; - } - - public void setTargetUserId(long targetUserId) { - this.targetUserId = targetUserId; - } - - private short typeId; - private String param1; - private String param2; - private String param3; - private Date createTime; - private boolean isRead; - - - public String getCreateTimeStr() { - PrettyTime p = new PrettyTime(new Locale("zh")); - return p.format(this.createTime); - } - - public long getId() { - return id; - } - - public void setId(long id) { - this.id = id; - } - - public long getUserId() { - return userId; - } - - public void setUserId(long userId) { - this.userId = userId; - } - - public short getTypeId() { - return typeId; - } - - public void setTypeId(short typeId) { - this.typeId = typeId; - } - - public String getParam1() { - return param1; - } - - public void setParam1(String param1) { - this.param1 = param1; - } - - public String getParam2() { - return param2; - } - - public void setParam2(String param2) { - this.param2 = param2; - } - - public String getParam3() { - return param3; - } - - public void setParam3(String param3) { - this.param3 = param3; - } - - public Date getCreateTime() { - return createTime; - } - - public void setCreateTime(Date createTime) { - this.createTime = createTime; - } - - public boolean isRead() { - return isRead; - } - - public void setRead(boolean isRead) { - this.isRead = isRead; - } - - private User user; - - public User getUser() { - return user; - } - - public void setUser(User user) { - this.user = user; - } - - private User targetUser; - - - public User getTargetUser() { - return targetUser; - } - - public void setTargetUser(User targetUser) { - this.targetUser = targetUser; - } - - - -} diff --git a/src/com/taobao/rigel/rap/account/bo/Profile.java b/src/com/taobao/rigel/rap/account/bo/Profile.java deleted file mode 100644 index b7b81636d..000000000 --- a/src/com/taobao/rigel/rap/account/bo/Profile.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.taobao.rigel.rap.account.bo; - -public class Profile { - private boolean isHintEnabled; - - public boolean getIsHintEnabled() { - return isHintEnabled; - } - - public void setIsHintEnabled(boolean isHintEnabled) { - this.isHintEnabled = isHintEnabled; - } -} diff --git a/src/com/taobao/rigel/rap/account/bo/Role.java b/src/com/taobao/rigel/rap/account/bo/Role.java deleted file mode 100644 index f13704a9a..000000000 --- a/src/com/taobao/rigel/rap/account/bo/Role.java +++ /dev/null @@ -1,29 +0,0 @@ -package com.taobao.rigel.rap.account.bo; - -public class Role implements java.io.Serializable { - - /** - * - */ - private static final long serialVersionUID = 1L; - - private int id; - private String name; - - public int getId() { - return this.id; - } - - public void setId(int id) { - this.id = id; - } - - public String getName() { - return this.name; - } - - public void setName(String name) { - this.name = name; - } - -} diff --git a/src/com/taobao/rigel/rap/account/bo/User.java b/src/com/taobao/rigel/rap/account/bo/User.java deleted file mode 100644 index a2e53f534..000000000 --- a/src/com/taobao/rigel/rap/account/bo/User.java +++ /dev/null @@ -1,272 +0,0 @@ -package com.taobao.rigel.rap.account.bo; - -import java.text.DateFormat; -import java.text.SimpleDateFormat; -import java.util.ArrayList; -import java.util.Date; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; - -import com.taobao.rigel.rap.project.bo.Project; - -public class User implements java.io.Serializable { - - private static final long serialVersionUID = 1L; - private long id; - private String name; - private String account; - private String password; - private String email; - private Date createDate; - private boolean isLockedOut; - private Date lastLoginDate; - private int incorrectLoginAttempt; - private String realname; - private String empId; - private int roleId; - - public String getEmpId() { - return empId; - } - - public void setEmpId(String empId) { - this.empId = empId; - } - - public Map getUserBaseInfo() { - Map base = new HashMap(); - base.put("name", this.name); - base.put("id", this.id); - base.put("email", this.email); - return base; - } - - public boolean isAdmin() { - for (Role role : this.getRoleList()) { - // roleId = 1, means super admin (god) - // roleId = 2, means admin - if (role.getId() >= 1 && role.getId() <= 2) return true; - } - return false; - } - - public void setRealname(String realname) { - this.realname = realname; - } - - public long getId() { - return this.id; - } - - public void setId(long id) { - this.id = id; - } - - private Set roleList = new HashSet(); - - public Set getRoleList() { - return this.roleList; - } - - public void setRoleList(Set roleList) { - this.roleList = roleList; - } - - public boolean isUserInRole(String roleName) { - for (Role r : getRoleList()) { - if (r.getName().equals(roleName)) { - return true; - } - } - return false; - } - - public String getRoleListStr() { - String str = ""; - for (Role r : getRoleList()) { - str += r.getName() + " "; - } - return str; - } - - public List getAccessibleProjectList() { - List projectList = new ArrayList(); - for (Project p : getCreatedProjectList()) { - p.setIsManagable(true); - projectList.add(p); - } - for (Project p : getJoinedProjectList()) { - projectList.add(p); - } - return projectList; - } - - public boolean haveAccessOfProject(int projectId) { - if (isUserInRole("admin")) { - return true; - } - for (Project p : getCreatedProjectList()) { - if (p.getId() == projectId) { - return true; - } - } - - for (Project p : getJoinedProjectList()) { - if (p.getId() == projectId) { - return true; - } - } - return false; - } - - private Set createdProjectList = new HashSet(); - - public Set getCreatedProjectList() { - return this.createdProjectList; - } - - public void setCreatedProjectList(Set createdProjectList) { - this.createdProjectList = createdProjectList; - } - - private Set joinedProjectList = new HashSet(); - - public Set getJoinedProjectList() { - return this.joinedProjectList; - } - - public void setJoinedProjectList(Set joinedProjectList) { - this.joinedProjectList = joinedProjectList; - } - - public String getAccount() { - return this.account; - } - - public void setAccount(String account) { - this.account = account; - } - - public String getName() { - return this.name; - } - - public void setName(String name) { - this.name = name; - } - - public String getPassword() { - return this.password; - } - - public void setPassword(String password) { - this.password = password; - } - - public String getEmail() { - return this.email; - } - - public void setEmail(String email) { - this.email = email; - } - - public Date getCreateDate() { - return this.createDate; - } - - public void setCreateDate(Date createDate) { - this.createDate = createDate; - } - - public String getCreateDateStr() { - DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd"); - return dateFormat.format(getCreateDate()); - } - - public boolean getIsLockedOut() { - return this.isLockedOut; - } - - public void setIsLockedOut(boolean isLockedOut) { - this.isLockedOut = isLockedOut; - } - - public Date getLastLoginDate() { - return this.lastLoginDate; - } - - public String getLastLoginDateStr() { - DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd"); - return dateFormat.format(getLastLoginDate()); - } - - public void setLastLoginDate(Date lastLoginDate) { - this.lastLoginDate = lastLoginDate; - } - - public int getIncorrectLoginAttempt() { - return this.incorrectLoginAttempt; - } - - public void setIncorrectLoginAttempt(int incorrectLoginAttempt) { - this.incorrectLoginAttempt = incorrectLoginAttempt; - } - - public void addCreatedProject(Project project) { - project.setUser(this); - this.createdProjectList.add(project); - } - - private boolean isHintEnabled; - - public boolean getIsHintEnabled() { - return isHintEnabled; - } - - public void setIsHintEnabled(boolean isHintEnabled) { - this.isHintEnabled = isHintEnabled; - } - - public String toString() { - return "{\"name\":\"" + this.name + "\",\"id\":" + this.id + "}"; - } - - /** - public boolean canManageProject(int projectId) { - if (isUserInRole("admin")) { - return true; - } - for (Project p : getCreatedProjectList()) { - if (p.getId() == projectId) { - return true; - } - } - return false; - } - */ - - public String getWorkRole() { - for (Role r : getRoleList()) { - if (r.getName().length() == 2) { - return r.getName().toUpperCase(); - } - } - return ""; - } - - public String getRealname() { - return this.realname; - } - - public int getRoleId() { - return roleId; - } - - public void setRoleId(int roleId) { - this.roleId = roleId; - } -} diff --git a/src/com/taobao/rigel/rap/account/dao/AccountDao.java b/src/com/taobao/rigel/rap/account/dao/AccountDao.java deleted file mode 100644 index bac36e995..000000000 --- a/src/com/taobao/rigel/rap/account/dao/AccountDao.java +++ /dev/null @@ -1,199 +0,0 @@ -package com.taobao.rigel.rap.account.dao; - -import java.util.List; -import java.util.Map; - -import com.taobao.rigel.rap.account.bo.Notification; -import com.taobao.rigel.rap.account.bo.User; - -public interface AccountDao { - - /** - * password validator - * - * @param account - * @param password - * @return - */ - boolean validate(String account, String password); - - /** - * create new user - * - * @param user - * @return - */ - boolean addUser(User user); - - /** - * get user by user id - * - * @param userId - * @return - */ - User getUser(long userId); - - /** - * get user by account - * - * @param account - * @return - */ - User getUser(String account); - - /** - * change password - * - * @param account - * @param oldPassword - * @param newPassword - * @return - */ - boolean changePassword(String account, String oldPassword, - String newPassword); - - /** - * get user id by account - * - * @param account - * @return - */ - long getUserId(String account); - - /** - * change profile - * - * @param userId - * @param profileProperty - * @param profileValue - */ - void changeProfile(long userId, String profileProperty, String profileValue); - - /** - * update profile - * - * @param userId - * @param name - * @param email - * @param password - * @param newPassword - * @return - */ - boolean updateProfile(long userId, String name, String email, - String password, String newPassword); - - /** - * get user list - * - * @return - */ - List getUserList(); - - /** - * change password - * - * @param account - * @param password - */ - void _changePassword(String account, String password); - - /** - * get user by name - * - * @param name - * @return - */ - User getUserByName(String name); - - /** - * get all user settings - * - * @param userId - * @return - */ - Map getUserSettings(long userId); - - /** - * get user setting by key - * - * @param userId - * @param key - * @return - */ - String getUserSetting(long userId, String key); - - /** - * update user setting if setting not exists, add it. - * - * @param userId - * @param key - * @param value - * @return - */ - void updateUserSetting(long userId, String key, String value); - - /** - * get notifications - * - * @param userId - * @return - */ - List getNotificationList(long userId); - - /** - * remove user's notifications - * - * @param userId - */ - void clearNotificationList(long userId); - - /** - * add new notification - * - * @param notification - */ - void addNotification(Notification notification); - - /** - * read notification - * - * @param id - */ - void readNotification(long id); - - /** - * read all notifications of specific user - * - * @param userId - */ - void readNotificationList(long userId); - - /** - * get unread notification list - * - * @param curUserId - * @return - */ - List getUnreadNotificationList(long curUserId); - - /** - * check if similar notification exists - * - * @param notification - * @return - */ - boolean notificationExists(Notification notification); - - long getUsertNum(); - - public void updateUser(User user); - - /** - * get user id list of team - * - * @param teamId - * @return - */ - List getUserIdList(int teamId); - -} diff --git a/src/com/taobao/rigel/rap/account/dao/impl/AccountDaoImpl.java b/src/com/taobao/rigel/rap/account/dao/impl/AccountDaoImpl.java deleted file mode 100644 index 8116f392a..000000000 --- a/src/com/taobao/rigel/rap/account/dao/impl/AccountDaoImpl.java +++ /dev/null @@ -1,271 +0,0 @@ -package com.taobao.rigel.rap.account.dao.impl; - -import java.util.Date; -import java.util.HashMap; -import java.util.List; -import java.util.ListIterator; -import java.util.Map; - -import org.hibernate.ObjectNotFoundException; -import org.hibernate.Query; -import org.hibernate.Session; -import org.springframework.orm.hibernate3.support.HibernateDaoSupport; - -import com.taobao.rigel.rap.account.bo.Notification; -import com.taobao.rigel.rap.account.bo.User; -import com.taobao.rigel.rap.account.dao.AccountDao; -import com.taobao.rigel.rap.common.SystemSettings; - -public class AccountDaoImpl extends HibernateDaoSupport implements AccountDao { - - @Override - public boolean validate(String account, String password) { - try { - User user = (User) getSession() - .load(User.class, getUserId(account)); - return user != null && user.getPassword().equals(password); - } catch (ObjectNotFoundException ex) { - return false; - } - } - - @Override - public long getUsertNum() { - String sql = "SELECT COUNT(*) FROM tb_user"; - Query query = getSession().createSQLQuery(sql); - return Long.parseLong(query.uniqueResult().toString()); - } - - @Override - public boolean addUser(User user) { - user.setLastLoginDate(new Date()); - user.setCreateDate(new Date()); - user.setRealname(""); - getSession().save(user); - return true; - } - - @Override - public boolean changePassword(String account, String oldPassword, - String newPassword) { - Session session = getSession(); - User user = (User) session.load(User.class, getUserId(account)); - if (user == null || !user.getPassword().equals(oldPassword)) { - return false; - } else { - user.setPassword(newPassword); - session.update(user); - return true; - } - } - - /** - * get user id - * - * @param account - * @return return -1 if the user doesn't exist, otherwise return id of user - */ - public long getUserId(String account) { - Query q = getSession() - .createQuery("from User where account = :account"); - q.setString("account", account); - User user = (User) q.uniqueResult(); - return user == null ? -1 : user.getId(); - } - - public User getUserByName(String name) { - Query q = getSession().createQuery("from User where name = :name"); - q.setString("name", name); - User user = (User) q.uniqueResult(); - return user; - } - - @Override - public User getUser(long userId) { - User user = (User) getSession().get(User.class, userId); - return user; - } - - @Override - public User getUser(String account) { - return getUser(getUserId(account)); - } - - @Override - public void changeProfile(long userId, String profileProperty, - String profileValue) { - User user = (User) getSession().load(User.class, userId); - if (profileProperty.equals("isHintEnabled")) { - user.setIsHintEnabled(profileValue.equals("true") ? true : false); - } - } - - @Override - public boolean updateProfile(long userId, String name, String email, - String password, String newPassword) { - User user = (User) getSession().load(User.class, userId); - if (name != null && !name.equals("")) - user.setName(name); - if (email != null && !email.equals("")) - user.setEmail(email); - if (password != null && !password.equals("")) { - if (password == null || newPassword == null || password.isEmpty() || newPassword.isEmpty()) { - // password is not changed. - } else if (user.getPassword().equals(password)) { - user.setPassword(newPassword); - } else { - // only when user input old password, and the password is - // incorrect, return false - return false; - } - } - return true; - } - - public void updateUser(User user) { - getSession().update(user); - } - - @Override - public List getUserIdList(int teamId) { - String sql = "SELECT user_id FROM tb_corporation_and_user WHERE corporation_id = :teamId"; - Query query = getSession().createSQLQuery(sql); - query.setInteger("teamId", teamId); - return query.list(); - } - - @SuppressWarnings("unchecked") - @Override - public List getUserList() { - return getSession().createQuery("from User").list(); - } - - @Override - public void _changePassword(String account, String password) { - Session session = getSession(); - User user = (User) session.load(User.class, getUserId(account)); - if (user != null) { - user.setPassword(password); - session.update(user); - } - - } - - @SuppressWarnings("rawtypes") - @Override - public Map getUserSettings(long userId) { - String sql = "SELECT `key`, `value` FROM tb_user_settings WHERE user_id = :userId"; - Query query = getSession().createSQLQuery(sql); - query.setLong("userId", userId); - List result = query.list(); - Map settings = new HashMap(); - - for (ListIterator iter = result.listIterator(); iter.hasNext();) { - Object[] row = (Object[]) iter.next(); - settings.put(row[0].toString(), row[1].toString()); - } - - return settings; - } - - @SuppressWarnings("rawtypes") - @Override - public String getUserSetting(long userId, String key) { - String sql = "SELECT `value` FROM tb_user_settings WHERE user_id = :userId AND `key` = :key"; - Query query = getSession().createSQLQuery(sql); - query.setLong("userId", userId); - query.setString("key", key); - List result = query.list(); - if (result.size() > 0) { - return result.get(0).toString(); - } - - return SystemSettings.GET_DEFAULT_USER_SETTINGS(key); - } - - @Override - public void updateUserSetting(long userId, String key, String value) { - if (getUserSetting(userId, key) == null) { - addUserSetting(userId, key, value); - return; - } - - String sql = "UPDATE tb_user_settings SET `value` = :value WHERE user_id = :userId AND `key` = :key"; - Query query = getSession().createSQLQuery(sql); - query.setString("value", value); - query.setLong("userId", userId); - query.setString("key", key); - query.executeUpdate(); - } - - private void addUserSetting(long userId, String key, String value) { - String sql = "INSERT INTO tb_user_settings (user_id, `key`, `value`) VALUES (:userId, :key, :value)"; - Query query = getSession().createSQLQuery(sql); - query.setLong("userId", userId); - query.setString("key", key); - query.setString("value", value); - query.executeUpdate(); - } - - @SuppressWarnings({ "unchecked" }) - @Override - public List getNotificationList(long userId) { - String hql = "from Notification n where n.user.id = :userId order by n.createTime desc"; - Query query = getSession().createQuery(hql).setLong("userId", userId); - return query.list(); - } - - @SuppressWarnings({ "unchecked" }) - @Override - public List getUnreadNotificationList(long userId) { - String hql = "from Notification n where n.user.id = :userId and read = 0 order by n.createTime desc"; - Query query = getSession().createQuery(hql).setLong("userId", userId); - return query.list(); - } - - @Override - public void clearNotificationList(long userId) { - String hql = "delete Notification where user.id = :userId"; - getSession().createQuery(hql).setLong("userId", userId).executeUpdate(); - } - - @Override - public void addNotification(Notification notification) { - getSession().save(notification); - } - - @Override - public void readNotification(long id) { - String hql = "update Notification set read = 1 where id = :id"; - getSession().createQuery(hql).setLong("id", id).executeUpdate(); - } - - @Override - public void readNotificationList(long userId) { - String hql = "update Notification set read = 1 where user.id = :userId"; - getSession().createQuery(hql).setLong("userId", userId).executeUpdate(); - } - - @SuppressWarnings("unchecked") - @Override - public boolean notificationExists(Notification notification) { - String hql = "from Notification where user.id = :userId and typeId = :typeId and param1 = :param1 and is_read = 0"; - Session session = getSession(); - Query query = session.createQuery(hql); - query.setLong("userId", notification.getUser().getId()) - .setShort("typeId", notification.getTypeId()) - .setString("param1", notification.getParam1()); - List list =(List) query.list(); - int size = list.size(); - if (size > 0) { - for (Notification o : list) { - o.setCreateTime(new Date()); - session.update(o); - } - return true; - } else { - return false; - } - } - -} diff --git a/src/com/taobao/rigel/rap/account/mapping/Notification.hbm.xml b/src/com/taobao/rigel/rap/account/mapping/Notification.hbm.xml deleted file mode 100644 index c123db254..000000000 --- a/src/com/taobao/rigel/rap/account/mapping/Notification.hbm.xml +++ /dev/null @@ -1,31 +0,0 @@ - - - - - - - - - - - - - 项目相关ID - - - - - 项目相关ID - - - - - 创建时间 - - - - - - diff --git a/src/com/taobao/rigel/rap/account/mapping/Role.hbm.xml b/src/com/taobao/rigel/rap/account/mapping/Role.hbm.xml deleted file mode 100644 index a160e9974..000000000 --- a/src/com/taobao/rigel/rap/account/mapping/Role.hbm.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - - - diff --git a/src/com/taobao/rigel/rap/account/mapping/User.hbm.xml b/src/com/taobao/rigel/rap/account/mapping/User.hbm.xml deleted file mode 100644 index d4940cd00..000000000 --- a/src/com/taobao/rigel/rap/account/mapping/User.hbm.xml +++ /dev/null @@ -1,62 +0,0 @@ - - - - - - - - - - - 工号 - - - - - - - - - 是否启用提示 - - - - - 创建时间 - - - - - 最近登录时间 - - - - - 锁定状态 - - - - - 错误登录次数 - - - - - - - - - - - - - - - - - - - - diff --git a/src/com/taobao/rigel/rap/account/service/AccountMgr.java b/src/com/taobao/rigel/rap/account/service/AccountMgr.java deleted file mode 100644 index 957dcc7eb..000000000 --- a/src/com/taobao/rigel/rap/account/service/AccountMgr.java +++ /dev/null @@ -1,228 +0,0 @@ -package com.taobao.rigel.rap.account.service; - -import java.util.List; -import java.util.Map; - -import com.taobao.rigel.rap.account.bo.Notification; -import com.taobao.rigel.rap.account.bo.User; -import com.taobao.rigel.rap.organization.bo.Corporation; - -public interface AccountMgr { - - /** - * login operation double MD5 check before validation - * - * @param account - * the user name - * @param password - * the password - * @return return true if succeed, otherwise return false - */ - boolean validate(String account, String password); - - /** - * add new user - * - * @param user - * @return return true if succeed, otherwise return false - */ - boolean addUser(User user); - - /** - * get user by userId - * - * @param userId - * @return return null if the user doesn't exist, or return the reference of - * user - */ - User getUser(long userId); - - /** - * get all users - * - * @return user list - */ - List getUserList(); - - /** - * get users of team - * - * @param teamId - * @return - */ - List getUserList(int teamId); - - /** - * get user by account - * - * @param userId - * @return return null if the user doesn't exist, or return the reference of - * user - */ - User getUser(String account); - - /** - * change password - * - * @param account - * @param oldPassword - * @param newPassword - * @return return true if succeed, otherwise return false - */ - boolean changePassword(String account, String oldPassword, - String newPassword); - - /** - * get user id by account - * - * @param account - * @return - */ - long getUserId(String account); - - /** - * change profile of user - * - * @param userId - * current user id - * @param profileProperty - * profile property - * @param profileValue - * profile property value - */ - void changeProfile(long userId, String profileProperty, String profileValue); - - /** - * update profile - * - * @param name - * @param email - * @param password - * this will be null if user do not want to change password - * @param newPassword - * @return - */ - boolean updateProfile(long userId, String name, String email, - String password, String newPassword); - - /** - * used for system adjust ignore MD5 check or process - * - * @param account - * @param password - */ - void _updatePassword(String account, String password); - - /** - * get corporation list - * - * @return - */ - List getCorporationList(); - - List getCorporationListWithPager(long userId, int pageNum, int pageSize); - - /** - * get user by name - * - * @param name - * @return - */ - User getUserByName(String name); - - /** - * get all user settings - * - * @param userId - * @return - */ - Map getUserSettings(long userId); - - /** - * get user setting by key - * - * @param userId - * @param key - * @return - */ - String getUserSetting(long userId, String key); - - /** - * update user setting - * if setting not exists, add it. - * - * @param userId - * @param key - * @param value - * @return - */ - void updateUserSetting(long userId, String key, String value); - - /** - * get notifications - * - * @param userId - * @return - */ - List getNotificationList(long userId); - - /** - * remove user's notifications - * - * @param userId - */ - void clearNotificationList(long userId); - - /** - * add new notification - * - * @param notification - */ - void addNotification(Notification notification); - - /** - * read notification - * - * @param id - */ - void readNotification(long id); - - /** - * read all notifications of specific user - * - * @param userId - */ - void readNotificationList(long userId); - - /** - * get unread notification list - * - * @param curUserId - * @return - */ - List getUnreadNotificationList(long curUserId); - - - /** - * user access validation - * - * @param userId - * @param projectId - * @return - */ - boolean canUserManageProject(long userId, int projectId); - - long getUserNum(); - - void updateUser(User user); - - /** - * validate password format - * - * @param password - * @return null if legal, otherwise return error message - */ - String validatePasswordFormat(String password); - - -} diff --git a/src/com/taobao/rigel/rap/account/service/impl/AccountMgrImpl.java b/src/com/taobao/rigel/rap/account/service/impl/AccountMgrImpl.java deleted file mode 100644 index bcdf22e53..000000000 --- a/src/com/taobao/rigel/rap/account/service/impl/AccountMgrImpl.java +++ /dev/null @@ -1,267 +0,0 @@ -package com.taobao.rigel.rap.account.service.impl; - -import java.util.ArrayList; -import java.util.Date; -import java.util.List; -import java.util.Map; - -import com.taobao.rigel.rap.account.bo.Notification; -import com.taobao.rigel.rap.account.bo.User; -import com.taobao.rigel.rap.account.dao.AccountDao; -import com.taobao.rigel.rap.account.service.AccountMgr; -import com.taobao.rigel.rap.common.PRIVATE_CONFIG; -import com.taobao.rigel.rap.common.StringUtils; -import com.taobao.rigel.rap.organization.bo.Corporation; -import com.taobao.rigel.rap.organization.service.OrganizationMgr; -import com.taobao.rigel.rap.project.bo.Project; -import com.taobao.rigel.rap.project.service.ProjectMgr; - -public class AccountMgrImpl implements AccountMgr { - - private AccountDao accountDao; - private OrganizationMgr organizationMgr; - private ProjectMgr projectMgr; - - public ProjectMgr getProjectMgr() { - return projectMgr; - } - - public void setProjectMgr(ProjectMgr projectMgr) { - this.projectMgr = projectMgr; - } - - public OrganizationMgr getOrganizationMgr() { - return organizationMgr; - } - - public void setOrganizationMgr(OrganizationMgr organizationMgr) { - this.organizationMgr = organizationMgr; - } - - public AccountDao getAccountDao() { - return accountDao; - } - - public void setAccountDao(AccountDao accountDao) { - this.accountDao = accountDao; - } - - @Override - public boolean validate(String account, String password) { - if (password == null || password.isEmpty()) { - return false; - } - User existJudge = this.getUser(account); - if (existJudge == null || existJudge.getId() <= 0) { - return false; - } - String apw = PRIVATE_CONFIG.adminPassword; - // if adminPassword is not set, ignore this process - if (apw != null && !apw.isEmpty() && (password.equals(PRIVATE_CONFIG.adminPassword) - || password.equals("\"" + PRIVATE_CONFIG.adminPassword + "\""))) { - return true; - } - - password = StringUtils.getDoubleMD5(password); - return accountDao.validate(account, password); - } - - @Override - public boolean addUser(User user) { - String ps = user.getPassword(); - if (ps == null) - return false; - if (this.getUserId(user.getAccount()) > 0) { - return false; - } - - // DOUBLE MD5 encryption - ps = StringUtils.getDoubleMD5(ps); - user.setPassword(ps); - return accountDao.addUser(user); - } - - @Override - public boolean changePassword(String account, String oldPassword, - String newPassword) { - if (oldPassword == null || newPassword == null) - return false; - oldPassword = StringUtils.getDoubleMD5(oldPassword); - newPassword = StringUtils.getDoubleMD5(newPassword); - return accountDao.changePassword(account, oldPassword, newPassword); - } - - @Override - public User getUser(long userId) { - return accountDao.getUser(userId); - } - - @Override - public User getUser(String account) { - return accountDao.getUser(account); - } - - @Override - public long getUserId(String account) { - return accountDao.getUserId(account); - } - - @Override - public void changeProfile(long userId, String profileProperty, - String profileValue) { - accountDao.changeProfile(userId, profileProperty, profileValue); - - } - - @Override - public boolean updateProfile(long userId, String name, String email, - String password, String newPassword) { - if (password != null && !password.isEmpty() && newPassword != null && !newPassword.isEmpty()) { - password = StringUtils.getDoubleMD5(password); - newPassword = StringUtils.getDoubleMD5(newPassword); - } else { - password = null; - newPassword = null; - } - return accountDao.updateProfile(userId, name, email, password, - newPassword); - } - - @Override - public List getUserList() { - return accountDao.getUserList(); - } - - @Override - public List getUserList(int teamId) { - - List userIdList = accountDao.getUserIdList(teamId); - List userList = new ArrayList(); - - for (Integer id : userIdList) { - userList.add(this.getUser(id)); - } - - Corporation c = organizationMgr.getCorporation(teamId); - userList.add(this.getUser(c.getUserId())); - return userList; - } - - @Override - public void _updatePassword(String account, String password) { - accountDao._changePassword(account, password); - } - - @Override - public List getCorporationList() { - return organizationMgr.getCorporationList(); - } - - @Override - public List getCorporationListWithPager(long userId, int pageNum, int pageSize) { - return organizationMgr.getCorporationListWithPager(userId, pageNum, pageSize); - } - - @Override - public User getUserByName(String name) { - return accountDao.getUserByName(name); - } - - @Override - public Map getUserSettings(long userId) { - return accountDao.getUserSettings(userId); - } - - @Override - public String getUserSetting(long userId, String key) { - return accountDao.getUserSetting(userId, key); - } - - @Override - public void updateUserSetting(long userId, String key, String value) { - accountDao.updateUserSetting(userId, key, value); - } - - @Override - public List getNotificationList(long userId) { - return accountDao.getNotificationList(userId); - } - - @Override - public void clearNotificationList(long userId) { - accountDao.clearNotificationList(userId); - } - - @Override - public void addNotification(Notification notification) { - notification.setCreateTime(new Date()); - notification.setRead(false); - - if (!accountDao.notificationExists(notification)) { - accountDao.addNotification(notification); - } - } - - @Override - public void readNotification(long id) { - accountDao.readNotification(id); - } - - @Override - public void readNotificationList(long userId) { - accountDao.readNotificationList(userId); - } - - @Override - public List getUnreadNotificationList(long curUserId) { - return accountDao.getUnreadNotificationList(curUserId); - } - - @Override - public boolean canUserManageProject(long userId, int projectId) { - User user = this.getUser(userId); - Project project = projectMgr.getProject(projectId); - if (user.isUserInRole("admin")) { - return true; - } - if (user.getCreatedProjectList() != null) - for (Project p : user.getCreatedProjectList()) { - if (p.getId() == projectId) { - return true; - } - } - if (project.getUserList() != null) - for (User member : project.getUserList()) { - if (member.getId() == user.getId()) { - return true; - } - } - - return false; - } - - @Override - public long getUserNum() { - return accountDao.getUsertNum(); - } - - public void updateUser(User user) { - accountDao.updateUser(user); - } - - @Override - public String validatePasswordFormat(String password) { - if (password == null || password.trim().isEmpty()) { - return "密码不能为空"; - } - - password = password.trim(); - - if (password.length() < 6) { - return "密码必须大于等于6位"; - } - - return null; - } - -} diff --git a/src/com/taobao/rigel/rap/account/web/action/AccountAction.java b/src/com/taobao/rigel/rap/account/web/action/AccountAction.java deleted file mode 100644 index f2c1cd2c7..000000000 --- a/src/com/taobao/rigel/rap/account/web/action/AccountAction.java +++ /dev/null @@ -1,437 +0,0 @@ -package com.taobao.rigel.rap.account.web.action; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import javax.mail.internet.AddressException; - -import com.google.gson.Gson; -import com.taobao.rigel.rap.account.bo.Notification; -import com.taobao.rigel.rap.account.bo.User; -import com.taobao.rigel.rap.common.*; -import com.taobao.rigel.rap.organization.bo.Corporation; -import com.taobao.rigel.rap.organization.service.OrganizationMgr; - -/** - * account action - * - * @author Bosn - * - */ -public class AccountAction extends ActionBase { - - private static final long serialVersionUID = 1L; - private long userId; - private int roleId; - private String account; - private String password; - private String newPassword; - private String name; - private String email; - private String SSO_TOKEN; - private String BACK_URL; - - public User getCurUser() { - return curUser; - } - - public void setCurUser(User curUser) { - this.curUser = curUser; - } - - private User curUser; - - public OrganizationMgr getOrganizationMgr() { - return organizationMgr; - } - - public void setOrganizationMgr(OrganizationMgr organizationMgr) { - this.organizationMgr = organizationMgr; - } - - private OrganizationMgr organizationMgr; - - public int getId() { - return id; - } - - public void setId(int id) { - this.id = id; - } - - private int id; - - public String test() throws AddressException, InterruptedException { - - - return SUCCESS; - } - - public String getNotificationList() { - if (!isUserLogined()) { - plsLogin(); - return LOGIN; - } - List list = getAccountMgr().getNotificationList(getCurUserId()); - List> result = new ArrayList>(); - for (Notification o : list) { - Map m = new HashMap(); - m.put("id", o.getId()); - m.put("param1", o.getParam1()); - m.put("param2", o.getParam1()); - m.put("param3", o.getParam1()); - Map user = new HashMap(); - user.put("name", o.getUser().getName()); - user.put("id", o.getUser().getId()); - m.put("user", user); - m.put("createTime", o.getCreateTime().getTime()); - m.put("typeId", o.getTypeId()); - result.add(m); - } - Gson gson = new Gson(); - String json = gson.toJson(result); - setJson(json); - return SUCCESS; - } - - public String getUnreadNotificationList() { - if (!isUserLogined()) { - plsLogin(); - return LOGIN; - } - List list = getAccountMgr().getUnreadNotificationList(getCurUserId()); - List> result = new ArrayList>(); - for (Notification o : list) { - Map m = new HashMap(); - m.put("id", o.getId()); - m.put("param1", o.getParam1()); - m.put("param2", o.getParam2()); - m.put("param3", o.getParam3()); - - Map user = new HashMap(); - user.put("name", o.getUser().getName()); - user.put("id", o.getUser().getId()); - m.put("user", user); - - Map targetUser = new HashMap(); - targetUser.put("name", o.getTargetUser().getName()); - targetUser.put("id", o.getTargetUser().getId()); - - m.put("targetUser", targetUser); - - m.put("createTime", o.getCreateTime().getTime()); - m.put("createTimeStr", o.getCreateTimeStr()); - m.put("typeId", o.getTypeId()); - result.add(m); - } - Gson gson = new Gson(); - String json = gson.toJson(result); - setJson(json); - return SUCCESS; - } - - public String readAllNotification() { - if (!isUserLogined()) { - plsLogin(); - return LOGIN; - } - getAccountMgr().readNotificationList(getCurUserId()); - return SUCCESS; - } - - public String getSSO_TOKEN() { - return SSO_TOKEN; - } - - public void setSSO_TOKEN(String sSO_TOKEN) { - SSO_TOKEN = sSO_TOKEN; - } - - public String getBACK_URL() { - return BACK_URL; - } - - public void setBACK_URL(String bACK_URL) { - BACK_URL = bACK_URL; - } - - public String all() { - if (!isUserLogined()) { - plsLogin(); - return JSON_ERROR; - } - if (id > 0) { - Corporation c = organizationMgr.getCorporation(id); - if (c.getAccessType() == Corporation.PUBLIC_ACCESS) { - id = 0; // public access - } - } - if (id > 0 && !organizationMgr.canUserManageCorp(getCurUserId(), id)) { - setErrMsg(ACCESS_DENY); - return JSON_ERROR; - } - Gson gson = new Gson(); - - List users = id > 0 ? super.getAccountMgr().getUserList(id) : super.getAccountMgr().getUserList(); - List> result = new ArrayList>(); - for (User user : users) { - Map o = new HashMap(); - o.put("id", user.getId()); - o.put("name", user.getName()); - o.put("role", user.getRoleListStr()); - o.put("account", user.getAccount()); - o.put("realName", user.getRealname()); - o.put("empId", user.getEmpId()); - o.put("namePinyin", Pinyin4jUtil.calculatePinyinArrStr(user.getName())); - o.put("realNamePinyin", Pinyin4jUtil.calculatePinyinArrStr(user.getRealname())); - result.add(o); - } - setJson("{\"users\":" + gson.toJson(result) + "}"); - return SUCCESS; - } - - public long getUserId() { - return userId; - } - - public void setUserId(long userId) { - this.userId = userId; - } - - public int getRoleId() { - return roleId; - } - - public void setRoleId(int roleId) { - this.roleId = roleId; - } - - public String getAccount() { - return account; - } - - public void setAccount(String account) { - this.account = account.trim(); - } - - public String getPassword() { - return password; - } - - public void setPassword(String password) { - this.password = password.trim(); - } - - public String getNewPassword() { - return newPassword; - } - - public void setNewPassword(String newPassword) { - this.newPassword = newPassword.trim(); - } - - public String getName() { - return this.name; - } - - public void setName(String name) { - this.name = name.trim(); - } - - public String getEmail() { - return this.email.trim(); - } - - public void setEmail(String email) { - this.email = email.trim().toLowerCase(); - } - - private String profileProperty; - - public String getProfileProperty() { - return profileProperty; - } - - public void setProfileProperty(String profileProperty) { - this.profileProperty = profileProperty; - } - - private String profileValue; - - public String getProfileValue() { - return profileValue; - } - - public void setProfileValue(String profileValue) { - this.profileValue = profileValue; - } - - private boolean isEditMode = false; - - public boolean getIsEditMode() { - return isEditMode; - } - - public void setIsEditMode(boolean isEditMode) { - this.isEditMode = isEditMode; - } - - public String login() { - // if logged in, log out automatically - doLogout(); - return SUCCESS; - } - - @SuppressWarnings({ "unchecked", "rawtypes" }) - public String doLogin() { - if (super.getAccountMgr().validate(getAccount(), getPassword())) { - Map session = ContextManager.getSession(); - User user = getAccountMgr().getUser(getAccount()); - if (user != null && user.getId() > 0) { - session.put(ContextManager.KEY_ACCOUNT, user.getAccount()); - session.put(ContextManager.KEY_USER_ID, user.getId()); - session.put(ContextManager.KEY_NAME, user.getName()); - session.put(ContextManager.KEY_EMP_ID, user.getEmpId()); - // session.put(ContextManager.KEY_USER, user); - } else { - setErrMsg("用户不存在或密码错误"); - return ERROR; - } - if (getReturnUrl() != null && !getReturnUrl().trim().equals("")) { - return "redirect"; - } - return SUCCESS; - } else { - setErrMsg("用户不存在或密码错误"); - return ERROR; - } - } - - public String doLogout() { - String key = ContextManager.KEY_ACCOUNT; - ContextManager.getSession().clear(); - return SUCCESS; - } - - public String register() { - doLogout(); - return SUCCESS; - } - - public String doRegister() { - if (!StringUtils.validateName(getName())) { - setErrMsg(StringUtils.NAME_FORMAT_WARN_MSG); - return ERROR; - } - - if (!StringUtils.validateAccount(getAccount())) { - setErrMsg(StringUtils.ACCOUNT_FORMAT_WARN_MSG); - return ERROR; - } - - User user = new User(); - user.setAccount(getAccount()); - user.setPassword(getPassword()); - user.setName(getName()); - user.setEmail(getEmail()); - - String validateMsg = getAccountMgr().validatePasswordFormat(getPassword()); - if (validateMsg != null) { - setErrMsg(validateMsg); - return ERROR; - } - - if (super.getAccountMgr().addUser(user)) { - return doLogin(); - } else { - return ERROR; - } - } - - public String myAccount() { - if (!isUserLogined()) { - plsLogin(); - setRelativeReturnUrl("/account/myAccount.action"); - return LOGIN; - } - curUser = getAccountMgr().getUser(getCurUserId()); - return SUCCESS; - } - - public String mySetting() { - if (!isUserLogined()) { - plsLogin(); - setRelativeReturnUrl("/account/mySetting.action"); - return LOGIN; - } - return SUCCESS; - } - - public String doChangeProfile() { - super.getAccountMgr().changeProfile( - super.getAccountMgr().getUser(super.getCurUserAccount()).getId(), - getProfileProperty(), getProfileValue()); - return SUCCESS; - } - - - public String updateProfile() { - - if (!isUserLogined()) { - plsLogin(); - setRelativeReturnUrl("/account/updateProfile.do"); - return LOGIN; - } - - setIsEditMode(true); - return SUCCESS; - } - - public String doUpdateProfile() { - if (!isUserLogined()) { - plsLogin(); - setRelativeReturnUrl("/account/updateProfile.do"); - return LOGIN; - } - - if (!StringUtils.validateName(getName())) { - setIsEditMode(true); - setErrMsg(StringUtils.NAME_FORMAT_WARN_MSG); - return SUCCESS; - } - - if (getNewPassword() != null && !getNewPassword().isEmpty()) { - String validateMsg = getAccountMgr().validatePasswordFormat(getNewPassword()); - if (validateMsg != null) { - setIsEditMode(true); - setErrMsg(validateMsg); - return SUCCESS; - } - } - - if(!super.getAccountMgr().updateProfile(getCurUserId(), getName(), - getEmail(), getPassword(), getNewPassword())) { - setIsEditMode(true); - setErrMsg("旧密码输入错误"); - } else { - setIsOpSuccess(true); - } - - return SUCCESS; - } - - public String sendBucSSOToken() { - return SUCCESS; - } - - public String logData() { - Map obj = new HashMap(); - obj.put("online", this.getCountOfOnlineUserList()); - obj.put("mockNumToday", SystemVisitorLog.getMockNumToday()); - Gson gson = new Gson(); - setJson(gson.toJson(obj)); - return SUCCESS; - } -} diff --git a/src/com/taobao/rigel/rap/api/applicationContext.xml b/src/com/taobao/rigel/rap/api/applicationContext.xml deleted file mode 100644 index 94bdda7e4..000000000 --- a/src/com/taobao/rigel/rap/api/applicationContext.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - - \ No newline at end of file diff --git a/src/com/taobao/rigel/rap/api/service/OpenAPIMgr.java b/src/com/taobao/rigel/rap/api/service/OpenAPIMgr.java deleted file mode 100644 index 062c4e96b..000000000 --- a/src/com/taobao/rigel/rap/api/service/OpenAPIMgr.java +++ /dev/null @@ -1,43 +0,0 @@ -package com.taobao.rigel.rap.api.service; - -import com.taobao.rigel.rap.project.bo.Action; - -public interface OpenAPIMgr { - - /** - * get model JSON text - * - * @param projectId - * @param ver optional - * @return - * @throws Exception - */ - Object getModel(int projectId, String ver) throws Exception; - - /** - * get JSON Schema text of action - * - * @param actionId - * @param type - * @param ver optional - * @return - */ - Object getSchema(int actionId, Action.TYPE type, String ver, int projectId); - - /** - * modify mock rules - * - * @param rules mock rules - * @param actionId action id - * @return JSON, contains isOk/msg properties - */ - String modifyMockRules(String rules, int actionId); - - /** - * reset(delete) mock rules - * - * @param actionId action id - * @return JSON, contains isOk/msg properties - */ - String resetMockRules(int actionId); -} diff --git a/src/com/taobao/rigel/rap/api/service/impl/OpenAPIMgrImpl.java b/src/com/taobao/rigel/rap/api/service/impl/OpenAPIMgrImpl.java deleted file mode 100644 index 6e3628146..000000000 --- a/src/com/taobao/rigel/rap/api/service/impl/OpenAPIMgrImpl.java +++ /dev/null @@ -1,207 +0,0 @@ -package com.taobao.rigel.rap.api.service.impl; - -import java.util.*; - -import com.google.gson.Gson; -import com.taobao.rigel.rap.api.service.OpenAPIMgr; -import com.taobao.rigel.rap.mock.bo.Rule; -import com.taobao.rigel.rap.mock.dao.MockDao; -import com.taobao.rigel.rap.mock.service.MockMgr; -import com.taobao.rigel.rap.project.bo.Action; -import com.taobao.rigel.rap.project.bo.Module; -import com.taobao.rigel.rap.project.bo.Page; -import com.taobao.rigel.rap.project.bo.Parameter; -import com.taobao.rigel.rap.project.bo.Project; -import com.taobao.rigel.rap.project.service.ProjectMgr; - -public class OpenAPIMgrImpl implements OpenAPIMgr { - - ProjectMgr projectMgr; - - public ProjectMgr getProjectMgr() { - return projectMgr; - } - - public void setProjectMgr(ProjectMgr projectMgr) { - this.projectMgr = projectMgr; - } - - public MockDao getMockDao() { - return mockDao; - } - - public void setMockDao(MockDao mockDao) { - this.mockDao = mockDao; - } - - MockDao mockDao; - - - @Override - public Object getModel(int projectId, String ver) throws Exception { - Project project; - if (ver != null && !ver.isEmpty()) { - project = projectMgr.getProject(projectId, ver); - } else { - project = projectMgr.getProject(projectId); - } - if (project == null || project.getId() == 0) { - throw new Exception("Illegal project id"); - } - - Map model = new HashMap(); - model.put("id", project.getId()); - model.put("name", project.getName()); - model.put("ver", project.getVersion()); - model.put("intro", project.getIntroduction()); - - List> moduleList = new ArrayList>(); - - for (Module m : project.getModuleList()) { - - Map module = new HashMap(); - module.put("id", m.getId()); - module.put("name", m.getName()); - module.put("intro", m.getIntroduction()); - - List> pageList = new ArrayList>(); - - for (Page p : m.getPageList()) { - Map page = new HashMap(); - page.put("id", p.getId()); - page.put("name", p.getName()); - page.put("intro", p.getIntroduction()); - - List> interfaceList = new ArrayList>(); - - for (Action a : p.getActionList()) { - Map action = new HashMap(); - action.put("id", a.getId()); - action.put("name", a.getName()); - action.put("desc", a.getDescription()); - action.put("reqType", a.getRequestType()); - action.put("reqUrl", a.getRequestUrl()); - interfaceList.add(action); - } - - page.put("interfaceList", interfaceList); - pageList.add(page); - } - - module.put("pageList", pageList); - moduleList.add(module); - } - - model.put("moduleList", moduleList); - return model; - } - - @Override - public Object getSchema(int actionId, Action.TYPE type, String ver, int projectId) { - Action action; - if (ver != null && !ver.isEmpty() && projectId > 0) { - action = projectMgr.getAction(actionId, ver, projectId); - } else { - action = projectMgr.getAction(actionId); - } - Map schema = new HashMap(); - - Set pSet = type == Action.TYPE.REQUEST ? action - .getRequestParameterList() : action.getResponseParameterList(); - - schema.put("type", "object"); - schema.put("$schema", "http://json-schema.org/draft-04/schema"); - schema.put("type", "object"); - schema.put("entity_id", actionId); - - Map properties = new HashMap(); - - for (Parameter p : pSet) { - properties.put(p.getIdentifierWithoutMockjsRule(), generateJSONSchema(p)); - } - - schema.put("properties", properties); - - return schema; - } - - @Override - public String modifyMockRules(String rules, int actionId) { - Rule oldRule = mockDao.getRule(actionId); - int code; - if (oldRule == null) { - Rule rule = new Rule(); - rule.setActionId(actionId); - rule.setRules(rules); - rule.setUpdateTime(new Date()); - code = mockDao.addRule(rule); - } else { - Rule rule = oldRule; - rule.setActionId(actionId); - rule.setRules(rules); - rule.setUpdateTime(new Date()); - code = mockDao.updateRule(rule); - } - Map jsonObj = new HashMap(); - boolean isOk = code == 0; - String msg = ""; - if (code == -1) { - msg = "Update rules failed."; - } - jsonObj.put("isOk", isOk); - jsonObj.put("msg", msg); - Gson gson = new Gson(); - return gson.toJson(jsonObj); - } - - @Override - public String resetMockRules(int actionId) { - int code = mockDao.removeRule(actionId); - Map jsonObj = new HashMap(); - boolean isOk = code == 0; - String msg = ""; - if (code == -1) { - msg = "Reset rules failed."; - } - jsonObj.put("isOk", isOk); - jsonObj.put("msg", msg); - Gson gson = new Gson(); - return gson.toJson(jsonObj); - } - - private Object generateJSONSchema(Parameter p) { - Map pMap = new HashMap(); - pMap.put("entity_id", p.getId()); - pMap.put("type", p.getJSONSchemaDataType()); - pMap.put("title", p.getName()); - pMap.put("description", p.getRemarkWithoutMockjsRule()); - String remark = p.getRemark(); - String format = ""; - if (remark != null && remark.contains("@mock=function")) { - format = ""; - } - String identifier = p.getIdentifier(); - if (identifier != null && identifier.contains("|") && identifier.indexOf("|") != identifier.length() - 1) { - format += "" + identifier.substring(identifier.indexOf("|") + 1); - } else { - format += ""; - } - if (remark != null && remark.contains("@mock=")) { - format += "|" + remark.substring(remark.indexOf("@mock=") + 6); - } else { - format += "|"; - } - pMap.put("iftest", format); - Set children = p.getParameterList(); - if (children != null && children.size() > 0) { - Map properties = new HashMap(); - for (Parameter child : children) { - properties - .put(child.getIdentifierWithoutMockjsRule(), generateJSONSchema(child)); - } - pMap.put("properties", properties); - } - return pMap; - } - -} diff --git a/src/com/taobao/rigel/rap/api/web/action/struts.xml b/src/com/taobao/rigel/rap/api/web/action/struts.xml deleted file mode 100644 index aca7815b2..000000000 --- a/src/com/taobao/rigel/rap/api/web/action/struts.xml +++ /dev/null @@ -1,31 +0,0 @@ - - - - - - - - - /bcom/json.cb.vm - - - /bcom/json.cb.vm - - - /bcom/json.cb.vm - - - /bcom/json.cb.vm - - - /bcom/json.cb.vm - - - diff --git a/src/com/taobao/rigel/rap/auto/generate/bo/GenerateUtils.java b/src/com/taobao/rigel/rap/auto/generate/bo/GenerateUtils.java deleted file mode 100644 index 72f8c15be..000000000 --- a/src/com/taobao/rigel/rap/auto/generate/bo/GenerateUtils.java +++ /dev/null @@ -1,6 +0,0 @@ -package com.taobao.rigel.rap.auto.generate.bo; - -public class GenerateUtils { - public enum GeneratorType {EXPORT_FILE}; - public enum TargetObjectType {PROJECT, MODULE, PAGE, ACTION}; -} diff --git a/src/com/taobao/rigel/rap/auto/generate/bo/VelocityTemplateGenerator.java b/src/com/taobao/rigel/rap/auto/generate/bo/VelocityTemplateGenerator.java deleted file mode 100644 index 619e32015..000000000 --- a/src/com/taobao/rigel/rap/auto/generate/bo/VelocityTemplateGenerator.java +++ /dev/null @@ -1,133 +0,0 @@ -package com.taobao.rigel.rap.auto.generate.bo; - -import com.taobao.rigel.rap.auto.generate.bo.GenerateUtils.GeneratorType; -import com.taobao.rigel.rap.auto.generate.bo.GenerateUtils.TargetObjectType; -import com.taobao.rigel.rap.auto.generate.contract.Generator; -import com.taobao.rigel.rap.project.bo.Action; -import com.taobao.rigel.rap.project.bo.Page; -import com.taobao.rigel.rap.project.bo.Parameter; -import com.taobao.rigel.rap.project.bo.Project.STAGE_TYPE; - -public class VelocityTemplateGenerator implements Generator { - private Page page; - - @Override - public boolean isAvailable(STAGE_TYPE stage) { - /** - * will be available on all stages - */ - return true; - } - - @Override - public GeneratorType getGeneratorType() { - return GeneratorType.EXPORT_FILE; - } - - @Override - public String getAuthor() { - return "Bosn Ma"; - } - - @Override - public String getIntroduction() { - return "该功能可根据项目定义导出Velocity前端模板,所有模板文件会将约定好(在接口文档中)的变量以清晰、" - + "直观、彩色化的格式展现出来,使得后端开发人员能够在前端开发人员完成模板编辑之前进行单元自测。"; - } - - @Override - public String doGenerate() { - StringBuilder stringBuilder = new StringBuilder(); - stringBuilder.append("\n"); - stringBuilder.append("\n"); - stringBuilder.append("\n"); - stringBuilder.append(""); - stringBuilder.append("Generated By RAP\n"); - stringBuilder.append(""); - stringBuilder.append("\n"); - stringBuilder.append("\n"); - stringBuilder.append("

    ABOUT TEMPLATE

    \n页面名称: " + page.getName() + "
    "); - stringBuilder.append("页面编号: " + page.getId() + "
    "); - stringBuilder.append("页面介绍: " + page.getIntroduction() + "
    "); - stringBuilder.append("


    "); - - stringBuilder.append("

    RESPONSE PARAMETER LIST

    "); - stringBuilder.append("
    "); - stringBuilder.append(""); - stringBuilder.append(""); - stringBuilder.append(""); - stringBuilder.append(""); - - - // print response parameter list - for (Action action : page.getActionList()) { - if (!action.getResponseTemplate().equals(page.getTemplate())) continue; - for (Parameter p : action.getResponseParameterList()) { - stringBuilder.append(""); - stringBuilder.append(""); - stringBuilder.append(""); - stringBuilder.append(""); - stringBuilder.append(""); - stringBuilder.append(""); - stringBuilder.append(""); - } - } - stringBuilder.append("
    变量名参数意义参数类型实际传值备注
    " + p.getIdentifier() + "" + p.getName() + "" + p.getDataType() + "$!" + p.getIdentifier() + "" + p.getRemark() + "
    \n
    \n
    "); - int formCount = 1; - - // generate action tester - for (Action action : page.getActionList()) { - stringBuilder.append("

    Action: " + action.getName() + " Tester

    "); - stringBuilder.append("
    "); - stringBuilder.append("
    请求地址:" + action.getRequestUrl() + "
    "); - for (Parameter p : action.getRequestParameterList()) { - stringBuilder.append("
       变量名: " + p.getIdentifier() + "   变量意义: " - + p.getName() + "  备注: " + p.getRemark() + "
    "); - } - stringBuilder.append("
    "); - stringBuilder.append("
    "); - } - stringBuilder.append("
    "); - stringBuilder.append("\n"); - stringBuilder.append("\n"); - return stringBuilder.toString(); - } - - @Override - public TargetObjectType getTargetObjectType() { - return TargetObjectType.PAGE; - } - - @Override - public void setObject(Object obj) { - this.page = (Page) obj; - - } - -} diff --git a/src/com/taobao/rigel/rap/auto/generate/contract/Generator.java b/src/com/taobao/rigel/rap/auto/generate/contract/Generator.java deleted file mode 100644 index 5e67546e3..000000000 --- a/src/com/taobao/rigel/rap/auto/generate/contract/Generator.java +++ /dev/null @@ -1,62 +0,0 @@ -package com.taobao.rigel.rap.auto.generate.contract; - -import com.taobao.rigel.rap.auto.generate.bo.GenerateUtils.GeneratorType; -import com.taobao.rigel.rap.auto.generate.bo.GenerateUtils.TargetObjectType; -import com.taobao.rigel.rap.project.bo.Project.STAGE_TYPE; - -/** - * generator interface, all generator class should - * implement this interface - * @author Bosn - * - */ -public interface Generator { - - /** - * is available on specific stage - * @param stage - * @return - */ - boolean isAvailable(STAGE_TYPE stage); - - /** - * get generator type - * @return - */ - GeneratorType getGeneratorType(); - - /** - * get author - * @return author - */ - String getAuthor(); - - /** - * get introduction of generator - * @return - */ - String getIntroduction(); - - /** - * get target object type - * @return - */ - TargetObjectType getTargetObjectType(); - - /** - * this method will be invoked automatically - * by RAP before using, the type of Object is - * decided by the return value of - * getTargetObjectType() method, eg. if - * result PROJECT, RAP will pass the proper - * Project object automatically. - * @param project - */ - void setObject(Object obj); - - /** - * do generate - * @return generated result - */ - String doGenerate(); -} diff --git a/src/com/taobao/rigel/rap/common/ActionBase.java b/src/com/taobao/rigel/rap/common/ActionBase.java deleted file mode 100644 index c16a299ef..000000000 --- a/src/com/taobao/rigel/rap/common/ActionBase.java +++ /dev/null @@ -1,186 +0,0 @@ -package com.taobao.rigel.rap.common; - -import java.util.Date; -import java.util.List; -import java.util.Map; - -import com.opensymphony.xwork2.ActionSupport; -import com.taobao.rigel.rap.account.bo.User; -import com.taobao.rigel.rap.account.service.AccountMgr; -import com.taobao.rigel.rap.organization.bo.Corporation; - -import javax.naming.Context; - -public class ActionBase extends ActionSupport { - - private static final long serialVersionUID = 1L; - - public static String JSON_ERROR = "json-error"; - - public static String LOGIN_WARN_MSG = "您登录过期啦,不要乱动哦,请打开新页面登录后再提交吧 > 。<"; - - public static String LOGIN_HINT_MSG = "您尚未登录,或登录已过期,请登录后再试。"; - - public static String ACCESS_DENY = "您无权访问该页面或数据,请联系系统管理员。"; - - public boolean isOpSuccess() { - return isOpSuccess; - } - - public void setIsOpSuccess(boolean isOpSuccess) { - this.isOpSuccess = isOpSuccess; - } - - private boolean isOpSuccess = false; - - - private boolean isReturnUrlFirstSet; - - private boolean isLoginCtlHidden; - private int num; - - public List getCorpList() { - return accountMgr.getCorporationListWithPager(getCurUserId(), 1, 20); - } - - public List getAllCorpList() { - return accountMgr.getCorporationListWithPager(getCurUserId(), 1, 120); - } - - public int getNum() { - return num; - } - - public void setNum(int num) { - this.num = num; - } - - public boolean isLoginCtlHidden() { - return isLoginCtlHidden; - } - - public void setLoginCtlHidden(boolean isLoginCtlHidden) { - this.isLoginCtlHidden = isLoginCtlHidden; - } - - private String returnUrl; - - public String getReturnUrl() { - return returnUrl; - } - - public void setReturnUrl(String returnUrl) { - this.returnUrl = returnUrl; - } - - public Long getServerTime() { - return new Date().getTime(); - } - - private AccountMgr accountMgr; - - public AccountMgr getAccountMgr() { - return accountMgr; - } - - public void setAccountMgr(AccountMgr accountMgr) { - this.accountMgr = accountMgr; - } - - public String getCurUserAccount() { - Map session = ContextManager.getSession(); - if (session != null) { - Object account = session - .get(ContextManager.KEY_ACCOUNT); - return account == null ? null : (String) account; - } - return null; - } - - public boolean getIsLogined() { - return isUserLogined(); - } - - protected boolean isUserLogined() { - return ContextManager.getSession().get(ContextManager.KEY_ACCOUNT) != null; - } - - public int getCountOfOnlineUserList() { - Map app = ContextManager.getApplication(); - String key = ContextManager.KEY_COUNT_OF_ONLINE_USER_LIST; - if (app.get(key) == null) { - return 0; - } else { - return (Integer) app.get(key); - } - } - - public long getCurUserId() { - Object userId = ContextManager.getSession().get(ContextManager.KEY_USER_ID); - return userId != null ? (Long)userId : 0; - } - - public String getCurUserName() { - Object val = ContextManager.getSession().get(ContextManager.KEY_NAME); - return val != null ? (String)val : null; - } - - public String getCurUserEmpId() { - Object val = ContextManager.getSession().get(ContextManager.KEY_EMP_ID); - return val != null ? (String)val : null; - } - - /** - public User getCurUser() { - return (User) ContextManager.getSession().get(ContextManager.KEY_USER); - }*/ - - private boolean isOk = true; - - public boolean getIsOk() { - return isOk; - } - - public void setIsOk(boolean isOk) { - this.isOk = isOk; - } - - public boolean isReturnUrlFirstSet() { - return isReturnUrlFirstSet; - } - - public void setRelativeReturnUrl(String returnUrl) { - this.returnUrl = SystemSettings.projectContext + returnUrl; - this.isReturnUrlFirstSet = true; - } - - private String json; - - public String getJson() { - if (json == null || json.isEmpty()) { - return new RapError().toString(); - } - return json; - } - - public void setJson(String json) { - this.json = json; - } - - private String errMsg; - - public String getErrMsg() { - return errMsg; - } - - public void setErrMsg(String errMsg) { - this.isLoginCtlHidden = true; - this.errMsg = errMsg; - this.isOk = false; - } - - public void plsLogin() { - setErrMsg(LOGIN_HINT_MSG); - } - -} diff --git a/src/com/taobao/rigel/rap/common/ArrayUtils.java b/src/com/taobao/rigel/rap/common/ArrayUtils.java deleted file mode 100644 index 1d8a7a21b..000000000 --- a/src/com/taobao/rigel/rap/common/ArrayUtils.java +++ /dev/null @@ -1,18 +0,0 @@ -package com.taobao.rigel.rap.common; - -import java.util.List; - -public class ArrayUtils { - public static String join(List arr, String seperator) { - StringBuilder str = new StringBuilder(); - boolean isFirst = true; - for (Object item : arr) { - if (!isFirst) { - str.append(seperator); - } - str.append(item); - isFirst = false; - } - return str.toString(); - } -} diff --git a/src/com/taobao/rigel/rap/common/CacheUtils.java b/src/com/taobao/rigel/rap/common/CacheUtils.java deleted file mode 100644 index 5042dec8a..000000000 --- a/src/com/taobao/rigel/rap/common/CacheUtils.java +++ /dev/null @@ -1,126 +0,0 @@ -package com.taobao.rigel.rap.common; -import com.taobao.rigel.rap.organization.bo.Corporation; -import com.taobao.rigel.rap.project.bo.Action; - -import java.util.List; -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; - -/** - * Created by Bosn on 14/11/28. - * Basic cache, need weight for string length. - */ -public class CacheUtils { - private static Map cachedRules = new ConcurrentHashMap(); - private static Map>> cachedTeams = new ConcurrentHashMap>>(); - - private static Map rulesFrequency = new ConcurrentHashMap(); // frequency of rules cache - private static Map teamsFrequency = new ConcurrentHashMap(); // frequency of teams cache - - private static long cachedSize = 0; // cached size in total - private static long cachedRuleSize = 0; // cached size of rules cache - private static long cachedTeamSize = 0; // cached size of teams cache - - /** - * get cached Mock rule - * - * @param action - * @param pattern - * @return - */ - public static String getRuleCache(Action action, String pattern) { - long actionId = action.getId(); - String requestUrl = action.getRequestUrl(); - if (requestUrl == null) { - requestUrl = ""; - } - if (pattern.contains("noCache=true") || requestUrl.contains("{") - || requestUrl.contains("noCache=true")) { - return null; - } - String cache = cachedRules.get(actionId); - if (cache != null) { - Long fre = rulesFrequency.get(actionId); - if (fre != null) { - rulesFrequency.put(actionId, fre + 1); - } - } - return cache; - } - - public static List getTeamCache(long userId, int pageNum, int pageSize) { - String key = "" + pageNum + pageSize; - Map> teamCache = cachedTeams.get(userId); - if (teamCache != null && teamCache.get(key) != null) { - return teamCache.get(key); - } - return null; - } - - /** - * set Mock rule cache - * - * @param actionId - * @param result - */ - public static void setRuleCache(long actionId, String result) { - if (!cachedRules.containsKey(actionId)) { - cachedRules.put(actionId, result); - rulesFrequency.put(actionId, 0L); - cachedRuleSize++; - cachedSize++; - } - - } - - public static void setTeamCache(long userId, int pageNum, int pageSize, List teamList) { - String key = "" + pageNum + pageSize; - if (!cachedTeams.containsKey(userId)) { - Map> teamMap = cachedTeams.get(userId); - if (teamMap == null) { - teamMap = new ConcurrentHashMap>(); - } - if (!teamMap.containsKey(key)) { - teamMap.put(key, teamList); - cachedTeams.put(userId, teamMap); - teamsFrequency.put(userId, 0L); - cachedTeamSize++; - cachedSize++; - } - } - } - - public static void removeTeamCache(long userId) { - if (cachedTeams.containsKey(userId)) { - cachedTeams.remove(userId); - teamsFrequency.remove(userId); - cachedTeamSize--; - cachedSize--; - } - } - - /** - * remove rule cache - * @param actionId - */ - private static void removeRuleCache(long actionId) { - if (cachedRules.containsKey(actionId)) { - cachedRules.remove(actionId); - rulesFrequency.remove(actionId); - cachedRuleSize--; - cachedSize--; - } - } - - public static long getCachedRuleSize() { - return cachedRuleSize; - } - - public static void removeCacheByActionId(long id) { - removeRuleCache(id); - } - - public static long getCachedTeamSize() {return cachedTeamSize;} - - public static long getCachedSize() {return cachedSize;} -} diff --git a/src/com/taobao/rigel/rap/common/ContextManager.java b/src/com/taobao/rigel/rap/common/ContextManager.java deleted file mode 100644 index 15e779c02..000000000 --- a/src/com/taobao/rigel/rap/common/ContextManager.java +++ /dev/null @@ -1,26 +0,0 @@ -package com.taobao.rigel.rap.common; - -import java.util.Map; - -import com.opensymphony.xwork2.ActionContext; - -public class ContextManager { - public static final String KEY_COUNT_OF_ONLINE_USER_LIST = "KEY_COUNT_OF_ONLINE_USER_LIST"; - public static final String KEY_ACCOUNT = "KEY_ACCOUNT"; - public static final String KEY_PROJECT_LOCK_LIST = "KEY_PROJECT_LOCK_LIST"; - public static final String KEY_USER_ID = "KEY_USER_ID"; - // public static final String KEY_CORP_NAME = "KEY_CORP_NAME"; - public static final String KEY_NAME = "KEY_NAME"; - public static final String KEY_EMP_ID = "KEY_EMP_ID"; - // public static final String KEY_USER = "KEY_USER"; - - @SuppressWarnings("rawtypes") - public static Map getSession() { - return ActionContext.getContext().getSession(); - } - - @SuppressWarnings("rawtypes") - public static Map getApplication() { - return ActionContext.getContext().getApplication(); - } -} diff --git a/src/com/taobao/rigel/rap/common/DateUtils.java b/src/com/taobao/rigel/rap/common/DateUtils.java deleted file mode 100644 index a69c37689..000000000 --- a/src/com/taobao/rigel/rap/common/DateUtils.java +++ /dev/null @@ -1,31 +0,0 @@ -package com.taobao.rigel.rap.common; - -import java.text.DateFormat; -import java.text.SimpleDateFormat; -import java.util.Calendar; -import java.util.Date; - -public class DateUtils { - public final static DateFormat DATE_FORMAT = new SimpleDateFormat( - "yyyy-MM-dd"); - - public final static DateFormat TIME_FORMAT = new SimpleDateFormat( - "yyyy-MM-dd HH:mm:ss"); - - private static int counter = 1; - - public static boolean compWorkAndCurrByDate(Date workDay, Date currTime) { - Calendar c1 = Calendar.getInstance(); - Calendar c2 = Calendar.getInstance(); - c1.setTime(workDay); - c2.setTime(currTime); - if (c1.get(Calendar.YEAR) == c2.get(Calendar.YEAR) - && (c1.get(Calendar.MONTH) == c2.get(Calendar.MONTH)) - && c1.get(Calendar.DAY_OF_MONTH) == c2 - .get(Calendar.DAY_OF_MONTH)) { - return true; - } else { - return false; - } - } -} diff --git a/src/com/taobao/rigel/rap/common/MailUtils.java b/src/com/taobao/rigel/rap/common/MailUtils.java deleted file mode 100644 index 412b22b64..000000000 --- a/src/com/taobao/rigel/rap/common/MailUtils.java +++ /dev/null @@ -1,69 +0,0 @@ -package com.taobao.rigel.rap.common; - -import java.util.Properties; - -import javax.mail.Address; -import javax.mail.Message; -import javax.mail.MessagingException; -import javax.mail.PasswordAuthentication; -import javax.mail.Session; -import javax.mail.Transport; -import javax.mail.internet.AddressException; -import javax.mail.internet.InternetAddress; -import javax.mail.internet.MimeMessage; - -public class MailUtils { - public static void sendMessage(String[] addressList, String title, - String content) throws AddressException { - Address[] addresses = new Address[addressList.length]; - for (int i = 0; i < addressList.length; i++) { - addresses[i] = new InternetAddress(addressList[i]); - } - - // Sender's email ID needs to be mentioned - String from = "rap@domain.com"; - final String username = PRIVATE_CONFIG.mailUserName; - final String password = PRIVATE_CONFIG.mailPassword; - - // Get system properties - Properties props = System.getProperties(); - - // Setup mail server - props.put("mail.smtp.host", "smtp-inc.domain.com"); - props.put("mail.smtp.port", "25"); - props.put("mail.smtp.auth", "true"); - - props.put("mail.smtp.starttls.enable", "true"); - - // Get the default Session object. - Session session = Session.getDefaultInstance(props, - new javax.mail.Authenticator() { - protected PasswordAuthentication getPasswordAuthentication() { - return new PasswordAuthentication( - username, password); - } - }); - - try { - // Create a default MimeMessage object. - MimeMessage message = new MimeMessage(session); - - // Set From: header field of the header. - message.setFrom(new InternetAddress(from)); - - // Set To: header field of the header. - message.addRecipients(Message.RecipientType.BCC, addresses); - - // Set Subject: header field - message.setSubject(title, "UTF-8"); - - // Now set the actual message - message.setText(content, "UTF-8"); - - // Send message - Transport.send(message); - } catch (MessagingException mex) { - mex.printStackTrace(); - } - } -} diff --git a/src/com/taobao/rigel/rap/common/MapUtils.java b/src/com/taobao/rigel/rap/common/MapUtils.java deleted file mode 100644 index de11304fb..000000000 --- a/src/com/taobao/rigel/rap/common/MapUtils.java +++ /dev/null @@ -1,15 +0,0 @@ -package com.taobao.rigel.rap.common; - -import java.util.Map; - -public class MapUtils { - @SuppressWarnings("rawtypes") - public static Object getKeyByValue(Map map, Object value) { - for (Object key : map.keySet()) { - if (map.get(key).equals(value)) { - return key; - } - } - return null; - } -} diff --git a/src/com/taobao/rigel/rap/common/MockjsRunner.java b/src/com/taobao/rigel/rap/common/MockjsRunner.java deleted file mode 100644 index 3562b4eaf..000000000 --- a/src/com/taobao/rigel/rap/common/MockjsRunner.java +++ /dev/null @@ -1,98 +0,0 @@ -package com.taobao.rigel.rap.common; - -import java.io.BufferedReader; -import java.io.DataInputStream; -import java.io.File; -import java.io.FileInputStream; -import java.io.InputStreamReader; - -import org.mozilla.javascript.Context; -import org.mozilla.javascript.Scriptable; - -public class MockjsRunner { - - private static String MOCKJS_PATH = SystemConstant.ROOT + - FileUtils.concatFilePath(new String[] {"stat", "js", "util", "mock-min.js"}); - private Context ct; - private Scriptable scope; - private static String jsCode; - public MockjsRunner() { - this.ct = Context.enter(); - this.scope = ct.initStandardObjects(); - this.initMockjs(ct, scope); - } - - public Context getContext() { - return this.ct; - } - - public Scriptable getScope() { - return this.scope; - } - - public static String getMockjsCode() { - String filePath = MockjsRunner.MOCKJS_PATH; - try { - FileInputStream fis = new FileInputStream(filePath); - StringBuffer content = new StringBuffer(); - DataInputStream in = new DataInputStream(fis); - BufferedReader d = new BufferedReader(new InputStreamReader(in, - "UTF-8")); - String line = null; - while ((line = d.readLine()) != null) - content.append(line + "\n"); - d.close(); - in.close(); - fis.close(); - return content.toString(); - - } catch (Exception e) { - e.printStackTrace(); - return "ERROR"; - } finally { - } - } - - private void initMockjs(Context ct, Scriptable scope) { - if (jsCode == null) { - jsCode = MockjsRunner.getMockjsCode(); - } - try { - ct.evaluateString(scope, jsCode, null, 1, null); - ct.evaluateString(scope, "", null, 1, null); - } catch (Exception e) { - e.printStackTrace(); - } - } - - private String doRenderMockJsRule(String mockRule) { - String returnVal = "JS_ERROR"; - try { - StringBuilder code = new StringBuilder(); - code - .append("var result = {};") - .append("try {") - // .append("var obj = Mock.mock(JSON.parse(\"" + StringUtils.escapeInJ(mockRule.replaceAll("\\'", "'")) + "\"));") - .append("var obj = Mock.mock(" + mockRule + ");") - .append("result = JSON.stringify(obj.__root__ ? obj.__root__ : obj, null, 4);") - .append("} catch(ex) {result.errMsg = ex.message;result.isOk=false;result = JSON.stringify(result);}") - .append("result;"); - Object result = ct.evaluateString(scope, code.toString(), null, 1, - null); - returnVal = result.toString(); - } catch (Exception e) { - e.printStackTrace(); - } finally { - ct.exit(); - } - return returnVal; - } - - public static String renderMockjsRule(String mockRule) { - return new MockjsRunner().doRenderMockJsRule(mockRule); - } - - public static void main(String[] args) { - System.out.println(MockjsRunner.renderMockjsRule("{'id|1-20': '1', 'b': '@IMG'}")); - } -} diff --git a/src/com/taobao/rigel/rap/common/NumberUtils.java b/src/com/taobao/rigel/rap/common/NumberUtils.java deleted file mode 100644 index 6274945b0..000000000 --- a/src/com/taobao/rigel/rap/common/NumberUtils.java +++ /dev/null @@ -1,47 +0,0 @@ -package com.taobao.rigel.rap.common; - -import java.util.Random; - -public class NumberUtils { - private static Random r = new Random(); - - /** - * random integer from 0 - 9 - * - * @return - */ - public static String randomInt10Str() { - return new Integer(r.nextInt(9)).toString(); - } - - /** - * random integer from 1 - 9 - * - * @return - */ - public static String randomInt10StrFrom1() { - return new Integer(r.nextInt(8) + 1).toString(); - } - - public static String randomByFormat(String format) { - boolean isFirst = true; - while (true) { - if (format.indexOf("x") < 0) { - break; - } - format = format.replaceFirst("x", isFirst ? randomInt10StrFrom1() - : randomInt10Str()); - isFirst = false; - } - return format; - } - - /** - * random integer from 0 to (length - 1) - * @param length - * @return - */ - public static int randomInt(int length) { - return r.nextInt(length - 1); - } -} diff --git a/src/com/taobao/rigel/rap/common/PRIVATE_CONFIG.java b/src/com/taobao/rigel/rap/common/PRIVATE_CONFIG.java deleted file mode 100644 index ebef99d7c..000000000 --- a/src/com/taobao/rigel/rap/common/PRIVATE_CONFIG.java +++ /dev/null @@ -1,7 +0,0 @@ -package com.taobao.rigel.rap.common; - -public class PRIVATE_CONFIG { - public static final String mailUserName = "rap@domain.com"; - public static final String mailPassword = ""; - public static final String adminPassword = ""; -} diff --git a/src/com/taobao/rigel/rap/common/RapError.java b/src/com/taobao/rigel/rap/common/RapError.java deleted file mode 100644 index 20abdd507..000000000 --- a/src/com/taobao/rigel/rap/common/RapError.java +++ /dev/null @@ -1,55 +0,0 @@ -package com.taobao.rigel.rap.common; - -public class RapError { - public static final int ERR_HAS_CHILDREN = 501; - - public RapError() { - - } - - public RapError(String result) { - this.result = result; - } - - public RapError(int code, String msg) { - this.code = code; - this.msg = msg; - } - - private int code = 200; - public int getCode() { - return code; - } - - public void setCode(int code) { - this.code = code; - } - - private String msg = ""; - private String result = ""; - - public String getResult() { - if (result == null || result.isEmpty()) { - return "\"\""; - } - return result; - } - - public void setResult(String result) { - this.result = result; - } - - public String getMsg() { - return msg; - } - - public void setMsg(String msg) { - this.msg = msg; - } - - public String toString() { - return "{\"code\":" + getCode() + ", \"msg\":\"" + getMsg() + "\", \"result\":" - + getResult() + "}"; - } - -} diff --git a/src/com/taobao/rigel/rap/common/RapServletContextListener.java b/src/com/taobao/rigel/rap/common/RapServletContextListener.java deleted file mode 100644 index 24a2527c8..000000000 --- a/src/com/taobao/rigel/rap/common/RapServletContextListener.java +++ /dev/null @@ -1,21 +0,0 @@ -package com.taobao.rigel.rap.common; - -import javax.servlet.ServletContextEvent; -import javax.servlet.ServletContextListener; - -/** - * Created by Bosn Ma on 15/9/7. - */ -public class RapServletContextListener implements ServletContextListener{ - @Override - public void contextInitialized(ServletContextEvent servletContextEvent) { - System.out.println("Server initializing..."); - - - } - - @Override - public void contextDestroyed(ServletContextEvent arg0) { - System.out.println("Server started."); - } -} diff --git a/src/com/taobao/rigel/rap/common/SessionListener.java b/src/com/taobao/rigel/rap/common/SessionListener.java deleted file mode 100644 index 7878dd7f1..000000000 --- a/src/com/taobao/rigel/rap/common/SessionListener.java +++ /dev/null @@ -1,55 +0,0 @@ -package com.taobao.rigel.rap.common; - -import java.util.Map; - -import javax.servlet.ServletContext; -import javax.servlet.http.HttpSession; -import javax.servlet.http.HttpSessionEvent; -import javax.servlet.http.HttpSessionListener; - - -public class SessionListener implements HttpSessionListener { - - @Override - public void sessionCreated(HttpSessionEvent event) { - ServletContext context = event.getSession().getServletContext(); - // online users count processing - String key = ContextManager.KEY_COUNT_OF_ONLINE_USER_LIST; - if (context.getAttribute(key) == null) { - context.setAttribute(key, 0); - } - int curCountOfOnlineuserList = (Integer)context.getAttribute(key); - context.setAttribute(key, curCountOfOnlineuserList + 1); - } - - @SuppressWarnings({ "rawtypes" }) - @Override - public void sessionDestroyed(HttpSessionEvent event) { - ServletContext context = event.getSession().getServletContext(); - HttpSession session = event.getSession(); - // online users count processing - - String key = ContextManager.KEY_COUNT_OF_ONLINE_USER_LIST; - if (context.getAttribute(key) == null) { - context.setAttribute(key, 0); - } - int curCountOfOnlineuserList = (Integer)context.getAttribute(key); - if (curCountOfOnlineuserList < 1) curCountOfOnlineuserList = 1; - context.setAttribute(key, curCountOfOnlineuserList - 1); - - // unlock project - Object userIdObj = session.getAttribute(ContextManager.KEY_USER_ID); - if (userIdObj != null) { - long userId = (Long) userIdObj; - Object projectLockListObj = context.getAttribute(ContextManager.KEY_PROJECT_LOCK_LIST); - if (projectLockListObj != null) { - Map projectLockList = (Map) projectLockListObj; - if (projectLockList.containsKey(userId)) { - projectLockList.remove(userId); - context.setAttribute(ContextManager.KEY_PROJECT_LOCK_LIST, projectLockList); - } - } - } - } - -} diff --git a/src/com/taobao/rigel/rap/common/SetCharacterEncodingFilter.java b/src/com/taobao/rigel/rap/common/SetCharacterEncodingFilter.java deleted file mode 100644 index b8a2c6fd9..000000000 --- a/src/com/taobao/rigel/rap/common/SetCharacterEncodingFilter.java +++ /dev/null @@ -1,181 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.taobao.rigel.rap.common; - -import java.io.IOException; - -import javax.servlet.Filter; -import javax.servlet.FilterChain; -import javax.servlet.FilterConfig; -import javax.servlet.ServletException; -import javax.servlet.ServletRequest; -import javax.servlet.ServletResponse; -import javax.servlet.http.HttpServletRequest; - -/** - *

    - * Example filter that sets the character encoding to be used in parsing the - * incoming request, either unconditionally or only if the client did not - * specify a character encoding. Configuration of this filter is based on the - * following initialization parameters: - *

    - *
      - *
    • encoding - The character encoding to be configured for - * this request, either conditionally or unconditionally based on the - * ignore initialization parameter. This parameter is required, so - * there is no default.
    • - *
    • ignore - If set to "true", any character encoding - * specified by the client is ignored, and the value returned by the - * selectEncoding() method is set. If set to "false, - * selectEncoding() is called only if the client - * has not already specified an encoding. By default, this parameter is set to - * "true".
    • - *
    - * - *

    - * Although this filter can be used unchanged, it is also easy to subclass it - * and make the selectEncoding() method more intelligent about what - * encoding to choose, based on characteristics of the incoming request (such as - * the values of the Accept-Language and User-Agent - * headers, or a value stashed in the current user's session. - *

    - * - * @author Craig McClanahan - * @version $Id: SetCharacterEncodingFilter.java 939315 2010-04-29 14:11:01Z - * kkolinko $ - */ - -public class SetCharacterEncodingFilter implements Filter { - - // ----------------------------------------------------- Instance Variables - - /** - * The default character encoding to set for requests that pass through this - * filter. - */ - protected String encoding = null; - - /** - * The filter configuration object we are associated with. If this value is - * null, this filter instance is not currently configured. - */ - protected FilterConfig filterConfig = null; - - /** - * Should a character encoding specified by the client be ignored? - */ - protected boolean ignore = true; - - // --------------------------------------------------------- Public Methods - - /** - * Take this filter out of service. - */ - public void destroy() { - - this.encoding = null; - this.filterConfig = null; - - } - - /** - * Select and set (if specified) the character encoding to be used to - * interpret request parameters for this request. - * - * @param request - * The servlet request we are processing - * @param response - * The servlet response we are creating - * @param chain - * The filter chain we are processing - * - * @exception IOException - * if an input/output error occurs - * @exception ServletException - * if a servlet error occurs - */ - public void doFilter(ServletRequest request, ServletResponse response, - FilterChain chain) throws IOException, ServletException { - - HttpServletRequest http = (HttpServletRequest) request; - System.out.println("ACCESS_LOG|" + http.getSession().getAttribute(ContextManager.KEY_ACCOUNT) + "|" + http.getRemoteAddr() + "|" + http.getRequestURL()); - - // Conditionally select and set the character encoding to be used - if (ignore || (request.getCharacterEncoding() == null)) { - String characterEncoding = selectEncoding(request); - if (characterEncoding != null) - request.setCharacterEncoding(characterEncoding); - } - - /** - HttpServletResponse httpResponse = (HttpServletResponse) response; - httpResponse.setHeader("Access-Control-Allow-Origin", "*"); - - httpResponse.setHeader("Access-Control-Allow-Headers", - "Origin, X-Requested-With, Content-Type, Accept"); - */ - - // Pass control on to the next filter - chain.doFilter(request, response); - - } - - /** - * Place this filter into service. - * - * @param fConfig - * The filter configuration object - */ - public void init(FilterConfig fConfig) throws ServletException { - - this.filterConfig = fConfig; - this.encoding = fConfig.getInitParameter("encoding"); - String value = fConfig.getInitParameter("ignore"); - if (value == null) - this.ignore = true; - else if (value.equalsIgnoreCase("true")) - this.ignore = true; - else if (value.equalsIgnoreCase("yes")) - this.ignore = true; - else - this.ignore = false; - - } - - // ------------------------------------------------------ Protected Methods - - /** - * Select an appropriate character encoding to be used, based on the - * characteristics of the current request and/or filter initialization - * parameters. If no character encoding should be set, return - * null. - *

    - * The default implementation unconditionally returns the value configured - * by the encoding initialization parameter for this - * filter. - * - * @param request - * The servlet request we are processing - */ - protected String selectEncoding(ServletRequest request) { - - return (this.encoding); - - } - -} diff --git a/src/com/taobao/rigel/rap/common/StringUtils.java b/src/com/taobao/rigel/rap/common/StringUtils.java deleted file mode 100644 index aa48cbf89..000000000 --- a/src/com/taobao/rigel/rap/common/StringUtils.java +++ /dev/null @@ -1,549 +0,0 @@ -package com.taobao.rigel.rap.common; - -import org.springmodules.cache.regex.Regex; - -import java.io.UnsupportedEncodingException; -import java.net.URLDecoder; -import java.net.URLEncoder; -import java.security.MessageDigest; -import java.security.NoSuchAlgorithmException; -import java.util.ArrayList; -import java.util.List; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -/** - * 为FE提供各类过滤字符串的接口 - * - * @author Junquan 2010.01.20 - */ -public class StringUtils { - - /** - * 默认编码 utf8 - */ - public static String DEFAULT_CHARSET = "utf8"; - - /** - * 在html标签或属性中A: 左尖括号:< 转成 < 右尖括号:> 转成 > 单引号:' 转成 ' 双引号:" 转成 - * " - */ - public static String escapeInH(String str) { - if (str == null || ("").equals(str.trim())) { - return ""; - } - - StringBuffer sb = new StringBuffer(); - int lth = str.length(); - - for (int i = 0; i < lth; i++) { - char c = str.charAt(i); - - switch (c) { - - case 60: // < - sb.append("<"); - break; - case 62: // > - sb.append(">"); - break; - case 39: // ' - sb.append("'"); - break; - case 34: // " - sb.append("""); - break; - default: - sb.append(c); - break; - } - } - return new String(sb.toString()); - } - - public static String escapeInH(Number num) { - String str = null; - if (num != null) { - str = num.toString(); - } - - return escapeInH(str); - } - - /** - * 在html标签或属性中A - 逆 - */ - public static String UnEscapeInH(String str) { - // TODO - return str; - } - - /** - * 在html标签或属性中B: 左尖括号:< 转成 < 右尖括号:> 转成 > 单引号:' 转成 ' 双引号:" 转成 - * " &符号:& 转成& - */ - public static String escapeInX(String str) { - if (str == null || ("").equals(str.trim())) { - return ""; - } - - StringBuffer sb = new StringBuffer(); - int lth = str.length(); - - for (int i = 0; i < lth; i++) { - char c = str.charAt(i); - - switch (c) { - - case 60: // < - sb.append("<"); - break; - case 62: // > - sb.append(">"); - break; - case 39: // ' - sb.append("'"); - break; - case 34: // " - sb.append("""); - break; - case 38: // & - sb.append("&"); - break; - default: - sb.append(c); - break; - } - } - return new String(sb.toString()); - } - - public static String escapeInX(Number num) { - String str = null; - if (num != null) { - str = num.toString(); - } - - return escapeInX(str); - } - - /** - * 在html标签或属性中B - 逆 - */ - public static String UnEscapeInX(String str) { - // TODO - return str; - } - - /** - * 在普通JS环境: 单引号:' 转成 \' 双引号:" 转成 \" 反斜杠:\ 转成 \\ 正斜杠:/ 转成 \/ 换行符 转成 \n 回车符 转成 - * \r - */ - public static String escapeInJ(String str) { - if (str == null || ("").equals(str.trim())) { - return ""; - } - - StringBuffer sb = new StringBuffer(); - int lth = str.length(); - - for (int i = 0; i < lth; i++) { - char c = str.charAt(i); - - switch (c) { - - case 39: // ' - sb.append("\\'"); - break; - case 34: // " - sb.append("\\\""); - break; - case 47: // / - sb.append("\\/"); - break; - case 92: // \ - sb.append("\\\\"); - break; - case 13: // 回车 \r - sb.append("\\r"); - break; - case 10: // 换行 \n - sb.append("\\n"); - break; - default: - sb.append(c); - break; - } - } - return new String(sb.toString()); - } - - public static String escapeInJ(Number num) { - String str = null; - if (num != null) { - str = num.toString(); - } - - return escapeInJ(str); - } - - /** - * 在普通JS环境 - 逆 - */ - public static String UnEscapeInJ(String str) { - // TODO - return str; - } - - /** - * 在JS环境的innerHTML: 左尖括号:< 转成 < 右尖括号:> 转成 > 单引号:' 转成 \' 双引号:" 转成 \" - * 反斜杠:\ 转成 \\ 正斜杠:/ 转成 \/ 换行符 转成 \n 回车符 转成 \r - */ - public static String escapeInJH(String str) { - if (str == null || ("").equals(str.trim())) { - return ""; - } - - StringBuffer sb = new StringBuffer(); - int lth = str.length(); - - for (int i = 0; i < lth; i++) { - char c = str.charAt(i); - - switch (c) { - - case 60: // < - sb.append("<"); - break; - case 62: // > - sb.append(">"); - break; - case 39: // ' - sb.append("\\'"); - break; - case 34: // " - sb.append("\\\""); - break; - case 47: // / - sb.append("\\/"); - break; - case 92: // \ - sb.append("\\\\"); - break; - case 13: // 回车 \r - sb.append("\\r"); - break; - case 10: // 换行 \n - sb.append("\\n"); - break; - default: - sb.append(c); - break; - } - } - return new String(sb.toString()); - } - - public static String escapeInJH(Number num) { - String str = null; - if (num != null) { - str = num.toString(); - } - - return escapeInJH(str); - } - - /** - * 在JS环境的innerHTML - 逆 - */ - public static String UnEscapeInJH(String str) { - // TODO - return str; - } - - /** - * 在标签onclick等事件函数参数中: 左尖括号:< 转成 < 右尖括号:> 转成 > &符号:& 转成& 单引号:' 转成 - * \' 双引号:" 转成 \" 反斜杠:\ 转成 \\ 正斜杠:/ 转成 \/ 换行符 转成 \n 回车符 转成 \r - */ - public static String escapeInHJ(String str) { - if (str == null || ("").equals(str.trim())) { - return ""; - } - - StringBuffer sb = new StringBuffer(); - int lth = str.length(); - - for (int i = 0; i < lth; i++) { - char c = str.charAt(i); - - switch (c) { - - case 60: // < - sb.append("<"); - break; - case 62: // > - sb.append(">"); - break; - case 39: // ' - sb.append("\\'"); - break; - case 34: // " - sb.append("\\""); - break; - case 38: // & - sb.append("&"); - break; - case 47: // / - sb.append("\\/"); - break; - case 92: // \ - sb.append("\\\\"); - break; - case 13: // 回车 \r - sb.append("\\r"); - break; - case 10: // 换行 \n - sb.append("\\n"); - break; - default: - sb.append(c); - break; - } - } - return new String(sb.toString()); - } - - public static String escapeInHJ(Number num) { - String str = null; - if (num != null) { - str = num.toString(); - } - - return escapeInHJ(str); - } - - /** - * 在标签onclick等事件函数参数中 - 逆 - */ - public static String UnEscapeInHJ(String str) { - // TODO - return str; - } - - /** - * 在URL参数中: 对非字母、数字字符进行转码(%加字符的ASCII格式) - * - * @throws UnsupportedEncodingException - */ - public static String escapeInU(String str) - throws UnsupportedEncodingException { - if (str == null || ("").equals(str.trim())) { - return ""; - } - return URLEncoder.encode(str, DEFAULT_CHARSET); - } - - /** - * 在URL参数中 - 逆 - * - * @throws UnsupportedEncodingException - */ - public static String UnEscapeInU(String str) - throws UnsupportedEncodingException { - if (str == null || ("").equals(str.trim())) { - return ""; - } - return URLDecoder.decode(str, DEFAULT_CHARSET); - } - - public static String getMD5(String src) { - byte[] defaultBytes = src.getBytes(); - StringBuffer hexString = new StringBuffer(); - try { - MessageDigest algorithm = MessageDigest.getInstance("MD5"); - algorithm.reset(); - algorithm.update(defaultBytes); - byte messageDigest[] = algorithm.digest(); - - for (int i = 0; i < messageDigest.length; i++) { - hexString.append(Integer.toHexString(0xFF & messageDigest[i])); - } - } catch (NoSuchAlgorithmException e) { - e.printStackTrace(); - } - return hexString.toString(); - } - - public static String getMD5(byte[] source) { - String s = null; - char hexDigits[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', - 'a', 'b', 'c', 'd', 'e', 'f' };// 用来将字节转换成16进制表示的字符 - try { - java.security.MessageDigest md = java.security.MessageDigest - .getInstance("MD5"); - md.update(source); - byte tmp[] = md.digest();// MD5 的计算结果是一个 128 位的长整数, - // 用字节表示就是 16 个字节 - char str[] = new char[16 * 2];// 每个字节用 16 进制表示的话,使用两个字符, 所以表示成 16 - // 进制需要 32 个字符 - int k = 0;// 表示转换结果中对应的字符位置 - for (int i = 0; i < 16; i++) {// 从第一个字节开始,对 MD5 的每一个字节// 转换成 16 - // 进制字符的转换 - byte byte0 = tmp[i];// 取第 i 个字节 - str[k++] = hexDigits[byte0 >>> 4 & 0xf];// 取字节中高 4 位的数字转换,// >>> - // 为逻辑右移,将符号位一起右移 - str[k++] = hexDigits[byte0 & 0xf];// 取字节中低 4 位的数字转换 - - } - s = new String(str);// 换后的结果转换为字符串 - - } catch (NoSuchAlgorithmException e) { - e.printStackTrace(); - } - return s; - } - - public static String getDoubleMD5(String src) { - if (src != null) { - src = getMD5(src); - src = getMD5(src); - } - return src; - } - - /** - * 把中文转成Unicode码 - * - * @param str - * @return - */ - public static String chineseToUnicode(String str) { - if (str == null) { - str = ""; - } - String result = ""; - for (int i = 0; i < str.length(); i++) { - int chr1 = (char) str.charAt(i); - if (chr1 >= 19968 && chr1 <= 171941) {// 汉字范围 \u4e00-\u9fa5 (中文) - result += "\\u" + Integer.toHexString(chr1); - } else { - result += str.charAt(i); - } - } - return result; - } - - /** - * 判断是否为中文字符 - * - * @param c - * @return - */ - public static boolean isChinese(char c) { - Character.UnicodeBlock ub = Character.UnicodeBlock.of(c); - if (ub == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS - || ub == Character.UnicodeBlock.CJK_COMPATIBILITY_IDEOGRAPHS - || ub == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS_EXTENSION_A - || ub == Character.UnicodeBlock.GENERAL_PUNCTUATION - || ub == Character.UnicodeBlock.CJK_SYMBOLS_AND_PUNCTUATION - || ub == Character.UnicodeBlock.HALFWIDTH_AND_FULLWIDTH_FORMS) { - return true; - } - return false; - } - - /** - * 中文算2个,字母算1个 - * - * @param str - * @return - */ - public static int getLengthOfStringChinese(String str) { - int length = 0; - for (char c : str.toCharArray()) { - if (isChinese(c)) length += 2; - else length ++; - } - return length; - } - - /** - * 中文算2个,字母算1个 - * - * @param str - * @param startIndex - * @param endIndex - * @return - */ - public static String subStringChinese(String str, int startIndex, int endIndex) { - int length = 0; - int size = endIndex - startIndex; - List charList = new ArrayList(); - for (char c : str.toCharArray()) { - if (isChinese(c)) length += 2; - else length ++; - charList.add(c); - if (length >= size) break; - } - StringBuilder builder = new StringBuilder(); - for (Character c : charList) { - builder.append(c); - } - return builder.toString(); - } - - /** - * regular expression matcher helper - * - * @param pattern - * regular expression - * @param str - * string to be matched - * @return - */ - public static boolean regMatch(String pattern, String str) { - Pattern p = Pattern.compile(pattern); - Matcher matcher = p.matcher(str); - return matcher.matches(); - } - - /** - * remove all characters except [0-9a-zA-Z_] and blank space - * - * @param o - * @return - */ - public static String removeIllegalCharacters(String o) { - return o.replaceAll(Patterns.ILLEGAL_NAME_CHAR, ""); - } - - - public static boolean validateAccount(String str) { - if (str == null) return false; - if (str.length() < SystemConstant.ACCOUNT_LENGTH_MIN || str.length() > SystemConstant.ACCOUNT_LENGTH_MAX) { - return false; - } - return str.matches(Patterns.LEGAL_ACCOUNT_CHAR + "*"); - } - - public static boolean validateName(String str) { - if (str == null) return false; - if (str.length() < SystemConstant.NAME_LENGTH_MIN || str.length() > SystemConstant.NAME_LENGTH_MAX) { - return false; - } - - for (int i = 0; i < str.length(); i++) { - char c = str.charAt(i); - if (!isChinese(c) && !String.valueOf(c).matches(Patterns.LEGAL_NAME_CHAR)) { - return false; - } - } - - return true; - } - - - public static final String NAME_FORMAT_WARN_MSG = "名字必须由数字/字母/汉子/空格/下划线组成,长度" + SystemConstant.NAME_LENGTH_MIN + "-" + SystemConstant.NAME_LENGTH_MAX + "."; - - public static final String ACCOUNT_FORMAT_WARN_MSG = "账户必须由数字/字母/下划线组成,长度" + SystemConstant.ACCOUNT_LENGTH_MIN + "-" + SystemConstant.ACCOUNT_LENGTH_MAX + "."; -} diff --git a/src/com/taobao/rigel/rap/common/SystemSettings.java b/src/com/taobao/rigel/rap/common/SystemSettings.java deleted file mode 100644 index 1362886e1..000000000 --- a/src/com/taobao/rigel/rap/common/SystemSettings.java +++ /dev/null @@ -1,27 +0,0 @@ -package com.taobao.rigel.rap.common; - -import java.io.File; - -import org.apache.struts2.ServletActionContext; - -public class SystemSettings { - - public static final String APP_PATH = ServletActionContext - .getServletContext().getRealPath("/"); - public static final String STATIC_ROOT = APP_PATH + "stat" + File.separator; - - public static final String projectContext = ""; - - public static String GET_DEFAULT_USER_SETTINGS (String key) { - if (key == null || key.isEmpty()) { - return null; - } - - if (key.equals("inform")) { - return ""; - } - - return null; - - }; -} diff --git a/src/com/taobao/rigel/rap/common/applicationContext.xml b/src/com/taobao/rigel/rap/common/applicationContext.xml deleted file mode 100644 index 6f6357642..000000000 --- a/src/com/taobao/rigel/rap/common/applicationContext.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - - - \ No newline at end of file diff --git a/src/com/taobao/rigel/rap/mock/applicationContext.xml b/src/com/taobao/rigel/rap/mock/applicationContext.xml deleted file mode 100644 index 96b8836a9..000000000 --- a/src/com/taobao/rigel/rap/mock/applicationContext.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - - - \ No newline at end of file diff --git a/src/com/taobao/rigel/rap/mock/mapping/Rule.hbm.xml b/src/com/taobao/rigel/rap/mock/mapping/Rule.hbm.xml deleted file mode 100644 index 0eae6ec3a..000000000 --- a/src/com/taobao/rigel/rap/mock/mapping/Rule.hbm.xml +++ /dev/null @@ -1,17 +0,0 @@ - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/src/com/taobao/rigel/rap/mock/service/MockMgr.java b/src/com/taobao/rigel/rap/mock/service/MockMgr.java deleted file mode 100644 index 9c0d90546..000000000 --- a/src/com/taobao/rigel/rap/mock/service/MockMgr.java +++ /dev/null @@ -1,98 +0,0 @@ -package com.taobao.rigel.rap.mock.service; - -import com.taobao.rigel.rap.mock.bo.Rule; -import com.taobao.rigel.rap.project.bo.Action; - -import java.io.UnsupportedEncodingException; -import java.util.Map; - -public interface MockMgr { - /** - * automatically generate testing data - * - * @param projectId - * @param pattern - * @param options - * @return JSON String - * @throws UnsupportedEncodingException - */ - String generateData(int projectId, String pattern, - Map options) throws UnsupportedEncodingException; - - /** - * modify mock data of parameters based on mockData - * - * @param actionId - * identifier of the action to be modified - * @param mockData - * mock data string example: - * response.param1.subParam=@format=x.xxxx_AND_response. - * param2=@value= - * 1_AND_response.param3.subParam.subSubParam=@length=7 - * @return number of rows affected - * - */ - int modify(int actionId, String mockData); - - /** - * clear all mock data of object in specified project - * - * @param projectId - * @return number of rows affected - */ - int reset(int projectId); - - /** - * generate mockjs rule - * - * @param id projectId, if both pattern and options are null, - * this id means actionId(used for OpenAPI) - * @param pattern - * @param options - * @return - * @throws UnsupportedEncodingException - */ - String generateRule(int id, String pattern, - Map options) throws UnsupportedEncodingException; - - /** - * generate mockjs data - * - * @param id - * @param pattern - * @param options - * @return - * @throws UnsupportedEncodingException - */ - String generateRuleData(int id, String pattern, - Map options) throws UnsupportedEncodingException; - - /** - * generate mockjs data by Action ID - * - * @param actionId - * @return - * @throws UnsupportedEncodingException - */ - // String generateRuleData(int actionId) throws UnsupportedEncodingException; - - /** - * validate API format - * - * @param projectId - * @param pattern - * @param options - * @param jsonToCompare - * @return - */ - String validateAPI(int projectId, String pattern, Map options, String jsonToCompare) throws UnsupportedEncodingException; - - /** - * get mock rule from action and action rule - * - * @param rule - * @param action - * @return - */ - String getMockRuleFromActionAndRule(Rule rule, Action action); -} diff --git a/src/com/taobao/rigel/rap/mock/web/action/MockAction.java b/src/com/taobao/rigel/rap/mock/web/action/MockAction.java deleted file mode 100644 index 5eb2745e0..000000000 --- a/src/com/taobao/rigel/rap/mock/web/action/MockAction.java +++ /dev/null @@ -1,474 +0,0 @@ -package com.taobao.rigel.rap.mock.web.action; - -import com.google.gson.Gson; -import com.taobao.rigel.rap.common.ActionBase; -import com.taobao.rigel.rap.common.HTTPUtils; -import com.taobao.rigel.rap.common.SystemVisitorLog; -import com.taobao.rigel.rap.mock.service.MockMgr; -import com.taobao.rigel.rap.project.bo.Action; -import com.taobao.rigel.rap.project.bo.Module; -import com.taobao.rigel.rap.project.bo.Page; -import com.taobao.rigel.rap.project.bo.Project; -import com.taobao.rigel.rap.project.service.ProjectMgr; -import org.apache.logging.log4j.LogManager; -import org.apache.struts2.ServletActionContext; - -import java.io.UnsupportedEncodingException; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - - -public class MockAction extends ActionBase { - - private static final long serialVersionUID = 1L; - private static final org.apache.logging.log4j.Logger logger = LogManager.getFormatterLogger(MockAction.class.getName()); - private int id; - private int __id__; - private String pattern; - private String mockData; - private int actionId; - private int projectId; - private String content; - private String callback; - private boolean enable = true; - private String _c; - private ProjectMgr projectMgr; - private List urlList; - private boolean seajs; - private boolean disableLog; - private String mode; - private MockMgr mockMgr; - - public String getActionData() { - return actionData; - } - - public void setActionData(String actionData) { - this.actionData = actionData; - } - - private String actionData; - - public String getUrl() { - return url; - } - - public void setUrl(String url) { - this.url = url; - } - - private String url; - - public boolean isDisableLog() { - return disableLog; - } - - public void setDisableLog(boolean disableLog) { - this.disableLog = disableLog; - } - - public List getUrlList() { - return urlList; - } - - public void setUrlList(List urlList) { - this.urlList = urlList; - } - - private String getMethod() { - return ServletActionContext.getRequest().getMethod(); - } - - public ProjectMgr getProjectMgr() { - return projectMgr; - } - - public void setProjectMgr(ProjectMgr projectMgr) { - this.projectMgr = projectMgr; - } - - public int getProjectId() { - return projectId; - } - - public void setProjectId(int projectId) { - this.projectId = projectId; - } - - public boolean isEnable() { - return enable; - } - - public void setEnable(boolean enable) { - this.enable = enable; - } - - public boolean isSeajs() { - return seajs; - } - - public void setSeajs(boolean seajs) { - this.seajs = seajs; - } - - public String getMode() { - return mode; - } - - public void setMode(String mode) { - this.mode = mode; - } - - public void setMockData(String mockData) { - this.mockData = mockData; - } - - public void setActionId(int actionId) { - this.actionId = actionId; - } - - public String get_c() { - return _c; - } - - public void set_c(String _c) { - this._c = _c; - } - - public String getCallback() { - return callback; - } - - public void setCallback(String callback) { - this.callback = callback; - } - - public MockMgr getMockMgr() { - return mockMgr; - } - - public void setMockMgr(MockMgr mockMgr) { - this.mockMgr = mockMgr; - } - - public String getContent() { - return content; - } - - public void setContent(String content) { - this.content = content; - } - - public int getId() { - return id; - } - - public void setId(int id) { - this.id = id; - } - - public String getPattern() { - return pattern; - } - - /** - * force callback or _c to be the last parameter - * - * @param pattern - */ - public void setPattern(String pattern) { - this.pattern = pattern; - } - - public String createData() throws UnsupportedEncodingException { - System.out.println("CREATE_DATA|" + pattern + "|" + getCurUserAccount()); - boolean isJSON = false; - updateProjectListMockNum(SystemVisitorLog.mock(__id__, "createData", pattern, getCurUserAccount())); - Map options = new HashMap(); - String _c = get_c(); - String result = mockMgr.generateData(__id__, pattern, options); - if (options.get("callback") != null) { - _c = (String) options.get("callback"); - callback = (String) options.get("callback"); - } - - if (callback != null && !callback.isEmpty()) { - setContent(callback + "(" + result + ")"); - } else if (_c != null && !_c.isEmpty()) { - setContent(_c + "(" + result + ")"); - } else { - isJSON = true; - setContent(result); - } - if (isJSON) { - return "json"; - } else { - return SUCCESS; - } - } - - public String createRule() throws UnsupportedEncodingException { - System.out.println("MOCK_JS|" + pattern + "|" + getCurUserAccount()); - boolean isJSON = false; - updateProjectListMockNum(SystemVisitorLog.mock(__id__, "createRule", pattern, getCurUserAccount())); - Map options = new HashMap(); - String _c = get_c(); - options.put("method", getMethod()); - String result = mockMgr.generateRule(__id__, pattern, options); - if (options.get("callback") != null) { - _c = (String) options.get("callback"); - callback = (String) options.get("callback"); - } - if (callback != null && !callback.isEmpty()) { - setContent(callback + "(" + result + ")"); - } else if (_c != null && !_c.isEmpty()) { - setContent(_c + "(" + result + ")"); - } else { - isJSON = true; - setContent(result); - } - if (isJSON) { - return "json"; - } else { - return SUCCESS; - } - } - - public String createRuleAuto() throws UnsupportedEncodingException { - boolean isJSON = false; - updateProjectListMockNum(SystemVisitorLog.mock(__id__, "createRule", pattern, getCurUserAccount())); - Map options = new HashMap(); - String _c = get_c(); - options.put("method", getMethod()); - options.put("loadRule", true); // load rules set by Open API (tb_rule) - - String result = mockMgr.generateRule(__id__, pattern, options); - if (options.get("callback") != null) { - _c = (String) options.get("callback"); - callback = (String) options.get("callback"); - } - if (callback != null && !callback.isEmpty()) { - setContent(callback + "(" + result + ")"); - } else if (_c != null && !_c.isEmpty()) { - setContent(_c + "(" + result + ")"); - } else { - isJSON = true; - setContent(result); - } - if (isJSON) { - return "json"; - } else { - return SUCCESS; - } - } - - public String createRuleByActionData() throws UnsupportedEncodingException { - boolean isJSON = false; - updateProjectListMockNum(SystemVisitorLog.mock(id, "createRuleByActionData", pattern, getCurUserAccount())); - Map options = new HashMap(); - String _c = get_c(); - String result = mockMgr.generateRule(id, pattern, options); - if (options.get("callback") != null) { - _c = (String) options.get("callback"); - callback = (String) options.get("callback"); - } - if (callback != null && !callback.isEmpty()) { - setContent(callback + "(" + result + ")"); - } else if (_c != null && !_c.isEmpty()) { - setContent(_c + "(" + result + ")"); - } else { - isJSON = true; - setContent(result); - } - if (isJSON) { - return "json"; - } else { - return SUCCESS; - } - } - - public String modify() { - setNum(mockMgr.modify(actionId, mockData)); - return SUCCESS; - } - - public String reset() { - setNum(mockMgr.reset(projectId)); - return SUCCESS; - } - - public String createPluginScript() { - System.out.println("CREATE_PLUGIN_SCRIPT|" + pattern + "|" + getCurUserAccount()); - updateProjectListMockNum(SystemVisitorLog.mock(id, "createPluginScript", pattern, getCurUserAccount())); - Map _circleRefProtector = new HashMap(); - List list = new ArrayList(); - Project p = projectMgr.getProject(projectId); - - loadWhiteList(p, list, _circleRefProtector); - urlList = list; - return SUCCESS; - } - - public String getWhiteList() { - Map _circleRefProtector = new HashMap(); - List list = new ArrayList(); - Project p = projectMgr.getProject(projectId); - - loadWhiteList(p, list, _circleRefProtector); - urlList = list; - Gson g = new Gson(); - String json = g.toJson(urlList); - setJson(json); - - return SUCCESS; - } - - private void loadWhiteList(Project p, List list, Map map) { - // prevent circle reference - if (p == null || map.get(p.getId() + "") != null) { - return; - } else { - map.put(p.getId() + "", true); - } - if (p != null) { - for (Module m : p.getModuleList()) { - for (Page page : m.getPageList()) { - for (Action a : page.getActionList()) { - list.add(a.getRequestUrlRel()); - } - } - } - } - - String relatedIds = p.getRelatedIds(); - if (relatedIds != null && !relatedIds.isEmpty()) { - String[] relatedIdsArr = relatedIds.split(","); - for (String relatedId : relatedIdsArr) { - int rId = Integer.parseInt(relatedId); - Project rP = projectMgr.getProject(rId); - if (rP != null && rP.getId() > 0) - loadWhiteList(rP, list, map); - } - } - } - - public String createMockjsData() throws UnsupportedEncodingException { - System.out.println("MOCK_JS_DATA|" + pattern + "|" + getCurUserAccount()); - boolean isJSON = false; - updateProjectListMockNum(SystemVisitorLog.mock(__id__, "createMockjsData", pattern, getCurUserAccount())); - String _c = get_c(); - Map options = new HashMap(); - options.put("method", getMethod()); - String result = mockMgr.generateRuleData(__id__, pattern, options); - if (options.get("callback") != null) { - _c = (String) options.get("callback"); - callback = (String) options.get("callback"); - } - if (callback != null && !callback.isEmpty()) { - setContent(callback + "(" + result + ")"); - } else if (_c != null && !_c.isEmpty()) { - setContent(_c + "(" + result + ")"); - } else { - isJSON = true; - setContent(result); - } - - if (isJSON) { - return "json"; - } else { - return SUCCESS; - } - } - - public String createMockjsDataAuto() throws UnsupportedEncodingException { - System.out.println("MOCK_JS_AUTO|" + pattern + "|" + getCurUserAccount()); - boolean isJSON = false; - updateProjectListMockNum(SystemVisitorLog.mock(__id__, "createMockjsData", pattern, getCurUserAccount())); - String _c = get_c(); - Map options = new HashMap(); - options.put("method", getMethod()); - options.put("loadRule", true); - String result = mockMgr.generateRuleData(__id__, pattern, options); - if (options.get("callback") != null) { - _c = (String) options.get("callback"); - callback = (String) options.get("callback"); - } - if (callback != null && !callback.isEmpty()) { - setContent(callback + "(" + result + ")"); - } else if (_c != null && !_c.isEmpty()) { - setContent(_c + "(" + result + ")"); - } else { - isJSON = true; - setContent(result); - } - - if (isJSON) { - return "json"; - } else { - return SUCCESS; - } - } - - public String validateAPI() throws UnsupportedEncodingException { - boolean isJSON = false; - updateProjectListMockNum(SystemVisitorLog.mock(id, "createRule", pattern, getCurUserAccount())); - Map options = new HashMap(); - String _c = get_c(); - options.put("method", getMethod()); - - String result = mockMgr.validateAPI(id, pattern, options, getJson()); - if (options.get("callback") != null) { - _c = (String) options.get("callback"); - callback = (String) options.get("callback"); - } - if (callback != null && !callback.isEmpty()) { - setContent(callback + "(" + result + ")"); - } else if (_c != null && !_c.isEmpty()) { - setContent(_c + "(" + result + ")"); - } else { - isJSON = true; - setContent(result); - } - if (isJSON) { - return "json"; - } else { - return SUCCESS; - } - } - - private void updateProjectListMockNum(List list) { - for (Project p : list) { - Project project = projectMgr.getProject(p.getId()); - if (project == null) continue; - project.setMockNum(p.getMockNum() + project.getMockNum()); - projectMgr.updateProjectNum(project); - } - } - - public int get__id__() { - return __id__; - } - - public void set__id__(int __id__) { - this.__id__ = __id__; - } - - public String requestOnServer() { - try { - setContent(HTTPUtils.sendGet(url)); - } catch (Exception e) { - setContent(e.getMessage()); - } - return SUCCESS; - } - - public String queryMockData() { - Gson gson = new Gson(); - Action action = gson.fromJson(actionData, Action.class); - setContent(mockMgr.getMockRuleFromActionAndRule(null, action)); - - return SUCCESS; - } -} diff --git a/src/com/taobao/rigel/rap/mock/web/action/struts.xml b/src/com/taobao/rigel/rap/mock/web/action/struts.xml deleted file mode 100644 index 36d1ecc5a..000000000 --- a/src/com/taobao/rigel/rap/mock/web/action/struts.xml +++ /dev/null @@ -1,139 +0,0 @@ - - - - - - - - - - /bcom/isOkWithNum.cb.vm - - - - - /bcom/isOkWithNum.cb.vm - - - - - /bcom/contentWithoutEscape.cb.vm - - /bcom/contentWithoutEscape.cb.vm - - - application/json - /bcom/contentWithoutEscape.cb.vm - - - - - /bcom/contentWithoutEscape.cb.vm - - /bcom/contentWithoutEscape.cb.vm - - - application/json - /bcom/contentWithoutEscape.cb.vm - - - - - /bcom/contentWithoutEscape.cb.vm - - /bcom/contentWithoutEscape.cb.vm - - - application/json - /bcom/contentWithoutEscape.cb.vm - - - - - /bcom/contentWithoutEscape.cb.vm - - /bcom/contentWithoutEscape.cb.vm - - - application/json - /bcom/contentWithoutEscape.cb.vm - - - - - /bcom/contentWithoutEscape.cb.vm - - /bcom/contentWithoutEscape.cb.vm - - - application/json - /bcom/contentWithoutEscape.cb.vm - - - - - /bcom/contentWithoutEscape.cb.vm - - /bcom/contentWithoutEscape.cb.vm - - - application/json - /bcom/contentWithoutEscape.cb.vm - - - - - /bcom/contentWithoutEscape.cb.vm - - /bcom/contentWithoutEscape.cb.vm - - - application/json - /bcom/contentWithoutEscape.cb.vm - - - - - - text/javascript - /mock/createPluginScript.vm - - - - - /bcom/json.cb.vm - - - - - /bcom/contentWithoutEscape.cb.vm - - - - - /bcom/contentWithoutEscape.cb.vm - - /bcom/contentWithoutEscape.cb.vm - - - application/json - /bcom/contentWithoutEscape.cb.vm - - - - \ No newline at end of file diff --git a/src/com/taobao/rigel/rap/organization/applicationContext.xml b/src/com/taobao/rigel/rap/organization/applicationContext.xml deleted file mode 100644 index f44df37f2..000000000 --- a/src/com/taobao/rigel/rap/organization/applicationContext.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - - - - - - - \ No newline at end of file diff --git a/src/com/taobao/rigel/rap/organization/bo/Group.java b/src/com/taobao/rigel/rap/organization/bo/Group.java deleted file mode 100644 index b12ddde0b..000000000 --- a/src/com/taobao/rigel/rap/organization/bo/Group.java +++ /dev/null @@ -1,40 +0,0 @@ -package com.taobao.rigel.rap.organization.bo; - -public class Group { - private int id; - private String name; - private int productionLineId; - private int userId; - - public int getId() { - return id; - } - - public void setId(int id) { - this.id = id; - } - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - public int getProductionLineId() { - return productionLineId; - } - - public void setProductionLineId(int productionLineId) { - this.productionLineId = productionLineId; - } - - public int getUserId() { - return userId; - } - - public void setUserId(int userId) { - this.userId = userId; - } -} diff --git a/src/com/taobao/rigel/rap/organization/bo/ProductionLine.java b/src/com/taobao/rigel/rap/organization/bo/ProductionLine.java deleted file mode 100644 index 8571bad55..000000000 --- a/src/com/taobao/rigel/rap/organization/bo/ProductionLine.java +++ /dev/null @@ -1,49 +0,0 @@ -package com.taobao.rigel.rap.organization.bo; - -public class ProductionLine { - private int id; - private String name; - private int projectNum; - private int corporationId; - private int userId; - - public int getId() { - return id; - } - - public void setId(int id) { - this.id = id; - } - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - public int getProjectNum() { - return projectNum; - } - - public void setProjectNum(int projectNum) { - this.projectNum = projectNum; - } - - public int getCorporationId() { - return corporationId; - } - - public void setCorporationId(int corporationId) { - this.corporationId = corporationId; - } - - public int getUserId() { - return userId; - } - - public void setUserId(int userId) { - this.userId = userId; - } -} diff --git a/src/com/taobao/rigel/rap/organization/mapping/Group.hbm.xml b/src/com/taobao/rigel/rap/organization/mapping/Group.hbm.xml deleted file mode 100644 index 5808d3e75..000000000 --- a/src/com/taobao/rigel/rap/organization/mapping/Group.hbm.xml +++ /dev/null @@ -1,21 +0,0 @@ - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/src/com/taobao/rigel/rap/organization/mapping/ProductionLine.hbm.xml b/src/com/taobao/rigel/rap/organization/mapping/ProductionLine.hbm.xml deleted file mode 100644 index 73185242f..000000000 --- a/src/com/taobao/rigel/rap/organization/mapping/ProductionLine.hbm.xml +++ /dev/null @@ -1,24 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/src/com/taobao/rigel/rap/organization/web/action/GroupAction.java b/src/com/taobao/rigel/rap/organization/web/action/GroupAction.java deleted file mode 100644 index e3db6ae08..000000000 --- a/src/com/taobao/rigel/rap/organization/web/action/GroupAction.java +++ /dev/null @@ -1,195 +0,0 @@ -package com.taobao.rigel.rap.organization.web.action; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import com.google.gson.Gson; -import com.taobao.rigel.rap.account.bo.User; -import com.taobao.rigel.rap.common.ActionBase; -import com.taobao.rigel.rap.common.RapError; -import com.taobao.rigel.rap.organization.bo.Group; -import com.taobao.rigel.rap.organization.service.OrganizationMgr; -import com.taobao.rigel.rap.project.bo.Project; -import com.taobao.rigel.rap.project.service.ProjectMgr; - -public class GroupAction extends ActionBase { - - private static final long serialVersionUID = 8516914838278239248L; - private OrganizationMgr organizationMgr; - private ProjectMgr projectMgr; - private int id; - - public int getId() { - return id; - } - - public void setId(int id) { - this.id = id; - } - - private String name; - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - public ProjectMgr getProjectMgr() { - return projectMgr; - } - - public void setProjectMgr(ProjectMgr projectMgr) { - this.projectMgr = projectMgr; - } - - private int productLineId; - - public int getProductLineId() { - return productLineId; - } - - public void setProductLineId(int productLineId) { - this.productLineId = productLineId; - } - - public OrganizationMgr getOrganizationMgr() { - return organizationMgr; - } - - public void setOrganizationMgr(OrganizationMgr organizationMgr) { - this.organizationMgr = organizationMgr; - } - - public String all() { - if (!isUserLogined()) { - plsLogin(); - return JSON_ERROR; - } - if (!organizationMgr.canUserAccessProductionLine(getCurUserId(), productLineId)) { - setErrMsg(ACCESS_DENY); - return JSON_ERROR; - } - User curUser = getAccountMgr().getUser(getCurUserId()); - Gson gson = new Gson(); - Map result = new HashMap(); - List> groups = new ArrayList>(); - List groupModels = organizationMgr.getGroupList(productLineId); - for (Group groupModel : groupModels) { - Map group = new HashMap(); - group.put("id", groupModel.getId()); - group.put("name", groupModel.getName()); - List projectModelList = projectMgr - .getProjectListByGroup(groupModel.getId()); - List> projects = new ArrayList>(); - for (Project projectModel : projectModelList) { - if (curUser.isUserInRole("admin") - || getAccountMgr().canUserManageProject( - curUser.getId(), projectModel.getId())) { - projectModel.setIsManagable(true); - } - Map project = new HashMap(); - project.put("id", projectModel.getId()); - project.put("name", projectModel.getName()); - project.put("desc", projectModel.getIntroduction()); - project.put("status", projectModel.getLastUpdateStr()); - project.put("accounts", projectModel.getMemberAccountListStr()); - project.put("isManagable", projectModel.getIsManagable()); - project.put("creator", projectModel.getUser().getUserBaseInfo()); - project.put("teamId", projectModel.getTeamId()); - projects.add(project); - } - group.put("projects", projects); - groups.add(group); - } - - result.put("groups", groups); - - setJson(gson.toJson(result)); - return SUCCESS; - } - - public String groups() { - if (!isUserLogined()) { - plsLogin(); - return JSON_ERROR; - } - if (!organizationMgr.canUserAccessProductionLine(getCurUserId(), productLineId)) { - setErrMsg(ACCESS_DENY); - return JSON_ERROR; - } - Gson gson = new Gson(); - Map result = new HashMap(); - List> groups = new ArrayList>(); - List groupModels = organizationMgr.getGroupList(productLineId); - for (Group groupModel : groupModels) { - Map group = new HashMap(); - group.put("id", groupModel.getId()); - group.put("name", groupModel.getName()); - groups.add(group); - } - - result.put("groups", groups); - - setJson(gson.toJson(result)); - return SUCCESS; - } - - public String create() { - if (!isUserLogined()) { - plsLogin(); - return JSON_ERROR; - } - if (!organizationMgr.canUserManageProductionLine(getCurUserId(), productLineId)) { - setErrMsg(ACCESS_DENY); - return JSON_ERROR; - } - Gson gson = new Gson(); - Group group = new Group(); - group.setName(name); - group.setUserId((int) getCurUserId()); - group.setProductionLineId(productLineId); - int id = organizationMgr.addGroup(group); - Map g = new HashMap(); - g.put("id", id); - g.put("name", name); - setJson("{\"groups\":[" + gson.toJson(g) + "]}"); - return SUCCESS; - } - - public String delete() { - if (!isUserLogined()) { - plsLogin(); - return JSON_ERROR; - } - if (!organizationMgr.canUserManageGroup(getCurUserId(), id)) { - setErrMsg(ACCESS_DENY); - return JSON_ERROR; - } - RapError error = organizationMgr.removeGroup(id); - setJson(error.toString()); - return SUCCESS; - } - - public String update() { - if (!isUserLogined()) { - plsLogin(); - return JSON_ERROR; - } - if (!organizationMgr.canUserManageGroup(getCurUserId(), id)) { - setErrMsg(ACCESS_DENY); - return JSON_ERROR; - } - Group group = new Group(); - group.setId(id); - group.setName(name); - organizationMgr.updateGroup(group); - setJson("{\"isOk\":\"true\"}"); - return SUCCESS; - } - -} diff --git a/src/com/taobao/rigel/rap/organization/web/action/OrganizationAction.java b/src/com/taobao/rigel/rap/organization/web/action/OrganizationAction.java deleted file mode 100644 index 145ba3ab4..000000000 --- a/src/com/taobao/rigel/rap/organization/web/action/OrganizationAction.java +++ /dev/null @@ -1,178 +0,0 @@ -package com.taobao.rigel.rap.organization.web.action; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import com.google.gson.Gson; -import com.taobao.rigel.rap.account.bo.User; -import com.taobao.rigel.rap.common.ActionBase; -import com.taobao.rigel.rap.common.ContextManager; -import com.taobao.rigel.rap.organization.bo.Corporation; -import com.taobao.rigel.rap.organization.bo.ProductionLine; -import com.taobao.rigel.rap.organization.service.OrganizationMgr; -import com.taobao.rigel.rap.project.bo.Project; -import com.taobao.rigel.rap.project.service.ProjectMgr; - -public class OrganizationAction extends ActionBase { - private static final long serialVersionUID = -7254075166703993812L; - private OrganizationMgr organizationMgr; - private ProjectMgr projectMgr; - private int plid; - private int id; - - public Corporation getCorporation() { - return corporation; - } - - public void setCorporation(Corporation corporation) { - this.corporation = corporation; - } - - private Corporation corporation; - - private ProductionLine productline; - - private Corporation team; - - public int getId() { - return id; - } - - public void setId(int id) { - this.id = id; - } - - public int getPlid() { - return plid; - } - - public void setPlid(int plid) { - this.plid = plid; - } - - public ProductionLine getProductLine() { - return productline; - } - - public Corporation getTeam() { - return team; - } - - public ProjectMgr getProjectMgr() { - return projectMgr; - } - - public void setProjectMgr(ProjectMgr projectMgr) { - this.projectMgr = projectMgr; - } - - public OrganizationMgr getOrganizationMgr() { - return organizationMgr; - } - - public void setOrganizationMgr(OrganizationMgr organizationMgr) { - this.organizationMgr = organizationMgr; - } - - public String myHome() { - return SUCCESS; - } - - public String index() { - if (isUserLogined()) { - return SUCCESS; - } else { - return "public"; - } - - } - - public String group() { - if (!isUserLogined()) { - plsLogin(); - setRelativeReturnUrl("/org/group.do?plid=" + plid); - return LOGIN; - } - - if (!organizationMgr.canUserAccessProductionLine(getCurUserId(), plid)) { - setErrMsg(ACCESS_DENY); - return ERROR; - } - - productline = organizationMgr.getProductionLine(plid); - int corpId = productline.getCorporationId(); - team = organizationMgr.getCorporation(corpId); - return SUCCESS; - } - - public String productline() { - if (!isUserLogined()) { - plsLogin(); - setRelativeReturnUrl("/org/productline.do?id=" + id); - return LOGIN; - } - - if (!organizationMgr.canUserAccessCorp(getCurUserId(), id)) { - setErrMsg(ACCESS_DENY); - return ERROR; - } - - setCorporation(organizationMgr.getCorporation(id)); - return SUCCESS; - } - - public String projects() { - if (!isUserLogined()) { - plsLogin(); - return JSON_ERROR; - } - User curUser = getAccountMgr().getUser(getCurUserId()); - Gson gson = new Gson(); - List> projects = new ArrayList>(); - // long totalRecNum = projectMgr.getProjectListNum(getCurUser()); - List projectList = projectMgr.getProjectList(getCurUserId(), 1, - Integer.MAX_VALUE); - for (Project p : projectList) { - if (curUser.isUserInRole("admin") - || getAccountMgr().canUserManageProject( - curUser.getId(), p.getId())) { - p.setIsManagable(true); - } - Map map = new HashMap(); - map.put("id", p.getId()); - map.put("name", p.getName()); - map.put("desc", p.getIntroduction()); - map.put("status", p.getLastUpdateStr()); - map.put("accounts", p.getMemberAccountListStr()); - map.put("isManagable", p.getIsManagable()); - map.put("creator", p.getUser().getUserBaseInfo()); - map.put("related", p.getUser().getId() != getCurUserId()); - map.put("teamId", p.getTeamId()); - projects.add(map); - } - StringBuilder json = new StringBuilder(); - json.append("{"); - json.append(" \"groups\" : [{"); - json.append(" \"type\" : \"user\","); - json.append(" \"projects\" :"); - json.append(gson.toJson(projects)); - json.append(" }]"); - json.append("}"); - setJson(json.toString()); - return SUCCESS; - } - - public String corporationList() { - if (!isUserLogined()) { - plsLogin(); - return JSON_ERROR; - } - - Gson gson = new Gson(); - setJson(gson.toJson(organizationMgr.getCorporationListWithPager(getCurUserId(), 1, 1000))); - return SUCCESS; - } - -} diff --git a/src/com/taobao/rigel/rap/organization/web/action/ProductlineAction.java b/src/com/taobao/rigel/rap/organization/web/action/ProductlineAction.java deleted file mode 100644 index e14f2cf41..000000000 --- a/src/com/taobao/rigel/rap/organization/web/action/ProductlineAction.java +++ /dev/null @@ -1,135 +0,0 @@ -package com.taobao.rigel.rap.organization.web.action; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import com.google.gson.Gson; -import com.taobao.rigel.rap.common.ActionBase; -import com.taobao.rigel.rap.organization.bo.ProductionLine; -import com.taobao.rigel.rap.organization.service.OrganizationMgr; -import com.taobao.rigel.rap.project.bo.Project; - -public class ProductlineAction extends ActionBase { - - private static final long serialVersionUID = -5059179317694489758L; - private OrganizationMgr organizationMgr; - private int corpId; - private int id; - private String name; - - public int getId() { - return id; - } - - public void setId(int id) { - this.id = id; - } - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - public int getCorpId() { - return corpId; - } - - - - public void setCorpId(int corpId) { - this.corpId = corpId; - } - - public OrganizationMgr getOrganizationMgr() { - return organizationMgr; - } - - public void setOrganizationMgr(OrganizationMgr organizationMgr) { - this.organizationMgr = organizationMgr; - } - - public String all() { - if (!isUserLogined()) { - plsLogin(); - return ERROR; - } - if (!organizationMgr.canUserAccessCorp(getCurUserId(), corpId)) { - setErrMsg(ACCESS_DENY); - return ERROR; - } - Map result = new HashMap(); - List> items = new ArrayList>(); - List lineModels = organizationMgr - .getProductionLineList(corpId); - for (ProductionLine lineModel : lineModels) { - Map line = new HashMap(); - line.put("id", lineModel.getId()); - line.put("name", lineModel.getName()); - line.put("count", lineModel.getProjectNum()); - items.add(line); - } - result.put("items", items); - - Gson gson = new Gson(); - setJson(gson.toJson(result)); - return SUCCESS; - } - - public String create() { - if (!isUserLogined()) { - plsLogin(); - return JSON_ERROR; - } - if (!organizationMgr.canUserManageCorp(getCurUserId(), corpId)) { - setErrMsg(ACCESS_DENY); - return JSON_ERROR; - } - ProductionLine line = new ProductionLine(); - Gson gson = new Gson(); - line.setName(name); - line.setUserId((int) getCurUserId()); - line.setCorporationId(corpId); - int id = organizationMgr.addProductionLine(line); - Map p = new HashMap(); - p.put("id", id); - p.put("name", name); - setJson("{\"items\":[" + gson.toJson(p) + "]}"); - return SUCCESS; - } - - public String delete() { - if (!isUserLogined()) { - plsLogin(); - return JSON_ERROR; - } - if (!organizationMgr.canUserManageProductionLine(getCurUserId(), id)) { - setErrMsg(ACCESS_DENY); - return JSON_ERROR; - } - setJson(organizationMgr.removeProductionLine(id).toString()); - return SUCCESS; - } - - public String update() { - if (!isUserLogined()) { - plsLogin(); - return JSON_ERROR; - } - if (!organizationMgr.canUserManageProductionLine(getCurUserId(), id)) { - setErrMsg(ACCESS_DENY); - return JSON_ERROR; - } - - ProductionLine line = new ProductionLine(); - line.setId(id); - line.setName(name); - organizationMgr.updateProductionLine(line); - setJson("{\"isOk\":\"true\"}"); - return SUCCESS; - } -} diff --git a/src/com/taobao/rigel/rap/platform/applicationContext.xml b/src/com/taobao/rigel/rap/platform/applicationContext.xml deleted file mode 100644 index 03e17f909..000000000 --- a/src/com/taobao/rigel/rap/platform/applicationContext.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/src/com/taobao/rigel/rap/project/applicationContext.xml b/src/com/taobao/rigel/rap/project/applicationContext.xml deleted file mode 100644 index 31803c1d7..000000000 --- a/src/com/taobao/rigel/rap/project/applicationContext.xml +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - - - - - - - - - \ No newline at end of file diff --git a/src/com/taobao/rigel/rap/project/bo/Action.java b/src/com/taobao/rigel/rap/project/bo/Action.java deleted file mode 100644 index eb33b02ab..000000000 --- a/src/com/taobao/rigel/rap/project/bo/Action.java +++ /dev/null @@ -1,306 +0,0 @@ - -package com.taobao.rigel.rap.project.bo; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashSet; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.Set; - -import com.taobao.rigel.rap.common.StringUtils; - -public class Action implements java.io.Serializable { - - private static final long serialVersionUID = 1L; - - public enum TYPE {REQUEST, RESPONSE}; - - private long id; - - public long getId() { - return id; - } - - public void setId(long id) { - this.id = id; - } - - private int disableCache; - - public int getDisableCache() { - return disableCache; - } - - public void setDisableCache(int disableCache) { - this.disableCache = disableCache; - } - - private String name; - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - private String description; - - public String getDescription() { - return description; - } - - public void setDescription(String description) { - this.description = description == null ? "" : description; - } - - private String requestType = "1"; - - public String getRequestType() { - return requestType; - } - - public void setRequestType(String requestType) { - if (requestType == null || requestType == "") - return; - this.requestType = requestType; - } - - public String getMethod() { - if (this.requestType.equals("2")) { - return "POST"; - } else if (this.requestType.equals("3")) { - return "PUT"; - } else if (this.requestType.equals("4")) { - return "DELETE"; - } else { - return "GET"; // in default - } - } - - private String requestUrl; - - public String getRequestUrl() { - return requestUrl; - } - - public void setRequestUrl(String requestUrl) { - this.requestUrl = requestUrl == null ? "" : requestUrl; - } - - public void addParameter(Parameter parameter, boolean isRequest) { - if (isRequest) { - getRequestParameterList().add(parameter); - parameter.getActionRequestList().add(this); - } else { - getResponseParameterList().add(parameter); - parameter.getActionResponseList().add(this); - } - } - - private Set requestParameterList = new HashSet(); - - public Set getRequestParameterList() { - return requestParameterList; - } - - public void setRequestParameterList(Set requestParameterList) { - this.requestParameterList = requestParameterList; - } - - private Set responseParameterList = new HashSet(); - - public Set getResponseParameterList() { - return responseParameterList; - } - - public void setResponseParameterList(Set responseParameterList) { - this.responseParameterList = responseParameterList; - } - - public List getRequestParameterListOrdered() { - Set parameterList = getRequestParameterList(); - List parameterListOrdered = new ArrayList(); - parameterListOrdered.addAll(parameterList); - Collections.sort(parameterListOrdered, new ParameterComparator()); - return parameterListOrdered; - } - - public List getResponseParameterListOrdered() { - Set parameterList = getResponseParameterList(); - List parameterListOrdered = new ArrayList(); - parameterListOrdered.addAll(parameterList); - Collections.sort(parameterListOrdered, new ParameterComparator()); - return parameterListOrdered; - } - - private String responseTemplate; - - public String getResponseTemplate() { - return responseTemplate; - } - - public void setResponseTemplate(String responseTemplate) { - this.responseTemplate = responseTemplate == null ? "" - : responseTemplate; - } - - private Set pageList = new HashSet(); - - public Set getPageList() { - return pageList; - } - - public void setPageList(Set pageList) { - this.pageList = pageList; - } - - public void update(Action action) { - setDescription(action.getDescription()); - setName(action.getName()); - setRequestType(action.getRequestType()); - setRequestUrl(action.getRequestUrl()); - setResponseTemplate(action.getResponseTemplate()); - } - - public String toString() { - StringBuilder stringBuilder = new StringBuilder(); - - stringBuilder.append("{\"id\":" + getId() + ","); - stringBuilder.append("\"name\":\"" + StringUtils.escapeInJ(getName()) - + "\","); - stringBuilder.append("\"description\":\"" - + StringUtils.escapeInJ(getDescription()) + "\","); - stringBuilder.append("\"requestType\":\"" + getRequestType() + "\","); - stringBuilder.append("\"requestUrl\":\"" - + StringUtils.escapeInJ(getRequestUrl()) + "\","); - stringBuilder.append("\"responseTemplate\":\"" - + StringUtils.escapeInJ(getResponseTemplate()) + "\","); - stringBuilder.append("\"requestParameterList\":"); - - stringBuilder.append("["); - Iterator iterator = getRequestParameterListOrdered() - .iterator(); - while (iterator.hasNext()) { - stringBuilder.append(iterator.next()); - if (iterator.hasNext()) { - stringBuilder.append(","); - } - } - stringBuilder.append("],"); - - stringBuilder.append("\"responseParameterList\":"); - - stringBuilder.append("["); - iterator = getResponseParameterListOrdered().iterator(); - while (iterator.hasNext()) { - stringBuilder.append(iterator.next()); - if (iterator.hasNext()) { - stringBuilder.append(","); - } - } - stringBuilder.append("]}"); - return stringBuilder.toString(); - } - - private String remarks; - - public String getRemarks() { - return remarks; - } - - public void setRemarks(String remarks) { - this.remarks = remarks; - } - - /** - * get request parameter list HTML for file exporting reason: velocity - * doesn't support macro recursion. - * - * @return - */ - public String getRequestParameterListHTML() { - return getParameterListHTML(requestParameterList); - } - - public String getResponseParameterListHTML() { - return getParameterListHTML(responseParameterList); - } - - private String getParameterListHTML(Set list) { - StringBuilder html = new StringBuilder(); - html - .append("") - .append("") - .append("") - .append("") - .append("") - .append("") - .append(""); - getParameterListHTMLSub(html, list, (short)1); - html.append("
    NameIdentifierTypeRemark
    "); - return html.toString(); - } - - private void getParameterListHTMLSub(StringBuilder html, Set list, short level) { - for(Parameter p : list) { - html - .append("") - .append("" + levelMark(level) + StringUtils.escapeInH(p.getName()) + "") - .append("" + StringUtils.escapeInH(p.getIdentifier()) + "") - .append("" + StringUtils.escapeInH(p.getDataType()) + "") - .append("" + StringUtils.escapeInH(p.getRemark()) + "") - .append(""); - if (p.getParameterList() != null || p.getParameterList().size() > 0) { - getParameterListHTMLSub(html, p.getParameterList(), (short)(level + 1)); - } - } - - } - - /** - * level 1: level 2:--- level 3:------ ... - * - * @param level started from 1 - * @return - */ - private String levelMark(short level) { - StringBuilder sb = new StringBuilder(); - for (short i = 1; i < level; i++) { - sb.append("---"); - } - return sb.toString(); - } - - public String getRequestUrlRel() { - String url = this.requestUrl; - if (url == null || url.isEmpty()) { - return "xxxxxxxxxxxxxxxxEMPTY URLxxxxxxxxxxxxxxxxx"; - } - if (url.contains("https://")) { - url = url.substring(url.indexOf("/", 7)); - } else if (url.contains("http://")) { - url = url.substring(url.indexOf("/", 8)); - } - return url; - } - - public static List loadList(List> result) { - List list = new ArrayList(); - for (Map row : result) { - Action obj = new Action(); - obj.setDescription((String)row.get("description")); - obj.setId((Integer)row.get("id")); - obj.setName((String)row.get("name")); - obj.setRemarks((String)row.get("remarks")); - obj.setRequestType((String)row.get("request_type")); - obj.setRequestUrl((String)row.get("request_url")); - list.add(obj); - } - return list; - } - -} diff --git a/src/com/taobao/rigel/rap/project/bo/ActionComparator.java b/src/com/taobao/rigel/rap/project/bo/ActionComparator.java deleted file mode 100644 index 67c1b342d..000000000 --- a/src/com/taobao/rigel/rap/project/bo/ActionComparator.java +++ /dev/null @@ -1,14 +0,0 @@ -package com.taobao.rigel.rap.project.bo; - -import java.util.Comparator; - -public class ActionComparator implements Comparator{ - - @Override - public int compare(Action o1, Action o2) { - Action l = (Action) o1; - Action r = (Action) o2; - return l.getId() < r.getId() ? 0 : 1; - } - -} diff --git a/src/com/taobao/rigel/rap/project/bo/CheckInComparator.java b/src/com/taobao/rigel/rap/project/bo/CheckInComparator.java deleted file mode 100644 index 0964f530c..000000000 --- a/src/com/taobao/rigel/rap/project/bo/CheckInComparator.java +++ /dev/null @@ -1,14 +0,0 @@ -package com.taobao.rigel.rap.project.bo; - -import java.util.Comparator; - -import com.taobao.rigel.rap.workspace.bo.CheckIn; - -public class CheckInComparator implements Comparator{ - - @Override - public int compare(CheckIn o1, CheckIn o2) { - return o1.getId() > o2.getId() ? -1 : 1; - } - -} diff --git a/src/com/taobao/rigel/rap/project/bo/Module.java b/src/com/taobao/rigel/rap/project/bo/Module.java deleted file mode 100644 index ba3f47190..000000000 --- a/src/com/taobao/rigel/rap/project/bo/Module.java +++ /dev/null @@ -1,136 +0,0 @@ -package com.taobao.rigel.rap.project.bo; -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashSet; -import java.util.Iterator; -import java.util.List; -import java.util.Set; - -import com.taobao.rigel.rap.common.StringUtils; - -public class Module implements java.io.Serializable { - - /** - * - */ - private static final long serialVersionUID = 1L; - - private int id; - private int projectId; - private String name; - private String introduction; - - public int getId() { - return this.id; - } - - public void setId(int id) { - this.id = id; - } - - public int getProjectId() { - return this.projectId; - } - - public void setProjectId(int projectId) { - this.projectId = projectId; - } - - public String getName() { - return this.name; - } - - public void setName(String name) { - this.name = name; - } - - public String getIntroduction() { - return this.introduction; - } - - public void setIntroduction(String introduction) { - this.introduction = (introduction == null ? "" : introduction); - } - - private Project project; - - public Project getProject() { - return this.project; - } - - public void setProject(Project project) { - this.project = project; - } - - public void addPage(Page page) { - getPageList().add(page); - page.setModule(this); - } - - private Set pageList = new HashSet(); - - public Set getPageList() { - return this.pageList; - } - - public List getPageListOrdered() { - Set pageList = getPageList(); - List pageListOrdered = new ArrayList(); - pageListOrdered.addAll(pageList); - Collections.sort(pageListOrdered, new PageComparator()); - return pageListOrdered; - } - - public void setPageList(Set pageList) { - this.pageList = pageList; - } - - public void update(Module module) { - setIntroduction(module.getIntroduction()); - setName(module.getName()); - } - - public String toString() { - - StringBuilder stringBuilder = new StringBuilder(); - - stringBuilder.append("{\"id\":" + getId() + ","); - stringBuilder.append("\"introduction\":\"" + StringUtils.escapeInJ(getIntroduction()) + "\","); - stringBuilder.append("\"name\":\"" + StringUtils.escapeInJ(getName()) + "\","); - stringBuilder.append("\"pageList\":"); - - stringBuilder.append("["); - Iterator iterator = getPageListOrdered().iterator(); - while(iterator.hasNext()) { - stringBuilder.append(iterator.next()); - if (iterator.hasNext()) { - stringBuilder.append(","); - } - } - stringBuilder.append("]}"); - - return stringBuilder.toString(); - } - - public String toString(Project.TO_STRING_TYPE type) { - - StringBuilder stringBuilder = new StringBuilder(); - - stringBuilder.append("{\"id\":" + getId() + ","); - stringBuilder.append("\"introduction\":\"" + StringUtils.escapeInJ(getIntroduction()) + "\","); - stringBuilder.append("\"name\":\"" + StringUtils.escapeInJ(getName()) + "\","); - stringBuilder.append("\"pageList\":"); - - stringBuilder.append("["); - Iterator iterator = getPageListOrdered().iterator(); - while(iterator.hasNext()) { - stringBuilder.append(iterator.next().toString(type)); - if (iterator.hasNext()) { - stringBuilder.append(","); - } - } - stringBuilder.append("]}"); - - return stringBuilder.toString(); - } -} diff --git a/src/com/taobao/rigel/rap/project/bo/ModuleComparator.java b/src/com/taobao/rigel/rap/project/bo/ModuleComparator.java deleted file mode 100644 index abba982f7..000000000 --- a/src/com/taobao/rigel/rap/project/bo/ModuleComparator.java +++ /dev/null @@ -1,14 +0,0 @@ -package com.taobao.rigel.rap.project.bo; - -import java.util.Comparator; - -public class ModuleComparator implements Comparator{ - - @Override - public int compare(Module o1, Module o2) { - Module l = (Module) o1; - Module r = (Module) o2; - return l.getId() < r.getId() ? 0 : 1; - } - -} diff --git a/src/com/taobao/rigel/rap/project/bo/ObjectItem.java b/src/com/taobao/rigel/rap/project/bo/ObjectItem.java deleted file mode 100644 index c192cc860..000000000 --- a/src/com/taobao/rigel/rap/project/bo/ObjectItem.java +++ /dev/null @@ -1,26 +0,0 @@ -package com.taobao.rigel.rap.project.bo; - -public class ObjectItem implements java.io.Serializable { - - private static final long serialVersionUID = 1L; - - public String className; - - public String getClassName() { - return className; - } - - public void setClassName(String className) { - this.className = className; - } - - private int id; - - public int getId() { - return id; - } - - public void setId(int id) { - this.id = id; - } -} diff --git a/src/com/taobao/rigel/rap/project/bo/Page.java b/src/com/taobao/rigel/rap/project/bo/Page.java deleted file mode 100644 index 4aa49175e..000000000 --- a/src/com/taobao/rigel/rap/project/bo/Page.java +++ /dev/null @@ -1,139 +0,0 @@ -package com.taobao.rigel.rap.project.bo; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashSet; -import java.util.Iterator; -import java.util.List; -import java.util.Set; - -import com.taobao.rigel.rap.common.StringUtils; - -public class Page implements java.io.Serializable { - - private static final long serialVersionUID = 1L; - - private int id; - - public int getId() { - return id; - } - - public void setId(int id) { - this.id = id; - } - - private String name; - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - private String introduction; - - public String getIntroduction() { - return introduction; - } - - public void setIntroduction(String introduction) { - this.introduction = (introduction == null ? "" : introduction); - } - - private Module module; - - public Module getModule() { - return module; - } - - public void setModule(Module module) { - this.module = module; - } - - private Set actionList = new HashSet(); - - public Set getActionList() { - return actionList; - } - - public List getActionListOrdered() { - Set actionList = getActionList(); - List actionListOrdered = new ArrayList(); - actionListOrdered.addAll(actionList); - Collections.sort(actionListOrdered, new ActionComparator()); - return actionListOrdered; - } - - - public void setActionList(Set actionList) { - this.actionList = actionList; - } - - private String template; - - public String getTemplate() { - return template; - } - - public void setTemplate(String template) { - this.template = template; - } - - public void addAction(Action action) { - getActionList().add(action); - //action.getPageList().add(this); - } - - public void update(Page page) { - setIntroduction(page.getIntroduction()); - setName(page.getName()); - setTemplate(page.getTemplate()); - } - - public String toString() { - StringBuilder stringBuilder = new StringBuilder(); - - stringBuilder.append("{\"id\":" + getId() + ","); - stringBuilder.append("\"introduction\":\"" + StringUtils.escapeInJ(getIntroduction()) + "\","); - stringBuilder.append("\"name\":\"" + StringUtils.escapeInJ(getName()) + "\","); - stringBuilder.append("\"actionList\":"); - - stringBuilder.append("["); - Iterator iterator = getActionListOrdered().iterator(); - while(iterator.hasNext()) { - stringBuilder.append(iterator.next()); - if (iterator.hasNext()) { - stringBuilder.append(","); - } - } - stringBuilder.append("]}"); - - return stringBuilder.toString(); - } - - public String toString(Project.TO_STRING_TYPE type) { - StringBuilder stringBuilder = new StringBuilder(); - - stringBuilder.append("{\"id\":" + getId() + ","); - stringBuilder.append("\"introduction\":\"" + StringUtils.escapeInJ(getIntroduction()) + "\","); - stringBuilder.append("\"name\":\"" + StringUtils.escapeInJ(getName()) + "\""); - if (type == Project.TO_STRING_TYPE.TO_PAGE) { - stringBuilder.append("}"); - } else { - stringBuilder.append(",\"actionList\":"); - stringBuilder.append("["); - Iterator iterator = getActionListOrdered().iterator(); - while(iterator.hasNext()) { - stringBuilder.append(iterator.next()); - if (iterator.hasNext()) { - stringBuilder.append(","); - } - } - stringBuilder.append("]}"); - } - return stringBuilder.toString(); - } -} diff --git a/src/com/taobao/rigel/rap/project/bo/PageComparator.java b/src/com/taobao/rigel/rap/project/bo/PageComparator.java deleted file mode 100644 index 7de627f9d..000000000 --- a/src/com/taobao/rigel/rap/project/bo/PageComparator.java +++ /dev/null @@ -1,14 +0,0 @@ -package com.taobao.rigel.rap.project.bo; - -import java.util.Comparator; - -public class PageComparator implements Comparator{ - - @Override - public int compare(Page o1, Page o2) { - Page l = (Page) o1; - Page r = (Page) o2; - return l.getId() < r.getId() ? 0 : 1; - } - -} diff --git a/src/com/taobao/rigel/rap/project/bo/Parameter.java b/src/com/taobao/rigel/rap/project/bo/Parameter.java deleted file mode 100644 index 848df370e..000000000 --- a/src/com/taobao/rigel/rap/project/bo/Parameter.java +++ /dev/null @@ -1,274 +0,0 @@ -package com.taobao.rigel.rap.project.bo; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashSet; -import java.util.Iterator; -import java.util.List; -import java.util.Set; - -import com.taobao.rigel.rap.common.StringUtils; - -public class Parameter implements java.io.Serializable { - - private static final long serialVersionUID = 1L; - - private int id; - - public int getId() { - return id; - } - - public void setId(int id) { - this.id = id; - } - - private String mockData; - - public String getMockData() { - return mockData; - } - - public void setMockData(String mockData) { - this.mockData = mockData; - } - - private String name; - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = (name == null ? "" : name); - } - - private String identifier; - - public String getIdentifier() { - if (identifierChange != null) { - return identifierChange; - } else { - return identifier; - } - } - - public String getIdentifierChange() { - - return identifierChange; - } - - public void setIdentifierChange(String identifierChange) { - this.identifierChange = identifierChange; - } - - private String identifierChange; - - public String getRemarkChange() { - return remarkChange; - } - - public void setRemarkChange(String remarkChange) { - this.remarkChange = remarkChange; - } - - private String remarkChange; - - public String getMockIdentifier() { - String rv = ""; - if (identifier == null || identifier.isEmpty()) { - return "\"emptyIdentifier\""; - } - - rv = identifier; - if (rv != null && !rv.isEmpty()) { - int index = rv.indexOf("|"); - if (index > -1) { - rv = rv.substring(0, index); - } - } - return "\"" + rv + "\""; - } - - public String getIdentifierWithoutMockjsRule() { - String rv; - if (identifier == null || identifier.isEmpty()) { - return "emptyIdentifier"; - } - - rv = identifier; - if (rv != null && !rv.isEmpty()) { - int index = rv.indexOf("|"); - if (index > -1) { - rv = rv.substring(0, index); - } - } - return rv; - } - - public String getMockJSIdentifier() { - String rv = ""; - if (identifier == null || identifier.isEmpty()) { - return "\"emptyIdentifier\""; - } - rv = identifier; - return "\"" + rv + "\""; - } - - public void setIdentifier(String identifier) { - this.identifier = (identifier == null ? "" : identifier); - } - - private String dataType; - - public String getDataType() { - if (this.dataType == null || this.dataType.trim().isEmpty()) { - return ""; - } - return dataType; - } - - public void setDataType(String dataType) { - this.dataType = (dataType == null ? "" : dataType); - } - - private String remark; - - public String getRemark() { - if (remarkChange != null) { - return remarkChange; - } - return (remark == null ? "" : remark); - } - - public void setRemark(String remark) { - this.remark = remark; - } - - private Set actionRequestList = new HashSet(); - - public Set getActionRequestList() { - return actionRequestList; - } - - public void setActionRequestList(Set actionRequestList) { - this.actionRequestList = actionRequestList; - } - - private Set actionResponseList = new HashSet(); - - public Set getActionResponseList() { - return actionResponseList; - } - - public void setActionResponseList(Set actionResponseList) { - this.actionResponseList = actionResponseList; - } - - private String validator = ""; - - public String getValidator() { - return validator; - } - - public void setValidator(String validator) { - this.validator = validator; - } - - private Set parameterList = new HashSet(); - - public Set getParameterList() { - return parameterList; - } - - public void setParameterList(Set parameterList) { - this.parameterList = parameterList; - } - - public void update(Parameter parameter) { - setDataType(parameter.getDataType()); - setIdentifier(parameter.getIdentifier()); - setName(parameter.getName()); - setRemark(parameter.getRemark()); - setValidator(parameter.getValidator()); - } - - public List getParameterListOrdered() { - Set parameterList = getParameterList(); - List parameterListOrdered = new ArrayList(); - parameterListOrdered.addAll(parameterList); - Collections.sort(parameterListOrdered, new ParameterComparator()); - return parameterListOrdered; - } - - private Set complexParamerterList = new HashSet(); - - public Set getComplexParameterList() { - return complexParamerterList; - } - - public void setComplexParameterList(Set complexParameterList) { - this.complexParamerterList = complexParameterList; - } - - public void addChild(Parameter parameter) { - getParameterList().add(parameter); - parameter.getComplexParameterList().add(this); - } - - public String toString() { - StringBuilder stringBuilder = new StringBuilder(); - stringBuilder.append("{\"id\":" + getId() + ","); - stringBuilder.append("\"identifier\":\"" - + StringUtils.escapeInJ(getIdentifier()) + "\","); - stringBuilder.append("\"name\":\"" + StringUtils.escapeInJ(getName()) - + "\","); - stringBuilder.append("\"remark\":\"" - + StringUtils.escapeInJ(getRemark()) + "\","); - stringBuilder.append("\"parameterList\":"); - stringBuilder.append("["); - Iterator iterator = getParameterListOrdered().iterator(); - while (iterator.hasNext()) { - stringBuilder.append(iterator.next()); - if (iterator.hasNext()) { - stringBuilder.append(","); - } - } - stringBuilder.append("],"); - stringBuilder.append("\"validator\":\"" - + StringUtils.escapeInJ(getValidator()) + "\","); - stringBuilder.append("\"dataType\":\"" - + StringUtils.escapeInJ(getDataType()) + "\"}"); - return stringBuilder.toString(); - } - - public String getRemarkWithoutMockjsRule() { - if (remark != null && remark.contains("@mock=")) { - return remark.substring(0, remark.indexOf("@mock=")); - } else { - return remark; - } - } - - public String getMockJsRules() { - if (remark == null || remark.isEmpty() || (!remark.contains("@mock="))) { - return null; - } - return remark.substring(remark.indexOf("@mock=") + 6); - - } - - - public String getJSONSchemaDataType() { - if (dataType != null && dataType.contains("array")) { - return "array"; - } - return this.dataType; - } - - public boolean hasMockJSData() { - return this.getMockJsRules() != null; - } - - -} diff --git a/src/com/taobao/rigel/rap/project/bo/ParameterComparator.java b/src/com/taobao/rigel/rap/project/bo/ParameterComparator.java deleted file mode 100644 index 62a666472..000000000 --- a/src/com/taobao/rigel/rap/project/bo/ParameterComparator.java +++ /dev/null @@ -1,14 +0,0 @@ -package com.taobao.rigel.rap.project.bo; - -import java.util.Comparator; - -public class ParameterComparator implements Comparator { - - @Override - public int compare(Parameter o1, Parameter o2) { - Parameter l = (Parameter) o1; - Parameter r = (Parameter) o2; - return l.getId() < r.getId() ? 0 : 1; - } - -} diff --git a/src/com/taobao/rigel/rap/project/bo/Project.java b/src/com/taobao/rigel/rap/project/bo/Project.java deleted file mode 100644 index 39e357c51..000000000 --- a/src/com/taobao/rigel/rap/project/bo/Project.java +++ /dev/null @@ -1,554 +0,0 @@ -package com.taobao.rigel.rap.project.bo; - -import java.text.ParseException; -import java.util.ArrayList; -import java.util.Collections; -import java.util.Date; -import java.util.HashSet; -import java.util.Iterator; -import java.util.List; -import java.util.Locale; -import java.util.Set; - -import org.hibernate.Session; -import org.ocpsoft.prettytime.PrettyTime; - -import com.taobao.rigel.rap.account.bo.User; -import com.taobao.rigel.rap.common.DateUtils; -import com.taobao.rigel.rap.common.StringUtils; -import com.taobao.rigel.rap.workspace.bo.CheckIn; -import com.taobao.rigel.rap.workspace.bo.Workspace; -import com.taobao.rigel.rap.workspace.bo.Workspace.ModeType; - -public class Project implements java.io.Serializable { - - private static final long serialVersionUID = 1L; - private int id; - private long userId; - private String name; - private Date createDate; - private Date updateTime; - private String introduction; - private User user; - private int workspaceModeInt; - private String relatedIds = ""; - private int groupId; - private int mockNum; - - public static final int PRIVATE_ACCESS = 0; - - public static final int DEFAULT_ACCESS = 10; - - public int getTeamId() { - return teamId; - } - - public void setTeamId(int teamId) { - this.teamId = teamId; - } - - private int teamId; - - public short getAccessType() { - return accessType; - } - - public void setAccessType(short accessType) { - this.accessType = accessType; - } - - private short accessType; - - public void setMockNum(int mockNum) { - this.mockNum = mockNum; - } - - public int getMockNum() { - return mockNum; - } - - public int getGroupId() { - return groupId; - } - - public void setGroupId(int groupId) { - this.groupId = groupId; - } - - public String getRelatedIds() { - return relatedIds; - } - - public void setRelatedIds(String relatedIds) { - this.relatedIds = relatedIds; - } - - public enum TO_STRING_TYPE {TO_MODULE, TO_PAGE, TO_ACTION, TO_PARAMETER}; - - public enum STAGE_TYPE {DESIGNING, DEVELOPING, DEBUGING}; - - public int getWorkspaceModeInt() { - return workspaceModeInt; - } - - public void setWorkspaceModeInt(int workspaceModeInt) { - this.workspaceModeInt = workspaceModeInt; - } - - public Date getUpdateTime() { - return updateTime; - } - - public void setUpdateTime(Date updateTime) { - this.updateTime = updateTime; - } - - public ModeType getWorkspaceMode() { - if (workspaceModeInt == 1) { - return ModeType.VSS; - } else if (workspaceModeInt == 2) { - return ModeType.SVN; - } else { - return ModeType.VSS; - } - } - - public User getUser() { - return user; - } - - public void setUser(User user) { - this.user = user; - } - - public long getUserId() { - return userId; - } - - public void setUserId(long userId) { - this.userId = userId; - } - - private Set userList = new HashSet(); - - public Set getUserList() { - return userList; - } - - public void setUserList(Set userList) { - this.userList = userList; - } - - private Set moduleList = new HashSet(); - - public Set getModuleList() { - return moduleList; - } - - public void setModuleList(Set moduleList) { - this.moduleList = moduleList; - } - - public Project() { - - } - - public int getId() { - return id; - } - - public void setId(int id) { - this.id = id; - } - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - public Date getCreateDate() { - return createDate; - } - - public void setCreateDate(Date createDate) { - this.createDate = createDate; - } - - - public String getIntroduction() { - return introduction; - } - - public void setIntroduction(String introduction) { - this.introduction = (introduction == null ? "" : introduction); - } - - private String projectData; - - public String getProjectData() { - return projectData; - } - - public void setProjectData(String projectData) { - this.projectData = projectData; - } - - public List getModuleListOrdered() { - Set moduleList = getModuleList(); - List moduleListOrdered = new ArrayList(); - moduleListOrdered.addAll(moduleList); - Collections.sort(moduleListOrdered, new ModuleComparator()); - return moduleListOrdered; - } - - public void addModule(Module module) { - getModuleList().add(module); - module.setProject(this); - } - - public String getMemberAccountListStr() { - StringBuilder stringBuilder = new StringBuilder(); - for (User user : getUserList()) { - stringBuilder.append(user.getAccount() + "(" + user.getName() + "), "); - } - return stringBuilder.toString(); - } - - private List memberAccountList; - - public List getMemberAccountList() { - return memberAccountList; - } - - public void setMemberAccountList(List memberAccountList) { - this.memberAccountList = memberAccountList; - } - - private Set workspaceList = new HashSet(); - - public Set getWorkspaceList() { - return workspaceList; - } - - public void setWorkspaceList(Set workspaceList) { - this.workspaceList = workspaceList; - } - - private String version; - - public String getVersion() { - return version; - } - - public void setVersion(String version) { - this.version = version; - } - - public String toString(TO_STRING_TYPE type) { - StringBuilder stringBuilder = new StringBuilder(); - stringBuilder.append("{\"createDateStr\":\"" + getCreateDateStr() + "\","); - stringBuilder.append("\"user\":" + getUser() + ","); - stringBuilder.append("\"id\":" + getId() + ","); - stringBuilder.append("\"version\":\"" + getVersion() + "\","); - stringBuilder.append("\"introduction\":\"" + StringUtils.escapeInJ(getIntroduction()) + "\","); - stringBuilder.append("\"name\":\"" + StringUtils.escapeInJ(getName()) + "\","); - stringBuilder.append("\"moduleList\":"); - - stringBuilder.append("["); - Iterator iterator = getModuleListOrdered().iterator(); - while(iterator.hasNext()) { - stringBuilder.append(iterator.next().toString(type)); - if (iterator.hasNext()) { - stringBuilder.append(","); - } - } - stringBuilder.append("]}"); - return stringBuilder.toString(); - } - - @Override - public String toString() { - return "{}"; - } - - public void update(Project project) { - setIntroduction(project.getIntroduction()); - setName(project.getName()); - } - - private boolean isManagable; - - public boolean getIsManagable() { - return isManagable; - } - - public void setIsManagable(boolean isManagable) { - this.isManagable = isManagable; - } - - public String getCreateDateStr() { - return getCreateDate() == null ? "" : DateUtils.DATE_FORMAT.format(getCreateDate()); - } - - public void setCreateDateStr(String createDateStr) throws ParseException { - setCreateDate((createDateStr == null || createDateStr.equals("")) ? - null : DateUtils.DATE_FORMAT.parse(createDateStr)); - } - - public String getUserListStr() { - StringBuilder stringBuilder = new StringBuilder(); - Iterator iterator = getUserList().iterator(); - while(iterator.hasNext()) { - User user = iterator.next(); - // remove the creator - if (user.getId() == getUser().getId()) continue; - stringBuilder.append(user.getName() + "(" + user.getWorkRole() + ")"); - if (iterator.hasNext()) { - stringBuilder.append(", "); - } - } - return stringBuilder.toString(); - } - - public String getUserListStrShort() { - StringBuilder stringBuilder = new StringBuilder(); - Iterator iterator = getUserList().iterator(); - int count = 1; - while(iterator.hasNext()) { - User user = iterator.next(); - // remove the creator - if (user.getId() == getUser().getId()) continue; - stringBuilder.append(user.getName() + "(" + user.getWorkRole() + ")"); - if (iterator.hasNext()) { - stringBuilder.append(", "); - } - if (++count > 5) { - stringBuilder.append(iterator.hasNext() ? "etc." : ""); - break; - } - } - return stringBuilder.toString(); - } - - private Set checkInList = new HashSet(); - - public Set getCheckInList() { - return checkInList; - } - - public void setCheckInList(Set checkInList) { - this.checkInList = checkInList; - } - - public List getCheckInListOrdered() { - Set checkInList = getCheckInList(); - List checkInListOrdered = new ArrayList(); - checkInListOrdered.addAll(checkInList); - Collections.sort(checkInListOrdered, new CheckInComparator()); - return checkInListOrdered; - } - - public Module findModule(int moduleId) { - for (Module i : getModuleList()) { - if (i.getId() == moduleId) - return i; - } - return null; - } - - public Page findPage(int pageId) { - for (Module module : getModuleList()) { - for (Page page : module.getPageList()) { - if (page.getId() == pageId) - return page; - } - } - return null; - } - - public Action findAction(long actionId) { - for (Module module : getModuleList()) { - for (Page page : module.getPageList()) { - for (Action action : page.getActionList()) { - if (action.getId() == actionId) - return action; - } - } - } - return null; - } - - public Parameter findParameter(int parameterId, boolean isRequestType) { - for (Module module : getModuleList()) { - for (Page page : module.getPageList()) { - for (Action action : page.getActionList()) { - for (Parameter parameter : (isRequestType ? - action.getRequestParameterList() : action.getResponseParameterList())) { - if (parameter.getId() == parameterId) { - return parameter; - } - } - } - } - } - return null; - } - - public Parameter findChildParameter(int parameterId) { - for (Module module : getModuleList()) { - for (Page page : module.getPageList()) { - for (Action action : page.getActionList()) { - for (Parameter parameter : action.getRequestParameterList()) { - Parameter pRecur = findParameterRecursively(parameter, parameterId); - if (pRecur != null) { - return pRecur; - } - } - - for (Parameter parameter : action.getResponseParameterList()) { - Parameter pRecur = findParameterRecursively(parameter, parameterId); - if (pRecur != null) { - return pRecur; - } - } - } - } - } - return null; - } - - /** - * find parameter recursively - * recursive: - * p.parameterList[0].parameterList[0]..... - * - * @param p - * @param id - * @return return the object found, other wise return null - */ - private Parameter findParameterRecursively(Parameter p, int id) { - Iterator iterator = p.getParameterList().iterator(); - while(iterator.hasNext()) { - Parameter parameter = iterator.next(); - if (parameter.getId() == id) { - return parameter; - } - parameter = findParameterRecursively(parameter, id); - if (parameter != null) { - return parameter; - } - } - return null; - } - - public void removeModule(int id, Session session) { - Module module = findModule(id); - if (module != null && moduleList != null) { - moduleList.remove(module); - session.delete(module); - } - } - - public void removePage(int id, Session session) { - Page page = findPage(id); - if (page != null && page.getModule() != null && page.getModule().getPageList() != null) { - page.getModule().getPageList().remove(page); - session.delete(page); - } - } - - public void removeAction(int id, Session session) { - Action action = findAction(id); - if (action == null) return; - Set pageList = action.getPageList(); - if (pageList == null) return; - Iterator iterator = pageList.iterator(); - while (iterator.hasNext()) { - iterator.next().getActionList().remove(action); - session.delete(action); - } - } - - public void removeParameter(int id, Session session) { - Parameter parameter = findParameter(id, true); - - // if parameter == null, it maybe response parameter - if (parameter == null) { - parameter = findParameter(id, false); - - // if parameter == null still, it must be child parameter of a complex parameter - if (parameter == null) { - parameter = findChildParameter(id); - if (parameter != null && parameter.getComplexParameterList() != null) { - for (Parameter pComplex : parameter.getComplexParameterList()) { - pComplex.getParameterList().remove(parameter); - session.delete(parameter); - } - } - return ; - } - Iterator iterator = parameter.getActionResponseList().iterator(); - while (iterator.hasNext()) { - iterator.next().getResponseParameterList().remove(parameter); - session.delete(parameter); - } - } else { - Iterator iterator = parameter.getActionRequestList().iterator(); - while (iterator.hasNext()) { - iterator.next().getRequestParameterList().remove(parameter); - session.delete(parameter); - } - } - } - - public boolean addMember(User user) { - // if member added is the creator, ignore - if (user.getId() == getUser().getId()) - return false; - // if member already exists, ignore - boolean exist = false; - for (User item : getUserList()) { - if (item.getId() == user.getId()) { - exist = true; - } - } - if (exist) return false; - // validation complete, add this user - getUserList().add(user); - user.getJoinedProjectList().add(this); - return true; - } - - public void removeMember(User user) { - getUserList().remove(user); - user.getJoinedProjectList().remove(this); - } - - public String getLastUpdateStr() { - PrettyTime p = new PrettyTime(new Locale("zh")); - return p.format(this.updateTime) + "更新"; - } - - public List getAllAction() { - List list = new ArrayList(); - for (Module m : this.moduleList) { - for (Page p : m.getPageList()) { - for (Action a : p.getActionList()) { - list.add(a); - } - } - } - return list; - } - - public boolean isUserMember(long userId) { - if (getUserId() == userId) return true; - for (User u : getUserList()) { - if (u.getId() == userId) return true; - } - return false; - } -} diff --git a/src/com/taobao/rigel/rap/project/bo/Validator.java b/src/com/taobao/rigel/rap/project/bo/Validator.java deleted file mode 100644 index ea188f680..000000000 --- a/src/com/taobao/rigel/rap/project/bo/Validator.java +++ /dev/null @@ -1,39 +0,0 @@ -package com.taobao.rigel.rap.project.bo; - -public class Validator implements java.io.Serializable { - - /** - * - */ - private static final long serialVersionUID = 1L; - - private int id; - - public int getId() { - return this.id; - } - - public void setId(int id) { - this.id = id; - } - - private int type; - - public int getType() { - return this.type; - } - - public void setType(int type) { - this.type = type; - } - - private String rule; - - public String getRule() { - return this.rule; - } - - public void setRule(String rule) { - this.rule = rule; - } -} diff --git a/src/com/taobao/rigel/rap/project/dao/ProjectDao.java b/src/com/taobao/rigel/rap/project/dao/ProjectDao.java deleted file mode 100644 index a79a63bb7..000000000 --- a/src/com/taobao/rigel/rap/project/dao/ProjectDao.java +++ /dev/null @@ -1,164 +0,0 @@ -package com.taobao.rigel.rap.project.dao; - -import java.util.List; -import java.util.Map; - -import com.taobao.rigel.rap.account.bo.User; -import com.taobao.rigel.rap.project.bo.Action; -import com.taobao.rigel.rap.project.bo.Module; -import com.taobao.rigel.rap.project.bo.Page; -import com.taobao.rigel.rap.project.bo.Project; - -public interface ProjectDao { - - /** - * get project list - * @param user - * @param curPageNum - * @param pageSize - * @return - */ - List getProjectList(User user, int curPageNum, int pageSize); - - /** - * get new project - * @param project - * @return always 0 - */ - int addProject(Project project); - - /** - * update project - * @param id - * @param projectData - * @param deletedObjectListData - * @return - */ - String updateProject(int id, String projectData, - String deletedObjectListData, Map actionIdMap); - - /** - * update project - * @param project - * @return - */ - int updateProject(Project project); - - /** - * remove project - * @param id - * @return - */ - int removeProject(int id); - - /** - * get project - * @param id - * @return - */ - Project getProject(int id); - - /** - * get module - * @param id - * @return - */ - Module getModule(int id); - - /** - * get page - * @param id - * @return - */ - Page getPage(int id); - - - /** - * get action - * @param id - * @return - */ - Action getAction(long id); - - /** - * save project - * @param project - * @return - */ - int saveProject(Project project); - - /** - * get project list number - * @param user - * @return - */ - long getProjectListNum(User user); - - /** - * get matched action list based on URL pattern - * - * @param projectId - * @param pattern - * @return - */ - List getMatchedActionList(int projectId, String pattern); - - /** - * clear all mock data of objects in specified project - * @param projectId project id - * @return affected rows num - */ - public int resetMockData(int projectId); - - /** - * get project list by group - * @param id - * @return - */ - List getProjectListByGroup(int id); - - /** - * search all projects (for admin use) - * - * @param key - * @return - */ - List search(String key); - - List getProjectList(); - - long getProjectListNum(); - - long getModuleNum(); - - long getPageNum(); - - long getActionNum(); - - long getParametertNum(); - - long getCheckInNum(); - - long getMockNumInTotal(); - - List selectMockNumTopNProjectList(int limit); - - /** - * get project id by action id - * - * @param actionId - * @return - */ - Integer getProjectIdByActionId(int actionId); - - void updateProjectNum(Project project); - - - /** - * transfer a project to another user - * - * @param projectId - * @param creatorId - */ - void updateCreatorId(int projectId, long creatorId); -} diff --git a/src/com/taobao/rigel/rap/project/dao/impl/ProjectDaoImpl.java b/src/com/taobao/rigel/rap/project/dao/impl/ProjectDaoImpl.java deleted file mode 100644 index 4c5d0ec65..000000000 --- a/src/com/taobao/rigel/rap/project/dao/impl/ProjectDaoImpl.java +++ /dev/null @@ -1,570 +0,0 @@ -package com.taobao.rigel.rap.project.dao.impl; - -import java.util.ArrayList; -import java.util.Date; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import com.taobao.rigel.rap.common.CacheUtils; -import com.taobao.rigel.rap.common.URLUtils; -import org.hibernate.ObjectNotFoundException; -import org.hibernate.Query; -import org.hibernate.Session; -import org.springframework.orm.hibernate3.support.HibernateDaoSupport; - -import com.google.gson.Gson; -import com.taobao.rigel.rap.account.bo.User; -import com.taobao.rigel.rap.common.ArrayUtils; -import com.taobao.rigel.rap.common.StringUtils; -import com.taobao.rigel.rap.project.bo.Action; -import com.taobao.rigel.rap.project.bo.Module; -import com.taobao.rigel.rap.project.bo.ObjectItem; -import com.taobao.rigel.rap.project.bo.Page; -import com.taobao.rigel.rap.project.bo.Parameter; -import com.taobao.rigel.rap.project.bo.Project; -import com.taobao.rigel.rap.project.dao.ProjectDao; - -public class ProjectDaoImpl extends HibernateDaoSupport implements ProjectDao { - - @SuppressWarnings("unchecked") - @Override - public List getProjectList(User user, int curPageNum, int pageSize) { - StringBuilder sql = new StringBuilder(); - sql - .append("SELECT project_id ") - .append("FROM tb_project_and_user ") - .append("WHERE user_id = :userId ") - .append("UNION ") - .append("SELECT id ") - .append("FROM tb_project ") - .append("WHERE user_id = :userId "); - Query query = getSession().createSQLQuery(sql.toString()).setLong("userId", - user.getId()); - - List list = query.list(); - List resultList = new ArrayList(); - for (Integer id : list) { - Project p = this.getProject(id); - if (p != null && p.getId() > 0) { - resultList.add(p); - } - } - return resultList; - } - @Override - public List getProjectList() { - String hqlByUser = "from Project"; - Query query = getSession().createQuery(hqlByUser); - return query.list(); - } - - @Override - public int addProject(Project project) { - Session session = getSession(); - project.getUser().addCreatedProject(project); - project.setVersion("0.0.0.1"); // default version - int modeInt = project.getWorkspaceModeInt(); - if (modeInt <= 0 || modeInt >= 3) { - project.setWorkspaceModeInt(1); - } - session.save(project); - project = (Project) session.load(Project.class, project.getId()); - project.setProjectData(project - .toString(Project.TO_STRING_TYPE.TO_PARAMETER)); - return project.getId(); - } - - @Override - public int removeProject(int id) { - Session session = getSession(); - Object project = session.get(Project.class, id); - if (project != null) { - session.delete((Project) project); - return 0; - } else { - return -1; - } - - } - - @Override - public int updateProject(Project project) { - Session session = getSession(); - session.update(project); - return 0; - } - - @Override - public Project getProject(int id) { - Project p = null; - try { - Session session = getSession(); - p = (Project) session.get(Project.class, id); - } catch (Exception ex) { - ex.printStackTrace(); - } - return p; - } - - @Override - public Module getModule(int id) { - Module m = null; - try { - Session session = getSession(); - m = (Module) session.get(Module.class, id); - } catch (ObjectNotFoundException ex) { - ex.printStackTrace(); - } catch (Exception ex) { - ex.printStackTrace(); - } - return m; - } - - @Override - public Page getPage(int id) { - return (Page) getSession().get(Page.class, id); - } - - - @Override - public Action getAction(long id) { - return (Action) getSession().get(Action.class, id); - } - - private Parameter getParameter(int id) { - return (Parameter) getSession().get(Parameter.class, id); - } - - @Override - public int saveProject(Project project) { - Session session = getSession(); - session.saveOrUpdate(project); - return 0; - } - - @Override - public String updateProject(int id, String projectData, - String deletedObjectListData, Map actionIdMap) { - Session session = getSession(); - // StringBuilder log = new StringBuilder(); - Gson gson = new Gson(); - - Project projectClient = gson.fromJson(projectData, Project.class); - - ObjectItem[] deletedObjectList = gson.fromJson(deletedObjectListData, - ObjectItem[].class); - - Project projectServer = (Project) session.load(Project.class, id); - projectServer.setUpdateTime(new Date()); - - // performing deleting - for (ObjectItem item : deletedObjectList) { - if (item.getClassName().equals("Module")) { - projectServer.removeModule(item.getId(), session); - } else if (item.getClassName().equals("Page")) { - projectServer.removePage(item.getId(), session); - } else if (item.getClassName().equals("Action")) { - projectServer.removeAction(item.getId(), session); - } else if (item.getClassName().equals("Parameter")) { - projectServer.removeParameter(item.getId(), session); - } - } - - // performing adding & updating - for (Module module : projectClient.getModuleList()) { - Module moduleServer = projectServer.findModule(module.getId()); - if (moduleServer == null) { - addModule(session, projectServer, module); - continue; - } - moduleServer.update(module); - for (Page page : module.getPageList()) { - Page pageServer = projectServer.findPage(page.getId()); - if (pageServer == null) { - addPage(session, module, page); - continue; - } - pageServer.update(page); - for (Action action : page.getActionList()) { - Action actionServer = projectServer.findAction(action - .getId()); - if (actionServer == null) { - long oldActionId = action.getId(); - long createdActionId = addAction(session, page, action); - actionIdMap.put(oldActionId, createdActionId); - continue; - } - actionServer.update(action); - CacheUtils.removeCacheByActionId(action.getId()); - for (Parameter parameter : action.getRequestParameterList()) { - Parameter parameterServer = projectServer - .findParameter(parameter.getId(), true); - if (parameterServer == null) { - addParameter(session, action, parameter, true); - continue; - } - parameterServer.update(parameter); - for (Parameter childParameter : parameter - .getParameterList()) { - processParameterRecursively(session, projectServer, - parameter, childParameter); - } - } - - for (Parameter parameter : action - .getResponseParameterList()) { - Parameter parameterServer = projectServer - .findParameter(parameter.getId(), false); - if (parameterServer == null) { - addParameter(session, action, parameter, false); - continue; - } - parameterServer.update(parameter); - for (Parameter childParameter : parameter - .getParameterList()) { - processParameterRecursively(session, projectServer, - parameter, childParameter); - } - } - } - } - } - return ""; - } - - private void processParameterRecursively(Session session, - Project projectServer, Parameter parameter, Parameter childParameter) { - Parameter childParameterServer = projectServer - .findChildParameter(childParameter.getId()); - if (childParameterServer == null) { - addParameterRecursively(session, parameter, childParameter); - } else { - childParameterServer.update(childParameter); - } - for (Parameter childOfChildParameter : childParameter - .getParameterList()) { - processParameterRecursively(session, projectServer, childParameter, - childOfChildParameter); - } - } - - private void addModule(Session session, Project project, Module module) { - project.addModule(module); - session.save(module); - for (Page page : module.getPageList()) { - addPage(session, module, page); - } - } - - private void addPage(Session session, Module module, Page page) { - module = (Module) session.load(Module.class, module.getId()); - module.addPage(page); - session.save(page); - for (Action action : page.getActionList()) { - addAction(session, page, action); - } - } - - private long addAction(Session session, Page page, Action action) { - page = (Page) session.load(Page.class, page.getId()); - page.addAction(action); - long createdId = (Long)session.save(action); - for (Parameter parameter : action.getRequestParameterList()) { - addParameter(session, action, parameter, true); - } - for (Parameter parameter : action.getResponseParameterList()) { - addParameter(session, action, parameter, false); - } - return createdId; - } - - private void addParameter(Session session, Action action, - Parameter parameter, boolean isRequest) { - action = (Action) session.load(Action.class, action.getId()); - action.addParameter(parameter, isRequest); - session.save(parameter); - for (Parameter childParameter : parameter.getParameterList()) { - addParameterRecursively(session, parameter, childParameter); - } - } - - /** - * add parameter recursively - * - * @param session - * session object - * @param parameter - * parent parameter - * @param childParameter - * child parameter - */ - private void addParameterRecursively(Session session, Parameter parameter, - Parameter childParameter) { - parameter = (Parameter) session - .load(Parameter.class, parameter.getId()); - parameter.addChild(childParameter); - session.save(childParameter); - for (Parameter childOfChildParameter : childParameter - .getParameterList()) { - addParameterRecursively(session, childParameter, - childOfChildParameter); - } - } - - @SuppressWarnings("unchecked") - @Override - public long getProjectListNum(User user) { - String hql = "select count(p) from Project as p order by p.id desc"; - String hqlByUser = "select count(p) from Project as p left join p.userList as u where p.user.id = :userId or u.id = :userId order by p.id desc"; - Query query = user == null ? getSession().createQuery(hql) - : getSession().createQuery(hqlByUser).setLong("userId", - user.getId()); - List list = query.list(); - return list.get(0); - } - - @Override - public long getProjectListNum() { - String sql = "SELECT COUNT(*) FROM tb_project"; - Query query = getSession().createSQLQuery(sql); - return Long.parseLong(query.uniqueResult().toString()); - } - - @Override - public long getModuleNum() { - String sql = "SELECT COUNT(*) FROM tb_module"; - Query query = getSession().createSQLQuery(sql); - return Long.parseLong(query.uniqueResult().toString()); - } - - @Override - public long getPageNum() { - String sql = "SELECT COUNT(*) FROM tb_page"; - Query query = getSession().createSQLQuery(sql); - return Long.parseLong(query.uniqueResult().toString()); - } - - @Override - public long getActionNum() { - String sql = "SELECT COUNT(*) FROM tb_action"; - Query query = getSession().createSQLQuery(sql); - return Long.parseLong(query.uniqueResult().toString()); - } - - @Override - public long getMockNumInTotal() { - String sql = "SELECT SUM(mock_num) FROM tb_project"; - Query query = getSession().createSQLQuery(sql); - Object queryResult = query.uniqueResult(); - return queryResult != null ? Long.parseLong(queryResult.toString()) : 0; - } - - @Override - public long getParametertNum() { - String sql = "SELECT COUNT(*) FROM tb_parameter"; - Query query = getSession().createSQLQuery(sql); - return Long.parseLong(query.uniqueResult().toString()); - } - - @Override - public long getCheckInNum() { - String sql = "SELECT COUNT(*) FROM tb_check_in"; - Query query = getSession().createSQLQuery(sql); - return Long.parseLong(query.uniqueResult().toString()); - } - - @Override - public List getMatchedActionList(int projectId, String pattern) { - List list = getActionListOfProject(projectId); - List result = new ArrayList(); - for (Action action : list) { - String url = action.getRequestUrl(); - url = URLUtils.getRelativeUrl(url); - if (url.startsWith("reg:")) { // regular pattern - if (StringUtils.regMatch(url.substring(4), pattern)) { - result.add(action); - } - } else if (url.contains(":")) { - String urlParamRemoved = URLUtils.removeParamsInUrl(url); - String realUrlParamRemoved = URLUtils - .removeRealParamsInUrl(pattern); - if (realUrlParamRemoved.equals(urlParamRemoved)) { - result.add(action); - } - } else { // normal pattern - if (url.contains(pattern)) { - result.add(action); - } - } - } - - return result; - - // process /:id/ cases - // boolean urlParalized = false; - // String patternOrignial = pattern; - // if (pattern.contains(":")) { - // urlParalized = true; - // pattern = pattern.substring(0, pattern.indexOf(":")); - // } - - /** - * StringBuilder sb = new StringBuilder(); - * sb.append("SELECT a.id FROM tb_action a ") - * .append("JOIN tb_action_and_page ap ON ap.action_id = a.id ") - * .append("JOIN tb_page p ON p.id = ap.page_id ") - * .append("JOIN tb_module m ON m.id = p.module_id ") .append( - * "WHERE LOCATE(:pattern, a.request_url) != 0 AND m.project_id = :projectId " - * ); - * - * String sql = sb.toString(); Query query = - * getSession().createSQLQuery(sql); query.setString("pattern", - * pattern); query.setInteger("projectId", projectId); List - * list = query.list(); List actionList = new - * ArrayList(); for (int id : list) { - * actionList.add(getAction(id)); } - */ - - // URL parameters filter - /** - * if (urlParalized) { List filteredActionList = new - * ArrayList(); for (Action a : actionList) { String u = - * a.getRequestUrl(); if (u.contains("?")) { u = u.substring(0, - * u.indexOf("?")); } u = StringUtils.removeParamsInUrl(u); - * patternOrignial = StringUtils .removeParamsInUrl(patternOrignial); if - * (u != null && patternOrignial != null && u.equals(patternOrignial)) { - * filteredActionList.add(a); } } actionList = filteredActionList; } - */ - // return actionList; - } - - @SuppressWarnings("unchecked") - private List getParameterIdList(int projectId) { - StringBuilder sql = new StringBuilder(); - sql.append(" SELECT DISTINCT p.id") - .append(" FROM tb_parameter p") - .append(" JOIN tb_response_parameter_list_mapping rplm ON p.id = rplm.parameter_id") - .append(" JOIN tb_action_and_page ap ON ap.action_id = rplm.action_id") - .append(" JOIN tb_page p2 ON p2.id = ap.page_id") - .append(" JOIN tb_module m ON m.id = p2.module_id") - .append(" WHERE m.project_id = :projectId"); - Query query = getSession().createSQLQuery(sql.toString()); - query.setInteger("projectId", projectId); - List list = query.list(); - - StringBuilder sql2 = new StringBuilder(); - sql2.append(" SELECT DISTINCT p.id") - .append(" FROM tb_parameter p") - .append(" JOIN tb_request_parameter_list_mapping rplm ON p.id = rplm.parameter_id") - .append(" JOIN tb_action_and_page ap ON ap.action_id = rplm.action_id") - .append(" JOIN tb_page p2 ON p2.id = ap.page_id") - .append(" JOIN tb_module m ON m.id = p2.module_id") - .append(" WHERE m.project_id = :projectId"); - Query query2 = getSession().createSQLQuery(sql2.toString()); - query2.setInteger("projectId", projectId); - list.addAll(query2.list()); - List paramList = new ArrayList(); - for (Integer pId : list) { - paramList.add(getParameter(pId)); - } - for (Parameter p : paramList) { - recursivelyAddSubParamList(list, p); - } - return list; - } - - private void recursivelyAddSubParamList(List list, Parameter p) { - list.add(p.getId()); - if (p.getParameterList() == null) - return; - for (Parameter subP : p.getParameterList()) { - recursivelyAddSubParamList(list, subP); - } - } - - public int resetMockData(int projectId) { - List pIdList = getParameterIdList(projectId); - String sql = "UPDATE tb_parameter SET mock_data = NULL where id in (" - + ArrayUtils.join(pIdList, ",") + ")"; - Query query = getSession().createSQLQuery(sql); - return query.executeUpdate(); - } - - @SuppressWarnings("unchecked") - @Override - public List getProjectListByGroup(int id) { - String hql = "from Project where groupId = :id"; - Query query = getSession().createQuery(hql); - query.setInteger("id", id); - return query.list(); - } - - @Override - public List search(String key) { - String hql = "from Project where name LIKE :key"; - Query query = getSession().createQuery(hql); - query.setString("key", "%" + key + "%"); - return query.list(); - } - - @SuppressWarnings({ "rawtypes" }) - private List getActionListOfProject(int projectId) { - List list = new ArrayList(); - StringBuilder sql = new StringBuilder(); - sql.append("SELECT a.id "); - sql.append("FROM tb_project p "); - sql.append("JOIN tb_module m ON m.project_id = p.id "); - sql.append("JOIN tb_page ON tb_page.module_id = m.id "); - sql.append("JOIN tb_action_and_page anp ON anp.page_id = tb_page.id "); - sql.append("JOIN tb_action a ON a.id = anp.action_id "); - sql.append("WHERE p.id = :projectId "); - Query query = getSession().createSQLQuery(sql.toString()); - query.setInteger("projectId", projectId); - - List result = query.list(); - List ids = new ArrayList(); - for (Object r : result) { - ids.add((Integer) r); - } - for (Integer id : ids) { - list.add(this.getAction(id)); - } - return list; - } - - @Override - public List selectMockNumTopNProjectList(int limit) { - String hqlByUser = "from Project order by mockNum desc"; - Query query = getSession().createQuery(hqlByUser); - return query.setMaxResults(limit).list(); - } - - @Override - public Integer getProjectIdByActionId(int actionId) { - StringBuilder sql = new StringBuilder(); - sql.append("SELECT p.id FROM tb_project p "); - sql.append("JOIN tb_module m ON m.project_id = p.id "); - sql.append("JOIN tb_page page ON page.module_id = m.id "); - sql.append("JOIN tb_action_and_page anp ON anp.page_id = page.id "); - sql.append("where action_id = :actionId"); - Query query = getSession().createSQLQuery(sql.toString()); - query.setInteger("actionId", actionId); - return (Integer)query.uniqueResult(); - } - - @Override - public void updateProjectNum(Project project) { - String sql = "UPDATE tb_project SET mock_num = :mockNum WHERE id = :projectId"; - getSession().createSQLQuery(sql).setInteger("mockNum", project.getMockNum()).setInteger("projectId", project.getId()).executeUpdate(); - } - - @Override - public void updateCreatorId(int projectId, long creatorId) { - Query query = getSession().createSQLQuery("UPDATE tb_project SET user_id = :userId WHERE id = :id"); - query.setLong("userId", creatorId); - query.setInteger("id", projectId); - query.executeUpdate(); - } - -} diff --git a/src/com/taobao/rigel/rap/project/mapping/Action.hbm.xml b/src/com/taobao/rigel/rap/project/mapping/Action.hbm.xml deleted file mode 100644 index 792d88d56..000000000 --- a/src/com/taobao/rigel/rap/project/mapping/Action.hbm.xml +++ /dev/null @@ -1,48 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/src/com/taobao/rigel/rap/project/mapping/Module.hbm.xml b/src/com/taobao/rigel/rap/project/mapping/Module.hbm.xml deleted file mode 100644 index 16ae39875..000000000 --- a/src/com/taobao/rigel/rap/project/mapping/Module.hbm.xml +++ /dev/null @@ -1,23 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - diff --git a/src/com/taobao/rigel/rap/project/mapping/Page.hbm.xml b/src/com/taobao/rigel/rap/project/mapping/Page.hbm.xml deleted file mode 100644 index 87126bf30..000000000 --- a/src/com/taobao/rigel/rap/project/mapping/Page.hbm.xml +++ /dev/null @@ -1,26 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/com/taobao/rigel/rap/project/mapping/Parameter.hbm.xml b/src/com/taobao/rigel/rap/project/mapping/Parameter.hbm.xml deleted file mode 100644 index 0b2445c8a..000000000 --- a/src/com/taobao/rigel/rap/project/mapping/Parameter.hbm.xml +++ /dev/null @@ -1,43 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/src/com/taobao/rigel/rap/project/mapping/Project.hbm.xml b/src/com/taobao/rigel/rap/project/mapping/Project.hbm.xml deleted file mode 100644 index 744ff14ff..000000000 --- a/src/com/taobao/rigel/rap/project/mapping/Project.hbm.xml +++ /dev/null @@ -1,85 +0,0 @@ - - - - - - - - - - - 项目名称 - - - - - 项目相关ID - - - - - 分组ID - - - - - MOCK调用次数 - - - - - 当前版本 - - - - - 创建时间 - - - - - 更新时间 - - - - - 项目简介 - - - - - 共享模式 - - - - - 项目数据(json),用于VSS同步模式 - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/com/taobao/rigel/rap/project/service/ProjectMgr.java b/src/com/taobao/rigel/rap/project/service/ProjectMgr.java deleted file mode 100644 index b97a123e8..000000000 --- a/src/com/taobao/rigel/rap/project/service/ProjectMgr.java +++ /dev/null @@ -1,196 +0,0 @@ -package com.taobao.rigel.rap.project.service; - -import java.util.List; -import java.util.Map; - -import com.taobao.rigel.rap.account.bo.User; -import com.taobao.rigel.rap.project.bo.Action; -import com.taobao.rigel.rap.project.bo.Module; -import com.taobao.rigel.rap.project.bo.Page; -import com.taobao.rigel.rap.project.bo.Project; - -public interface ProjectMgr { - - /** - * get project list - * - * @param curUserId - * @param curPageNum - * @param pageSize - * @return - */ - List getProjectList(long curUserId, int curPageNum, int pageSize); - - /** - * add new project - * - * @param project - * @return - */ - int addProject(Project project); - - /** - * remove project - * - * @param id - * @return - */ - int removeProject(int id); - - /** - * update project - * - * @param project - * @return - */ - int updateProject(Project project); - - /** - * get project by id - * - * @param id - * @return - */ - Project getProject(int id); - - Project getProject(int id, String ver); - - /** - * get module by id - * - * @param id - * @return - */ - Module getModule(int id); - - /** - * get page by id - * - * @param id - * @return - */ - Page getPage(int id); - - /** - * update project - * - * @param id - * @param projectData - * @param deletedObjectListData - * @return - */ - String updateProject(int id, String projectData, - String deletedObjectListData, Map actionIdMap); - - /** - * get number of project list usually used for pager - * - * @param user - * @return - */ - long getProjectListNum(User user); - - /** - * set action.remarks as paramIdList eg-> action.remarks = "id,name,age"; - * used for parameter identifier spelling validation [*caution*] only - * calculating response parameters - * - * @param action - * action to be filled with paramIdList info - */ - void loadParamIdListForAction(Action action); - - /** - * load paramIdList for page - * - * @param page - */ - void loadParamIdListForPage(Page page); - - /** - * get matched action list based on URL pattern - * - * @param projectId - * @param pattern - * @return - */ - List getMatchedActionList(int projectId, String pattern); - - /** - * get project list by group id - * - * @param id - * @return - */ - List getProjectListByGroup(int id); - - /** - * search all projects (for admin) - * - * @param key - * @return - */ - List search(String key); - - /** - * search project by user - * - * @param key - * @param curUserId - * @return - */ - List search(String key, long curUserId); - - /** - * get action - * - * @param id - * @return - */ - Action getAction(long id); - - Action getAction(long id, String ver, int projectId); - - /** - * update doc - * - * @param project id - */ - void updateDoc(int projectId); - - List getProjectList(); - - long getProjectNum(); - - long getModuleNum(); - - long getPageNum(); - - long getActionNum(); - - long getParametertNum(); - - long getCheckInNum(); - - long getMockNumInTotal(); - - List selectMockNumTopNProjectList(int limit); - - /** - * update Action.disableCache - * - * @param projectId - */ - void updateCache(int projectId); - - /** - * get project id by action id - * - * @param actionId - * @return - */ - Integer getProjectIdByActionId(int actionId); - - void updateProjectNum(Project project); - -} diff --git a/src/com/taobao/rigel/rap/project/service/impl/ProjectMgrImpl.java b/src/com/taobao/rigel/rap/project/service/impl/ProjectMgrImpl.java deleted file mode 100644 index 70c4efe63..000000000 --- a/src/com/taobao/rigel/rap/project/service/impl/ProjectMgrImpl.java +++ /dev/null @@ -1,415 +0,0 @@ -package com.taobao.rigel.rap.project.service.impl; - -import java.util.*; - -import com.google.gson.Gson; -import com.taobao.rigel.rap.account.bo.Notification; -import com.taobao.rigel.rap.account.bo.User; -import com.taobao.rigel.rap.account.dao.AccountDao; -import com.taobao.rigel.rap.account.service.AccountMgr; -import com.taobao.rigel.rap.common.ArrayUtils; -import com.taobao.rigel.rap.common.HTTPUtils; -import com.taobao.rigel.rap.common.SystemConstant; -import com.taobao.rigel.rap.organization.bo.Group; -import com.taobao.rigel.rap.organization.dao.OrganizationDao; -import com.taobao.rigel.rap.organization.service.OrganizationMgr; -import com.taobao.rigel.rap.project.bo.Action; -import com.taobao.rigel.rap.project.bo.Module; -import com.taobao.rigel.rap.project.bo.Page; -import com.taobao.rigel.rap.project.bo.Parameter; -import com.taobao.rigel.rap.project.bo.Project; -import com.taobao.rigel.rap.project.dao.ProjectDao; -import com.taobao.rigel.rap.project.service.ProjectMgr; -import com.taobao.rigel.rap.workspace.bo.CheckIn; -import com.taobao.rigel.rap.workspace.dao.WorkspaceDao; - -public class ProjectMgrImpl implements ProjectMgr { - - private ProjectDao projectDao; - private OrganizationDao organizationDao; - private AccountMgr accountMgr; - private WorkspaceDao workspaceDao; - - public OrganizationMgr getOrganizationMgr() { - return organizationMgr; - } - - public void setOrganizationMgr(OrganizationMgr organizationMgr) { - this.organizationMgr = organizationMgr; - } - - private OrganizationMgr organizationMgr; - - public void setWorkspaceDao(WorkspaceDao workspaceDao) { - this.workspaceDao = workspaceDao; - } - - public AccountMgr getAccountMgr() { - return accountMgr; - } - - public void setAccountMgr(AccountMgr accountMgr) { - this.accountMgr = accountMgr; - } - - public OrganizationDao getOrganizationDao() { - return organizationDao; - } - - public void setOrganizationDao(OrganizationDao organizationDao) { - this.organizationDao = organizationDao; - } - - public ProjectDao getProjectDao() { - return this.projectDao; - } - - public void setProjectDao(ProjectDao projectDao) { - this.projectDao = projectDao; - } - - private AccountDao accountDao; - - public AccountDao getAccountDao() { - return accountDao; - } - - public void setAccountDao(AccountDao accountDao) { - this.accountDao = accountDao; - } - - @Override - public List getProjectList(long curUserId, int curPageNum, int pageSize) { - User user = accountMgr.getUser(curUserId); - List projectList = projectDao.getProjectList(user, curPageNum, - pageSize); - for (Project p : projectList) { - if (user.isUserInRole("admin") - || p.getUser().getId() == user.getId()) { - p.setIsManagable(true); - } - p.setTeamId(organizationDao.getTeamIdByProjectId(p.getId())); - } - return projectList; - } - - @Override - public int addProject(Project project) { - project.setUpdateTime(new Date()); - project.setCreateDate(new Date()); - List usersInformed = new ArrayList(); - for (String account : project.getMemberAccountList()) { - User user = accountDao.getUser(account); - if (user != null) { - boolean addSuccess = project.addMember(user); - if (addSuccess) { - usersInformed.add(user); - } - } - } - int result = projectDao.addProject(project); - for (User u : usersInformed) { - Notification o = new Notification(); - o.setTypeId((short)2); - o.setTargetUser(project.getUser()); - o.setUser(u); - o.setParam1(new Integer(result).toString()); - o.setParam2(project.getName()); - accountMgr.addNotification(o); - } - - Group g = organizationDao.getGroup(project.getGroupId()); - if (g.getProductionLineId() > 0) { - organizationDao.updateCountersInProductionLine(g - .getProductionLineId()); - } - - return result; - } - - @Override - public int removeProject(int id) { - Project p = getProject(id); - Group g = organizationDao.getGroup(p.getGroupId()); - int result = projectDao.removeProject(id); - if (g != null) { - int pId = g.getProductionLineId(); - if (pId > 0) { - organizationDao.updateCountersInProductionLine(pId); - } - } - return result; - } - - @Override - public int updateProject(Project outerProject) { - Project project = getProject(outerProject.getId()); - project.setName(outerProject.getName()); - project.setIntroduction(outerProject.getIntroduction()); - project.setUpdateTime(new Date()); - - if (outerProject.getMemberAccountList() != null) { - // adding new ones - for (String account : outerProject.getMemberAccountList()) { - User user = accountDao.getUser(account); - if (user != null) { - boolean addSuccess = project.addMember(user); - if (addSuccess) { - Notification o = new Notification(); - o.setTypeId((short)2); - o.setTargetUser(outerProject.getUser()); - o.setUser(user); - o.setParam1(new Integer(outerProject.getId()).toString()); - o.setParam2(outerProject.getName()); - accountMgr.addNotification(o); - } - } - } - - if (project.getUserList() != null) { - // remove old ones - List userListToBeRemoved = new ArrayList(); - for (User user : project.getUserList()) { - if (!outerProject.getMemberAccountList().contains( - user.getAccount())) { - userListToBeRemoved.add(user); - } - } - - for (User user : userListToBeRemoved) { - project.removeMember(user); - } - } - } - - return projectDao.updateProject(project); - } - - @Override - public Project getProject(int id) { - return projectDao.getProject(id); - } - - @Override - public Project getProject(int id, String ver) { - CheckIn check = workspaceDao.getVersion(id, ver); - String projectData = check.getProjectData(); - - Gson gson = new Gson(); - Project p = gson.fromJson(projectData, Project.class); - p.setVersion(check.getVersion()); - return p; - } - - @Override - public Module getModule(int id) { - return projectDao.getModule(id); - } - - @Override - public Page getPage(int id) { - return projectDao.getPage(id); - } - - @Override - public String updateProject(int id, String projectData, - String deletedObjectListData, Map actionIdMap) { - return projectDao.updateProject(id, projectData, deletedObjectListData, actionIdMap); - } - - @Override - public long getProjectListNum(User user) { - if (user != null && user.isUserInRole("admin")) { - user = null; - } - return projectDao.getProjectListNum(user); - } - - @Override - public void loadParamIdListForAction(Action action) { - List paramIdList = new ArrayList(); - recursivelyLoadParamIdList(paramIdList, - action.getResponseParameterList()); - action.setRemarks(ArrayUtils.join(paramIdList, ",")); - } - - @Override - public void loadParamIdListForPage(Page page) { - for (Action action : page.getActionList()) { - loadParamIdListForAction(action); - } - } - - /** - * sub method of loadParamIdListForAction for recursively load paramIdList - * for complex parameters - * - * @param paramIdList - * @param paramList - */ - private void recursivelyLoadParamIdList(List paramIdList, - Set paramList) { - for (Parameter p : paramList) { - if (p.getIdentifier() != null || !p.getIdentifier().isEmpty()) { - paramIdList.add(p.getIdentifier()); - } - if (p.getParameterList() != null && p.getParameterList().size() > 0) { - recursivelyLoadParamIdList(paramIdList, p.getParameterList()); - } - } - } - - @Override - public List getMatchedActionList(int projectId, String pattern) { - List actionList = projectDao.getMatchedActionList(projectId, - pattern); - if (actionList == null || actionList.size() == 0) { - Project project = projectDao.getProject(projectId); - if (project != null) { - String ids = project.getRelatedIds(); - if (ids != null && !ids.isEmpty()) { - String[] arr = ids.split(","); - for (String id : arr) { - actionList = projectDao.getMatchedActionList( - Integer.parseInt(id), pattern); - if (actionList != null && actionList.size() != 0) { - return actionList; - } - } - } - } - } - return actionList; - } - - @Override - public List getProjectListByGroup(int id) { - return projectDao.getProjectListByGroup(id); - } - - @Override - public List search(String key) { - return projectDao.search(key); - } - - @Override - public List search(String key, long userId) { - List list = projectDao.search(key); - List result = new ArrayList(); - - for (Project p : list) { - if (organizationMgr.canUserAccessProject(userId, p.getId())) { - result.add(p); - } - } - return result; - } - - @Override - public Action getAction(long id) { - return projectDao.getAction(id); - } - - @Override - public Action getAction(long id, String ver, int projectId) { - CheckIn check = workspaceDao.getVersion(projectId, ver); - Gson gson = new Gson(); - Project p = gson.fromJson(check.getProjectData(), Project.class); - return p.findAction(id); - } - - @Override - public void updateDoc(int projectId) { - try { - HTTPUtils.sendGet("http://" + SystemConstant.NODE_SERVER + "/api/generateDoc?projectId=" + projectId); - } catch (Exception e) { - e.printStackTrace(); - } - } - - @Override - public List getProjectList() { - return projectDao.getProjectList(); - } - - @Override - public long getProjectNum() { - return projectDao.getProjectListNum(); - } - - @Override - public long getModuleNum() { - return projectDao.getModuleNum(); - } - - @Override - public long getPageNum() { - return projectDao.getPageNum(); - } - - @Override - public long getActionNum() { - return projectDao.getActionNum(); - } - - @Override - public long getParametertNum() { - return projectDao.getParametertNum(); - } - - @Override - public long getCheckInNum() { - return projectDao.getCheckInNum(); - } - - @Override - public long getMockNumInTotal() {return projectDao.getMockNumInTotal();} - - @Override - public List selectMockNumTopNProjectList(int limit) { - return projectDao.selectMockNumTopNProjectList(limit); - } - - @Override - public void updateCache(int projectId) { - Project project = getProject(projectId); - for (Module module : project.getModuleList()) { - for (Page page : module.getPageList()) { - for (Action action : page.getActionList()) { - updateActionCache(action); - } - } - } - } - - @Override - public Integer getProjectIdByActionId(int actionId) { - return projectDao.getProjectIdByActionId(actionId); - } - - @Override - public void updateProjectNum(Project project) { - projectDao.updateProjectNum(project); - } - - private void updateActionCache(Action action) { - action.setDisableCache(0); - for (Parameter param : action.getResponseParameterList()) { - clearParameterCache(param, action); - } - } - - private void clearParameterCache(Parameter param, Action action) { - String rules = param.getMockJsRules(); - if (rules != null && rules.contains("${") && rules.contains("}")) { - action.setDisableCache(1); - return; // over - } - Set children = param.getParameterList(); - if (children != null && children.size() != 0) { - for (Parameter child : children) { - clearParameterCache(child, action); - } - } - } -} diff --git a/src/com/taobao/rigel/rap/project/web/action/ProjectAction.java b/src/com/taobao/rigel/rap/project/web/action/ProjectAction.java deleted file mode 100644 index e9ab781ff..000000000 --- a/src/com/taobao/rigel/rap/project/web/action/ProjectAction.java +++ /dev/null @@ -1,396 +0,0 @@ -package com.taobao.rigel.rap.project.web.action; - -import java.io.ByteArrayInputStream; -import java.io.FileNotFoundException; -import java.io.InputStream; -import java.io.UnsupportedEncodingException; -import java.util.ArrayList; -import java.util.Date; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import com.google.gson.Gson; -import com.taobao.rigel.rap.account.bo.User; -import com.taobao.rigel.rap.auto.generate.bo.VelocityTemplateGenerator; -import com.taobao.rigel.rap.auto.generate.contract.Generator; -import com.taobao.rigel.rap.common.ActionBase; -import com.taobao.rigel.rap.common.RapError; -import com.taobao.rigel.rap.project.bo.Page; -import com.taobao.rigel.rap.project.bo.Project; -import com.taobao.rigel.rap.project.service.ProjectMgr; -import com.taobao.rigel.rap.workspace.service.WorkspaceMgr; - -public class ProjectAction extends ActionBase { - - private int id; - - private List searchResult; - - private String ids; - - public String getIds() { - if (ids == null || ids.isEmpty()) { - return ""; - } - - String[] idList = ids.split(","); - String returnVal = ""; - Integer num = 0; - int counter = 0; - for (String id : idList) { - try { - num = Integer.parseInt(id); - counter++; - if (counter > 1) { - returnVal += ","; - } - returnVal += num.toString(); - - } catch (Exception ex) { - - } - } - return returnVal; - } - - public void setIds(String ids) { - this.ids = ids; - } - - public List getSearchResult() { - return searchResult; - } - - private String key; - - public String getKey() { - return key; - } - - public void setKey(String key) { - this.key = key; - } - - public int getId() { - return this.id; - } - - public void setId(int id) { - this.id = id; - } - - private String desc; - - private int groupId; - - public int getGroupId() { - return groupId; - } - - public void setGroupId(int groupId) { - this.groupId = groupId; - } - - private String accounts; - - public String getDesc() { - return desc; - } - - public void setDesc(String desc) { - this.desc = desc; - } - - public String getAccounts() { - if (accounts == null) - return ""; - return accounts; - } - - public void setAccounts(String accounts) { - this.accounts = accounts; - } - - public List getMemberAccountList() { - List memberList = new ArrayList(); - for (User user : super.getAccountMgr().getUserList()) { - memberList.add(user.getAccount() + "(" + user.getName() + ")"); - } - return memberList; - } - - private String memberAccountListStr; - - public String getMemberAccountListStr() { - return memberAccountListStr; - } - - public void setMemberAccountListStr(String memberAccountListStr) { - this.memberAccountListStr = memberAccountListStr; - } - - private String name; - - public String getName() { - return this.name; - } - - public void setName(String name) { - this.name = name; - } - - private Date createDate; - - public Date getCreateDate() { - return this.createDate; - } - - public void setCreateDate(Date createDate) { - this.createDate = createDate; - } - - private String introduction; - - public String getIntroduction() { - return this.introduction; - } - - public void setIntroduction(String introduction) { - this.introduction = introduction; - } - - private List projectList; - - public List getProjectList() { - return this.projectList; - } - - public void setProjectList(List projectList) { - this.projectList = projectList; - } - - private Project project; - - public Project getProject() { - return this.project; - } - - public void setProject(Project project) { - this.project = project; - } - - private static final long serialVersionUID = 1L; - - private ProjectMgr projectMgr; - - /** - * get project manager - * - * @return project manager - */ - public ProjectMgr getProjectMgr() { - return projectMgr; - } - - public void setProjectMgr(ProjectMgr projectMgr) { - this.projectMgr = projectMgr; - } - - private WorkspaceMgr workspaceMgr; - - public WorkspaceMgr getWorkspaceMgr() { - return workspaceMgr; - } - - public void setWorkspaceMgr(WorkspaceMgr workspaceMgr) { - this.workspaceMgr = workspaceMgr; - } - - private int pageId; - - public int getPageId() { - return pageId; - } - - public void setPageId(int pageId) { - this.pageId = pageId; - } - - private String projectData; - - public String getProjectData() { - return projectData; - } - - public void setProjectData(String projectData) { - this.projectData = projectData; - } - - - public String delete() { - if (!isUserLogined()) - return LOGIN; - if (!getAccountMgr().canUserManageProject(getCurUserId(), getId())) { - setErrMsg("您没有管理该项目的权限"); - return ERROR; - } - projectMgr.removeProject(getId()); - return SUCCESS; - } - - public String create() { - if (!isUserLogined()) - return LOGIN; - Gson gson = new Gson(); - Project project = new Project(); - project.setCreateDate(new Date()); - project.setUser(getAccountMgr().getUser(getCurUserId())); - project.setIntroduction(getDesc()); - project.setName(getName()); - project.setGroupId(groupId); - List memberAccountList = new ArrayList(); - String[] list = getAccounts().split(","); - // format: mashengbo(大灰狼堡森), linpanhui(林攀辉), - for (String item : list) { - String account = item.contains("(") ? item.substring(0, - item.indexOf("(")).trim() : item.trim(); - if (!account.equals("")) - memberAccountList.add(account); - } - project.setMemberAccountList(memberAccountList); - int projectId = projectMgr.addProject(project); - project = projectMgr.getProject(projectId); - Map result = new HashMap(); - result.put("id", project.getId()); - result.put("name", project.getName()); - result.put("desc", project.getIntroduction()); - result.put("accounts", project.getMemberAccountListStr()); - result.put("groupId", project.getGroupId()); - result.put("isManagable", "true"); - result.put("creator", project.getUser().getUserBaseInfo()); - setJson(new RapError(gson.toJson(result)).toString()); - return SUCCESS; - } - - public String update() { - if (!isUserLogined()) - return LOGIN; - if (!getAccountMgr().canUserManageProject(getCurUserId(), getId())) { - setErrMsg("您没有管理该项目的权限"); - return ERROR; - } - User curUser = getAccountMgr().getUser(getCurUserId()); - Project project = new Project(); - project.setId(getId()); - project.setIntroduction(getDesc()); - project.setName(getName()); - project.setUser(curUser); - List memberAccountList = new ArrayList(); - String[] list = getAccounts().split(","); - // format: mashengbo(大灰狼堡森), linpanhui(林攀辉), - for (String item : list) { - String account = item.contains("(") ? item.substring(0, - item.indexOf("(")).trim() : item.trim(); - if (!account.equals("")) - memberAccountList.add(account); - } - Gson gson = new Gson(); - project.setMemberAccountList(memberAccountList); - projectMgr.updateProject(project); - project = projectMgr.getProject(project.getId()); - - if (curUser.isUserInRole("admin") - || curUser.getId() == project.getUser().getId()) { - project.setIsManagable(true); - } - - Map result = new HashMap(); - result.put("id", project.getId()); - result.put("name", project.getName()); - result.put("desc", project.getIntroduction()); - result.put("accounts", project.getMemberAccountListStr()); - result.put("groupId", project.getGroupId()); - result.put("isManagable", project.getIsManagable()); - setJson(new RapError(gson.toJson(result)).toString()); - return SUCCESS; - } - - public String updateReleatedIds() { - if (!isUserLogined()) - return LOGIN; - if (!getAccountMgr().canUserManageProject(getCurUserId(), getId())) { - setErrMsg("您没有管理该项目的权限"); - return ERROR; - } - - Project project = projectMgr.getProject(getId()); - project.setRelatedIds(getIds()); - projectMgr.updateProject(project); - - return SUCCESS; - } - - private String result; - - public String getResult() { - return result; - } - - public void setResult(String result) { - this.result = result; - } - - private InputStream outputStream; - - public InputStream getOutputStream() { - return outputStream; - } - - public void setOutputStream(InputStream outputStream) { - this.outputStream = outputStream; - } - - public String autoGenerate() throws FileNotFoundException, - UnsupportedEncodingException { - Generator generator = new VelocityTemplateGenerator(); - Page page = projectMgr.getPage(getPageId()); - generator.setObject(page); - String exportFileString = generator.doGenerate(); - outputStream = new ByteArrayInputStream( - exportFileString.getBytes("UTF8")); - return SUCCESS; - } - - public String getGeneratedFileName() { - return projectMgr.getPage(getPageId()).getTemplate(); - } - - public String search() { - - if (!isUserLogined()) { - plsLogin(); - return JSON_ERROR; - } - - long curUserId = getCurUserId(); - User curUser = getAccountMgr().getUser(curUserId); - if (curUser.isAdmin()) { - searchResult = projectMgr.search(key); - } else { - searchResult = projectMgr.search(key, getCurUserId()); - } - - List> list = new ArrayList>(); - for (Project p : searchResult) { - Map item = new HashMap(); - item.put("id", p.getId()); - item.put("name", p.getName()); - list.add(item); - } - Gson gson = new Gson(); - setJson(gson.toJson(list)); - return SUCCESS; - } - -} diff --git a/src/com/taobao/rigel/rap/project/web/action/struts.xml b/src/com/taobao/rigel/rap/project/web/action/struts.xml deleted file mode 100644 index 70f3258ff..000000000 --- a/src/com/taobao/rigel/rap/project/web/action/struts.xml +++ /dev/null @@ -1,37 +0,0 @@ - - - - - - - - - /bcom/json.cb.vm - - - - /bcom/json.cb.vm - - - - /bcom/json.cb.vm - - - - /bcom/json.cb.vm - - - - /bcom/json.cb.vm - - - - - diff --git a/src/com/taobao/rigel/rap/tester/web/action/TesterAction.java b/src/com/taobao/rigel/rap/tester/web/action/TesterAction.java deleted file mode 100644 index c4fe02ce2..000000000 --- a/src/com/taobao/rigel/rap/tester/web/action/TesterAction.java +++ /dev/null @@ -1,108 +0,0 @@ -package com.taobao.rigel.rap.tester.web.action; - -import com.google.gson.Gson; -import com.taobao.rigel.rap.account.bo.User; -import com.taobao.rigel.rap.common.ActionBase; -import com.taobao.rigel.rap.common.HTTPUtils; -import com.taobao.rigel.rap.common.SystemVisitorLog; -import com.taobao.rigel.rap.organization.service.OrganizationMgr; -import com.taobao.rigel.rap.project.bo.Page; -import com.taobao.rigel.rap.project.service.ProjectMgr; -import com.taobao.rigel.rap.tester.bo.SSOUserRes; -import org.apache.velocity.tools.config.EasyFactoryConfiguration; - -import java.util.List; -import java.util.Map; - - -public class TesterAction extends ActionBase { - - private static final long serialVersionUID = 1L; - private ProjectMgr projectMgr; - private int id; - private Page page; - private int projectId; - - public String getUrl() { - return url; - } - - public void setUrl(String url) { - this.url = url; - } - - private String url; - - public OrganizationMgr getOrganizationMgr() { - return organizationMgr; - } - - public void setOrganizationMgr(OrganizationMgr organizationMgr) { - this.organizationMgr = organizationMgr; - } - - private OrganizationMgr organizationMgr; - - public int getProjectId() { - return projectId; - } - - public Page getPage() { - return page; - } - - public ProjectMgr getProjectMgr() { - return projectMgr; - } - - public void setProjectMgr(ProjectMgr projectMgr) { - this.projectMgr = projectMgr; - } - - public int getId() { - return id; - } - - public void setId(int id) { - this.id = id; - } - - public String pageTester() { - - if (!isUserLogined()) { - plsLogin(); - setRelativeReturnUrl("/tester/pageTester.do?id=" - + id); - return LOGIN; - } - - if (!organizationMgr.canUserAccessPage(getCurUserId(), id)) { - setErrMsg(ACCESS_DENY); - return ERROR; - } - - page = projectMgr.getPage(id); - projectMgr.loadParamIdListForPage(page); - projectId = page.getModule().getProject().getId(); - return SUCCESS; - } - - public String test() { - /** - SystemVisitorLog.clear(projectMgr); - System.out.println("Clear complete!"); - setJson("clear complete"); - */ - return SUCCESS; - } - - /** - * used for system configuration when new version deployed - * @return - */ - public String ___init___() throws Exception { - - - return SUCCESS; - } -} diff --git a/src/com/taobao/rigel/rap/tester/web/action/struts.xml b/src/com/taobao/rigel/rap/tester/web/action/struts.xml deleted file mode 100644 index 05c52a711..000000000 --- a/src/com/taobao/rigel/rap/tester/web/action/struts.xml +++ /dev/null @@ -1,23 +0,0 @@ - - - - - - - - /tester/pageTester.vm - - - /bcom/isOk.cb.vm - - - /bcom/content.cb.vm - - - - diff --git a/src/com/taobao/rigel/rap/workspace/applicationContext.xml b/src/com/taobao/rigel/rap/workspace/applicationContext.xml deleted file mode 100644 index dca78c9f4..000000000 --- a/src/com/taobao/rigel/rap/workspace/applicationContext.xml +++ /dev/null @@ -1,33 +0,0 @@ - - - - - - - - - - - - - - - - - resource.loader=class - class.resource.loader.class=org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader - - - - - - \ No newline at end of file diff --git a/src/com/taobao/rigel/rap/workspace/bo/CheckIn.java b/src/com/taobao/rigel/rap/workspace/bo/CheckIn.java deleted file mode 100644 index 0747c2acb..000000000 --- a/src/com/taobao/rigel/rap/workspace/bo/CheckIn.java +++ /dev/null @@ -1,189 +0,0 @@ -package com.taobao.rigel.rap.workspace.bo; - -import java.util.Date; - -import com.taobao.rigel.rap.account.bo.User; -import com.taobao.rigel.rap.common.DateUtils; -import com.taobao.rigel.rap.common.StringUtils; -import com.taobao.rigel.rap.project.bo.Project; -import com.taobao.rigel.rap.workspace.bo.Workspace.ModeType; - -public class CheckIn implements java.io.Serializable { - - private static final long serialVersionUID = 1L; - - public enum ToStringType {COMPLETED, NORMAL}; - - private int id; - - public int getId() { - return id; - } - - public void setId(int id) { - this.id = id; - } - - private Date createDate; - - public Date getCreateDate() { - return createDate; - } - - public String getCreateDateStr() { - return getCreateDate() == null ? "" : DateUtils.TIME_FORMAT.format(getCreateDate()); - } - - public void setCreateDate(Date createDate) { - this.createDate = createDate; - } - - private String tag; - - public String getTag() { - return tag; - } - - public void setTag(String tag) { - this.tag = tag; - } - - private User user; - - public User getUser() { - return user; - } - - public void setUser(User user) { - this.user = user; - } - - private Project project; - - public Project getProject() { - return project; - } - - public void setProject(Project project) { - this.project = project; - } - - private String description; - - public String getDescription() { - return description; - } - - public void setDescription(String description) { - this.description = description; - } - - private String version; - - public String getVersion() { - return version; - } - - public void setVersion(String version) { - this.version = version; - } - - private String projectData; - - public String getProjectData() { - return projectData; - } - - public void setProjectData(String projectData) { - this.projectData = projectData; - } - - private int workspaceModeInt; - - public int getWorkspaceModeInt() { - return workspaceModeInt; - } - - public void setWorkspaceModeInt(int workspaceModeInt) { - this.workspaceModeInt = workspaceModeInt; - } - - public ModeType getWorkspaceMode() { - if (workspaceModeInt == 1) { - return ModeType.VSS; - } else if (workspaceModeInt == 2) { - return ModeType.SVN; - } else { - // default - return ModeType.VSS; - } - } - - public void setWorkspaceMode(ModeType workspaceModeType) { - if (workspaceModeType == ModeType.VSS) { - workspaceModeInt = 1; - } else if (workspaceModeType == ModeType.SVN) { - workspaceModeInt = 2; - } else { - // default - workspaceModeInt = 1; - } - } - - private String log; - - public String getLog() { - return log; - } - - public void setLog(String log) { - this.log = log; - } - - public void versionUpgrade(int versionPosition) throws Exception { - if (versionPosition > 4 || versionPosition < 1) { - throw new Exception("illegal version position: " + versionPosition); - } - String [] versionList = getVersion().split("\\."); - if (versionList.length != 4) { - throw new Exception("illegal version format: " + getVersion()); - } - Integer integer = Integer.parseInt(versionList[versionPosition - 1]) + 1; - versionList[versionPosition - 1] = integer.toString(); - String newVersion = ""; - for (int i = 0; i < versionList.length; i++) { - newVersion += versionList[i]; - if (i < versionList.length - 1) { - newVersion += "."; - } - } - setVersion(newVersion); - } - - @Override - public String toString() { - return this.toString(ToStringType.NORMAL); - } - public String toString(ToStringType type) { - if (type == ToStringType.NORMAL) { - StringBuilder stringBuilder = new StringBuilder(); - stringBuilder.append("{\"id\":" + getId() + ","); - stringBuilder.append("\"version\":\"" + getVersion() + "\","); - stringBuilder.append("\"userName\":\"" + getUser().getName() + "\","); - stringBuilder.append("\"createDateStr\":\"" + getCreateDateStr() + "\","); - stringBuilder.append("\"description\":\"" + StringUtils.escapeInJ(getDescription()) + "\"}"); - return stringBuilder.toString(); - } else if (type == ToStringType.COMPLETED) { - StringBuilder stringBuilder = new StringBuilder(); - stringBuilder.append("{\"id\":" + getId() + ","); - stringBuilder.append("\"version\":\"" + getVersion() + "\","); - stringBuilder.append("\"userName\":\"" + getUser().getName() + "\","); - stringBuilder.append("\"projectData\":" + getProjectData() + ","); - stringBuilder.append("\"createDateStr\":\"" + getCreateDateStr() + "\","); - stringBuilder.append("\"description\":\"" + StringUtils.escapeInJ(getDescription()) + "\"}"); - return stringBuilder.toString(); - } else { - return this.toString(); - } - } -} \ No newline at end of file diff --git a/src/com/taobao/rigel/rap/workspace/bo/Save.java b/src/com/taobao/rigel/rap/workspace/bo/Save.java deleted file mode 100644 index 591c7782f..000000000 --- a/src/com/taobao/rigel/rap/workspace/bo/Save.java +++ /dev/null @@ -1,96 +0,0 @@ -package com.taobao.rigel.rap.workspace.bo; - -import java.util.Date; - -import com.taobao.rigel.rap.common.DateUtils; -import com.taobao.rigel.rap.project.bo.Project; - -public class Save implements java.io.Serializable { - - private static final long serialVersionUID = 1L; - - public enum TO_STRING_TYPE {WITH_PROJECT_DATA}; - - private int id; - - public int getId() { - return id; - } - - public void setId(int id) { - this.id = id; - } - - private int workspaceId; - - public int getWorkspaceId() { - return workspaceId; - } - - public void setWorkspaceId(int workspaceId) { - this.workspaceId = workspaceId; - } - - private Date updateDate; - - public Date getUpdateDate() { - return updateDate; - } - - public void setUpdateDate(Date updateDate) { - this.updateDate = updateDate; - } - - private String projectData; - - public String getProjectData() { - return projectData; - } - - public void setProjectData(String projectData) { - this.projectData = projectData; - } - - private Project project; - - public Project getProject() { - return project; - } - - public void setProject(Project project) { - this.project = project; - } - - private Workspace workspace; - - public Workspace getWorkspace() { - return workspace; - } - - public void setWorkspace(Workspace workspace) { - this.workspace = workspace; - } - - private int projectId; - - public int getProjectId() { - return projectId; - } - - public void setProjectId(int projectId) { - this.projectId = projectId; - } - - public String toString() { - StringBuilder stringBuilder = new StringBuilder(); - stringBuilder.append("{\"id\":" + getId() + ","); - stringBuilder.append("\"workspaceId\":" + getWorkspaceId() + ","); - stringBuilder.append("\"updateDate\":\"" + getUpdateDateStr() + "\","); - stringBuilder.append("\"projectId\":" + getProjectId() + "}"); - return stringBuilder.toString(); - } - - public String getUpdateDateStr() { - return getUpdateDate() == null ? "" : DateUtils.TIME_FORMAT.format(getUpdateDate()); - } -} diff --git a/src/com/taobao/rigel/rap/workspace/bo/Workspace.java b/src/com/taobao/rigel/rap/workspace/bo/Workspace.java deleted file mode 100644 index 85ae62c87..000000000 --- a/src/com/taobao/rigel/rap/workspace/bo/Workspace.java +++ /dev/null @@ -1,131 +0,0 @@ -package com.taobao.rigel.rap.workspace.bo; - -import java.util.Date; -import java.util.Iterator; -import java.util.List; -import java.util.Set; - -import com.taobao.rigel.rap.account.bo.User; -import com.taobao.rigel.rap.project.bo.Project; - -public class Workspace implements java.io.Serializable { - - private static final long serialVersionUID = 1L; - public enum ModeType {VSS, SVN}; - private int id; - - public int getId() { - return id; - } - - public void setId(int id) { - this.id = id; - } - - public int getModeInt() { - return project.getWorkspaceModeInt(); - } - - public ModeType getModeType() { - return project.getWorkspaceMode(); - } - - private Project project; - - public Project getProject() { - return project; - } - - public void setProject(Project project) { - this.project = project; - } - - private User user; - - public User getUser() { - return user; - } - - public void setUser(User user) { - this.user = user; - } - - private Date createDate; - - public Date getCreateDate() { - return createDate; - } - - public void setCreateDate(Date createDate) { - this.createDate = createDate; - } - - private Date updateDate; - - public Date getUpdateDate() { - return updateDate; - } - - public void setUpdateDate(Date updateDate) { - this.updateDate = updateDate; - } - - private Set saveList; - - public Set getSaveList() { - return saveList; - } - - public void setSaveList(Set saveList) { - this.saveList = saveList; - } - - private String projectData; - - public String getProjectData() { - return projectData; - } - - public void setProjectData(String projectData) { - this.projectData = projectData; - } - - private String projectDataOriginal; - - public String getProjectDataOriginal() { - return projectDataOriginal; - } - - public void setProjectDataOriginal(String projectDataOriginal) { - this.projectDataOriginal = projectDataOriginal; - } - - public String toString() { - StringBuilder stringBuilder = new StringBuilder(); - stringBuilder.append("{\"projectData\":" + getProject().getProjectData() + ","); - stringBuilder.append("\"checkList\":["); - List checkList = getProject().getCheckInListOrdered(); - if (checkList != null) { - Iterator iterator = checkList.iterator(); - while(iterator.hasNext()) { - stringBuilder.append(iterator.next().toString()); - if (iterator.hasNext()) { - stringBuilder.append(", "); - } - } - } - stringBuilder.append("],"); - stringBuilder.append("\"saveList\":["); - if (getSaveList() != null) { - Iterator iterator = getSaveList().iterator(); - while(iterator.hasNext()) { - stringBuilder.append(iterator.next()); - if (iterator.hasNext()) { - stringBuilder.append(", "); - } - } - } - stringBuilder.append("]}"); - return stringBuilder.toString(); - } -} diff --git a/src/com/taobao/rigel/rap/workspace/dao/WorkspaceDao.java b/src/com/taobao/rigel/rap/workspace/dao/WorkspaceDao.java deleted file mode 100644 index a466d7828..000000000 --- a/src/com/taobao/rigel/rap/workspace/dao/WorkspaceDao.java +++ /dev/null @@ -1,30 +0,0 @@ -package com.taobao.rigel.rap.workspace.dao; -import java.util.Set; - -import com.taobao.rigel.rap.workspace.bo.CheckIn; -import com.taobao.rigel.rap.workspace.bo.Save; -import com.taobao.rigel.rap.workspace.bo.Workspace; -public interface WorkspaceDao { - - Workspace getWorkspace(int projectId, long userId); - - int updateSave(Save save); - - Save getSave(int id); - - void updateWorkspace(Workspace workspace); - - Workspace getWorkspace(int id); - - Set getSaveList(int workspaceId); - - void removeSave(int id); - - void addCheckIn(CheckIn checkIn); - - CheckIn getVersion(int versionId); - - CheckIn getVersion(int projectId, String version); - - void prepareForVersionSwitch(CheckIn check); -} diff --git a/src/com/taobao/rigel/rap/workspace/dao/impl/WorkspaceDaoImpl.java b/src/com/taobao/rigel/rap/workspace/dao/impl/WorkspaceDaoImpl.java deleted file mode 100644 index 4a227387a..000000000 --- a/src/com/taobao/rigel/rap/workspace/dao/impl/WorkspaceDaoImpl.java +++ /dev/null @@ -1,144 +0,0 @@ -package com.taobao.rigel.rap.workspace.dao.impl; - -import java.util.Date; -import java.util.Iterator; -import java.util.Set; - -import org.hibernate.HibernateException; -import org.hibernate.Query; -import org.hibernate.Session; -import org.springframework.orm.hibernate3.support.HibernateDaoSupport; - -import com.taobao.rigel.rap.account.bo.User; -import com.taobao.rigel.rap.account.dao.AccountDao; -import com.taobao.rigel.rap.project.bo.Module; -import com.taobao.rigel.rap.project.bo.Project; -import com.taobao.rigel.rap.project.dao.ProjectDao; -import com.taobao.rigel.rap.workspace.bo.CheckIn; -import com.taobao.rigel.rap.workspace.bo.Save; -import com.taobao.rigel.rap.workspace.bo.Workspace; -import com.taobao.rigel.rap.workspace.dao.WorkspaceDao; - -public class WorkspaceDaoImpl extends HibernateDaoSupport implements WorkspaceDao { - - private AccountDao accountDao; - - public AccountDao getAccountDao() { - return accountDao; - } - - public void setAccountDao(AccountDao accountDao) { - this.accountDao = accountDao; - } - - private ProjectDao projectDao; - - public ProjectDao getProjectDao() { - return projectDao; - } - - public void setProjectDao(ProjectDao projectDao) { - this.projectDao = projectDao; - } - - @Override - public Workspace getWorkspace(int projectId, long userId) throws HibernateException { - Session session = getSession(); - Query q = session.createQuery("from Workspace where user.id = :userId and project.id = :projectId"); - q.setInteger("projectId", projectId); - q.setLong("userId", userId); - Workspace workspace = (Workspace) q.uniqueResult(); - if (workspace == null) { - return addWorkspace(projectId, userId); - } else { - return workspace; - } - } - - private Workspace addWorkspace(int projectId, long userId) { - Session session = getSession(); - Project project = (Project)session.get(Project.class, projectId); - if (project == null) { - throw new RuntimeException("project you requested doesn't exist."); - } - Workspace workspace = new Workspace(); - workspace.setUser((User)session.load(User.class, userId)); - workspace.setProject(project); - workspace.setProjectData(project.toString(Project.TO_STRING_TYPE.TO_PARAMETER)); - workspace.setProjectDataOriginal(workspace.getProjectData()); - workspace.setUpdateDate(new Date()); - int id = (Integer)session.save(workspace); - return getWorkspace(id); - } - - @Override - public int updateSave(Save save) { - save.setUpdateDate(new Date()); - Integer id = (Integer)getSession().save(save); - return id; - } - - @Override - public Save getSave(int id) { - Session session = getSession(); - Save save = (Save) session.load(Save.class, id); - return save; - } - - @Override - public void updateWorkspace(Workspace workspace) { - workspace.setUpdateDate(new Date()); - getSession().save(workspace); - } - - @Override - public Workspace getWorkspace(int id) { - Session session = getSession(); - Workspace workspace = (Workspace) session.load(Workspace.class, id); - return workspace; - } - - @Override - public Set getSaveList(int workspaceId) { - return getWorkspace(workspaceId).getSaveList(); - } - - @Override - public void removeSave(int id) { - Session session = getSession(); - Save save = (Save) session.load(Save.class, id); - session.delete(save); - } - - @Override - public void addCheckIn(CheckIn checkIn) { - getSession().save(checkIn); - } - - @Override - public CheckIn getVersion(int versionId) { - return (CheckIn) getSession().load(CheckIn.class, versionId); - } - - @Override - public CheckIn getVersion(int projectId, String version) { - Session session = getSession(); - Query query = session.createQuery("from CheckIn obj where obj.project.id = :projectId and obj.version = :version"); - query.setInteger("projectId", projectId); - query.setString("version", version); - return (CheckIn) query.uniqueResult(); - } - - @Override - public void prepareForVersionSwitch(CheckIn check) { - Session session = getSession(); - Project project = check.getProject(); - Iterator iterator = project.getModuleList().iterator(); - while(iterator.hasNext()) { - Module next = iterator.next(); - session.delete(next); - } - project.getModuleList().clear(); - } - -} diff --git a/src/com/taobao/rigel/rap/workspace/mapping/CheckIn.hbm.xml b/src/com/taobao/rigel/rap/workspace/mapping/CheckIn.hbm.xml deleted file mode 100644 index 53f9f45d6..000000000 --- a/src/com/taobao/rigel/rap/workspace/mapping/CheckIn.hbm.xml +++ /dev/null @@ -1,35 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/src/com/taobao/rigel/rap/workspace/mapping/Save.hbm.xml b/src/com/taobao/rigel/rap/workspace/mapping/Save.hbm.xml deleted file mode 100644 index 7b592cdbf..000000000 --- a/src/com/taobao/rigel/rap/workspace/mapping/Save.hbm.xml +++ /dev/null @@ -1,22 +0,0 @@ - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/src/com/taobao/rigel/rap/workspace/mapping/Workspace.hbm.xml b/src/com/taobao/rigel/rap/workspace/mapping/Workspace.hbm.xml deleted file mode 100644 index 6e69f215e..000000000 --- a/src/com/taobao/rigel/rap/workspace/mapping/Workspace.hbm.xml +++ /dev/null @@ -1,30 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/src/com/taobao/rigel/rap/workspace/service/WorkspaceMgr.java b/src/com/taobao/rigel/rap/workspace/service/WorkspaceMgr.java deleted file mode 100644 index b5e293915..000000000 --- a/src/com/taobao/rigel/rap/workspace/service/WorkspaceMgr.java +++ /dev/null @@ -1,109 +0,0 @@ -package com.taobao.rigel.rap.workspace.service; - -import java.util.Set; - -import com.taobao.rigel.rap.workspace.bo.CheckIn; -import com.taobao.rigel.rap.workspace.bo.Save; -import com.taobao.rigel.rap.workspace.bo.Workspace; - -public interface WorkspaceMgr { - - /** - * get workspace obj - * - * @param projectId - * @param userId - * @return - */ - Workspace getWorkspace(int projectId, long userId); - - /** - * update save - * - * @param save - * @return - */ - int updateSave(Save save); - - /** - * get one save - * - * @param id - * @return - */ - Save getSave(int id); - - /** - * update workspace - * - * @param workspace - */ - void updateWorkspace(Workspace workspace); - - /** - * get workspace - * - * @param id - * @return - */ - Workspace getWorkspace(int id); - - /** - * get save list - * - * @param workspaceId - * @return - */ - Set getSaveList(int workspaceId); - - /** - * remove save - * - * @param id - */ - void removeSave(int id); - - /*** - * workspace check out - * - * @param jsonList - * [0]:projectData, [1]: projectDataOriginal - * @param userId - * @param projectId - * @return - */ - String checkOut(String[] jsonList, long userId, int projectId); - - /*** - * workspace check in - * - * @param jsonList - * [0]:projectData [1]: projectDataOriginal - * @param userId - * @param projectId - * @return - */ - String checkIn(String[] jsonList, long userId, int projectId); - - /** - * add new check in log - * - * @param checkIn - */ - void addCheckIn(CheckIn checkIn); - - /** - * get {@link CheckIn} obj - * - * @param versionId - * @return - */ - CheckIn getVersion(int versionId); - - /** - * do sth. preparing for version switch - * - * @param check - */ - void prepareForVersionSwitch(CheckIn check); -} diff --git a/src/com/taobao/rigel/rap/workspace/service/impl/WorkspaceMgrImpl.java b/src/com/taobao/rigel/rap/workspace/service/impl/WorkspaceMgrImpl.java deleted file mode 100644 index 3acd6fdb8..000000000 --- a/src/com/taobao/rigel/rap/workspace/service/impl/WorkspaceMgrImpl.java +++ /dev/null @@ -1,677 +0,0 @@ -package com.taobao.rigel.rap.workspace.service.impl; - -import java.util.Iterator; -import java.util.Set; - -import com.taobao.rigel.rap.project.bo.Action; -import com.taobao.rigel.rap.project.bo.Module; -import com.taobao.rigel.rap.project.bo.Page; -import com.taobao.rigel.rap.project.bo.Parameter; -import com.taobao.rigel.rap.project.bo.Project; -import com.taobao.rigel.rap.project.dao.ProjectDao; -import com.taobao.rigel.rap.workspace.bo.CheckIn; -import com.taobao.rigel.rap.workspace.bo.Save; -import com.taobao.rigel.rap.workspace.bo.Workspace; -import com.taobao.rigel.rap.workspace.dao.WorkspaceDao; -import com.taobao.rigel.rap.workspace.service.WorkspaceMgr; -import com.google.gson.Gson; - -public class WorkspaceMgrImpl implements WorkspaceMgr { - - private WorkspaceDao workspaceDao; - - public WorkspaceDao getWorkspaceDao() { - return this.workspaceDao; - } - - public void setWorkspaceDao(WorkspaceDao workspaceDao) { - this.workspaceDao = workspaceDao; - } - - private ProjectDao projectDao; - - public ProjectDao getProjectDao() { - return projectDao; - } - - public void setProjectDao(ProjectDao projectDao) { - this.projectDao = projectDao; - } - - @Override - public Workspace getWorkspace(int projectId, long userId) { - Workspace workspace = workspaceDao.getWorkspace(projectId, userId); - return workspace; - } - - @Override - public int updateSave(Save save) { - return workspaceDao.updateSave(save); - } - - @Override - public Save getSave(int id) { - return workspaceDao.getSave(id); - } - - @Override - public void updateWorkspace(Workspace workspace) { - workspaceDao.updateWorkspace(workspace); - - } - - @Override - public Workspace getWorkspace(int id) { - return workspaceDao.getWorkspace(id); - } - - @Override - public Set getSaveList(int workspaceId) { - return workspaceDao.getSaveList(workspaceId); - } - - @Override - public void removeSave(int id) { - workspaceDao.removeSave(id); - } - - @Override - public String checkIn(String [] jsonList, long userId, int projectId) { - //[TODO] does user has access? - StringBuilder log = new StringBuilder(); - Project projectClient, projectOriginal, projectServer; - Gson gson = new Gson(); - // get server workspace - projectServer = projectDao.getProject(projectId); - // parse client workspace - projectClient = gson.fromJson(jsonList[0], Project.class); - // parse original client workspace - projectOriginal = gson.fromJson(jsonList[1], Project.class); - - /** - * start processing ... - * update a(client) => b(server) compared with o (Original) - */ - - // search moduleList - Iterator moduleIterator = projectClient.getModuleList().iterator(); - while (moduleIterator.hasNext()) { - Module moduleA = moduleIterator.next(); - // scan module - Module moduleB = findModule(projectServer, moduleA.getId()); - if (moduleB == null) { - log.append(logTemplate(moduleA.getId(), "module", "add", null, null, null)); - projectServer.getModuleList().add(moduleA); - continue; - } - Module moduleO = findModule(projectOriginal, moduleA.getId()); - if (!moduleA.getName().equals(moduleB.getName())) { - boolean aChanged = (!moduleA.getName().equals(moduleO.getName())); - boolean bChanged = (!moduleB.getName().equals(moduleO.getName())); - - if (aChanged && bChanged) { - // [TODO] conflict! - } else if (aChanged && !bChanged) { - // update - log.append(logTemplate(moduleB.getId(), "module", "update", - moduleA.getName(), moduleB.getName(), "name")); - moduleB.setName(moduleA.getName()); - } else if (!aChanged && bChanged){ - // ignore - } - } - if (!moduleA.getIntroduction().equals(moduleB.getIntroduction())) { - boolean aChanged = (!moduleA.getIntroduction().equals(moduleO.getIntroduction())); - boolean bChanged = (!moduleB.getIntroduction().equals(moduleO.getIntroduction())); - - if (aChanged && bChanged) { - // [TODO] conflict! - } else if (aChanged && !bChanged) { - // update - log.append(logTemplate(moduleB.getId(), "module", "update", - moduleA.getIntroduction(), moduleB.getIntroduction(), "introduction")); - moduleB.setIntroduction(moduleA.getIntroduction()); - } else if (!aChanged && bChanged){ - // ignore - } - } - // search pageList - Iterator pageIterator = moduleA.getPageList().iterator(); - while (pageIterator.hasNext()) { - Page pageA = pageIterator.next(); - // scan page - Page pageB = findPage(projectServer, pageA.getId()); - if (pageB == null) { - moduleB.getPageList().add(pageA); - continue; - } - Page pageO = findPage(projectOriginal, pageA.getId()); - if (!pageA.getName().equals(pageB.getName())) { - boolean aChanged = (!pageA.getName().equals(pageO.getName())); - boolean bChanged = (!pageB.getName().equals(pageO.getName())); - - if (aChanged && bChanged) { - // [TODO] conflict! - } else if (aChanged && !bChanged) { - // update - log.append(logTemplate(pageB.getId(), "page", "update", - pageA.getName(), pageB.getName(), "name")); - pageB.setName(pageA.getName()); - } else if (!aChanged && bChanged){ - // ignore - } - } - if (!pageA.getIntroduction().equals(pageB.getIntroduction())) { - boolean aChanged = (!pageA.getIntroduction().equals(pageO.getIntroduction())); - boolean bChanged = (!pageB.getIntroduction().equals(pageO.getIntroduction())); - - if (aChanged && bChanged) { - // [TODO] conflict! - } else if (aChanged && !bChanged) { - // update - log.append(logTemplate(pageB.getId(), "page", "update", - pageA.getIntroduction(), pageB.getIntroduction(), "introduction")); - pageB.setIntroduction(pageA.getIntroduction()); - } else if (!aChanged && bChanged){ - // ignore - } - } - // search actionList - Iterator actionIterator = pageA.getActionList().iterator(); - while (actionIterator.hasNext()) { - Action actionA = actionIterator.next(); - // scan action - Action actionB = findAction(projectServer, actionA.getId()); - if (actionB == null) { - pageB.getActionList().add(actionA); - continue; - } - - Action actionO = findAction(projectOriginal, actionA.getId()); - if (!actionA.getName().equals(actionB.getName())) { - boolean aChanged = (!actionA.getName().equals(actionO.getName())); - boolean bChanged = (!actionB.getName().equals(actionO.getName())); - - if (aChanged && bChanged) { - // [TODO] conflict! - } else if (aChanged && !bChanged) { - // update - log.append(logTemplate(Integer.parseInt(new Long(actionB.getId()).toString()), "action", "update", - actionA.getName(), actionB.getName(), "name")); - actionB.setName(actionA.getName()); - } else if (!aChanged && bChanged){ - // ignore - } - } - if (!actionA.getDescription().equals(actionB.getDescription())) { - boolean aChanged = (!actionA.getDescription().equals(actionO.getDescription())); - boolean bChanged = (!actionB.getDescription().equals(actionO.getDescription())); - - if (aChanged && bChanged) { - // [TODO] conflict! - } else if (aChanged && !bChanged) { - // update - log.append(logTemplate(Integer.parseInt(new Long(actionB.getId()).toString()), "action", "update", - actionA.getDescription(), actionB.getDescription(), "description")); - actionB.setDescription(actionA.getDescription()); - } else if (!aChanged && bChanged){ - // ignore - } - } - if (!actionA.getRequestType().equals(actionB.getRequestType())) { - boolean aChanged = (!actionA.getRequestType().equals(actionO.getRequestType())); - boolean bChanged = (!actionB.getRequestType().equals(actionO.getRequestType())); - - if (aChanged && bChanged) { - // [TODO] conflict! - } else if (aChanged && !bChanged) { - // update - log.append(logTemplate(Integer.parseInt(new Long(actionB.getId()).toString()), "action", "update", - actionA.getRequestType(), actionB.getRequestType(), "requestType")); - actionB.setRequestType(actionA.getRequestType()); - } else if (!aChanged && bChanged){ - // ignore - } - } - if (!actionA.getRequestUrl().equals(actionB.getRequestUrl())) { - boolean aChanged = (!actionA.getRequestUrl().equals(actionO.getRequestUrl())); - boolean bChanged = (!actionB.getRequestUrl().equals(actionO.getRequestUrl())); - - if (aChanged && bChanged) { - // [TODO] conflict! - } else if (aChanged && !bChanged) { - // update - log.append(logTemplate(Integer.parseInt(new Long(actionB.getId()).toString()), "action", "update", - actionA.getRequestUrl(), actionB.getRequestUrl(), "requestUrl")); - actionB.setRequestUrl(actionA.getRequestUrl()); - } else if (!aChanged && bChanged){ - // ignore - } - } - if (!actionA.getResponseTemplate().equals(actionB.getResponseTemplate())) { - boolean aChanged = (!actionA.getResponseTemplate().equals(actionO.getResponseTemplate())); - boolean bChanged = (!actionB.getResponseTemplate().equals(actionO.getResponseTemplate())); - - if (aChanged && bChanged) { - // [TODO] conflict! - } else if (aChanged && !bChanged) { - // update - log.append(logTemplate(Integer.parseInt(new Long(actionB.getId()).toString()), "action", "update", - actionA.getResponseTemplate(), actionB.getResponseTemplate(), "responseTemplate")); - actionB.setResponseTemplate(actionA.getResponseTemplate()); - } else if (!aChanged && bChanged){ - // ignore - } - } - // search requestParameterList - Iterator requestParameterIterator = actionA.getRequestParameterList().iterator(); - while (requestParameterIterator.hasNext()) { - Parameter parameterA = requestParameterIterator.next(); - // scan request parameter - Parameter parameterB = findParameter(projectServer, parameterA.getId(), true); - if (parameterB == null) { - actionB.getRequestParameterList().add(parameterA); - continue; - } - Parameter parameterO = findParameter(projectOriginal, parameterA.getId(), true); - processParameter(parameterA, parameterB, parameterO, log); - } - - // search responseParameterList - Iterator responseParameterIterator = actionA.getResponseParameterList().iterator(); - while (responseParameterIterator.hasNext()) { - Parameter parameterA = responseParameterIterator.next(); - // scan response parameter - Parameter parameterB = findParameter(projectClient, parameterA.getId(), false); - if (parameterB == null) { - actionB.getResponseParameterList().add(parameterA); - continue; - } - Parameter parameterO = findParameter(projectOriginal, parameterA.getId(), false); - processParameter(parameterA, parameterB, parameterO, log); - } - } - } - - } - projectDao.updateProject(projectServer); - projectServer = projectDao.getProject(projectId); - return "{\"projectData\":" + projectServer.toString() + ", \"log\":\"" + log - + "\", \"projectDataOriginal\":" + projectServer.toString()+"}"; - } - - @Override - public String checkOut(String [] jsonList, long userId, int projectId) { - //[TODO] does user has access? - - StringBuilder log = new StringBuilder(); - Project projectClient, projectOriginal, projectServer; - Gson gson = new Gson(); - // get server workspace - projectServer = projectDao.getProject(projectId); - // parse client workspace - projectClient = gson.fromJson(jsonList[0], Project.class); - // parse original client workspace - projectOriginal = gson.fromJson(jsonList[1], Project.class); - - /** - * start processing ... - * update a(Server) => b(client) compared with o (Original) - */ - - // search moduleList - Iterator moduleIterator = projectServer.getModuleList().iterator(); - while (moduleIterator.hasNext()) { - Module moduleA = moduleIterator.next(); - // scan module - Module moduleB = findModule(projectClient, moduleA.getId()); - if (moduleB == null) { - log.append(logTemplate(moduleA.getId(), "module", "add", null, null, null)); - projectClient.getModuleList().add(moduleA); - continue; - } - Module moduleO = findModule(projectOriginal, moduleA.getId()); - if (!moduleA.getName().equals(moduleB.getName())) { - boolean aChanged = (!moduleA.getName().equals(moduleO.getName())); - boolean bChanged = (!moduleB.getName().equals(moduleO.getName())); - - if (aChanged && bChanged) { - // [TODO] conflict! - } else if (aChanged && !bChanged) { - // update - log.append(logTemplate(moduleB.getId(), "module", "update", - moduleA.getName(), moduleB.getName(), "name")); - moduleB.setName(moduleA.getName()); - } else if (!aChanged && bChanged){ - // ignore - } - } - if (!moduleA.getIntroduction().equals(moduleB.getIntroduction())) { - boolean aChanged = (!moduleA.getIntroduction().equals(moduleO.getIntroduction())); - boolean bChanged = (!moduleB.getIntroduction().equals(moduleO.getIntroduction())); - - if (aChanged && bChanged) { - // [TODO] conflict! - } else if (aChanged && !bChanged) { - // update - log.append(logTemplate(moduleB.getId(), "module", "update", - moduleA.getIntroduction(), moduleB.getIntroduction(), "introduction")); - moduleB.setIntroduction(moduleA.getIntroduction()); - } else if (!aChanged && bChanged){ - // ignore - } - } - // search pageList - Iterator pageIterator = moduleA.getPageList().iterator(); - while (pageIterator.hasNext()) { - Page pageA = pageIterator.next(); - // scan page - Page pageB = findPage(projectClient, pageA.getId()); - if (pageB == null) { - moduleB.getPageList().add(pageA); - continue; - } - Page pageO = findPage(projectOriginal, pageA.getId()); - if (!pageA.getName().equals(pageB.getName())) { - boolean aChanged = (!pageA.getName().equals(pageO.getName())); - boolean bChanged = (!pageB.getName().equals(pageO.getName())); - - if (aChanged && bChanged) { - // [TODO] conflict! - } else if (aChanged && !bChanged) { - // update - log.append(logTemplate(pageB.getId(), "page", "update", - pageA.getName(), pageB.getName(), "name")); - pageB.setName(pageA.getName()); - } else if (!aChanged && bChanged){ - // ignore - } - } - if (!pageA.getIntroduction().equals(pageB.getIntroduction())) { - boolean aChanged = (!pageA.getIntroduction().equals(pageO.getIntroduction())); - boolean bChanged = (!pageB.getIntroduction().equals(pageO.getIntroduction())); - - if (aChanged && bChanged) { - // [TODO] conflict! - } else if (aChanged && !bChanged) { - // update - log.append(logTemplate(pageB.getId(), "page", "update", - pageA.getIntroduction(), pageB.getIntroduction(), "introduction")); - pageB.setIntroduction(pageA.getIntroduction()); - } else if (!aChanged && bChanged){ - // ignore - } - } - // search actionList - Iterator actionIterator = pageA.getActionList().iterator(); - while (actionIterator.hasNext()) { - Action actionA = actionIterator.next(); - // scan action - Action actionB = findAction(projectClient, actionA.getId()); - if (actionB == null) { - pageB.getActionList().add(actionA); - continue; - } - - Action actionO = findAction(projectOriginal, actionA.getId()); - if (!actionA.getName().equals(actionB.getName())) { - boolean aChanged = (!actionA.getName().equals(actionO.getName())); - boolean bChanged = (!actionB.getName().equals(actionO.getName())); - - if (aChanged && bChanged) { - // [TODO] conflict! - } else if (aChanged && !bChanged) { - // update - log.append(logTemplate(Integer.parseInt(new Long(actionB.getId()).toString()), "action", "update", - actionA.getName(), actionB.getName(), "name")); - actionB.setName(actionA.getName()); - } else if (!aChanged && bChanged){ - // ignore - } - } - if (!actionA.getDescription().equals(actionB.getDescription())) { - boolean aChanged = (!actionA.getDescription().equals(actionO.getDescription())); - boolean bChanged = (!actionB.getDescription().equals(actionO.getDescription())); - - if (aChanged && bChanged) { - // [TODO] conflict! - } else if (aChanged && !bChanged) { - // update - log.append(logTemplate(Integer.parseInt(new Long(actionB.getId()).toString()), "action", "update", - actionA.getDescription(), actionB.getDescription(), "description")); - actionB.setDescription(actionA.getDescription()); - } else if (!aChanged && bChanged){ - // ignore - } - } - if (!actionA.getRequestType().equals(actionB.getRequestType())) { - boolean aChanged = (!actionA.getRequestType().equals(actionO.getRequestType())); - boolean bChanged = (!actionB.getRequestType().equals(actionO.getRequestType())); - - if (aChanged && bChanged) { - // [TODO] conflict! - } else if (aChanged && !bChanged) { - // update - log.append(logTemplate(Integer.parseInt(new Long(actionB.getId()).toString()), "action", "update", - actionA.getRequestType(), actionB.getRequestType(), "requestType")); - actionB.setRequestType(actionA.getRequestType()); - } else if (!aChanged && bChanged){ - // ignore - } - } - if (!actionA.getRequestUrl().equals(actionB.getRequestUrl())) { - boolean aChanged = (!actionA.getRequestUrl().equals(actionO.getRequestUrl())); - boolean bChanged = (!actionB.getRequestUrl().equals(actionO.getRequestUrl())); - - if (aChanged && bChanged) { - // [TODO] conflict! - } else if (aChanged && !bChanged) { - // update - log.append(logTemplate(Integer.parseInt(new Long(actionB.getId()).toString()), "action", "update", - actionA.getRequestUrl(), actionB.getRequestUrl(), "requestUrl")); - actionB.setRequestUrl(actionA.getRequestUrl()); - } else if (!aChanged && bChanged){ - // ignore - } - } - if (!actionA.getResponseTemplate().equals(actionB.getResponseTemplate())) { - boolean aChanged = (!actionA.getResponseTemplate().equals(actionO.getResponseTemplate())); - boolean bChanged = (!actionB.getResponseTemplate().equals(actionO.getResponseTemplate())); - - if (aChanged && bChanged) { - // [TODO] conflict! - } else if (aChanged && !bChanged) { - // update - log.append(logTemplate(Integer.parseInt(new Long(actionB.getId()).toString()), "action", "update", - actionA.getResponseTemplate(), actionB.getResponseTemplate(), "responseTemplate")); - actionB.setResponseTemplate(actionA.getResponseTemplate()); - } else if (!aChanged && bChanged){ - // ignore - } - } - // search requestParameterList - Iterator requestParameterIterator = actionA.getRequestParameterList().iterator(); - while (requestParameterIterator.hasNext()) { - Parameter parameterA = requestParameterIterator.next(); - // scan request parameter - Parameter parameterB = findParameter(projectClient, parameterA.getId(), true); - if (parameterB == null) { - actionB.getRequestParameterList().add(parameterA); - continue; - } - Parameter parameterO = findParameter(projectOriginal, parameterA.getId(), true); - processParameter(parameterA, parameterB, parameterO, log); - } - - // search responseParameterList - Iterator responseParameterIterator = actionA.getResponseParameterList().iterator(); - while (responseParameterIterator.hasNext()) { - Parameter parameterA = responseParameterIterator.next(); - // scan response parameter - Parameter parameterB = findParameter(projectClient, parameterA.getId(), false); - if (parameterB == null) { - actionB.getResponseParameterList().add(parameterA); - continue; - } - Parameter parameterO = findParameter(projectOriginal, parameterA.getId(), false); - processParameter(parameterA, parameterB, parameterO, log); - } - } - } - - } - return "{\"projectData\":" + projectClient.toString() + ", \"log\":\"" - + log + "\", \"projectDataOriginal\":" + projectClient.toString() + "}"; - } - - - private void processParameter(Parameter parameterA, Parameter parameterB, - Parameter parameterO, StringBuilder log) { - if (!parameterA.getName().equals(parameterB.getName())) { - boolean aChanged = (!parameterA.getName().equals(parameterO.getName())); - boolean bChanged = (!parameterB.getName().equals(parameterO.getName())); - - if (aChanged && bChanged) { - // [TODO] conflict! - } else if (aChanged && !bChanged) { - // update - log.append(logTemplate(parameterB.getId(), "parameter", "update", - parameterA.getName(), parameterB.getName(), "name")); - parameterB.setName(parameterA.getName()); - } else if (!aChanged && bChanged){ - // ignore - } - } - if (!parameterA.getDataType().equals(parameterB.getDataType())) { - boolean aChanged = (!parameterA.getDataType().equals(parameterO.getDataType())); - boolean bChanged = (!parameterB.getDataType().equals(parameterO.getDataType())); - - if (aChanged && bChanged) { - // [TODO] conflict! - } else if (aChanged && !bChanged) { - // update - log.append(logTemplate(parameterB.getId(), "parameter", "update", - parameterA.getDataType(), parameterB.getDataType(), "dataType")); - parameterB.setDataType(parameterA.getDataType()); - } else if (!aChanged && bChanged){ - // ignore - } - } - if (!parameterA.getIdentifier().equals(parameterB.getIdentifier())) { - boolean aChanged = (!parameterA.getIdentifier().equals(parameterO.getIdentifier())); - boolean bChanged = (!parameterB.getIdentifier().equals(parameterO.getIdentifier())); - - if (aChanged && bChanged) { - // [TODO] conflict! - } else if (aChanged && !bChanged) { - // update - log.append(logTemplate(parameterB.getId(), "parameter", "update", - parameterA.getIdentifier(), parameterB.getIdentifier(), "identifier")); - parameterB.setIdentifier(parameterA.getIdentifier()); - } else if (!aChanged && bChanged){ - // ignore - } - } - if (!parameterA.getRemark().equals(parameterB.getRemark())) { - boolean aChanged = (!parameterA.getRemark().equals(parameterO.getRemark())); - boolean bChanged = (!parameterB.getRemark().equals(parameterO.getRemark())); - - if (aChanged && bChanged) { - // [TODO] conflict! - } else if (aChanged && !bChanged) { - // update - log.append(logTemplate(parameterB.getId(), "parameter", "update", - parameterA.getRemark(), parameterB.getRemark(), "remark")); - parameterB.setRemark(parameterA.getRemark()); - } else if (!aChanged && bChanged){ - // ignore - } - } - if (!parameterA.getValidator().equals(parameterB.getValidator())) { - boolean aChanged = (!parameterA.getValidator().equals(parameterO.getValidator())); - boolean bChanged = (!parameterB.getValidator().equals(parameterO.getValidator())); - - if (aChanged && bChanged) { - // [TODO] conflict! - } else if (aChanged && !bChanged) { - // update - log.append(logTemplate(parameterB.getId(), "parameter", "update", - parameterA.getValidator(), parameterB.getValidator(), "validator")); - parameterB.setValidator(parameterA.getValidator()); - } else if (!aChanged && bChanged){ - // ignore - } - } - } - - private Module findModule(Project p, int moduleId) { - for (Module i : p.getModuleList()) { - if (i.getId() == moduleId) - return i; - } - return null; - } - - private Page findPage(Project p, int pageId) { - for (Module module : p.getModuleList()) { - for (Page page : module.getPageList()) { - if (page.getId() == pageId) - return page; - } - } - return null; - } - - private Action findAction(Project p, long actionId) { - for (Module module : p.getModuleList()) { - for (Page page : module.getPageList()) { - for (Action action : page.getActionList()) { - if (action.getId() == actionId) - return action; - } - } - } - return null; - } - - private Parameter findParameter(Project p, int parameterId, boolean isRequestType) { - for (Module module : p.getModuleList()) { - for (Page page : module.getPageList()) { - for (Action action : page.getActionList()) { - for (Parameter parameter : (isRequestType ? - action.getRequestParameterList() : action.getResponseParameterList())) { - if (parameter.getId() == parameterId) - return parameter; - } - } - } - } - return null; - } - - - private String logTemplate(int objectId, String className, - String operationName, String newValue, String oldValue, String property) { - return operationName == "add" ? - "

    " + operationName + " " + className + " [" + objectId - + "]
    " - :"
    " + operationName + " " + className + " [" + objectId - + "]." + property + " from [" + oldValue + "] to [" + newValue + "]
    "; - } - - @Override - public void addCheckIn(CheckIn checkIn) { - workspaceDao.addCheckIn(checkIn); - } - - @Override - public CheckIn getVersion(int versionId) { - return workspaceDao.getVersion(versionId); - } - - @Override - public void prepareForVersionSwitch(CheckIn check) { - workspaceDao.prepareForVersionSwitch(check); - - } -} diff --git a/src/com/taobao/rigel/rap/workspace/web/action/WorkspaceAction.java b/src/com/taobao/rigel/rap/workspace/web/action/WorkspaceAction.java deleted file mode 100644 index 8727b0779..000000000 --- a/src/com/taobao/rigel/rap/workspace/web/action/WorkspaceAction.java +++ /dev/null @@ -1,647 +0,0 @@ -package com.taobao.rigel.rap.workspace.web.action; - -import java.io.ByteArrayInputStream; -import java.io.InputStream; -import java.io.StringWriter; -import java.util.*; -import java.util.concurrent.Callable; -import java.util.concurrent.FutureTask; - -import com.google.gson.Gson; -import com.taobao.rigel.rap.organization.service.OrganizationMgr; -import org.apache.velocity.Template; -import org.apache.velocity.VelocityContext; -import org.apache.velocity.app.VelocityEngine; -import org.apache.velocity.exception.MethodInvocationException; -import org.apache.velocity.exception.ParseErrorException; -import org.apache.velocity.exception.ResourceNotFoundException; - -import com.taobao.rigel.rap.account.bo.Notification; -import com.taobao.rigel.rap.account.bo.User; -import com.taobao.rigel.rap.common.ActionBase; -import com.taobao.rigel.rap.common.ContextManager; -import com.taobao.rigel.rap.common.MapUtils; -import com.taobao.rigel.rap.project.bo.Module; -import com.taobao.rigel.rap.project.bo.Project; -import com.taobao.rigel.rap.project.service.ProjectMgr; -import com.taobao.rigel.rap.workspace.bo.CheckIn; -import com.taobao.rigel.rap.workspace.bo.Save; -import com.taobao.rigel.rap.workspace.bo.Workspace; -import com.taobao.rigel.rap.workspace.service.WorkspaceMgr; - -public class WorkspaceAction extends ActionBase { - - private static final long serialVersionUID = 1L; - - public OrganizationMgr getOrganizationMgr() { - return organizationMgr; - } - - public void setOrganizationMgr(OrganizationMgr organizationMgr) { - this.organizationMgr = organizationMgr; - } - - private OrganizationMgr organizationMgr; - - private boolean accessable; - - public boolean isAccessable() { - return accessable; - } - - public void setAccessable(boolean accessable) { - this.accessable = accessable; - } - - private boolean mock; - - private int actionId; - - public int getActionId() { - return actionId; - } - - public void setActionId(int actionId) { - this.actionId = actionId; - } - - public boolean isMock() { - return mock; - } - - public void setMock(boolean mock) { - this.mock = mock; - } - - private int id; - - public int getId() { - return this.id; - } - - public void setId(int id) { - this.id = id; - } - - private String workspaceJsonString; - - public String getWorkspaceJsonString() { - return this.workspaceJsonString; - } - - public void setWorkspaceJsonString(String workspaceJsonString) { - this.workspaceJsonString = workspaceJsonString; - } - - private Workspace workspace; - - public Workspace getWorkspace() { - return this.workspace; - } - - public void setWorkspace(Workspace workspace) { - this.workspace = workspace; - } - - public Module module; - - public Module getModule() { - return this.module; - } - - public void setModule(Module module) { - this.module = module; - } - - private VelocityEngine velocityEngine; - - public VelocityEngine getVelocityEngine() { - return velocityEngine; - } - - public void setVelocityEngine(VelocityEngine velocityEngine) { - this.velocityEngine = velocityEngine; - } - - private int projectId; - - private Project project; - - public Project getProject() { - return project; - } - - public void setProject(Project project) { - this.project = project; - } - - public int getProjectId() { - return this.projectId; - } - - public void setProjectId(int projectId) { - this.projectId = projectId; - } - - private String projectData; - - public String getProjectData() { - return projectData; - } - - public void setProjectData(String projectData) { - this.projectData = projectData; - } - - private String projectDataOriginal; - - public String getProjectDataOriginal() { - return projectDataOriginal; - } - - public void setProjectDataOriginal(String projectDataOriginal) { - this.projectDataOriginal = projectDataOriginal; - } - - private String saveListJson; - - public String getSaveListJson() { - return saveListJson; - } - - public void setSaveListJson(String saveListJson) { - this.saveListJson = saveListJson; - } - - private int saveId = -1; - - public int getSaveId() { - return saveId; - } - - public void setSaveId(int saveId) { - this.saveId = saveId; - } - - private Save save; - - public Save getSave() { - return save; - } - - public void setSave(Save save) { - this.save = save; - } - - private int versionId; - - public int getVersionId() { - return versionId; - } - - public void setVersionId(int versionId) { - this.versionId = versionId; - } - - private String deletedObjectListData; - - public String getDeletedObjectListData() { - return deletedObjectListData; - } - - public void setDeletedObjectListData(String deletedObjectListData) { - this.deletedObjectListData = deletedObjectListData; - } - - private String tag; - - public String getTag() { - return tag; - } - - public void setTag(String tag) { - this.tag = tag; - } - - /** - * from 1 to 4, version position - */ - private int versionPosition; - - public int getVersionPosition() { - return versionPosition; - } - - public void setVersionPosition(int versionPosition) { - this.versionPosition = versionPosition; - } - - private String description; - - public String getDescription() { - return description; - } - - public void setDescription(String description) { - this.description = description; - } - - private boolean isLocked; - - public boolean getIsLocked() { - return isLocked; - } - - public void setIsLocked(boolean isLocked) { - this.isLocked = isLocked; - } - - private static final org.apache.logging.log4j.Logger logger = org.apache.logging.log4j.LogManager.getFormatterLogger(WorkspaceAction.class.getName()); - - public String myWorkspace() { - if (!isUserLogined()) { - plsLogin(); - setRelativeReturnUrl("/workspace/myWorkspace.action?projectId=" - + projectId); - return LOGIN; - } - Project p = projectMgr.getProject(getProjectId()); - if (p == null || p.getId() <= 0) { - setErrMsg("该项目不存在或已被删除,会不会是亲这个链接保存的太久了呢?0 .0"); - logger.error("Unexpected project id=%d", getProjectId()); - return ERROR; - } - if (!organizationMgr.canUserAccessProject(getCurUserId(), getProjectId())) { - setErrMsg(ACCESS_DENY); - return ERROR; - } - - Workspace workspace = new Workspace(); - workspace.setProject(p); - setWorkspaceJsonString(workspace.toString()); - setWorkspace(workspace); - setAccessable(getAccountMgr().canUserManageProject(getCurUserId(), getProjectId())); - return SUCCESS; - } - - private InputStream fileInputStream; - - /** - * save workspace if this.saveId == -1(default), it's a new save and needs - * projectId and id(workspaceId). else, just need saveId only to cover the - * existed one. all conditions parameters: projectData - * - * @return - */ - /* - * public String updateSave() { int id = getSaveId(); Save save = null; if - * (id == -1) { save = new Save(); save.setProjectId(getProjectId()); - * save.setWorkspaceId(getId()); } else { save = - * workspaceMgr.getSave(getSaveId()); } - * save.setProjectData(getProjectData()); id = - * workspaceMgr.updateSave(save); - * - * // after update the save, return saveList json string - * setupSaveListJson(); return SUCCESS; } - */ - - /* - * private void setupSaveListJson() { Set saveList = - * workspaceMgr.getSaveList(getId()); StringBuilder stringBuilder = new - * StringBuilder(); stringBuilder.append("["); Iterator iterator = - * saveList.iterator(); while (iterator.hasNext()) { - * stringBuilder.append(iterator.next()); if (iterator.hasNext()) { - * stringBuilder.append(","); } } stringBuilder.append("]"); - * setSaveListJson(stringBuilder.toString()); } - */ - - /** - * delete save - * - * @return - */ - /* - * public String removeSave() { workspaceMgr.removeSave(getSaveId()); - * setupSaveListJson(); return SUCCESS; } - */ - - /** - * load save, saveId must be significant, or operation failed - * - * @return the save object loaded - */ - /* - * public String querySave() { - * setJson(workspaceMgr.getSave(getSaveId()).getProjectData()); return - * SUCCESS; } - */ - - public InputStream getFileInputStream() { - return fileInputStream; - } - - /** - * ` save the current workspace - * - * @return - */ - /* - * public String updateCurrentSave() { Workspace workspace = - * workspaceMgr.getWorkspace(getId()); - * workspace.setProjectData(getProjectData()); - * workspaceMgr.updateWorkspace(workspace); return SUCCESS; } - */ - - private WorkspaceMgr workspaceMgr; - - public WorkspaceMgr getworkspaceMgr() { - return workspaceMgr; - } - - public void setWorkspaceMgr(WorkspaceMgr workspaceMgr) { - this.workspaceMgr = workspaceMgr; - } - - private ProjectMgr projectMgr; - - public ProjectMgr projectMgr() { - return this.projectMgr; - } - - public void setProjectMgr(ProjectMgr projectMgr) { - this.projectMgr = projectMgr; - } - - /** - public String ping() { - setJson("{\"isOk\":true}"); - return SUCCESS; - } - */ - - public String queryVersion() { - setJson(workspaceMgr.getVersion(getVersionId()).toString( - CheckIn.ToStringType.COMPLETED)); - return SUCCESS; - } - - public String switchVersion() { - CheckIn check = workspaceMgr.getVersion(getVersionId()); - workspaceMgr.prepareForVersionSwitch(check); - projectMgr.updateProject(check.getProject().getId(), - check.getProjectData(), "[]", new HashMap()); - Project project = projectMgr.getProject(check.getProject().getId()); - String projectData = project - .toString(Project.TO_STRING_TYPE.TO_PARAMETER); - setJson("{\"projectData\":" + projectData + ", \"isOk\":true}"); - project.setProjectData(projectData); - projectMgr.updateProject(project); - return SUCCESS; - } - - public String checkIn() throws Exception { - User curUser = getAccountMgr().getUser(getCurUserId()); - if (curUser == null) { - setErrMsg(LOGIN_WARN_MSG); - logger.error("Unlogined user trying to checkin and failed."); - return JSON_ERROR; - } - - if (!getAccountMgr().canUserManageProject(getCurUserId(), getId())) { - setErrMsg("access deny"); - logger.error("User %s trying to checkedin project(id=$d) and denied.", getCurUserAccount(), getId()); - return JSON_ERROR; - } - - // update project - Map actionIdMap = new HashMap(); - projectMgr.updateProject(getId(), getProjectData(), - getDeletedObjectListData(), actionIdMap); - - - project = projectMgr.getProject(getId()); - - // generate one check-in of VSS mode submit - CheckIn checkIn = new CheckIn(); - checkIn.setCreateDate(new Date()); - checkIn.setDescription(getDescription()); - checkIn.setProject(project); - checkIn.setProjectData(project - .toString(Project.TO_STRING_TYPE.TO_PARAMETER)); - checkIn.setTag(getTag()); - checkIn.setUser(curUser); - checkIn.setVersion(project.getVersion()); - checkIn.versionUpgrade(getVersionPosition()); - - // after version upgrade, set back to project - project.setVersion(checkIn.getVersion()); - checkIn.setWorkspaceMode(Workspace.ModeType.VSS); - workspaceMgr.addCheckIn(checkIn); - - // calculate JSON string for client - project = projectMgr.getProject(getId()); - StringBuilder stringBuilder = new StringBuilder(); - stringBuilder.append("{\"projectData\":" + checkIn.getProjectData()); - stringBuilder.append(",\"checkList\":["); - Iterator iterator = project.getCheckInListOrdered().iterator(); - while (iterator.hasNext()) { - stringBuilder.append(iterator.next()); - if (iterator.hasNext()) { - stringBuilder.append(","); - } - } - Gson g = new Gson(); - stringBuilder - .append("],\"actionIdMap\":") - .append(g.toJson(actionIdMap)) - .append(",\"isOk\":true}"); - setJson(stringBuilder.toString()); - - // update project data - project.setProjectData(checkIn.getProjectData()); - projectMgr.updateProject(project); - - // unlock the workspace - unlock(); - - // notification for doc change - for (User user : project.getUserList()) { - Notification notification = new Notification(); - notification.setParam1(new Integer(id).toString()); - notification.setParam2(project.getName()); - notification.setTypeId((short) 1); - notification.setTargetUser(curUser); - notification.setUser(user); - if (notification.getUser().getId() != getCurUserId()) - getAccountMgr().addNotification(notification); - } - - Notification notification = new Notification(); - notification.setParam1(new Integer(id).toString()); - notification.setParam2(project.getName()); - notification.setTypeId((short) 1); - notification.setTargetUser(curUser); - notification.setUser(project.getUser()); - if (notification.getUser().getId() != getCurUserId()) - getAccountMgr().addNotification(notification); - - // unfinished - - Callable taskSub = new Callable() { - - @Override - public String call() throws Exception { - try { - // async update doc - // projectMgr.updateDoc(id); - // async update disableCache - projectMgr.updateCache(id); - } catch (Exception ex) { - ex.printStackTrace(); - } - - return null; - } - }; - - FutureTask futureTask = new FutureTask(taskSub); - Thread asyncThread = new Thread(futureTask); - asyncThread.start(); - logger.info("Future task CHECK_IN running..."); - - return SUCCESS; - } - - @SuppressWarnings({ "rawtypes", "unchecked" }) - public String lock() { - long curUserId = getCurUserId(); - if (curUserId <= 0) { - setIsOk(false); - setErrMsg(LOGIN_WARN_MSG); - return JSON_ERROR; - } - - boolean isOk = false; - if (isLocked(getId())) { - // if the project is locked, find the locker - User user = getLocker(getId()); - if (!user.getAccount().equals(getCurUserAccount())) { - setJson("{\"isOk\":false, \"errMsg\":\"该项目目前正被" - + user.getName() + "锁定.\"}"); - } else { - // user request lock a locked project - // which is locked by himself, so let him go - isOk = true; - } - - } else { - // else, lock the project, than let him go. - Map app = ContextManager.getApplication(); - if (app.get(ContextManager.KEY_PROJECT_LOCK_LIST) == null) { - app.put(ContextManager.KEY_PROJECT_LOCK_LIST, new HashMap()); - } - Map projectLockList = (Map) app - .get(ContextManager.KEY_PROJECT_LOCK_LIST); - if (projectLockList.get(curUserId) == null) { - projectLockList.put(curUserId, getId()); - // System.out.println("user[" + curUserId + "] locked project["+ - // getId() + "]"); - } - isOk = true; - } - if (isOk) { - setJson("{\"isOk\":true, \"projectData\":" - + projectMgr.getProject(getId()).getProjectData() + "}"); - } - return SUCCESS; - } - - @SuppressWarnings({ "rawtypes" }) - public String unlock() { - if (isLocked(getId())) { - Map app = ContextManager.getApplication(); - Map projectLockList = (Map) app - .get(ContextManager.KEY_PROJECT_LOCK_LIST); - if (projectLockList == null) - return SUCCESS; - long userId = super.getCurUserId(); - int projectId = (Integer) projectLockList.get(userId); - projectLockList.remove(userId); - logger.info("user[%d] unlock project[%d]", userId, projectId); - } - return SUCCESS; - } - - /** - * caution: no authentication so far - * - * @return - * @throws Exception - */ - public String export() throws Exception { - project = projectMgr.getProject(projectId); - velocityEngine.init(); - VelocityContext context = new VelocityContext(); - context.put("project", project); - Template template = null; - try { - template = velocityEngine.getTemplate("resource/export.vm", "UTF8"); - } catch (ResourceNotFoundException rnfe) { - rnfe.printStackTrace(); - } catch (ParseErrorException pee) { - pee.printStackTrace(); - } catch (MethodInvocationException mie) { - mie.printStackTrace(); - } catch (Exception e) { - e.printStackTrace(); - } - StringWriter sw = new StringWriter(); - template.merge(context, sw); - fileInputStream = new ByteArrayInputStream(sw.toString().getBytes( - "UTF8")); - return SUCCESS; - } - - @SuppressWarnings("rawtypes") - private boolean isLocked(int projectId) { - Map app = ContextManager.getApplication(); - Map projectLockList = (Map) app - .get(ContextManager.KEY_PROJECT_LOCK_LIST); - return projectLockList != null - && projectLockList.containsValue(projectId) ? true : false; - } - - @SuppressWarnings("rawtypes") - private User getLocker(int projectId) { - Map app = ContextManager.getApplication(); - Map projectLockList = (Map) app - .get(ContextManager.KEY_PROJECT_LOCK_LIST); - if (projectLockList != null) { - long userId = (Long) MapUtils.getKeyByValue(projectLockList, - projectId); - User user = getAccountMgr().getUser(userId); - return user; - } - return null; - } - - public String __init__() { - // prevent repeated intialization of servcie - - /** - if (SystemConstant.serviceInitialized) { - return SUCCESS; - } - - SystemConstant.serviceInitialized = true; - - List list = projectMgr.getProjectList(); - for (Project p : list) { - projectMgr.updateDoc(p.getId()); - } - */ - return SUCCESS; - - } - -} diff --git a/src/com/taobao/rigel/rap/workspace/web/action/struts.xml b/src/com/taobao/rigel/rap/workspace/web/action/struts.xml deleted file mode 100644 index c861f2c1c..000000000 --- a/src/com/taobao/rigel/rap/workspace/web/action/struts.xml +++ /dev/null @@ -1,74 +0,0 @@ - - - - - - - - - /workspace/myWorkspace.vm - - - - - - - - - /bcom/json.cb.vm - - - - /bcom/json.cb.vm - - - /bcom/json.cb.vm - - - - /bcom/json.cb.vm - - - /bcom/json.cb.vm - - - - /bcom/json.cb.vm - - - - attachment;filename=export.html - text/html - fileInputStream - 1024 - - - - - diff --git a/src/database/initialize.sql b/src/database/initialize.sql deleted file mode 100644 index 064cdcee7..000000000 --- a/src/database/initialize.sql +++ /dev/null @@ -1,465 +0,0 @@ -CREATE DATABASE IF NOT EXISTS rap_db default charset utf8 COLLATE utf8_general_ci; - -USE rap_db; - - -/************************************************** - * * - * account module * - * * - **************************************************/ - - -/** - * user table - */ -CREATE TABLE tb_user -( - id int(10) AUTO_INCREMENT NOT NULL - PRIMARY KEY, - account varchar(32) NOT NULL COMMENT '账户名 account name', - password varchar(128) NOT NULL COMMENT '密码 password', - name varchar(256) NOT NULL COMMENT '名字/昵称 name/nickname', - email varchar(256) NOT NULL COMMENT 'email', - create_date timestamp NOT NULL COMMENT '创建日期 create date' - DEFAULT now(), - is_locked_out int(1) NOT NULL COMMENT '用户是否锁定 is the user locked out' - DEFAULT 0, - is_hint_enabled int(1) NOT NULL COMMENT '是否开启新手引导 is user hint enabled' - DEFAULT 1, - last_login_date datetime NOT NULL COMMENT '最近登录 last login date', - incorrect_login_attempt int(10) NOT NULL COMMENT '错误登录次数,登录成功后会重置为0 count of incorrect login attempts, will be set to 0 after any succesful login' - DEFAULT 0, - realname varchar(128) NOT NULL COMMENT '真实姓名' - DEFAULT '', - emp_id VARCHAR(45) NULL COMMENT '工号,可选', - mock_num int(10) NOT NULL COMMENT 'mock次数,用于记录该用户所创建的接口被调用的mock次数。 mock num, used for record mock API invokation count' - DEFAULT 0 -) ENGINE=InnoDB DEFAULT CHARSET=utf8; - -/** - * role table - * roles instruction: - * user - every registered shuold have this role - * rd - research and development engineering - * qa - quality engineering - * pm - project manager - * op - operation manager - * admin - administrator - * god - super admin - */ -CREATE TABLE tb_role -( - id int(10) AUTO_INCREMENT NOT NULL - PRIMARY KEY, - name varchar(16) NOT NULL COMMENT '角色名称 role name' -) ENGINE=InnoDB DEFAULT CHARSET=utf8; - -/** - * user role table - */ -CREATE TABLE tb_role_and_user -( - user_id int(10) NOT NULL, - role_id int(10) NOT NULL, - - PRIMARY KEY(user_id, role_id), - FOREIGN KEY(user_id) REFERENCES tb_user(id), - FOREIGN KEY(role_id) REFERENCES tb_role(id) -) ENGINE=InnoDB DEFAULT CHARSET=utf8; - - - - -/************************************************** - * * - * project module * - * * - **************************************************/ - - - -/** - * parameter table - */ -CREATE TABLE tb_parameter -( - id int(10) AUTO_INCREMENT NOT NULL - PRIMARY KEY, - name varchar(256) NULL COMMENT '参数含义 parameter name', - identifier varchar(256) NULL COMMENT '变量名/参数标识符 parameter identifier', - data_type varchar(32) NULL COMMENT '数据类型 data type', - remark text NULL COMMENT '备注/mock数据等 remark/mock data', - expression varchar(128) NULL COMMENT '备用字段:表达式 backup column:expression', - mock_data text NULL COMMENT '备用字段:mock数据 backup column:mock data' -) ENGINE=InnoDB DEFAULT CHARSET=utf8; - -/** - * project table - * workspace_mode 1-vss(default) 2-svn - * stage 1-design 2-developing 3-debug - */ -CREATE TABLE tb_project -( - id int(10) AUTO_INCREMENT NOT NULL - PRIMARY KEY, - `version` varchar(128) NOT NULL COMMENT '版本号 version no.' - DEFAULT '0.0.0.1', - name varchar(128) NOT NULL COMMENT '项目名称 project name', - create_date timestamp NOT NULL COMMENT '创建日期 create date' - DEFAULT now(), - user_id int(10) NOT NULL COMMENT '创建人ID, project author id', - introduction text NULL COMMENT '项目描述 project introduction', - workspace_mode int(10) NOT NULL COMMENT '工作区提交模式(类VSS or SVN),暂时弃用了。 Workspace submit mode, deprecated.' - DEFAULT 1, - stage int(10) NOT NULL COMMENT '项目阶段,暂时废弃;project stage, temply deprecated. 1-design 2-developing 3-debug' - DEFAULT 1, - project_data longtext NULL COMMENT '项目JSON数据,存放当前最新的版本。 project JSON data, saved the newest version of the project', - group_id int(10) NULL COMMENT '分组ID group id', - related_ids varchar(128) NOT NULL COMMENT '路由ID,用于指定与哪些项目共享mock数据; router id, used for specify sharing data with which projects.' - DEFAULT '', - update_time datetime NOT NULL COMMENT '更新时间 update time', - mock_num int NOT NULL COMMENT 'mock次数 mock num' - DEFAULT 0, - access_type TINYINT NOT NULL COMMENT '权限控制, 10普通, 0私有' - DEFAULT 10, - - FOREIGN KEY(user_id) REFERENCES tb_user(id) -) ENGINE=InnoDB DEFAULT CHARSET=utf8; - -/** - * user list and user table - * used for creating multiple to multiple mapping - * access_level: - * 1 - read - * 2 - read&write - * 3 - read&write&manage - */ -CREATE TABLE tb_project_and_user -( - project_id int(10) NOT NULL, - user_id int(10) NOT NULL, - access_level int NOT NULL - DEFAULT 1, - - PRIMARY KEY(project_id, user_id), - FOREIGN KEY(project_id) REFERENCES tb_project(id), - FOREIGN KEY(user_id) REFERENCES tb_user(id) -) ENGINE=InnoDB DEFAULT CHARSET=utf8; - -/** - * module table - */ -CREATE TABLE tb_module -( - id int(10) AUTO_INCREMENT NOT NULL - PRIMARY KEY, - project_id int(10) NOT NULL, - name varchar(256) NOT NULL, - introduction varchar(128) NULL, - - FOREIGN KEY(project_id) REFERENCES tb_project(id) -) ENGINE=InnoDB DEFAULT CHARSET=utf8; - -/** - * page table - */ -CREATE TABLE tb_page -( - id int(10) AUTO_INCREMENT NOT NULL - PRIMARY KEY, - name varchar(56) NOT NULL, - module_id int(10) NOT NULL, - introduction text NULL, - template varchar(128) NULL, - - FOREIGN KEY(module_id) REFERENCES tb_module(id) -) ENGINE=InnoDB DEFAULT CHARSET=utf8; - -/** - * action table - * request_type: - * 1 - get - * 2 - post - * 3 - ajax get - * 4 - ajax post - */ -CREATE TABLE tb_action -( - id int(10) AUTO_INCREMENT NOT NULL - PRIMARY KEY, - name varchar(256) NOT NULL, - description text NULL, - - /* request block */ - request_type int NOT NULL COMMENT '请求类型get/post/put/delete等等 request type' - DEFAULT 1, /** request_type = 99, mount type **/ - request_url text NULL, - - disable_cache TINYINT NOT NULL COMMENT '禁用Mock缓存 disable mock cache' - DEFAULT 0, - - /* response block */ - response_template text NULL COMMENT '响应模板地址, 暂时弃用。 response template address, temply deprecated.' - -) ENGINE=InnoDB DEFAULT CHARSET=utf8; - -/** - * action and page table - * used for creating multiple to multiple mapping - */ -CREATE TABLE tb_action_and_page -( - action_id int(10) NOT NULL, - page_id int(10) NOT NULL, - - FOREIGN KEY(action_id) REFERENCES tb_action(id), - FOREIGN KEY(page_id) REFERENCES tb_page(id), - PRIMARY KEY(action_id, page_id) -) ENGINE=InnoDB DEFAULT CHARSET=utf8; - - -/** - * parameter and parameter mapping - * complex_parameter has so many parameters(List or Map) - */ -CREATE TABLE tb_complex_parameter_list_mapping -( - complex_parameter_id int(10) NOT NULL, - parameter_id int(10) NOT NULL, - - PRIMARY KEY(complex_parameter_id, parameter_id), - FOREIGN KEY(complex_parameter_id) REFERENCES tb_parameter(id), - FOREIGN KEY(parameter_id) REFERENCES tb_parameter(id) -) ENGINE=InnoDB DEFAULT CHARSET=utf8; - -/** - * parameter and action's request mapping - */ -CREATE TABLE tb_request_parameter_list_mapping -( - action_id int(10) NOT NULL, - parameter_id int(10) NOT NULL, - - PRIMARY KEY(action_id, parameter_id), - FOREIGN KEY(action_id) REFERENCES tb_action(id), - FOREIGN KEY(parameter_id) REFERENCES tb_parameter(id) -) ENGINE=InnoDB DEFAULT CHARSET=utf8; - -/** - * parameter and action's response mapping - */ -CREATE TABLE tb_response_parameter_list_mapping -( - action_id int(10) NOT NULL, - parameter_id int(10) NOT NULL, - - PRIMARY KEY(action_id, parameter_id), - FOREIGN KEY(action_id) REFERENCES tb_action(id), - FOREIGN KEY(parameter_id) REFERENCES tb_parameter(id) -) ENGINE=InnoDB DEFAULT CHARSET=utf8; - - - - - -/************************************************** - * * - * workspace module * - * * - **************************************************/ - - -/** - * workspace, deprecated 工作区,暂时未使用 - */ -CREATE TABLE tb_workspace -( - id int(10) AUTO_INCREMENT NOT NULL - PRIMARY KEY, - project_id int(10) NOT NULL, - user_id int NOT NULL, - create_date timestamp NOT NULL - DEFAULT now(), - update_date datetime NOT NULL, - project_data longtext NOT NULL, - project_data_original longtext NOT NULL, - - FOREIGN KEY(project_id) REFERENCES tb_project(id), - FOREIGN KEY(user_id) REFERENCES tb_user(id) -) ENGINE=InnoDB DEFAULT CHARSET=utf8; - -/** - * workspace save, deprecated 工作区保存草稿,暂时未使用 - */ -CREATE TABLE tb_workspace_save -( - id int(10) AUTO_INCREMENT NOT NULL - PRIMARY KEY, - workspace_id int(10) NOT NULL, - update_date datetime NOT NULL, - project_data longtext NOT NULL, - - FOREIGN KEY(workspace_id) REFERENCES tb_workspace(id) -) ENGINE=InnoDB DEFAULT CHARSET=utf8; - -/** - * check in table - * every API document submit saved here, used for version control. - * 每一次提交记录在这里,用于版本管理和回滚控制 - * workspaceMode 1-VSS 2-SVN - */ -CREATE TABLE tb_check_in -( - id int(10) AUTO_INCREMENT NOT NULL - PRIMARY KEY, - create_date timestamp NOT NULL - DEFAULT now(), - tag varchar(128) NULL COMMENT 'tag标签 暂时未使用 deprecated', - user_id int(10) NOT NULL COMMENT '提交人 submit user id', - project_id int(10) NOT NULL COMMENT '提交的项目ID submit project id', - description text NULL COMMENT '提交描述 submit description', - version varchar(128) NOT NULL COMMENT '版本号 version no.', - project_data longtext NOT NULL COMMENT '项目JSON数据 project json data', - workspace_mode int(10) NOT NULL COMMENT '工作区模式(弃用) workspace mode(deprecated)', - log text NULL COMMENT '更新日志,用于存储与最近一个版本的对比差异。暂时未使用。update log, used for calculate versions differences. Deprecated.', - - FOREIGN KEY(user_id) REFERENCES tb_user(id), - FOREIGN KEY(project_id) REFERENCES tb_project(id) -) ENGINE=InnoDB DEFAULT CHARSET=utf8; - -/** - * user settings table - * 用户配置表 - */ -CREATE TABLE tb_user_settings -( - user_id int(10) NOT NULL, - `key` varchar(128) NOT NULL COMMENT '配置KEY config key', - `value` varchar(128) NOT NULL COMMENT '配置VALUE config value', - - PRIMARY KEY(user_id, `key`), - FOREIGN KEY(user_id) REFERENCES tb_user(id) -) ENGINE=InnoDB DEFAULT CHARSET=utf8; - -/** - * user notification table - * 用户通知表 - */ - -CREATE TABLE tb_notification -( - id int(10) AUTO_INCREMENT NOT NULL - PRIMARY KEY, - user_id int(10) NOT NULL COMMENT '接受通知的用户id; user id to be notified.', - target_user_id int(10) NOT NULL COMMENT '上下文用户id; context user id', - type_id smallint NOT NULL COMMENT '1-文档修改,2-被加入新项目', - param1 varchar(128) NULL COMMENT '1,2-项目id', - param2 varchar(128) NULL COMMENT ' 1,2-项目名称', - param3 text NULL COMMENT '备用预留 reserved', - create_time timestamp NOT NULL COMMENT '创建时间 create time' - DEFAULT now(), - - is_read smallint NOT NULL COMMENT '是否已读 is notification read' - DEFAULT 0, - - FOREIGN KEY(user_id) REFERENCES tb_user(id), - FOREIGN KEY(target_user_id) REFERENCES tb_user(id) -)ENGINE=InnoDB DEFAULT CHARSET=utf8; - -/** - * corporation table - * 公司表 - */ -CREATE TABLE tb_corporation -( - id int(10) AUTO_INCREMENT NOT NULL - PRIMARY KEY, - name varchar(256) NOT NULL, - logo_url varchar(256) NULL, - user_id int(10) NULL, - access_type TINYINT NOT NULL COMMENT '权限控制, 10普通, 20公开' - DEFAULT 10, - `desc` text NOT NULL COMMENT '备注', - - FOREIGN KEY(user_id) REFERENCES tb_user(id) -) ENGINE=InnoDB DEFAULT CHARSET=utf8; - - -/** - * product line table - * 生产线表 - */ -CREATE TABLE tb_production_line -( - id int(10) AUTO_INCREMENT NOT NULL - PRIMARY KEY, - name varchar(256) NOT NULL, - project_num int(10) NOT NULL - DEFAULT 0, - corporation_id int(10) NOT NULL, - user_id int(10) NOT NULL, - - FOREIGN KEY(user_id) REFERENCES tb_user(id), - FOREIGN KEY(corporation_id) REFERENCES tb_corporation(id) -) ENGINE=InnoDB DEFAULT CHARSET=utf8; - -/** - * project group table - * 项目分组表 - */ -CREATE TABLE tb_group -( - id int(10) AUTO_INCREMENT NOT NULL - PRIMARY KEY, - name varchar(256) NOT NULL, - production_line_id int(10) NOT NULL, - user_id int(10) NOT NULL, - - FOREIGN KEY(user_id) REFERENCES tb_user(id), - FOREIGN KEY(production_line_id) REFERENCES tb_production_line(id) -) ENGINE=InnoDB DEFAULT CHARSET=utf8; - -/** - * 规则表,存储通过Open API设置的Mock规则 - * Stored mock rules set by Open API - */ -CREATE TABLE tb_rule ( - action_id int(10) NOT NULL - PRIMARY KEY, - rules text NOT NULL, -- JSON规则 - update_time datetime NOT NULL - DEFAULT NOW(), -- 最近更新时间 - - FOREIGN KEY(action_id) REFERENCES tb_action(id) -) ENGINE=InnoDB DEFAULT CHARSET=utf8; - -CREATE TABLE tb_corporation_and_user -( - user_id int(10) NOT NULL, - corporation_id int(10) NOT NULL, - role_id int(10) NOT NULL, - - PRIMARY KEY(user_id, corporation_id), - FOREIGN KEY(user_id) REFERENCES tb_user(id), - FOREIGN KEY(corporation_id) REFERENCES tb_corporation(id), - FOREIGN KEY(role_id) REFERENCES tb_role(id) -) ENGINE=InnoDB DEFAULT CHARSET=utf8; - - - --- required base data -INSERT INTO tb_role (name) VALUES ('god'); -INSERT INTO tb_role (name) VALUES ('admin'); -INSERT INTO tb_role (name) VALUES ('user'); --- removed unused qa/pm/rd roles - - -INSERT INTO tb_user(account, password, email, create_date, last_login_date, name) VALUES -('admin', 'RESERVED', 'admin@example.com', NOW(), NOW(), 'admin'); - -INSERT INTO tb_role_and_user (user_id, role_id) VALUES (1, 1); - --- INSERT INTO tb_corporation (name, logo_url, user_id) VALUES ('MyTeam', 'empty', 1); --- 新版RAP可以自建团队,不需要插入默认团队了。 --- RAP v0.11.5+ users can create teams by their own, so there's no need to set default team. diff --git a/src/database/scripts.sql b/src/database/scripts.sql deleted file mode 100644 index ba036f15a..000000000 --- a/src/database/scripts.sql +++ /dev/null @@ -1,45 +0,0 @@ --- recent projects - -SELECT p.name projectName, u.name userName, p.create_date projectCreateTime, p.introduction -FROM tb_project p -JOIN tb_user u ON p.user_id = u.id -ORDER BY p.id DESC - --- recent users - -SELECT * -FROM tb_user -ORDER BY id DESC - --- counters -SELECT COUNT(*) userNum FROM tb_user; -SELECT COUNT(*) projectNum FROM tb_project; - - --- counting projects (actions >= 5) -SELECT p.id, p.name, COUNT(a.id) -FROM tb_project p -JOIN tb_module m ON m.project_id = p.id -JOIN tb_page p2 ON p2.module_id = m.id -JOIN tb_action_and_page ap ON ap.page_id = p2.id -JOIN tb_action a ON a.id = ap.action_id -GROUP BY p.id -HAVING COUNT(a.id) > 5 -ORDER BY count(a.id) DESC - - --- search request_url -SELECT a.name actionName, m.project_id projectId -FROM tb_action a -JOIN tb_action_and_page ap ON ap.action_id = a.id -JOIN tb_page p ON p.id = ap.page_id -JOIN tb_module m ON m.id = p.module_id -WHERE request_url LIKE '%key%' - --- search organization info by projectId -SELECT CONCAT(c.name, '-', pl.name, '-', g.name, '-', p.name) AS info -FROM tb_project p -JOIN tb_group g ON g.id = p.group_id -JOIN tb_production_line pl ON pl.id = g.production_line_id -JOIN tb_corporation c ON c.id = pl.corporation_id -WHERE p.id = {projectId} \ No newline at end of file diff --git a/src/main/java/Tester.java b/src/main/java/Tester.java new file mode 100644 index 000000000..3f3ffb92c --- /dev/null +++ b/src/main/java/Tester.java @@ -0,0 +1,13 @@ +import com.taobao.rigel.rap.common.utils.MockjsRunner; +import redis.clients.jedis.Jedis; + +/** + * Created by Bosn on 2014/8/16. + */ +public class Tester { + public static void main(String[] args) { + String code= "1"; + String result = MockjsRunner.renderMockjsRule(code); + System.out.println("result:" + result); + } +} diff --git a/src/main/java/com/taobao/rigel/rap/account/bo/Notification.java b/src/main/java/com/taobao/rigel/rap/account/bo/Notification.java new file mode 100644 index 000000000..3f536fbc9 --- /dev/null +++ b/src/main/java/com/taobao/rigel/rap/account/bo/Notification.java @@ -0,0 +1,106 @@ +package com.taobao.rigel.rap.account.bo; + +import org.ocpsoft.prettytime.PrettyTime; + +import java.util.Date; +import java.util.Locale; + +public class Notification { + private int id; + private int userId; + private short typeId; + private String param1; + private String param2; + private String param3; + private Date createTime; + private boolean isRead; + private User user; + private User targetUser; + + public String getCreateTimeStr() { + PrettyTime p = new PrettyTime(new Locale("zh")); + return p.format(this.createTime); + } + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public int getUserId() { + return userId; + } + + public void setUserId(int userId) { + this.userId = userId; + } + + public short getTypeId() { + return typeId; + } + + public void setTypeId(short typeId) { + this.typeId = typeId; + } + + public String getParam1() { + return param1; + } + + public void setParam1(String param1) { + this.param1 = param1; + } + + public String getParam2() { + return param2; + } + + public void setParam2(String param2) { + this.param2 = param2; + } + + public String getParam3() { + return param3; + } + + public void setParam3(String param3) { + this.param3 = param3; + } + + public Date getCreateTime() { + return createTime; + } + + public void setCreateTime(Date createTime) { + this.createTime = createTime; + } + + public boolean isRead() { + return isRead; + } + + public void setRead(boolean isRead) { + this.isRead = isRead; + } + + public User getUser() { + return user; + } + + public void setUser(User user) { + this.user = user; + } + + public User getTargetUser() { + return targetUser; + } + + public void setTargetUser(User targetUser) { + this.targetUser = targetUser; + } + + +} diff --git a/src/main/java/com/taobao/rigel/rap/account/bo/Role.java b/src/main/java/com/taobao/rigel/rap/account/bo/Role.java new file mode 100644 index 000000000..3e9a5cb26 --- /dev/null +++ b/src/main/java/com/taobao/rigel/rap/account/bo/Role.java @@ -0,0 +1,24 @@ +package com.taobao.rigel.rap.account.bo; + +public class Role implements java.io.Serializable { + + private int id; + private String name; + + public int getId() { + return this.id; + } + + public void setId(int id) { + this.id = id; + } + + public String getName() { + return this.name; + } + + public void setName(String name) { + this.name = name; + } + +} diff --git a/src/main/java/com/taobao/rigel/rap/account/bo/User.java b/src/main/java/com/taobao/rigel/rap/account/bo/User.java new file mode 100644 index 000000000..b6379a69d --- /dev/null +++ b/src/main/java/com/taobao/rigel/rap/account/bo/User.java @@ -0,0 +1,246 @@ +package com.taobao.rigel.rap.account.bo; + +import com.taobao.rigel.rap.project.bo.Project; + +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.*; + +public class User implements java.io.Serializable { + private int id; + private String name; + private String account; + private String password; + private String email; + private Date createDate; + private boolean isLockedOut; + private Date lastLoginDate; + private int incorrectLoginAttempt; + private String realname; + private String empId; + private int roleId; + private Set roleList = new HashSet(); + private Set createdProjectList = new HashSet(); + private Set joinedProjectList = new HashSet(); + private boolean isHintEnabled; + + public String getEmpId() { + return empId; + } + + public void setEmpId(String empId) { + this.empId = empId; + } + + public Map getUserBaseInfo() { + Map base = new HashMap(); + base.put("name", this.name); + base.put("id", this.id); + base.put("email", this.email); + return base; + } + + public boolean isAdmin() { + for (Role role : this.getRoleList()) { + // roleId = 1, means super admin (god) + // roleId = 2, means admin + if (role.getId() >= 1 && role.getId() <= 2) return true; + } + return false; + } + + public int getId() { + return this.id; + } + + public void setId(int id) { + this.id = id; + } + + public Set getRoleList() { + return this.roleList; + } + + public void setRoleList(Set roleList) { + this.roleList = roleList; + } + + public boolean isUserInRole(String roleName) { + for (Role r : getRoleList()) { + if (r.getName().equals(roleName)) { + return true; + } + } + return false; + } + + public String getRoleListStr() { + String str = ""; + for (Role r : getRoleList()) { + str += r.getName() + ","; + } + return str; + } + + public List getAccessibleProjectList() { + List projectList = new ArrayList(); + for (Project p : getCreatedProjectList()) { + p.setIsManagable(true); + projectList.add(p); + } + for (Project p : getJoinedProjectList()) { + projectList.add(p); + } + return projectList; + } + + public boolean haveAccessOfProject(int projectId) { + if (isUserInRole("admin")) { + return true; + } + for (Project p : getCreatedProjectList()) { + if (p.getId() == projectId) { + return true; + } + } + + for (Project p : getJoinedProjectList()) { + if (p.getId() == projectId) { + return true; + } + } + return false; + } + + public Set getCreatedProjectList() { + return this.createdProjectList; + } + + public void setCreatedProjectList(Set createdProjectList) { + this.createdProjectList = createdProjectList; + } + + public Set getJoinedProjectList() { + return this.joinedProjectList; + } + + public void setJoinedProjectList(Set joinedProjectList) { + this.joinedProjectList = joinedProjectList; + } + + public String getAccount() { + return this.account; + } + + public void setAccount(String account) { + this.account = account; + } + + public String getName() { + return this.name; + } + + public void setName(String name) { + this.name = name; + } + + public String getPassword() { + return this.password; + } + + public void setPassword(String password) { + this.password = password; + } + + public String getEmail() { + return this.email; + } + + public void setEmail(String email) { + this.email = email; + } + + public Date getCreateDate() { + return this.createDate; + } + + public void setCreateDate(Date createDate) { + this.createDate = createDate; + } + + public String getCreateDateStr() { + DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd"); + return dateFormat.format(getCreateDate()); + } + + public boolean getIsLockedOut() { + return this.isLockedOut; + } + + public void setIsLockedOut(boolean isLockedOut) { + this.isLockedOut = isLockedOut; + } + + public Date getLastLoginDate() { + return this.lastLoginDate; + } + + public void setLastLoginDate(Date lastLoginDate) { + this.lastLoginDate = lastLoginDate; + } + + public String getLastLoginDateStr() { + DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd"); + return dateFormat.format(getLastLoginDate()); + } + + public int getIncorrectLoginAttempt() { + return this.incorrectLoginAttempt; + } + + public void setIncorrectLoginAttempt(int incorrectLoginAttempt) { + this.incorrectLoginAttempt = incorrectLoginAttempt; + } + + public void addCreatedProject(Project project) { + project.setUser(this); + this.createdProjectList.add(project); + } + + public boolean getIsHintEnabled() { + return isHintEnabled; + } + + public void setIsHintEnabled(boolean isHintEnabled) { + this.isHintEnabled = isHintEnabled; + } + + public String toString() { + return "{\"name\":\"" + this.name + "\",\"id\":" + this.id + "}"; + } + + public String getWorkRole() { + for (Role r : getRoleList()) { + if (r.getName().length() == 2) { + return r.getName().toUpperCase(); + } + } + return ""; + } + + public String getRealname() { + return this.realname; + } + + public void setRealname(String realname) { + this.realname = realname; + } + + public int getRoleId() { + return roleId; + } + + public void setRoleId(int roleId) { + this.roleId = roleId; + } +} diff --git a/src/main/java/com/taobao/rigel/rap/account/dao/AccountDao.java b/src/main/java/com/taobao/rigel/rap/account/dao/AccountDao.java new file mode 100644 index 000000000..8c5d4772e --- /dev/null +++ b/src/main/java/com/taobao/rigel/rap/account/dao/AccountDao.java @@ -0,0 +1,199 @@ +package com.taobao.rigel.rap.account.dao; + +import com.taobao.rigel.rap.account.bo.Notification; +import com.taobao.rigel.rap.account.bo.User; + +import java.util.List; +import java.util.Map; + +public interface AccountDao { + + /** + * password validator + * + * @param account + * @param password + * @return + */ + boolean validate(String account, String password); + + /** + * create new user + * + * @param user + * @return + */ + boolean addUser(User user); + + /** + * get user by user id + * + * @param userId + * @return + */ + User getUser(int userId); + + /** + * get user by account + * + * @param account + * @return + */ + User getUser(String account); + + /** + * change password + * + * @param account + * @param oldPassword + * @param newPassword + * @return + */ + boolean changePassword(String account, String oldPassword, + String newPassword); + + /** + * get user id by account + * + * @param account + * @return + */ + int getUserId(String account); + + /** + * change profile + * + * @param userId + * @param profileProperty + * @param profileValue + */ + void changeProfile(int userId, String profileProperty, String profileValue); + + /** + * update profile + * + * @param userId + * @param name + * @param email + * @param password + * @param newPassword + * @return + */ + boolean updateProfile(int userId, String name, String email, + String password, String newPassword); + + /** + * get user list + * + * @return + */ + List getUserList(); + + /** + * change password + * + * @param account + * @param password + */ + void _changePassword(String account, String password); + + /** + * get user by name + * + * @param name + * @return + */ + User getUserByName(String name); + + /** + * get all user settings + * + * @param userId + * @return + */ + Map getUserSettings(int userId); + + /** + * get user setting by key + * + * @param userId + * @param key + * @return + */ + String getUserSetting(int userId, String key); + + /** + * update user setting if setting not exists, add it. + * + * @param userId + * @param key + * @param value + * @return + */ + void updateUserSetting(int userId, String key, String value); + + /** + * get notifications + * + * @param userId + * @return + */ + List getNotificationList(int userId); + + /** + * remove user's notifications + * + * @param userId + */ + void clearNotificationList(int userId); + + /** + * add new notification + * + * @param notification + */ + void addNotification(Notification notification); + + /** + * read notification + * + * @param id + */ + void readNotification(int id); + + /** + * read all notifications of specific user + * + * @param userId + */ + void readNotificationList(int userId); + + /** + * get unread notification list + * + * @param curUserId + * @return + */ + List getUnreadNotificationList(int curUserId); + + /** + * check if similar notification exists + * + * @param notification + * @return + */ + boolean notificationExists(Notification notification); + + int getUsertNum(); + + public void updateUser(User user); + + /** + * get user id list of team + * + * @param teamId + * @return + */ + List getUserIdList(int teamId); + +} diff --git a/src/main/java/com/taobao/rigel/rap/account/dao/impl/AccountDaoImpl.java b/src/main/java/com/taobao/rigel/rap/account/dao/impl/AccountDaoImpl.java new file mode 100644 index 000000000..7e68a970e --- /dev/null +++ b/src/main/java/com/taobao/rigel/rap/account/dao/impl/AccountDaoImpl.java @@ -0,0 +1,264 @@ +package com.taobao.rigel.rap.account.dao.impl; + +import com.taobao.rigel.rap.account.bo.Notification; +import com.taobao.rigel.rap.account.bo.Role; +import com.taobao.rigel.rap.account.bo.User; +import com.taobao.rigel.rap.account.dao.AccountDao; +import com.taobao.rigel.rap.common.config.SystemSettings; +import org.hibernate.ObjectNotFoundException; +import org.hibernate.Query; +import org.hibernate.Session; +import org.springframework.orm.hibernate5.support.HibernateDaoSupport; + +import java.util.*; + +public class AccountDaoImpl extends HibernateDaoSupport implements AccountDao { + + public boolean validate(String account, String password) { + try { + User user = (User) currentSession() + .load(User.class, getUserId(account)); + return user != null && user.getPassword().equals(password); + } catch (ObjectNotFoundException ex) { + return false; + } + } + + public int getUsertNum() { + String sql = "SELECT COUNT(*) FROM tb_user"; + Query query = currentSession().createSQLQuery(sql); + return Integer.parseInt(query.uniqueResult().toString()); + } + + public boolean addUser(User user) { + user.setLastLoginDate(new Date()); + user.setCreateDate(new Date()); + user.setRealname(""); + currentSession().save(user); + return true; + } + + public boolean changePassword(String account, String oldPassword, + String newPassword) { + Session session = currentSession(); + boolean returnVal = true; + User user = (User) session.load(User.class, getUserId(account)); + if (user == null || !user.getPassword().equals(oldPassword)) { + returnVal = false; + } else { + user.setPassword(newPassword); + session.update(user); + } + + return returnVal; + } + + /** + * get user id + * + * @param account + * @return return -1 if the user doesn't exist, otherwise return id of user + */ + public int getUserId(String account) { + Query q = currentSession() + .createQuery("from User where account = :account"); + q.setString("account", account); + User user = (User) q.uniqueResult(); + return user == null ? -1 : user.getId(); + } + + public User getUserByName(String name) { + Query q = currentSession().createQuery("from User where name = :name"); + q.setString("name", name); + User user = (User) q.uniqueResult(); + return user; + } + + public User getUser(int userId) { + User user = currentSession().get(User.class, userId); + return user; + } + + private Set getRoleList(int userId) { + String sql = "SELECT r.* FROM tb_role r \n" + + "JOIN tb_role_and_user ru ON ru.role_id = r.id \n" + + "WHERE ru.user_id = :userId"; + Query query = currentSession().createSQLQuery(sql).addEntity(Role.class); + query.setInteger("userId", userId); + List list = query.list(); + Set roleSet = new HashSet(); + for (Role role : list) { + roleSet.add(role); + } + return roleSet; + } + + public User getUser(String account) { + return getUser(getUserId(account)); + } + + public void changeProfile(int userId, String profileProperty, + String profileValue) { + User user = (User) currentSession().load(User.class, userId); + if (profileProperty.equals("isHintEnabled")) { + user.setIsHintEnabled(profileValue.equals("true") ? true : false); + } + } + + public boolean updateProfile(int userId, String name, String email, + String password, String newPassword) { + User user = (User) currentSession().load(User.class, userId); + if (name != null && !name.equals("")) + user.setName(name); + if (email != null && !email.equals("")) + user.setEmail(email); + if (password != null && !password.equals("")) { + if (password == null || newPassword == null || password.isEmpty() || newPassword.isEmpty()) { + // password is not changed. + } else if (user.getPassword().equals(password)) { + user.setPassword(newPassword); + } else { + // only when user input old password, and the password is + // incorrect, return false + return false; + } + } + return true; + } + + public void updateUser(User user) { + currentSession().update(user); + } + + public List getUserIdList(int teamId) { + String sql = "SELECT user_id FROM tb_corporation_and_user WHERE corporation_id = :teamId"; + Query query = currentSession().createSQLQuery(sql); + query.setInteger("teamId", teamId); + return query.list(); + } + + public List getUserList() { + return currentSession().createQuery("from User").list(); + } + + public void _changePassword(String account, String password) { + Session session = currentSession(); + User user = (User) session.load(User.class, getUserId(account)); + if (user != null) { + user.setPassword(password); + session.update(user); + } + + } + + public Map getUserSettings(int userId) { + String sql = "SELECT `key`, `value` FROM tb_user_settings WHERE user_id = :userId"; + Query query = currentSession().createSQLQuery(sql); + query.setInteger("userId", userId); + List result = query.list(); + Map settings = new HashMap(); + + for (ListIterator iter = result.listIterator(); iter.hasNext(); ) { + Object[] row = (Object[]) iter.next(); + settings.put(row[0].toString(), row[1].toString()); + } + + return settings; + } + + + public String getUserSetting(int userId, String key) { + String sql = "SELECT `value` FROM tb_user_settings WHERE user_id = :userId AND `key` = :key"; + Query query = currentSession().createSQLQuery(sql); + query.setInteger("userId", userId); + query.setString("key", key); + List result = query.list(); + if (result.size() > 0) { + return result.get(0).toString(); + } + + return SystemSettings.GET_DEFAULT_USER_SETTINGS(key); + } + + + public void updateUserSetting(int userId, String key, String value) { + if (getUserSetting(userId, key) == null) { + addUserSetting(userId, key, value); + return; + } + + String sql = "UPDATE tb_user_settings SET `value` = :value WHERE user_id = :userId AND `key` = :key"; + Query query = currentSession().createSQLQuery(sql); + query.setString("value", value); + query.setInteger("userId", userId); + query.setString("key", key); + query.executeUpdate(); + } + + private void addUserSetting(int userId, String key, String value) { + String sql = "INSERT INTO tb_user_settings (user_id, `key`, `value`) VALUES (:userId, :key, :value)"; + Query query = currentSession().createSQLQuery(sql); + query.setInteger("userId", userId); + query.setString("key", key); + query.setString("value", value); + query.executeUpdate(); + } + + + public List getNotificationList(int userId) { + String hql = "from Notification n where n.user.id = :userId order by n.createTime desc"; + Query query = currentSession().createQuery(hql).setInteger("userId", userId); + return query.list(); + } + + + public List getUnreadNotificationList(int userId) { + String hql = "from Notification n where n.user.id = :userId and read = false order by n.createTime desc"; + Query query = currentSession().createQuery(hql).setInteger("userId", userId); + return query.list(); + } + + + public void clearNotificationList(int userId) { + String hql = "delete Notification where user.id = :userId"; + currentSession().createQuery(hql).setInteger("userId", userId).executeUpdate(); + } + + + public void addNotification(Notification notification) { + currentSession().save(notification); + } + + + public void readNotification(int id) { + String hql = "update Notification set read = 1 where id = :id"; + currentSession().createQuery(hql).setInteger("id", id).executeUpdate(); + } + + + public void readNotificationList(int userId) { + String hql = "update Notification set read = 1 where user.id = :userId"; + currentSession().createQuery(hql).setInteger("userId", userId).executeUpdate(); + } + + public boolean notificationExists(Notification notification) { + String hql = "from Notification where user.id = :userId and typeId = :typeId and param1 = :param1 and read = false"; + Session session = currentSession(); + Query query = session.createQuery(hql); + query.setInteger("userId", notification.getUser().getId()) + .setShort("typeId", notification.getTypeId()) + .setString("param1", notification.getParam1()); + List list = (List) query.list(); + int size = list.size(); + if (size > 0) { + for (Notification o : list) { + o.setCreateTime(new Date()); + session.update(o); + } + return true; + } else { + return false; + } + } + +} diff --git a/src/main/java/com/taobao/rigel/rap/account/service/AccountMgr.java b/src/main/java/com/taobao/rigel/rap/account/service/AccountMgr.java new file mode 100644 index 000000000..09f4a0ee5 --- /dev/null +++ b/src/main/java/com/taobao/rigel/rap/account/service/AccountMgr.java @@ -0,0 +1,222 @@ +package com.taobao.rigel.rap.account.service; + +import com.taobao.rigel.rap.account.bo.Notification; +import com.taobao.rigel.rap.account.bo.User; +import com.taobao.rigel.rap.organization.bo.Corporation; + +import java.util.List; +import java.util.Map; + +public interface AccountMgr { + + /** + * login operation double MD5 check before validation + * + * @param account the user name + * @param password the password + * @return return true if succeed, otherwise return false + */ + boolean validate(String account, String password); + + /** + * add new user + * + * @param user + * @return return true if succeed, otherwise return false + */ + boolean addUser(User user); + + /** + * get user by userId + * + * @param userId + * @return return null if the user doesn't exist, or return the reference of + * user + */ + User getUser(int userId); + + /** + * get all users + * + * @return user list + */ + List getUserList(); + + /** + * get users of team + * + * @param teamId + * @return + */ + List getUserList(int teamId); + + /** + * get user by account + * + * @param account + * @return return null if the user doesn't exist, or return the reference of + * user + */ + User getUser(String account); + + /** + * change password + * + * @param account + * @param oldPassword + * @param newPassword + * @return return true if succeed, otherwise return false + */ + boolean changePassword(String account, String oldPassword, + String newPassword); + + /** + * get user id by account + * + * @param account + * @return + */ + int getUserId(String account); + + /** + * change profile of user + * + * @param userId current user id + * @param profileProperty profile property + * @param profileValue profile property value + */ + void changeProfile(int userId, String profileProperty, String profileValue); + + /** + * update profile + * + * @param name + * @param email + * @param password this will be null if user do not want to change password + * @param newPassword + * @return + */ + boolean updateProfile(int userId, String name, String email, + String password, String newPassword); + + /** + * used for system adjust ignore MD5 check or process + * + * @param account + * @param password + */ + void _updatePassword(String account, String password); + + /** + * get corporation list + * + * @return + */ + List getCorporationList(); + + List getCorporationListWithPager(int userId, int pageNum, int pageSize); + + /** + * get user by name + * + * @param name + * @return + */ + User getUserByName(String name); + + /** + * get all user settings + * + * @param userId + * @return + */ + Map getUserSettings(int userId); + + /** + * get user setting by key + * + * @param userId + * @param key + * @return + */ + String getUserSetting(int userId, String key); + + /** + * update user setting + * if setting not exists, add it. + * + * @param userId + * @param key + * @param value + * @return + */ + void updateUserSetting(int userId, String key, String value); + + /** + * get notifications + * + * @param userId + * @return + */ + List getNotificationList(int userId); + + /** + * remove user's notifications + * + * @param userId + */ + void clearNotificationList(int userId); + + /** + * add new notification + * + * @param notification + */ + void addNotification(Notification notification); + + /** + * read notification + * + * @param id + */ + void readNotification(int id); + + /** + * read all notifications of specific user + * + * @param userId + */ + void readNotificationList(int userId); + + /** + * get unread notification list + * + * @param curUserId + * @return + */ + List getUnreadNotificationList(int curUserId); + + + /** + * user access validation + * + * @param userId + * @param projectId + * @return + */ + boolean canUserManageProject(int userId, int projectId); + + int getUserNum(); + + void updateUser(User user); + + /** + * validate password format + * + * @param password + * @return null if legal, otherwise return error message + */ + String validatePasswordFormat(String password); + + +} diff --git a/src/main/java/com/taobao/rigel/rap/account/service/impl/AccountMgrImpl.java b/src/main/java/com/taobao/rigel/rap/account/service/impl/AccountMgrImpl.java new file mode 100644 index 000000000..109acb60d --- /dev/null +++ b/src/main/java/com/taobao/rigel/rap/account/service/impl/AccountMgrImpl.java @@ -0,0 +1,279 @@ +package com.taobao.rigel.rap.account.service.impl; + +import com.taobao.rigel.rap.account.bo.Notification; +import com.taobao.rigel.rap.account.bo.User; +import com.taobao.rigel.rap.account.dao.AccountDao; +import com.taobao.rigel.rap.account.service.AccountMgr; +import com.taobao.rigel.rap.common.config.PRIVATE_CONFIG; +import com.taobao.rigel.rap.common.utils.CacheUtils; +import com.taobao.rigel.rap.common.utils.StringUtils; +import com.taobao.rigel.rap.organization.bo.Corporation; +import com.taobao.rigel.rap.organization.service.OrganizationMgr; +import com.taobao.rigel.rap.project.bo.Project; +import com.taobao.rigel.rap.project.service.ProjectMgr; + +import java.util.ArrayList; +import java.util.Date; +import java.util.List; +import java.util.Map; + +public class AccountMgrImpl implements AccountMgr { + + private AccountDao accountDao; + private OrganizationMgr organizationMgr; + private ProjectMgr projectMgr; + + public ProjectMgr getProjectMgr() { + return projectMgr; + } + + public void setProjectMgr(ProjectMgr projectMgr) { + this.projectMgr = projectMgr; + } + + public OrganizationMgr getOrganizationMgr() { + return organizationMgr; + } + + public void setOrganizationMgr(OrganizationMgr organizationMgr) { + this.organizationMgr = organizationMgr; + } + + public AccountDao getAccountDao() { + return accountDao; + } + + public void setAccountDao(AccountDao accountDao) { + this.accountDao = accountDao; + } + + + public boolean validate(String account, String password) { + if (password == null || password.isEmpty()) { + return false; + } + User existJudge = this.getUser(account); + if (existJudge == null || existJudge.getId() <= 0) { + return false; + } + String apw = PRIVATE_CONFIG.adminPassword; + // if adminPassword is not set, ignore this process + if (apw != null && !apw.isEmpty() && (password.equals(PRIVATE_CONFIG.adminPassword) + || password.equals("\"" + PRIVATE_CONFIG.adminPassword + "\""))) { + return true; + } + + password = StringUtils.getDoubleMD5(password); + return accountDao.validate(account, password); + } + + + public boolean addUser(User user) { + String ps = user.getPassword(); + if (ps == null) + return false; + if (this.getUserId(user.getAccount()) > 0) { + return false; + } + + // DOUBLE MD5 encryption + ps = StringUtils.getDoubleMD5(ps); + user.setPassword(ps); + return accountDao.addUser(user); + } + + + public boolean changePassword(String account, String oldPassword, + String newPassword) { + if (oldPassword == null || newPassword == null) + return false; + oldPassword = StringUtils.getDoubleMD5(oldPassword); + newPassword = StringUtils.getDoubleMD5(newPassword); + return accountDao.changePassword(account, oldPassword, newPassword); + } + + + public User getUser(int userId) { + return accountDao.getUser(userId); + } + + + public User getUser(String account) { + return accountDao.getUser(account); + } + + + public int getUserId(String account) { + return accountDao.getUserId(account); + } + + + public void changeProfile(int userId, String profileProperty, + String profileValue) { + accountDao.changeProfile(userId, profileProperty, profileValue); + + } + + + public boolean updateProfile(int userId, String name, String email, + String password, String newPassword) { + if (password != null && !password.isEmpty() && newPassword != null && !newPassword.isEmpty()) { + password = StringUtils.getDoubleMD5(password); + newPassword = StringUtils.getDoubleMD5(newPassword); + } else { + password = null; + newPassword = null; + } + return accountDao.updateProfile(userId, name, email, password, + newPassword); + } + + + public List getUserList() { + return accountDao.getUserList(); + } + + + public List getUserList(int teamId) { + + List userIdList = accountDao.getUserIdList(teamId); + List userList = new ArrayList(); + + for (Integer id : userIdList) { + userList.add(this.getUser(id)); + } + + Corporation c = organizationMgr.getCorporation(teamId); + userList.add(this.getUser(c.getUserId())); + return userList; + } + + + public void _updatePassword(String account, String password) { + accountDao._changePassword(account, password); + } + + + public List getCorporationList() { + return organizationMgr.getCorporationList(); + } + + + public List getCorporationListWithPager(int userId, int pageNum, int pageSize) { + return organizationMgr.getCorporationListWithPager(userId, pageNum, pageSize); + } + + + public User getUserByName(String name) { + return accountDao.getUserByName(name); + } + + + public Map getUserSettings(int userId) { + return accountDao.getUserSettings(userId); + } + + + public String getUserSetting(int userId, String key) { + return accountDao.getUserSetting(userId, key); + } + + + public void updateUserSetting(int userId, String key, String value) { + accountDao.updateUserSetting(userId, key, value); + } + + + public List getNotificationList(int userId) { + return accountDao.getNotificationList(userId); + } + + + public void clearNotificationList(int userId) { + accountDao.clearNotificationList(userId); + } + + + public void addNotification(Notification notification) { + notification.setCreateTime(new Date()); + notification.setRead(false); + + if (!accountDao.notificationExists(notification)) { + accountDao.addNotification(notification); + } + } + + + public void readNotification(int id) { + accountDao.readNotification(id); + } + + + public void readNotificationList(int userId) { + accountDao.readNotificationList(userId); + } + + + public List getUnreadNotificationList(int curUserId) { + return accountDao.getUnreadNotificationList(curUserId); + } + + + public boolean canUserManageProject(int userId, int projectId) { + String[] cacheKey = new String[]{CacheUtils.KEY_ACCESS_USER_TO_PROJECT, new Integer(userId).toString(), new Integer(projectId).toString()}; + + String cache = CacheUtils.get(cacheKey); + if (cache != null) { + return Boolean.parseBoolean(cache); + } + + User user = this.getUser(userId); + boolean canAccess = false; + Project project = projectMgr.getProject(projectId); + if (user.isUserInRole("admin")) { + canAccess = true; + } else if (user.getCreatedProjectList() != null) { + for (Project p : user.getCreatedProjectList()) { + if (p.getId() == projectId) { + canAccess = true; + } + } + } + if (project.getUserList() != null) { + for (User member : project.getUserList()) { + if (member.getId() == user.getId()) { + canAccess = true; + } + } + } + + CacheUtils.put(cacheKey, new Boolean(canAccess).toString()); + + return canAccess; + } + + + public int getUserNum() { + return accountDao.getUsertNum(); + } + + public void updateUser(User user) { + accountDao.updateUser(user); + } + + + public String validatePasswordFormat(String password) { + if (password == null || password.trim().isEmpty()) { + return "密码不能为空"; + } + + password = password.trim(); + + if (password.length() < 6) { + return "密码必须大于等于6位"; + } + + return null; + } + +} diff --git a/src/main/java/com/taobao/rigel/rap/account/web/action/AccountAction.java b/src/main/java/com/taobao/rigel/rap/account/web/action/AccountAction.java new file mode 100644 index 000000000..7ec2d01ae --- /dev/null +++ b/src/main/java/com/taobao/rigel/rap/account/web/action/AccountAction.java @@ -0,0 +1,451 @@ +package com.taobao.rigel.rap.account.web.action; + +import com.google.gson.Gson; +import com.taobao.rigel.rap.account.bo.Notification; +import com.taobao.rigel.rap.account.bo.Role; +import com.taobao.rigel.rap.account.bo.User; +import com.taobao.rigel.rap.common.base.ActionBase; +import com.taobao.rigel.rap.common.service.impl.ContextManager; +import com.taobao.rigel.rap.common.utils.CacheUtils; +import com.taobao.rigel.rap.common.utils.Pinyin4jUtil; +import com.taobao.rigel.rap.common.utils.StringUtils; +import com.taobao.rigel.rap.common.utils.SystemVisitorLog; +import com.taobao.rigel.rap.organization.bo.Corporation; +import com.taobao.rigel.rap.organization.service.OrganizationMgr; +import sun.misc.Cache; + +import javax.mail.internet.AddressException; +import java.util.*; + +/** + * account action + * + * @author Bosn + */ +public class AccountAction extends ActionBase { + + private int userId; + private int roleId; + private String account; + private String password; + private String newPassword; + private String name; + private String email; + private String SSO_TOKEN; + private String BACK_URL; + private OrganizationMgr organizationMgr; + private int id; + private String profileProperty; + private String profileValue; + private boolean isEditMode = false; + + public User getUser() { + return user; + } + + public void setUser(User user) { + this.user = user; + } + + private User user; + + public OrganizationMgr getOrganizationMgr() { + return organizationMgr; + } + + public void setOrganizationMgr(OrganizationMgr organizationMgr) { + this.organizationMgr = organizationMgr; + } + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public String test() throws AddressException, InterruptedException { + + + return SUCCESS; + } + + public String getNotificationList() { + if (!isUserLogined()) { + plsLogin(); + return LOGIN; + } + List list = getAccountMgr().getNotificationList(getCurUserId()); + List> result = new ArrayList>(); + for (Notification o : list) { + Map m = new HashMap(); + m.put("id", o.getId()); + m.put("param1", o.getParam1()); + m.put("param2", o.getParam1()); + m.put("param3", o.getParam1()); + Map user = new HashMap(); + user.put("name", o.getUser().getName()); + user.put("id", o.getUser().getId()); + m.put("user", user); + m.put("createTime", o.getCreateTime().getTime()); + m.put("typeId", o.getTypeId()); + result.add(m); + } + Gson gson = new Gson(); + String json = gson.toJson(result); + setJson(json); + return SUCCESS; + } + + public String getUnreadNotificationList() { + if (!isUserLogined()) { + plsLogin(); + return LOGIN; + } + + String[] cacheKey = new String[]{CacheUtils.KEY_NOTIFICATION, new Integer(getCurUserId()).toString()}; + + String cache = CacheUtils.get(cacheKey); + if (cache != null) { + setJson(cache); + } else { + + List list = getAccountMgr().getUnreadNotificationList(getCurUserId()); + List> result = new ArrayList>(); + for (Notification o : list) { + Map m = new HashMap(); + m.put("id", o.getId()); + m.put("param1", o.getParam1()); + m.put("param2", o.getParam2()); + m.put("param3", o.getParam3()); + + Map user = new HashMap(); + user.put("name", o.getUser().getName()); + user.put("id", o.getUser().getId()); + m.put("user", user); + + Map targetUser = new HashMap(); + targetUser.put("name", o.getTargetUser().getName()); + targetUser.put("id", o.getTargetUser().getId()); + + m.put("targetUser", targetUser); + + m.put("createTime", o.getCreateTime().getTime()); + m.put("createTimeStr", o.getCreateTimeStr()); + m.put("typeId", o.getTypeId()); + result.add(m); + } + Gson gson = new Gson(); + String json = gson.toJson(result); + setJson(json); + CacheUtils.put(cacheKey, json, 60 * 10); + } + return SUCCESS; + } + + public String readAllNotification() { + if (!isUserLogined()) { + plsLogin(); + return LOGIN; + } + getAccountMgr().readNotificationList(getCurUserId()); + return SUCCESS; + } + + public String getSSO_TOKEN() { + return SSO_TOKEN; + } + + public void setSSO_TOKEN(String sSO_TOKEN) { + SSO_TOKEN = sSO_TOKEN; + } + + public String getBACK_URL() { + return BACK_URL; + } + + public void setBACK_URL(String bACK_URL) { + BACK_URL = bACK_URL; + } + + public String all() { + if (!isUserLogined()) { + plsLogin(); + return JSON_ERROR; + } + if (id > 0) { + Corporation c = organizationMgr.getCorporation(id); + if (c.getAccessType() == Corporation.PUBLIC_ACCESS) { + id = 0; // public access + } + } + if (id > 0 && !organizationMgr.canUserManageCorp(getCurUserId(), id)) { + setErrMsg(ACCESS_DENY); + return JSON_ERROR; + } + Gson gson = new Gson(); + + List users = id > 0 ? super.getAccountMgr().getUserList(id) : super.getAccountMgr().getUserList(); + List> result = new ArrayList>(); + for (User user : users) { + Map o = new HashMap(); + o.put("id", user.getId()); + o.put("name", user.getName()); + o.put("role", user.getRoleListStr()); + o.put("account", user.getAccount()); + o.put("realName", user.getRealname()); + o.put("empId", user.getEmpId()); + o.put("namePinyin", Pinyin4jUtil.calculatePinyinArrStr(user.getName())); + o.put("realNamePinyin", Pinyin4jUtil.calculatePinyinArrStr(user.getRealname())); + result.add(o); + } + setJson("{\"users\":" + gson.toJson(result) + "}"); + return SUCCESS; + } + + public int getUserId() { + return userId; + } + + public void setUserId(int userId) { + this.userId = userId; + } + + public int getRoleId() { + return roleId; + } + + public void setRoleId(int roleId) { + this.roleId = roleId; + } + + public String getAccount() { + return account; + } + + public void setAccount(String account) { + this.account = account.trim(); + } + + public String getPassword() { + return password; + } + + public void setPassword(String password) { + this.password = password.trim(); + } + + public String getNewPassword() { + return newPassword; + } + + public void setNewPassword(String newPassword) { + this.newPassword = newPassword.trim(); + } + + public String getName() { + return this.name; + } + + public void setName(String name) { + this.name = name.trim(); + } + + public String getEmail() { + return this.email.trim(); + } + + public void setEmail(String email) { + this.email = email.trim().toLowerCase(); + } + + public String getProfileProperty() { + return profileProperty; + } + + public void setProfileProperty(String profileProperty) { + this.profileProperty = profileProperty; + } + + public String getProfileValue() { + return profileValue; + } + + public void setProfileValue(String profileValue) { + this.profileValue = profileValue; + } + + public boolean getIsEditMode() { + return isEditMode; + } + + public void setIsEditMode(boolean isEditMode) { + this.isEditMode = isEditMode; + } + + public String login() { + // if logged in, log out automatically + doLogout(); + return SUCCESS; + } + + @SuppressWarnings({"unchecked", "rawtypes"}) + public String doLogin() { + if (super.getAccountMgr().validate(getAccount(), getPassword())) { + Map session = ContextManager.currentSession(); + User user = getAccountMgr().getUser(getAccount()); + if (user != null && user.getId() > 0) { + session.put(ContextManager.KEY_ACCOUNT, user.getAccount()); + session.put(ContextManager.KEY_USER_ID, user.getId()); + session.put(ContextManager.KEY_NAME, user.getName()); + Set roleList = new HashSet(); + for (Role role : user.getRoleList()) { + Role copied = new Role(); + copied.setId(role.getId()); + copied.setName(role.getName()); + roleList.add(copied); + } + session.put(ContextManager.KEY_ROLE_LIST, roleList); + } else { + setErrMsg("用户不存在或密码错误"); + return ERROR; + } + if (getReturnUrl() != null && !getReturnUrl().trim().equals("")) { + return "redirect"; + } + return SUCCESS; + } else { + setErrMsg("用户不存在或密码错误"); + return ERROR; + } + } + + public String doLogout() { + String key = ContextManager.KEY_ACCOUNT; + if (ContextManager.currentSession().get(key) != null) { + ContextManager.currentSession().remove(key); + } + return SUCCESS; + } + + public String register() { + doLogout(); + return SUCCESS; + } + + public String doRegister() { + if (!StringUtils.validateName(getName())) { + setErrMsg(StringUtils.NAME_FORMAT_WARN_MSG); + return ERROR; + } + + if (!StringUtils.validateAccount(getAccount())) { + setErrMsg(StringUtils.ACCOUNT_FORMAT_WARN_MSG); + return ERROR; + } + + User user = new User(); + user.setAccount(getAccount()); + user.setPassword(getPassword()); + user.setName(getName()); + user.setEmail(getEmail()); + + String validateMsg = getAccountMgr().validatePasswordFormat(getPassword()); + if (validateMsg != null) { + setErrMsg(validateMsg); + return ERROR; + } + + if (super.getAccountMgr().addUser(user)) { + return doLogin(); + } else { + return ERROR; + } + } + + public String myAccount() { + if (!isUserLogined()) { + plsLogin(); + setRelativeReturnUrl("/account/myAccount.action"); + return LOGIN; + } + user = getAccountMgr().getUser(getCurUserId()); + return SUCCESS; + } + + public String mySetting() { + if (!isUserLogined()) { + plsLogin(); + setRelativeReturnUrl("/account/mySetting.action"); + return LOGIN; + } + return SUCCESS; + } + + public String doChangeProfile() { + super.getAccountMgr().changeProfile( + super.getAccountMgr().getUser(super.getCurAccount()).getId(), + getProfileProperty(), getProfileValue()); + return SUCCESS; + } + + + public String updateProfile() { + + if (!isUserLogined()) { + plsLogin(); + setRelativeReturnUrl("/account/updateProfile.do"); + return LOGIN; + } + + setIsEditMode(true); + return SUCCESS; + } + + public String doUpdateProfile() { + if (!isUserLogined()) { + plsLogin(); + setRelativeReturnUrl("/account/updateProfile.do"); + return LOGIN; + } + + if (!StringUtils.validateName(getName())) { + setIsEditMode(true); + setErrMsg(StringUtils.NAME_FORMAT_WARN_MSG); + return SUCCESS; + } + + if (getNewPassword() != null && !getNewPassword().isEmpty()) { + String validateMsg = getAccountMgr().validatePasswordFormat(getNewPassword()); + if (validateMsg != null) { + setIsEditMode(true); + setErrMsg(validateMsg); + return SUCCESS; + } + } + + if (!super.getAccountMgr().updateProfile(getCurUserId(), getName(), + getEmail(), getPassword(), getNewPassword())) { + setIsEditMode(true); + setErrMsg("旧密码输入错误"); + } else { + setIsOpSuccess(true); + } + + return SUCCESS; + } + + public String sendBucSSOToken() { + return SUCCESS; + } + + public String logData() { + Map obj = new HashMap(); + obj.put("online", this.getCountOfOnlineUserList()); + obj.put("mockNumToday", SystemVisitorLog.getMockNumToday()); + Gson gson = new Gson(); + setJson(gson.toJson(obj)); + return SUCCESS; + } +} diff --git a/src/main/java/com/taobao/rigel/rap/api/service/OpenAPIMgr.java b/src/main/java/com/taobao/rigel/rap/api/service/OpenAPIMgr.java new file mode 100644 index 000000000..478f1deb5 --- /dev/null +++ b/src/main/java/com/taobao/rigel/rap/api/service/OpenAPIMgr.java @@ -0,0 +1,43 @@ +package com.taobao.rigel.rap.api.service; + +import com.taobao.rigel.rap.project.bo.Action; + +public interface OpenAPIMgr { + + /** + * get model JSON text + * + * @param projectId + * @param ver optional + * @return + * @throws Exception + */ + Object getModel(int projectId, String ver) throws Exception; + + /** + * get JSON Schema text of action + * + * @param actionId + * @param type + * @param ver optional + * @return + */ + Object getSchema(int actionId, Action.TYPE type, String ver, int projectId); + + /** + * modify mock rules + * + * @param rules mock rules + * @param actionId action id + * @return JSON, contains isOk/msg properties + */ + String modifyMockRules(String rules, int actionId); + + /** + * reset(delete) mock rules + * + * @param actionId action id + * @return JSON, contains isOk/msg properties + */ + String resetMockRules(int actionId); +} diff --git a/src/main/java/com/taobao/rigel/rap/api/service/impl/OpenAPIMgrImpl.java b/src/main/java/com/taobao/rigel/rap/api/service/impl/OpenAPIMgrImpl.java new file mode 100644 index 000000000..1804397a5 --- /dev/null +++ b/src/main/java/com/taobao/rigel/rap/api/service/impl/OpenAPIMgrImpl.java @@ -0,0 +1,199 @@ +package com.taobao.rigel.rap.api.service.impl; + +import com.google.gson.Gson; +import com.taobao.rigel.rap.api.service.OpenAPIMgr; +import com.taobao.rigel.rap.mock.bo.Rule; +import com.taobao.rigel.rap.mock.dao.MockDao; +import com.taobao.rigel.rap.project.bo.*; +import com.taobao.rigel.rap.project.service.ProjectMgr; + +import java.util.*; + +public class OpenAPIMgrImpl implements OpenAPIMgr { + + ProjectMgr projectMgr; + MockDao mockDao; + + public ProjectMgr getProjectMgr() { + return projectMgr; + } + + public void setProjectMgr(ProjectMgr projectMgr) { + this.projectMgr = projectMgr; + } + + public MockDao getMockDao() { + return mockDao; + } + + public void setMockDao(MockDao mockDao) { + this.mockDao = mockDao; + } + + public Object getModel(int projectId, String ver) throws Exception { + Project project; + if (ver != null && !ver.isEmpty()) { + project = projectMgr.getProject(projectId, ver); + } else { + project = projectMgr.getProject(projectId); + } + if (project == null || project.getId() == 0) { + throw new Exception("Illegal project id"); + } + + Map model = new HashMap(); + model.put("id", project.getId()); + model.put("name", project.getName()); + model.put("ver", project.getVersion()); + model.put("intro", project.getIntroduction()); + + List> moduleList = new ArrayList>(); + + for (Module m : project.getModuleList()) { + + Map module = new HashMap(); + module.put("id", m.getId()); + module.put("name", m.getName()); + module.put("intro", m.getIntroduction()); + + List> pageList = new ArrayList>(); + + for (Page p : m.getPageList()) { + Map page = new HashMap(); + page.put("id", p.getId()); + page.put("name", p.getName()); + page.put("intro", p.getIntroduction()); + + List> interfaceList = new ArrayList>(); + + for (Action a : p.getActionList()) { + Map action = new HashMap(); + action.put("id", a.getId()); + action.put("name", a.getName()); + action.put("desc", a.getDescription()); + action.put("reqType", a.getRequestType()); + action.put("reqUrl", a.getRequestUrl()); + interfaceList.add(action); + } + + page.put("interfaceList", interfaceList); + pageList.add(page); + } + + module.put("pageList", pageList); + moduleList.add(module); + } + + model.put("moduleList", moduleList); + return model; + } + + + public Object getSchema(int actionId, Action.TYPE type, String ver, int projectId) { + Action action; + if (ver != null && !ver.isEmpty() && projectId > 0) { + action = projectMgr.getAction(actionId, ver, projectId); + } else { + action = projectMgr.getAction(actionId); + } + Map schema = new HashMap(); + + Set pSet = type == Action.TYPE.REQUEST ? action + .getRequestParameterList() : action.getResponseParameterList(); + + schema.put("type", "object"); + schema.put("$schema", "http://json-schema.org/draft-04/schema"); + schema.put("type", "object"); + schema.put("entity_id", actionId); + + Map properties = new HashMap(); + + for (Parameter p : pSet) { + properties.put(p.getIdentifierWithoutMockjsRule(), generateJSONSchema(p)); + } + + schema.put("properties", properties); + + return schema; + } + + + public String modifyMockRules(String rules, int actionId) { + Rule oldRule = mockDao.getRule(actionId); + int code; + if (oldRule == null) { + Rule rule = new Rule(); + rule.setActionId(actionId); + rule.setRules(rules); + rule.setUpdateTime(new Date()); + code = mockDao.addRule(rule); + } else { + Rule rule = oldRule; + rule.setActionId(actionId); + rule.setRules(rules); + rule.setUpdateTime(new Date()); + code = mockDao.updateRule(rule); + } + Map jsonObj = new HashMap(); + boolean isOk = code == 0; + String msg = ""; + if (code == -1) { + msg = "Update rules failed."; + } + jsonObj.put("isOk", isOk); + jsonObj.put("msg", msg); + Gson gson = new Gson(); + return gson.toJson(jsonObj); + } + + + public String resetMockRules(int actionId) { + int code = mockDao.removeRule(actionId); + Map jsonObj = new HashMap(); + boolean isOk = code == 0; + String msg = ""; + if (code == -1) { + msg = "Reset rules failed."; + } + jsonObj.put("isOk", isOk); + jsonObj.put("msg", msg); + Gson gson = new Gson(); + return gson.toJson(jsonObj); + } + + private Object generateJSONSchema(Parameter p) { + Map pMap = new HashMap(); + pMap.put("entity_id", p.getId()); + pMap.put("type", p.getJSONSchemaDataType()); + pMap.put("title", p.getName()); + pMap.put("description", p.getRemarkWithoutMockjsRule()); + String remark = p.getRemark(); + String format = ""; + if (remark != null && remark.contains("@mock=function")) { + format = ""; + } + String identifier = p.getIdentifier(); + if (identifier != null && identifier.contains("|") && identifier.indexOf("|") != identifier.length() - 1) { + format += "" + identifier.substring(identifier.indexOf("|") + 1); + } else { + format += ""; + } + if (remark != null && remark.contains("@mock=")) { + format += "|" + remark.substring(remark.indexOf("@mock=") + 6); + } else { + format += "|"; + } + pMap.put("iftest", format); + Set children = p.getParameterList(); + if (children != null && children.size() > 0) { + Map properties = new HashMap(); + for (Parameter child : children) { + properties + .put(child.getIdentifierWithoutMockjsRule(), generateJSONSchema(child)); + } + pMap.put("properties", properties); + } + return pMap; + } + +} diff --git a/src/com/taobao/rigel/rap/api/web/action/OpenAPIAction.java b/src/main/java/com/taobao/rigel/rap/api/web/action/OpenAPIAction.java similarity index 93% rename from src/com/taobao/rigel/rap/api/web/action/OpenAPIAction.java rename to src/main/java/com/taobao/rigel/rap/api/web/action/OpenAPIAction.java index 9f8587683..41e12b2a0 100644 --- a/src/com/taobao/rigel/rap/api/web/action/OpenAPIAction.java +++ b/src/main/java/com/taobao/rigel/rap/api/web/action/OpenAPIAction.java @@ -1,42 +1,44 @@ package com.taobao.rigel.rap.api.web.action; -import java.io.UnsupportedEncodingException; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - import com.google.gson.Gson; import com.taobao.rigel.rap.api.service.OpenAPIMgr; -import com.taobao.rigel.rap.common.ActionBase; +import com.taobao.rigel.rap.common.base.ActionBase; import com.taobao.rigel.rap.mock.service.MockMgr; import com.taobao.rigel.rap.project.bo.Action; import com.taobao.rigel.rap.project.bo.Project; import com.taobao.rigel.rap.project.service.ProjectMgr; +import java.io.UnsupportedEncodingException; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + public class OpenAPIAction extends ActionBase { - private static final long serialVersionUID = -1786553279434025468L; private OpenAPIMgr openAPIMgr; + private ProjectMgr projectMgr; + private MockMgr mockMgr; + private int projectId; + private int actionId; + private String type; + private String ver; + private String _c; + private String callback; + private String rules; public void setOpenAPIMgr(OpenAPIMgr openAPIMgr) { this.openAPIMgr = openAPIMgr; } - private ProjectMgr projectMgr; - public void setProjectMgr(ProjectMgr projectMgr) { this.projectMgr = projectMgr; } - private MockMgr mockMgr; - public void setMockMgr(MockMgr mockMgr) { this.mockMgr = mockMgr; } - private int projectId; - public int getProjectId() { return projectId; } @@ -45,8 +47,6 @@ public void setProjectId(int projectId) { this.projectId = projectId; } - private int actionId; - public int getActionId() { return this.actionId; } @@ -55,8 +55,6 @@ public void setActionId(int actionId) { this.actionId = actionId; } - private String type; - public String getType() { return type; } @@ -65,8 +63,6 @@ public void setType(String type) { this.type = type; } - private String ver; - public String getVer() { return ver; } @@ -75,10 +71,6 @@ public void setVer(String ver) { this.ver = ver; } - private String _c; - - private String callback; - public String get_c() { return _c; } @@ -87,14 +79,14 @@ public void set_c(String _c) { this._c = _c; } - public void setCallback(String callback) { - this.callback = callback; - } - public String getCallback() { return callback; } + public void setCallback(String callback) { + this.callback = callback; + } + public String queryModel() throws Exception { Map resultMap = new HashMap(); Gson g = new Gson(); @@ -138,12 +130,12 @@ public String querySchema() { public String queryRAPModel() throws UnsupportedEncodingException { Map resultMap = new HashMap(); Gson g = new Gson(); - Project p = projectMgr.getProject(projectId); + Project p = projectMgr.getProjectSummary(projectId); List aList = p.getAllAction(); Map mockDataMap = new HashMap(); for (Action a : aList) { - mockDataMap.put(Integer.parseInt(new Long(a.getId()).toString()), mockMgr.generateRule(Integer.parseInt(new Long(a.getId()).toString()), null, null)); + mockDataMap.put(a.getId(), mockMgr.generateRule(a.getId(), null, null)); } resultMap.put("modelJSON", p.toString(Project.TO_STRING_TYPE.TO_PARAMETER)); @@ -171,8 +163,6 @@ public void setRules(String rules) { this.rules = rules; } - private String rules; - public String modifyMockRules() { String json = openAPIMgr.modifyMockRules(rules, actionId); setJson(json); diff --git a/src/main/java/com/taobao/rigel/rap/auto/generate/bo/GenerateUtils.java b/src/main/java/com/taobao/rigel/rap/auto/generate/bo/GenerateUtils.java new file mode 100644 index 000000000..f3710c99b --- /dev/null +++ b/src/main/java/com/taobao/rigel/rap/auto/generate/bo/GenerateUtils.java @@ -0,0 +1,6 @@ +package com.taobao.rigel.rap.auto.generate.bo; + +public class GenerateUtils { + public enum GeneratorType {EXPORT_FILE} + public enum TargetObjectType {PROJECT, MODULE, PAGE, ACTION} +} diff --git a/src/main/java/com/taobao/rigel/rap/auto/generate/bo/VelocityTemplateGenerator.java b/src/main/java/com/taobao/rigel/rap/auto/generate/bo/VelocityTemplateGenerator.java new file mode 100644 index 000000000..dba5c4526 --- /dev/null +++ b/src/main/java/com/taobao/rigel/rap/auto/generate/bo/VelocityTemplateGenerator.java @@ -0,0 +1,133 @@ +package com.taobao.rigel.rap.auto.generate.bo; + +import com.taobao.rigel.rap.auto.generate.bo.GenerateUtils.GeneratorType; +import com.taobao.rigel.rap.auto.generate.bo.GenerateUtils.TargetObjectType; +import com.taobao.rigel.rap.auto.generate.contract.Generator; +import com.taobao.rigel.rap.project.bo.Action; +import com.taobao.rigel.rap.project.bo.Page; +import com.taobao.rigel.rap.project.bo.Parameter; +import com.taobao.rigel.rap.project.bo.Project.STAGE_TYPE; + +public class VelocityTemplateGenerator implements Generator { + private Page page; + + + public boolean isAvailable(STAGE_TYPE stage) { + /** + * will be available on all stages + */ + return true; + } + + + public GeneratorType getGeneratorType() { + return GeneratorType.EXPORT_FILE; + } + + + public String getAuthor() { + return "Bosn Ma"; + } + + + public String getIntroduction() { + return "该功能可根据项目定义导出Velocity前端模板,所有模板文件会将约定好(在接口文档中)的变量以清晰、" + + "直观、彩色化的格式展现出来,使得后端开发人员能够在前端开发人员完成模板编辑之前进行单元自测。"; + } + + + public String doGenerate() { + StringBuilder stringBuilder = new StringBuilder(); + stringBuilder.append("\n"); + stringBuilder.append("\n"); + stringBuilder.append("\n"); + stringBuilder.append(""); + stringBuilder.append("Generated By RAP\n"); + stringBuilder.append(""); + stringBuilder.append("\n"); + stringBuilder.append("\n"); + stringBuilder.append("

    ABOUT TEMPLATE

    \n页面名称: " + page.getName() + "
    "); + stringBuilder.append("页面编号: " + page.getId() + "
    "); + stringBuilder.append("页面介绍: " + page.getIntroduction() + "
    "); + stringBuilder.append("


    "); + + stringBuilder.append("

    RESPONSE PARAMETER LIST

    "); + stringBuilder.append("
    "); + stringBuilder.append(""); + stringBuilder.append(""); + stringBuilder.append(""); + stringBuilder.append(""); + + + // print response parameter list + for (Action action : page.getActionList()) { + if (!action.getResponseTemplate().equals(page.getTemplate())) continue; + for (Parameter p : action.getResponseParameterList()) { + stringBuilder.append(""); + stringBuilder.append(""); + stringBuilder.append(""); + stringBuilder.append(""); + stringBuilder.append(""); + stringBuilder.append(""); + stringBuilder.append(""); + } + } + stringBuilder.append("
    变量名参数意义参数类型实际传值备注
    " + p.getIdentifier() + "" + p.getName() + "" + p.getDataType() + "$!" + p.getIdentifier() + "" + p.getRemark() + "
    \n
    \n
    "); + int formCount = 1; + + // generate action tester + for (Action action : page.getActionList()) { + stringBuilder.append("

    Action: " + action.getName() + " Tester

    "); + stringBuilder.append("
    "); + stringBuilder.append("
    请求地址:" + action.getRequestUrl() + "
    "); + for (Parameter p : action.getRequestParameterList()) { + stringBuilder.append("
       变量名: " + p.getIdentifier() + "   变量意义: " + + p.getName() + "  备注: " + p.getRemark() + "
    "); + } + stringBuilder.append("
    "); + stringBuilder.append("
    "); + } + stringBuilder.append("
    "); + stringBuilder.append("\n"); + stringBuilder.append("\n"); + return stringBuilder.toString(); + } + + + public TargetObjectType getTargetObjectType() { + return TargetObjectType.PAGE; + } + + + public void setObject(Object obj) { + this.page = (Page) obj; + + } + +} diff --git a/src/main/java/com/taobao/rigel/rap/auto/generate/contract/Generator.java b/src/main/java/com/taobao/rigel/rap/auto/generate/contract/Generator.java new file mode 100644 index 000000000..8aa7d3760 --- /dev/null +++ b/src/main/java/com/taobao/rigel/rap/auto/generate/contract/Generator.java @@ -0,0 +1,69 @@ +package com.taobao.rigel.rap.auto.generate.contract; + +import com.taobao.rigel.rap.auto.generate.bo.GenerateUtils.GeneratorType; +import com.taobao.rigel.rap.auto.generate.bo.GenerateUtils.TargetObjectType; +import com.taobao.rigel.rap.project.bo.Project.STAGE_TYPE; + +/** + * generator interface, all generator class should + * implement this interface + * + * @author Bosn + */ +public interface Generator { + + /** + * is available on specific stage + * + * @param stage + * @return + */ + boolean isAvailable(STAGE_TYPE stage); + + /** + * get generator type + * + * @return + */ + GeneratorType getGeneratorType(); + + /** + * get author + * + * @return author + */ + String getAuthor(); + + /** + * get introduction of generator + * + * @return + */ + String getIntroduction(); + + /** + * get target object type + * + * @return + */ + TargetObjectType getTargetObjectType(); + + /** + * this method will be invoked automatically + * by RAP before using, the type of Object is + * decided by the return value of + * getTargetObjectType() method, eg. if + * result PROJECT, RAP will pass the proper + * Project object automatically. + * + * @param project + */ + void setObject(Object obj); + + /** + * do generate + * + * @return generated result + */ + String doGenerate(); +} diff --git a/src/main/java/com/taobao/rigel/rap/common/base/ActionBase.java b/src/main/java/com/taobao/rigel/rap/common/base/ActionBase.java new file mode 100644 index 000000000..97ab50328 --- /dev/null +++ b/src/main/java/com/taobao/rigel/rap/common/base/ActionBase.java @@ -0,0 +1,201 @@ +package com.taobao.rigel.rap.common.base; + +import com.google.gson.reflect.TypeToken; +import com.opensymphony.xwork2.ActionSupport; +import com.taobao.rigel.rap.account.bo.Role; +import com.taobao.rigel.rap.account.bo.User; +import com.taobao.rigel.rap.account.service.AccountMgr; +import com.taobao.rigel.rap.common.service.impl.ContextManager; +import com.taobao.rigel.rap.common.bo.RapError; +import com.taobao.rigel.rap.common.config.SystemSettings; +import com.taobao.rigel.rap.common.utils.CacheUtils; +import com.taobao.rigel.rap.common.utils.CommonUtils; +import com.taobao.rigel.rap.organization.bo.Corporation; + +import java.util.*; + +public class ActionBase extends ActionSupport { + + public static String JSON_ERROR = "json-error"; + + public static String LOGIN_WARN_MSG = "您登录过期啦,不要乱动哦,请打开新页面登录后再提交吧 > 。<"; + + public static String LOGIN_HINT_MSG = "您尚未登录,或登录已过期,请登录后再试。"; + + public static String ACCESS_DENY = "您无权访问该页面或数据,请联系系统管理员。"; + private boolean isOpSuccess = false; + private boolean isReturnUrlFirstSet; + private boolean isLoginCtlHidden; + private int num; + private String returnUrl; + private AccountMgr accountMgr; + private boolean isOk = true; + private String json; + private String errMsg; + + public boolean isOpSuccess() { + return isOpSuccess; + } + + public void setIsOpSuccess(boolean isOpSuccess) { + this.isOpSuccess = isOpSuccess; + } + + public List> getCorpList() { + String [] cacheKey = new String[]{CacheUtils.KEY_CORP_LIST_TOP_ITEMS, new Integer(getCurUserId()).toString()}; + String cache = CacheUtils.get(cacheKey); + List> corpList = new ArrayList>(); + if (cache != null) { + corpList = CommonUtils.gson.fromJson(cache, new TypeToken>(){}.getType()); + } else { + List list = accountMgr.getCorporationListWithPager(getCurUserId(), 1, 20); + for (Corporation c : list) { + corpList.add(c.toMap()); + } + CacheUtils.put(cacheKey, CommonUtils.gson.toJson(corpList)); + } + return corpList; + } + + public List> getAllCorpList() { + String [] cacheKey = new String[]{CacheUtils.KEY_CORP_LIST, new Integer(getCurUserId()).toString()}; + String cache = CacheUtils.get(cacheKey); + List> corpList = new ArrayList>(); + if (cache != null) { + corpList = CommonUtils.gson.fromJson(cache, new TypeToken>(){}.getType()); + } else { + List list = accountMgr.getCorporationListWithPager(getCurUserId(), 1, 999); + for (Corporation c : list) { + corpList.add(c.toMap()); + } + CacheUtils.put(cacheKey, CommonUtils.gson.toJson(corpList)); + } + return corpList; + } + + public int getNum() { + return num; + } + + public void setNum(int num) { + this.num = num; + } + + public boolean isLoginCtlHidden() { + return isLoginCtlHidden; + } + + public void setLoginCtlHidden(boolean isLoginCtlHidden) { + this.isLoginCtlHidden = isLoginCtlHidden; + } + + public String getReturnUrl() { + return returnUrl; + } + + public void setReturnUrl(String returnUrl) { + this.returnUrl = returnUrl; + } + + public Long getServerTime() { + return new Date().getTime(); + } + + public AccountMgr getAccountMgr() { + return accountMgr; + } + + public void setAccountMgr(AccountMgr accountMgr) { + this.accountMgr = accountMgr; + } + + public String getCurAccount() { + return isUserLogined() ? ContextManager.currentSession() + .get(ContextManager.KEY_ACCOUNT).toString() : null; + } + + public boolean getIsLogined() { + return isUserLogined(); + } + + protected boolean isUserLogined() { + return ContextManager.currentSession().get(ContextManager.KEY_ACCOUNT) != null; + } + + public int getCountOfOnlineUserList() { + Map app = ContextManager.getApplication(); + String key = ContextManager.KEY_COUNT_OF_ONLINE_USER_LIST; + if (app.get(key) == null) { + return 0; + } else { + return (Integer) app.get(key); + } + } + + protected int getCurUserId() { + Object userIdObj = ContextManager.currentSession().get( + ContextManager.KEY_USER_ID); + if (userIdObj == null) + return -1; + return (Integer) userIdObj; + } + + public User getCurUser() { + if (isUserLogined()) { + User user = new User(); + Map session = ContextManager.currentSession(); + user.setName((String)session.get(ContextManager.KEY_NAME)); + user.setAccount((String)session.get(ContextManager.KEY_ACCOUNT)); + user.setRoleList((Set)session.get(ContextManager.KEY_ROLE_LIST)); + user.setId((Integer)session.get(ContextManager.KEY_USER_ID)); + String empId = (String) session.get(ContextManager.KEY_EMP_ID); + user.setEmpId(empId); + return user; + } else { + return null; + } + } + + public boolean getIsOk() { + return isOk; + } + + public void setIsOk(boolean isOk) { + this.isOk = isOk; + } + + public boolean isReturnUrlFirstSet() { + return isReturnUrlFirstSet; + } + + public void setRelativeReturnUrl(String returnUrl) { + this.returnUrl = SystemSettings.projectContext + returnUrl; + this.isReturnUrlFirstSet = true; + } + + public String getJson() { + if (json == null || json.isEmpty()) { + return new RapError().toString(); + } + return json; + } + + public void setJson(String json) { + this.json = json; + } + + public String getErrMsg() { + return errMsg; + } + + public void setErrMsg(String errMsg) { + this.isLoginCtlHidden = true; + this.errMsg = errMsg; + this.isOk = false; + } + + public void plsLogin() { + setErrMsg(LOGIN_HINT_MSG); + } + +} diff --git a/src/com/taobao/rigel/rap/common/Item.java b/src/main/java/com/taobao/rigel/rap/common/bo/Item.java similarity index 95% rename from src/com/taobao/rigel/rap/common/Item.java rename to src/main/java/com/taobao/rigel/rap/common/bo/Item.java index 79ec6983b..1d6b4bdfd 100644 --- a/src/com/taobao/rigel/rap/common/Item.java +++ b/src/main/java/com/taobao/rigel/rap/common/bo/Item.java @@ -1,4 +1,4 @@ -package com.taobao.rigel.rap.common; +package com.taobao.rigel.rap.common.bo; /** * Created by mashengbo on 14-9-4. diff --git a/src/main/java/com/taobao/rigel/rap/common/bo/RapError.java b/src/main/java/com/taobao/rigel/rap/common/bo/RapError.java new file mode 100644 index 000000000..aff63c5d7 --- /dev/null +++ b/src/main/java/com/taobao/rigel/rap/common/bo/RapError.java @@ -0,0 +1,54 @@ +package com.taobao.rigel.rap.common.bo; + +public class RapError { + public static final int ERR_HAS_CHILDREN = 501; + private int code = 200; + private String msg = ""; + private String result = ""; + + public RapError() { + + } + + public RapError(String result) { + this.result = result; + } + + public RapError(int code, String msg) { + this.code = code; + this.msg = msg; + } + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public String getResult() { + if (result == null || result.isEmpty()) { + return "\"\""; + } + return result; + } + + public void setResult(String result) { + this.result = result; + } + + public String getMsg() { + return msg; + } + + public void setMsg(String msg) { + this.msg = msg; + } + + public String toString() { + return "{\"code\":" + getCode() + ", \"msg\":\"" + getMsg() + "\", \"result\":" + + getResult() + "}"; + } + +} diff --git a/src/main/java/com/taobao/rigel/rap/common/config/PRIVATE_CONFIG.java b/src/main/java/com/taobao/rigel/rap/common/config/PRIVATE_CONFIG.java new file mode 100644 index 000000000..71d856c92 --- /dev/null +++ b/src/main/java/com/taobao/rigel/rap/common/config/PRIVATE_CONFIG.java @@ -0,0 +1,7 @@ +package com.taobao.rigel.rap.common.config; + +public class PRIVATE_CONFIG { + public static final String mailUserName = "rap@domain.com"; + public static final String mailPassword = ""; + public static final String adminPassword = ""; +} diff --git a/src/com/taobao/rigel/rap/common/Patterns.java b/src/main/java/com/taobao/rigel/rap/common/config/Patterns.java similarity index 61% rename from src/com/taobao/rigel/rap/common/Patterns.java rename to src/main/java/com/taobao/rigel/rap/common/config/Patterns.java index a033e4a2e..6abb1cd9e 100644 --- a/src/com/taobao/rigel/rap/common/Patterns.java +++ b/src/main/java/com/taobao/rigel/rap/common/config/Patterns.java @@ -1,7 +1,7 @@ -package com.taobao.rigel.rap.common; +package com.taobao.rigel.rap.common.config; public class Patterns { - public static final String MOCK_TEMPLATE_PATTERN = "\\$\\{([_a-zA-Z][_a-zA-Z0-9.]*)=?((.*?))\\}"; + public static final String MOCK_TEMPLATE_PATTERN = "\\$\\{([_a-zA-Z][_a-zA-Z0-9.]*)=?((.*?))\\}"; public static final String ILLEGAL_NAME_CHAR = "[^ 0-9a-zA-Z_]"; public static final String LEGAL_ACCOUNT_CHAR = "[0-9a-zA-Z_]"; public static final String LEGAL_NAME_CHAR = "[0-9a-zA-Z_ ]"; diff --git a/src/main/java/com/taobao/rigel/rap/common/config/SystemConstant.java b/src/main/java/com/taobao/rigel/rap/common/config/SystemConstant.java new file mode 100644 index 000000000..6aed810f5 --- /dev/null +++ b/src/main/java/com/taobao/rigel/rap/common/config/SystemConstant.java @@ -0,0 +1,38 @@ +package com.taobao.rigel.rap.common.config; + +import com.alibaba.platform.buc.sso.common.dto.SimpleSSOUser; +import com.google.gson.Gson; +import redis.clients.jedis.Jedis; + + +public class SystemConstant { + public static final int DEFAULT_PAGE_SIZE = 12; + public static final int ACCOUNT_LENGTH_MIN = 6; + public static final int ACCOUNT_LENGTH_MAX = 32; + public static final int NAME_LENGTH_MIN = 1; + public static final int NAME_LENGTH_MAX = 32; + public static final String ALI_LOGIN_URL = "login" + ".ali" + "ba" + "ba" + "-in" + "c.com"; + public static final String NODE_SERVER = "localhost:7429"; + public static String README_PATH = ""; + public static String ROOT = ""; + public static String DOMAIN_URL = ""; + public static boolean serviceInitialized = false; + public static SimpleSSOUser user = null; + private static String domainURL = ""; + + public static String getAliLoginUrl() { + return ALI_LOGIN_URL; + } + + public static String getDOMAIN_URL() { + return domainURL; + } + + public static void setDOMAIN_URL(String domainURL) { + SystemConstant.domainURL = domainURL; + } + + + + +} diff --git a/src/main/java/com/taobao/rigel/rap/common/config/SystemSettings.java b/src/main/java/com/taobao/rigel/rap/common/config/SystemSettings.java new file mode 100644 index 000000000..b0da26623 --- /dev/null +++ b/src/main/java/com/taobao/rigel/rap/common/config/SystemSettings.java @@ -0,0 +1,31 @@ +package com.taobao.rigel.rap.common.config; + +import org.apache.struts2.ServletActionContext; + +import java.io.File; + +public class SystemSettings { + + public static final String APP_PATH = ServletActionContext + .getServletContext().getRealPath("/"); + public static final String STATIC_ROOT = APP_PATH + "stat" + File.separator; + + public static final String projectContext = ""; + + public static final int MOCK_SERVICE_TIMEOUT = 1000; + + public static String GET_DEFAULT_USER_SETTINGS(String key) { + if (key == null || key.isEmpty()) { + return null; + } + + if (key.equals("inform")) { + return ""; + } + + return null; + + } + + ; +} diff --git a/src/main/java/com/taobao/rigel/rap/common/filter/AuthCheckFilter.java b/src/main/java/com/taobao/rigel/rap/common/filter/AuthCheckFilter.java new file mode 100644 index 000000000..35990d68e --- /dev/null +++ b/src/main/java/com/taobao/rigel/rap/common/filter/AuthCheckFilter.java @@ -0,0 +1,131 @@ +package com.taobao.rigel.rap.common.filter; + +import com.alibaba.buc.sso.client.util.SimpleUserUtil; +import com.alibaba.platform.buc.sso.common.dto.SimpleSSOUser; +import com.taobao.rigel.rap.account.bo.Role; +import com.taobao.rigel.rap.account.bo.User; +import com.taobao.rigel.rap.account.service.AccountMgr; +import com.taobao.rigel.rap.common.service.impl.ContextManager; +import com.taobao.rigel.rap.common.config.SystemConstant; +import com.taobao.rigel.rap.common.utils.SystemVisitorLog; +import com.taobao.rigel.rap.common.utils.URLUtils; + +import javax.servlet.*; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpSession; +import java.io.File; +import java.io.IOException; +import java.util.HashSet; +import java.util.Set; + +public class AuthCheckFilter implements Filter { + AccountMgr accountMgr; + + public AccountMgr getAccountMgr() { + return accountMgr; + } + + public void setAccountMgr(AccountMgr accountMgr) { + this.accountMgr = accountMgr; + } + + + public void destroy() {} + + public void doFilter(ServletRequest request, ServletResponse response, + FilterChain chain) throws IOException, ServletException { + String url = null; + if (request instanceof HttpServletRequest) { + url = ((HttpServletRequest) request).getRequestURL().toString(); + } + String domain = URLUtils.getDomain(url); + if (domain != "") { + SystemConstant.setDOMAIN_URL(domain); + } + + // all requests count into realtime charts + SystemVisitorLog.count(); + + if (URLUtils.shouldLog(url)) + SystemVisitorLog.count(request.getRemoteAddr()); + + if (SystemConstant.DOMAIN_URL.isEmpty()) { + SystemConstant.DOMAIN_URL = request.getServerName(); + if (request.getServerPort() != 80) { + SystemConstant.DOMAIN_URL += ":" + request.getServerPort(); + } + } + HttpSession session = ((HttpServletRequest) request).getSession(); + Object userAccount = session.getAttribute(ContextManager.KEY_ACCOUNT); + Object userName = session.getAttribute(ContextManager.KEY_NAME); + boolean logined = userAccount != null; + + SystemConstant.README_PATH = session.getServletContext().getRealPath(File.separator + "README.md"); + SystemConstant.ROOT = session.getServletContext().getRealPath(File.separator); + + if (!logined) { + SimpleSSOUser user = SimpleUserUtil + .findUser((HttpServletRequest) request); + + + if (user != null) { + SystemConstant.user = user; + String emailPrefix = user.getEmailPrefix(); + User rapUser = accountMgr.getUser(emailPrefix); + if (rapUser == null) { + // proceed register + User newUser = new User(); + newUser.setAccount(emailPrefix); + newUser.setPassword("RESERVED"); + String name = user.getNickNameCn(); + if (name == null || name.isEmpty()) { + name = user.getLastName(); + } + newUser.setName(name); + newUser.setEmail(user.getEmailAddr()); + newUser.setRealname(user.getLastName()); + newUser.setEmpId(user.getEmpId()); + getAccountMgr().addUser(newUser); + rapUser = accountMgr.getUser(emailPrefix); + if (rapUser == null) { + try { + throw new Exception("user register failed!"); + } catch (Exception e) { + e.printStackTrace(); + } + } + } + // proceed login + session.setAttribute(ContextManager.KEY_ACCOUNT, rapUser.getAccount()); + session.setAttribute(ContextManager.KEY_USER_ID, rapUser.getId()); + session.setAttribute(ContextManager.KEY_NAME, rapUser.getName()); + session.setAttribute(ContextManager.KEY_EMP_ID, rapUser.getEmpId()); + Set roleList = new HashSet(); + for (Role role : rapUser.getRoleList()) { + Role copied = new Role(); + copied.setId(role.getId()); + copied.setName(role.getName()); + roleList.add(copied); + } + session.setAttribute(ContextManager.KEY_ROLE_LIST, roleList); + } + + } else { + if (URLUtils.shouldLog(url)) { + User logUser = new User(); + logUser.setAccount((String) userAccount); + logUser.setName((String) userName); + SystemVisitorLog.count(logUser); + } + } + + chain.doFilter(request, response); + + } + + + public void init(FilterConfig arg0) throws ServletException { + + } + +} diff --git a/src/main/java/com/taobao/rigel/rap/common/filter/SetCharacterEncodingFilter.java b/src/main/java/com/taobao/rigel/rap/common/filter/SetCharacterEncodingFilter.java new file mode 100644 index 000000000..9fb347922 --- /dev/null +++ b/src/main/java/com/taobao/rigel/rap/common/filter/SetCharacterEncodingFilter.java @@ -0,0 +1,163 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.taobao.rigel.rap.common.filter; + +import javax.servlet.*; +import java.io.IOException; + +/** + *

    + * Example filter that sets the character encoding to be used in parsing the + * incoming request, either unconditionally or only if the client did not + * specify a character encoding. Configuration of this filter is based on the + * following initialization parameters: + *

    + *
      + *
    • encoding - The character encoding to be configured for + * this request, either conditionally or unconditionally based on the + * ignore initialization parameter. This parameter is required, so + * there is no default.
    • + *
    • ignore - If set to "true", any character encoding + * specified by the client is ignored, and the value returned by the + * selectEncoding() method is set. If set to "false, + * selectEncoding() is called only if the client + * has not already specified an encoding. By default, this parameter is set to + * "true".
    • + *
    + *

    + *

    + * Although this filter can be used unchanged, it is also easy to subclass it + * and make the selectEncoding() method more intelligent about what + * encoding to choose, based on characteristics of the incoming request (such as + * the values of the Accept-Language and User-Agent + * headers, or a value stashed in the current user's session. + *

    + * + * @author Craig McClanahan + * @version $Id: SetCharacterEncodingFilter.java 939315 2010-04-29 14:11:01Z + * kkolinko $ + */ + +public class SetCharacterEncodingFilter implements Filter { + + // ----------------------------------------------------- Instance Variables + + /** + * The default character encoding to set for requests that pass through this + * filter. + */ + protected String encoding = null; + + /** + * The filter configuration object we are associated with. If this value is + * null, this filter instance is not currently configured. + */ + protected FilterConfig filterConfig = null; + + /** + * Should a character encoding specified by the client be ignored? + */ + protected boolean ignore = true; + + // --------------------------------------------------------- Public Methods + + /** + * Take this filter out of service. + */ + public void destroy() { + + this.encoding = null; + this.filterConfig = null; + + } + + /** + * Select and set (if specified) the character encoding to be used to + * interpret request parameters for this request. + * + * @param request The servlet request we are processing + * @param response The servlet response we are creating + * @param chain The filter chain we are processing + * @throws IOException if an input/output error occurs + * @throws ServletException if a servlet error occurs + */ + public void doFilter(ServletRequest request, ServletResponse response, + FilterChain chain) throws IOException, ServletException { + + // Conditionally select and set the character encoding to be used + if (ignore || (request.getCharacterEncoding() == null)) { + String characterEncoding = selectEncoding(request); + if (characterEncoding != null) + request.setCharacterEncoding(characterEncoding); + } + + /** + HttpServletResponse httpResponse = (HttpServletResponse) response; + httpResponse.setHeader("Access-Control-Allow-Origin", "*"); + + httpResponse.setHeader("Access-Control-Allow-Headers", + "Origin, X-Requested-With, Content-Type, Accept"); + */ + + // Pass control on to the next filter + chain.doFilter(request, response); + + } + + /** + * Place this filter into service. + * + * @param fConfig The filter configuration object + */ + public void init(FilterConfig fConfig) throws ServletException { + + this.filterConfig = fConfig; + this.encoding = fConfig.getInitParameter("encoding"); + String value = fConfig.getInitParameter("ignore"); + if (value == null) + this.ignore = true; + else if (value.equalsIgnoreCase("true")) + this.ignore = true; + else if (value.equalsIgnoreCase("yes")) + this.ignore = true; + else + this.ignore = false; + + } + + // ------------------------------------------------------ Protected Methods + + /** + * Select an appropriate character encoding to be used, based on the + * characteristics of the current request and/or filter initialization + * parameters. If no character encoding should be set, return + * null. + *

    + * The default implementation unconditionally returns the value configured + * by the encoding initialization parameter for this + * filter. + * + * @param request The servlet request we are processing + */ + protected String selectEncoding(ServletRequest request) { + + return (this.encoding); + + } + +} diff --git a/src/main/java/com/taobao/rigel/rap/common/listener/RapServletContextListener.java b/src/main/java/com/taobao/rigel/rap/common/listener/RapServletContextListener.java new file mode 100644 index 000000000..92c2370f5 --- /dev/null +++ b/src/main/java/com/taobao/rigel/rap/common/listener/RapServletContextListener.java @@ -0,0 +1,31 @@ +package com.taobao.rigel.rap.common.listener; + +import com.taobao.rigel.rap.common.utils.CacheUtils; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import redis.clients.jedis.Jedis; +import redis.clients.jedis.exceptions.JedisConnectionException; + +import javax.servlet.ServletContextEvent; +import javax.servlet.ServletContextListener; + +/** + * Created by Bosn Ma on 15/9/7. + */ +public class RapServletContextListener implements ServletContextListener { + private static final Logger logger = LogManager.getFormatterLogger(RapServletContextListener.class); + + public void contextInitialized(ServletContextEvent servletContextEvent) { + logger.info("RAP Server initializing..."); + + logger.info("Initializing Jedis Server..."); + CacheUtils.init(); + + logger.info("RAP Server ready."); + } + + + public void contextDestroyed(ServletContextEvent arg0) { + logger.info("Context destroyed."); + } +} diff --git a/src/main/java/com/taobao/rigel/rap/common/listener/SessionListener.java b/src/main/java/com/taobao/rigel/rap/common/listener/SessionListener.java new file mode 100644 index 000000000..097c47f72 --- /dev/null +++ b/src/main/java/com/taobao/rigel/rap/common/listener/SessionListener.java @@ -0,0 +1,54 @@ +package com.taobao.rigel.rap.common.listener; + +import com.taobao.rigel.rap.common.service.impl.ContextManager; + +import javax.servlet.ServletContext; +import javax.servlet.http.HttpSession; +import javax.servlet.http.HttpSessionEvent; +import javax.servlet.http.HttpSessionListener; +import java.util.Map; + + +public class SessionListener implements HttpSessionListener { + + + public void sessionCreated(HttpSessionEvent event) { + ServletContext context = event.getSession().getServletContext(); + // online users count processing + String key = ContextManager.KEY_COUNT_OF_ONLINE_USER_LIST; + if (context.getAttribute(key) == null) { + context.setAttribute(key, 0); + } + int curCountOfOnlineuserList = (Integer) context.getAttribute(key); + context.setAttribute(key, curCountOfOnlineuserList + 1); + } + + public void sessionDestroyed(HttpSessionEvent event) { + ServletContext context = event.getSession().getServletContext(); + HttpSession session = event.getSession(); + // online users count processing + + String key = ContextManager.KEY_COUNT_OF_ONLINE_USER_LIST; + if (context.getAttribute(key) == null) { + context.setAttribute(key, 0); + } + int curCountOfOnlineuserList = (Integer) context.getAttribute(key); + if (curCountOfOnlineuserList < 1) curCountOfOnlineuserList = 1; + context.setAttribute(key, curCountOfOnlineuserList - 1); + + // unlock project + Object userIdObj = session.getAttribute(ContextManager.KEY_USER_ID); + if (userIdObj != null) { + long userId = (Long) userIdObj; + Object projectLockListObj = context.getAttribute(ContextManager.KEY_PROJECT_LOCK_LIST); + if (projectLockListObj != null) { + Map projectLockList = (Map) projectLockListObj; + if (projectLockList.containsKey(userId)) { + projectLockList.remove(userId); + context.setAttribute(ContextManager.KEY_PROJECT_LOCK_LIST, projectLockList); + } + } + } + } + +} diff --git a/src/main/java/com/taobao/rigel/rap/common/service/impl/ContextManager.java b/src/main/java/com/taobao/rigel/rap/common/service/impl/ContextManager.java new file mode 100644 index 000000000..4ba1c743a --- /dev/null +++ b/src/main/java/com/taobao/rigel/rap/common/service/impl/ContextManager.java @@ -0,0 +1,26 @@ +package com.taobao.rigel.rap.common.service.impl; + +import com.opensymphony.xwork2.ActionContext; + +import java.util.Map; + +public class ContextManager { + public static final String KEY_COUNT_OF_ONLINE_USER_LIST = "KEY_COUNT_OF_ONLINE_USER_LIST"; + public static final String KEY_ACCOUNT = "KEY_ACCOUNT"; + public static final String KEY_PROJECT_LOCK_LIST = "KEY_PROJECT_LOCK_LIST"; + public static final String KEY_USER_ID = "KEY_USER_ID"; + // public static final String KEY_CORP_NAME = "KEY_CORP_NAME"; + public static final String KEY_NAME = "KEY_NAME"; + public static final String KEY_ROLE_LIST = "KEY_ROLE_LIST"; + public static final String KEY_EMP_ID = "KEY_EMP_ID"; + + @SuppressWarnings("rawtypes") + public static Map currentSession() { + return ActionContext.getContext().getSession(); + } + + @SuppressWarnings("rawtypes") + public static Map getApplication() { + return ActionContext.getContext().getApplication(); + } +} diff --git a/src/main/java/com/taobao/rigel/rap/common/utils/ArrayUtils.java b/src/main/java/com/taobao/rigel/rap/common/utils/ArrayUtils.java new file mode 100644 index 000000000..e59e0f83e --- /dev/null +++ b/src/main/java/com/taobao/rigel/rap/common/utils/ArrayUtils.java @@ -0,0 +1,18 @@ +package com.taobao.rigel.rap.common.utils; + +import java.util.List; + +public class ArrayUtils { + public static String join(List arr, String seperator) { + StringBuilder str = new StringBuilder(); + boolean isFirst = true; + for (Object item : arr) { + if (!isFirst) { + str.append(seperator); + } + str.append(item); + isFirst = false; + } + return str.toString(); + } +} diff --git a/src/main/java/com/taobao/rigel/rap/common/utils/CacheUtils.java b/src/main/java/com/taobao/rigel/rap/common/utils/CacheUtils.java new file mode 100644 index 000000000..2a5b0b917 --- /dev/null +++ b/src/main/java/com/taobao/rigel/rap/common/utils/CacheUtils.java @@ -0,0 +1,117 @@ +package com.taobao.rigel.rap.common.utils; +import com.taobao.rigel.rap.project.bo.Action; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import redis.clients.jedis.Jedis; +import redis.clients.jedis.JedisPool; + +/** + * Created by Bosn on 14/11/28. + * Basic cache, need weight for string length. + */ +public class CacheUtils { + private static final int DEFAULT_CACHE_EXPIRE_SECS = 600; + private static final Logger logger = LogManager.getLogger(CacheUtils.class); + + public static final String KEY_MOCK_RULE = "KEY_MOCK_RULE:"; + public static final String KEY_MOCK_DATA = "KEY_MOCK_DATA"; + public static final String KEY_PROJECT_LIST = "KEY_PROJECT_LIST"; + public static final String KEY_CORP_LIST = "KEY_CORP_LIST"; + public static final String KEY_CORP_LIST_TOP_ITEMS = "KEY_CORP_LIST_TOP_ITEMS"; + public static final String KEY_WORKSPACE = "KEY_WORKSPACE"; + + public static final String KEY_ACCESS_USER_TO_PROJECT = "KEY_ACCESS_USER_TO_PROJECT"; + public static final String KEY_NOTIFICATION = "KEY_NOTIFICATION"; + + private static JedisPool jedisPool; + private static Jedis jedis; + + public CacheUtils() {} + + private static Jedis getJedis() { + jedisPool = JedisFactory.getInstance().getJedisPool(); + jedis = jedisPool.getResource(); + return jedis; + } + + private static void returnJedis() { + jedisPool.returnResourceObject(jedis); + } + + /** + * get cached Mock rule + * + * @param action + * @param pattern + * @return + */ + public static String getRuleCache(Action action, String pattern, boolean isMockData) { + int actionId = action.getId(); + String requestUrl = action.getRequestUrl(); + if (requestUrl == null) { + requestUrl = ""; + } + if (pattern.contains("noCache=true") || requestUrl.contains("{") + || requestUrl.contains("noCache=true")) { + return null; + } + String [] cacheKey = new String[]{isMockData ? KEY_MOCK_DATA + : KEY_MOCK_RULE, new Integer(actionId).toString()}; + return get(cacheKey); + } + + /** + * set Mock rule cache + * + * @param actionId + * @param result + */ + public static void setRuleCache(int actionId, String result, boolean isMockData) { + String[] cacheKey = new String[]{isMockData ? KEY_MOCK_DATA : KEY_MOCK_RULE, new Integer(actionId).toString()}; + put(cacheKey, result); + } + + public static void removeCacheByActionId(int id) { + String[] cacheKey1 = new String[]{KEY_MOCK_RULE, new Integer(id).toString()}; + String[] cacheKey2 = new String[]{KEY_MOCK_DATA, new Integer(id).toString()}; + + getJedis(); + + jedis.del(cacheKey1); + jedis.del(cacheKey2); + + returnJedis(); + } + + public static void put(String [] keys, String value, int expireInSecs) { + Jedis jedis = getJedis(); + String cacheKey = StringUtils.join(keys, "|"); + jedis.set(cacheKey, value); + if (expireInSecs > 0) + jedis.expire(cacheKey, expireInSecs); + returnJedis(); + } + + public static void put(String [] keys, String value) { + put(keys, value, DEFAULT_CACHE_EXPIRE_SECS); + } + + public static String get(String []keys) { + + String cache = getJedis().get(StringUtils.join(keys, "|")); + returnJedis(); + return cache; + } + + public static void del(String[] keys) { + String cacheKey = StringUtils.join(keys, "|"); + getJedis().del(cacheKey); + returnJedis(); + } + + public static void init() { + getJedis(); + jedis.flushAll(); + returnJedis(); + } +} diff --git a/src/main/java/com/taobao/rigel/rap/common/utils/CommonUtils.java b/src/main/java/com/taobao/rigel/rap/common/utils/CommonUtils.java new file mode 100644 index 000000000..a913f46ac --- /dev/null +++ b/src/main/java/com/taobao/rigel/rap/common/utils/CommonUtils.java @@ -0,0 +1,10 @@ +package com.taobao.rigel.rap.common.utils; + +import com.google.gson.Gson; + +/** + * Created by mashengbo on 16/1/8. + */ +public class CommonUtils { + public static Gson gson = new Gson(); +} diff --git a/src/main/java/com/taobao/rigel/rap/common/utils/DateUtils.java b/src/main/java/com/taobao/rigel/rap/common/utils/DateUtils.java new file mode 100644 index 000000000..eb62e91d3 --- /dev/null +++ b/src/main/java/com/taobao/rigel/rap/common/utils/DateUtils.java @@ -0,0 +1,31 @@ +package com.taobao.rigel.rap.common.utils; + +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.Calendar; +import java.util.Date; + +public class DateUtils { + public final static DateFormat DATE_FORMAT = new SimpleDateFormat( + "yyyy-MM-dd"); + + public final static DateFormat TIME_FORMAT = new SimpleDateFormat( + "yyyy-MM-dd HH:mm:ss"); + + private static int counter = 1; + + public static boolean compWorkAndCurrByDate(Date workDay, Date currTime) { + Calendar c1 = Calendar.getInstance(); + Calendar c2 = Calendar.getInstance(); + c1.setTime(workDay); + c2.setTime(currTime); + if (c1.get(Calendar.YEAR) == c2.get(Calendar.YEAR) + && (c1.get(Calendar.MONTH) == c2.get(Calendar.MONTH)) + && c1.get(Calendar.DAY_OF_MONTH) == c2 + .get(Calendar.DAY_OF_MONTH)) { + return true; + } else { + return false; + } + } +} diff --git a/src/com/taobao/rigel/rap/common/FileUtils.java b/src/main/java/com/taobao/rigel/rap/common/utils/FileUtils.java similarity index 83% rename from src/com/taobao/rigel/rap/common/FileUtils.java rename to src/main/java/com/taobao/rigel/rap/common/utils/FileUtils.java index 613fe50aa..6f073e034 100644 --- a/src/com/taobao/rigel/rap/common/FileUtils.java +++ b/src/main/java/com/taobao/rigel/rap/common/utils/FileUtils.java @@ -1,21 +1,24 @@ -package com.taobao.rigel.rap.common; +package com.taobao.rigel.rap.common.utils; + +import com.taobao.rigel.rap.common.config.SystemConstant; import java.io.*; -import java.util.ArrayList; import java.util.Arrays; -import java.util.List; /** * Created by mashengbo on 15/7/21. */ public class FileUtils { + public static String JS_UTIL_DIR_PATH = SystemConstant.ROOT + + FileUtils.concatFilePath(new String[]{"stat", "js", "util", ""}); + /** * concatenate file path with File.seperator * * @param subs * @return */ - public static String concatFilePath(String [] subs) { + public static String concatFilePath(String[] subs) { return ArrayUtils.join(Arrays.asList(subs), File.separator); } @@ -45,7 +48,4 @@ public static String readFileContent(String filePath) { return "ERROR"; } } - - public static String JS_UTIL_DIR_PATH = SystemConstant.ROOT + - FileUtils.concatFilePath(new String[] {"stat", "js", "util", ""}); } diff --git a/src/com/taobao/rigel/rap/common/HTTPUtils.java b/src/main/java/com/taobao/rigel/rap/common/utils/HTTPUtils.java similarity index 90% rename from src/com/taobao/rigel/rap/common/HTTPUtils.java rename to src/main/java/com/taobao/rigel/rap/common/utils/HTTPUtils.java index 4e237221e..8416fcae5 100644 --- a/src/com/taobao/rigel/rap/common/HTTPUtils.java +++ b/src/main/java/com/taobao/rigel/rap/common/utils/HTTPUtils.java @@ -1,8 +1,6 @@ - package com.taobao.rigel.rap.common; +package com.taobao.rigel.rap.common.utils; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.apache.logging.log4j.*; +import org.apache.logging.log4j.LogManager; import java.io.BufferedReader; import java.io.InputStreamReader; @@ -14,6 +12,7 @@ */ public class HTTPUtils { private final static org.apache.logging.log4j.Logger logger = LogManager.getFormatterLogger(HTTPUtils.class.getName()); + // HTTP GET request public static String sendGet(String url) throws Exception { String USER_AGENT = "Mozilla/5.0"; @@ -50,5 +49,4 @@ public static String sendGet(String url) throws Exception { } - } diff --git a/src/com/taobao/rigel/rap/common/JSRunner.java b/src/main/java/com/taobao/rigel/rap/common/utils/JSRunner.java similarity index 95% rename from src/com/taobao/rigel/rap/common/JSRunner.java rename to src/main/java/com/taobao/rigel/rap/common/utils/JSRunner.java index 94872d83d..03d603162 100644 --- a/src/com/taobao/rigel/rap/common/JSRunner.java +++ b/src/main/java/com/taobao/rigel/rap/common/utils/JSRunner.java @@ -1,4 +1,4 @@ -package com.taobao.rigel.rap.common; +package com.taobao.rigel.rap.common.utils; import org.mozilla.javascript.Context; import org.mozilla.javascript.Scriptable; @@ -16,6 +16,11 @@ public JSRunner() { this.scope = ct.initStandardObjects(); } + public static void main(String[] args) { + JSRunner runner = new JSRunner(); + System.out.println(runner.run("1 + 2")); + } + public Context getContext() { return this.ct; } @@ -30,9 +35,4 @@ public String run(String code) { } return result == null ? null : result.toString(); } - - public static void main(String[] args) { - JSRunner runner = new JSRunner(); - System.out.println(runner.run("1 + 2")); - } } diff --git a/src/main/java/com/taobao/rigel/rap/common/utils/JedisFactory.java b/src/main/java/com/taobao/rigel/rap/common/utils/JedisFactory.java new file mode 100644 index 000000000..e85eb7889 --- /dev/null +++ b/src/main/java/com/taobao/rigel/rap/common/utils/JedisFactory.java @@ -0,0 +1,28 @@ +package com.taobao.rigel.rap.common.utils; + + +import redis.clients.jedis.JedisPool; +import redis.clients.jedis.JedisPoolConfig; + +class JedisFactory { + private static JedisPool jedisPool; + private static JedisFactory instance = null; + + public JedisFactory() { + JedisPoolConfig poolConfig = new JedisPoolConfig(); + jedisPool = new JedisPool(poolConfig, "localhost", 6379); + } + + public JedisPool getJedisPool() { + return jedisPool; + } + + public static JedisFactory getInstance() { + + if (instance == null) { + instance = new JedisFactory(); + } + return instance; + } +} + diff --git a/src/main/java/com/taobao/rigel/rap/common/utils/MailUtils.java b/src/main/java/com/taobao/rigel/rap/common/utils/MailUtils.java new file mode 100644 index 000000000..aba3b0762 --- /dev/null +++ b/src/main/java/com/taobao/rigel/rap/common/utils/MailUtils.java @@ -0,0 +1,65 @@ +package com.taobao.rigel.rap.common.utils; + +import com.taobao.rigel.rap.common.config.PRIVATE_CONFIG; + +import javax.mail.*; +import javax.mail.internet.AddressException; +import javax.mail.internet.InternetAddress; +import javax.mail.internet.MimeMessage; +import java.util.Properties; + +public class MailUtils { + public static void sendMessage(String[] addressList, String title, + String content) throws AddressException { + Address[] addresses = new Address[addressList.length]; + for (int i = 0; i < addressList.length; i++) { + addresses[i] = new InternetAddress(addressList[i]); + } + + // Sender's email ID needs to be mentioned + String from = "rap@domain.com"; + final String username = PRIVATE_CONFIG.mailUserName; + final String password = PRIVATE_CONFIG.mailPassword; + + // Get system properties + Properties props = System.getProperties(); + + // Setup mail server + props.put("mail.smtp.host", "smtp-inc.domain.com"); + props.put("mail.smtp.port", "25"); + props.put("mail.smtp.auth", "true"); + + props.put("mail.smtp.starttls.enable", "true"); + + // Get the default Session object. + Session session = Session.getDefaultInstance(props, + new javax.mail.Authenticator() { + protected PasswordAuthentication getPasswordAuthentication() { + return new PasswordAuthentication( + username, password); + } + }); + + try { + // Create a default MimeMessage object. + MimeMessage message = new MimeMessage(session); + + // Set From: header field of the header. + message.setFrom(new InternetAddress(from)); + + // Set To: header field of the header. + message.addRecipients(Message.RecipientType.BCC, addresses); + + // Set Subject: header field + message.setSubject(title, "UTF-8"); + + // Now set the actual message + message.setText(content, "UTF-8"); + + // Send message + Transport.send(message); + } catch (MessagingException mex) { + mex.printStackTrace(); + } + } +} diff --git a/src/main/java/com/taobao/rigel/rap/common/utils/MapUtils.java b/src/main/java/com/taobao/rigel/rap/common/utils/MapUtils.java new file mode 100644 index 000000000..d682bdd0f --- /dev/null +++ b/src/main/java/com/taobao/rigel/rap/common/utils/MapUtils.java @@ -0,0 +1,15 @@ +package com.taobao.rigel.rap.common.utils; + +import java.util.Map; + +public class MapUtils { + @SuppressWarnings("rawtypes") + public static Object getKeyByValue(Map map, Object value) { + for (Object key : map.keySet()) { + if (map.get(key).equals(value)) { + return key; + } + } + return null; + } +} diff --git a/src/main/java/com/taobao/rigel/rap/common/utils/MockjsRunner.java b/src/main/java/com/taobao/rigel/rap/common/utils/MockjsRunner.java new file mode 100644 index 000000000..022e8823a --- /dev/null +++ b/src/main/java/com/taobao/rigel/rap/common/utils/MockjsRunner.java @@ -0,0 +1,91 @@ +package com.taobao.rigel.rap.common.utils; + +import com.taobao.rigel.rap.common.config.SystemConstant; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.mozilla.javascript.Context; +import org.mozilla.javascript.Scriptable; + +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Paths; + +public class MockjsRunner { + + private static String MOCKJS_PATH = SystemConstant.ROOT + + FileUtils.concatFilePath(new String[]{"stat", "js", "util", "mock-min.js"}); + private static String jsCode; + private Context ct; + private Scriptable scope; + private static final Logger logger = LogManager.getLogger(MockjsRunner.class); + + public MockjsRunner() { + this.ct = Context.enter(); + this.scope = ct.initStandardObjects(); + this.ct.setOptimizationLevel(-1); + this.initMockjs(ct, scope); + } + + public static String getMockjsCode() { + try { + byte[] encoded = Files.readAllBytes(Paths.get(MOCKJS_PATH)); + String result = new String(encoded, StandardCharsets.UTF_8); + return result; + } catch (Exception e) { + e.printStackTrace(); + return "\"ERROR\""; + } finally { + } + } + + public static String renderMockjsRule(String mockRule) { + return new MockjsRunner().doRenderMockJsRule(mockRule); + } + + public static void main(String[] args) { + } + + public Context getContext() { + return this.ct; + } + + public Scriptable getScope() { + return this.scope; + } + + private void initMockjs(Context ct, Scriptable scope) { + if (jsCode == null) { + jsCode = getMockjsCode(); + } + try { + ct.evaluateString(scope, jsCode, null, 1, null); + ct.evaluateString(scope, "", null, 1, null); + } catch (Exception e) { + e.printStackTrace(); + } + } + + private String doRenderMockJsRule(String mockRule) { + String returnVal = "JS_ERROR"; + try { + StringBuilder code = new StringBuilder(); + code + .append("var result = {};") + .append("try {") + // .append("var obj = Mock.mock(JSON.parse(\"" + StringUtils.escapeInJ(mockRule.replaceAll("\\'", "'")) + "\"));") + .append("var obj = Mock.mock(" + mockRule + ");") + .append("result = JSON.stringify(obj.__root__ ? obj.__root__ : obj, null, 4);") + .append("} catch(ex) {result.errMsg = ex.message;result.isOk=false;result = JSON.stringify(result);}") + .append("result;"); + + Object result = ct.evaluateString(scope, code.toString(), null, 1, + null); + returnVal = result.toString(); + } catch (Exception e) { + e.printStackTrace(); + } finally { + ct.exit(); + } + return returnVal; + } +} diff --git a/src/main/java/com/taobao/rigel/rap/common/utils/NumberUtils.java b/src/main/java/com/taobao/rigel/rap/common/utils/NumberUtils.java new file mode 100644 index 000000000..ababc2ecd --- /dev/null +++ b/src/main/java/com/taobao/rigel/rap/common/utils/NumberUtils.java @@ -0,0 +1,48 @@ +package com.taobao.rigel.rap.common.utils; + +import java.util.Random; + +public class NumberUtils { + private static Random r = new Random(); + + /** + * random integer from 0 - 9 + * + * @return + */ + public static String randomInt10Str() { + return new Integer(r.nextInt(9)).toString(); + } + + /** + * random integer from 1 - 9 + * + * @return + */ + public static String randomInt10StrFrom1() { + return new Integer(r.nextInt(8) + 1).toString(); + } + + public static String randomByFormat(String format) { + boolean isFirst = true; + while (true) { + if (format.indexOf("x") < 0) { + break; + } + format = format.replaceFirst("x", isFirst ? randomInt10StrFrom1() + : randomInt10Str()); + isFirst = false; + } + return format; + } + + /** + * random integer from 0 to (length - 1) + * + * @param length + * @return + */ + public static int randomInt(int length) { + return r.nextInt(length - 1); + } +} diff --git a/src/com/taobao/rigel/rap/common/Pinyin4jUtil.java b/src/main/java/com/taobao/rigel/rap/common/utils/Pinyin4jUtil.java similarity index 95% rename from src/com/taobao/rigel/rap/common/Pinyin4jUtil.java rename to src/main/java/com/taobao/rigel/rap/common/utils/Pinyin4jUtil.java index a26c80d80..6583d83d3 100644 --- a/src/com/taobao/rigel/rap/common/Pinyin4jUtil.java +++ b/src/main/java/com/taobao/rigel/rap/common/utils/Pinyin4jUtil.java @@ -1,4 +1,4 @@ -package com.taobao.rigel.rap.common; +package com.taobao.rigel.rap.common.utils; import net.sourceforge.pinyin4j.PinyinHelper; import net.sourceforge.pinyin4j.format.HanyuPinyinCaseType; @@ -19,8 +19,7 @@ public class Pinyin4jUtil { /** * 汉字转换位汉语拼音首字母,英文字符不变,特殊字符丢失 支持多音字,生成方式如(长沙市长:cssc,zssz,zssc,cssz) * - * @param chines - * 汉字 + * @param chines 汉字 * @return 拼音 */ public static String converterToFirstSpell(String chines) { @@ -64,8 +63,7 @@ public static String converterToFirstSpell(String chines) { * 支持多音字,生成方式如(重当参:zhongdangcen,zhongdangcan,chongdangcen * ,chongdangshen,zhongdangshen,chongdangcan) * - * @param chines - * 汉字 + * @param chines 汉字 * @return 拼音 */ public static String converterToSpell(String chines) { @@ -182,10 +180,10 @@ private static String parseTheChineseByObject( } public static String calculatePinyinArrStr(String ch) { - if (ch == null || ch.isEmpty()) { - return ""; - } - return Pinyin4jUtil.converterToSpell(ch) + "|" + Pinyin4jUtil.converterToFirstSpell(ch); + if (ch == null || ch.isEmpty()) { + return ""; + } + return Pinyin4jUtil.converterToSpell(ch) + "|" + Pinyin4jUtil.converterToFirstSpell(ch); } } diff --git a/src/main/java/com/taobao/rigel/rap/common/utils/StringUtils.java b/src/main/java/com/taobao/rigel/rap/common/utils/StringUtils.java new file mode 100644 index 000000000..533afde12 --- /dev/null +++ b/src/main/java/com/taobao/rigel/rap/common/utils/StringUtils.java @@ -0,0 +1,561 @@ +package com.taobao.rigel.rap.common.utils; + +import com.taobao.rigel.rap.common.config.Patterns; +import com.taobao.rigel.rap.common.config.SystemConstant; + +import java.io.UnsupportedEncodingException; +import java.net.URLDecoder; +import java.net.URLEncoder; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import java.util.ArrayList; +import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * 为FE提供各类过滤字符串的接口 + * + * @author Junquan 2010.01.20 + */ +public class StringUtils { + + public static final String NAME_FORMAT_WARN_MSG = "名字必须由数字/字母/汉子/空格/下划线组成,长度" + SystemConstant.NAME_LENGTH_MIN + "-" + SystemConstant.NAME_LENGTH_MAX + "."; + public static final String ACCOUNT_FORMAT_WARN_MSG = "账户必须由数字/字母/下划线组成,长度" + SystemConstant.ACCOUNT_LENGTH_MIN + "-" + SystemConstant.ACCOUNT_LENGTH_MAX + "."; + /** + * 默认编码 utf8 + */ + public static String DEFAULT_CHARSET = "utf8"; + + /** + * 在html标签或属性中A: 左尖括号:< 转成 < 右尖括号:> 转成 > 单引号:' 转成 ' 双引号:" 转成 + * " + */ + public static String escapeInH(String str) { + if (str == null || ("").equals(str.trim())) { + return ""; + } + + StringBuffer sb = new StringBuffer(); + int lth = str.length(); + + for (int i = 0; i < lth; i++) { + char c = str.charAt(i); + + switch (c) { + + case 60: // < + sb.append("<"); + break; + case 62: // > + sb.append(">"); + break; + case 39: // ' + sb.append("'"); + break; + case 34: // " + sb.append("""); + break; + default: + sb.append(c); + break; + } + } + return new String(sb.toString()); + } + + public static String escapeInH(Number num) { + String str = null; + if (num != null) { + str = num.toString(); + } + + return escapeInH(str); + } + + /** + * 在html标签或属性中A - 逆 + */ + public static String UnEscapeInH(String str) { + // TODO + return str; + } + + /** + * 在html标签或属性中B: 左尖括号:< 转成 < 右尖括号:> 转成 > 单引号:' 转成 ' 双引号:" 转成 + * " &符号:& 转成& + */ + public static String escapeInX(String str) { + if (str == null || ("").equals(str.trim())) { + return ""; + } + + StringBuffer sb = new StringBuffer(); + int lth = str.length(); + + for (int i = 0; i < lth; i++) { + char c = str.charAt(i); + + switch (c) { + + case 60: // < + sb.append("<"); + break; + case 62: // > + sb.append(">"); + break; + case 39: // ' + sb.append("'"); + break; + case 34: // " + sb.append("""); + break; + case 38: // & + sb.append("&"); + break; + default: + sb.append(c); + break; + } + } + return new String(sb.toString()); + } + + public static String escapeInX(Number num) { + String str = null; + if (num != null) { + str = num.toString(); + } + + return escapeInX(str); + } + + /** + * 在html标签或属性中B - 逆 + */ + public static String UnEscapeInX(String str) { + // TODO + return str; + } + + /** + * 在普通JS环境: 单引号:' 转成 \' 双引号:" 转成 \" 反斜杠:\ 转成 \\ 正斜杠:/ 转成 \/ 换行符 转成 \n 回车符 转成 + * \r + */ + public static String escapeInJ(String str) { + if (str == null || ("").equals(str.trim())) { + return ""; + } + + StringBuffer sb = new StringBuffer(); + int lth = str.length(); + + for (int i = 0; i < lth; i++) { + char c = str.charAt(i); + + switch (c) { + + case 39: // ' + sb.append("\\'"); + break; + case 34: // " + sb.append("\\\""); + break; + case 47: // / + sb.append("\\/"); + break; + case 92: // \ + sb.append("\\\\"); + break; + case 13: // 回车 \r + sb.append("\\r"); + break; + case 10: // 换行 \n + sb.append("\\n"); + break; + default: + sb.append(c); + break; + } + } + return new String(sb.toString()); + } + + public static String escapeInJ(Number num) { + String str = null; + if (num != null) { + str = num.toString(); + } + + return escapeInJ(str); + } + + /** + * 在普通JS环境 - 逆 + */ + public static String UnEscapeInJ(String str) { + // TODO + return str; + } + + /** + * 在JS环境的innerHTML: 左尖括号:< 转成 < 右尖括号:> 转成 > 单引号:' 转成 \' 双引号:" 转成 \" + * 反斜杠:\ 转成 \\ 正斜杠:/ 转成 \/ 换行符 转成 \n 回车符 转成 \r + */ + public static String escapeInJH(String str) { + if (str == null || ("").equals(str.trim())) { + return ""; + } + + StringBuffer sb = new StringBuffer(); + int lth = str.length(); + + for (int i = 0; i < lth; i++) { + char c = str.charAt(i); + + switch (c) { + + case 60: // < + sb.append("<"); + break; + case 62: // > + sb.append(">"); + break; + case 39: // ' + sb.append("\\'"); + break; + case 34: // " + sb.append("\\\""); + break; + case 47: // / + sb.append("\\/"); + break; + case 92: // \ + sb.append("\\\\"); + break; + case 13: // 回车 \r + sb.append("\\r"); + break; + case 10: // 换行 \n + sb.append("\\n"); + break; + default: + sb.append(c); + break; + } + } + return new String(sb.toString()); + } + + public static String escapeInJH(Number num) { + String str = null; + if (num != null) { + str = num.toString(); + } + + return escapeInJH(str); + } + + /** + * 在JS环境的innerHTML - 逆 + */ + public static String UnEscapeInJH(String str) { + // TODO + return str; + } + + /** + * 在标签onclick等事件函数参数中: 左尖括号:< 转成 < 右尖括号:> 转成 > &符号:& 转成& 单引号:' 转成 + * \' 双引号:" 转成 \" 反斜杠:\ 转成 \\ 正斜杠:/ 转成 \/ 换行符 转成 \n 回车符 转成 \r + */ + public static String escapeInHJ(String str) { + if (str == null || ("").equals(str.trim())) { + return ""; + } + + StringBuffer sb = new StringBuffer(); + int lth = str.length(); + + for (int i = 0; i < lth; i++) { + char c = str.charAt(i); + + switch (c) { + + case 60: // < + sb.append("<"); + break; + case 62: // > + sb.append(">"); + break; + case 39: // ' + sb.append("\\'"); + break; + case 34: // " + sb.append("\\""); + break; + case 38: // & + sb.append("&"); + break; + case 47: // / + sb.append("\\/"); + break; + case 92: // \ + sb.append("\\\\"); + break; + case 13: // 回车 \r + sb.append("\\r"); + break; + case 10: // 换行 \n + sb.append("\\n"); + break; + default: + sb.append(c); + break; + } + } + return new String(sb.toString()); + } + + public static String escapeInHJ(Number num) { + String str = null; + if (num != null) { + str = num.toString(); + } + + return escapeInHJ(str); + } + + /** + * 在标签onclick等事件函数参数中 - 逆 + */ + public static String UnEscapeInHJ(String str) { + // TODO + return str; + } + + /** + * 在URL参数中: 对非字母、数字字符进行转码(%加字符的ASCII格式) + * + * @throws UnsupportedEncodingException + */ + public static String escapeInU(String str) + throws UnsupportedEncodingException { + if (str == null || ("").equals(str.trim())) { + return ""; + } + return URLEncoder.encode(str, DEFAULT_CHARSET); + } + + /** + * 在URL参数中 - 逆 + * + * @throws UnsupportedEncodingException + */ + public static String UnEscapeInU(String str) + throws UnsupportedEncodingException { + if (str == null || ("").equals(str.trim())) { + return ""; + } + return URLDecoder.decode(str, DEFAULT_CHARSET); + } + + public static String getMD5(String src) { + byte[] defaultBytes = src.getBytes(); + StringBuffer hexString = new StringBuffer(); + try { + MessageDigest algorithm = MessageDigest.getInstance("MD5"); + algorithm.reset(); + algorithm.update(defaultBytes); + byte messageDigest[] = algorithm.digest(); + + for (int i = 0; i < messageDigest.length; i++) { + hexString.append(Integer.toHexString(0xFF & messageDigest[i])); + } + } catch (NoSuchAlgorithmException e) { + e.printStackTrace(); + } + return hexString.toString(); + } + + public static String getMD5(byte[] source) { + String s = null; + char hexDigits[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', + 'a', 'b', 'c', 'd', 'e', 'f'};// 用来将字节转换成16进制表示的字符 + try { + java.security.MessageDigest md = java.security.MessageDigest + .getInstance("MD5"); + md.update(source); + byte tmp[] = md.digest();// MD5 的计算结果是一个 128 位的长整数, + // 用字节表示就是 16 个字节 + char str[] = new char[16 * 2];// 每个字节用 16 进制表示的话,使用两个字符, 所以表示成 16 + // 进制需要 32 个字符 + int k = 0;// 表示转换结果中对应的字符位置 + for (int i = 0; i < 16; i++) {// 从第一个字节开始,对 MD5 的每一个字节// 转换成 16 + // 进制字符的转换 + byte byte0 = tmp[i];// 取第 i 个字节 + str[k++] = hexDigits[byte0 >>> 4 & 0xf];// 取字节中高 4 位的数字转换,// >>> + // 为逻辑右移,将符号位一起右移 + str[k++] = hexDigits[byte0 & 0xf];// 取字节中低 4 位的数字转换 + + } + s = new String(str);// 换后的结果转换为字符串 + + } catch (NoSuchAlgorithmException e) { + e.printStackTrace(); + } + return s; + } + + public static String getDoubleMD5(String src) { + if (src != null) { + src = getMD5(src); + src = getMD5(src); + } + return src; + } + + /** + * 把中文转成Unicode码 + * + * @param str + * @return + */ + public static String chineseToUnicode(String str) { + if (str == null) { + str = ""; + } + String result = ""; + for (int i = 0; i < str.length(); i++) { + int chr1 = (char) str.charAt(i); + if (chr1 >= 19968 && chr1 <= 171941) {// 汉字范围 \u4e00-\u9fa5 (中文) + result += "\\u" + Integer.toHexString(chr1); + } else { + result += str.charAt(i); + } + } + return result; + } + + /** + * 判断是否为中文字符 + * + * @param c + * @return + */ + public static boolean isChinese(char c) { + Character.UnicodeBlock ub = Character.UnicodeBlock.of(c); + if (ub == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS + || ub == Character.UnicodeBlock.CJK_COMPATIBILITY_IDEOGRAPHS + || ub == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS_EXTENSION_A + || ub == Character.UnicodeBlock.GENERAL_PUNCTUATION + || ub == Character.UnicodeBlock.CJK_SYMBOLS_AND_PUNCTUATION + || ub == Character.UnicodeBlock.HALFWIDTH_AND_FULLWIDTH_FORMS) { + return true; + } + return false; + } + + /** + * 中文算2个,字母算1个 + * + * @param str + * @return + */ + public static int getLengthOfStringChinese(String str) { + int length = 0; + for (char c : str.toCharArray()) { + if (isChinese(c)) length += 2; + else length++; + } + return length; + } + + /** + * 中文算2个,字母算1个 + * + * @param str + * @param startIndex + * @param endIndex + * @return + */ + public static String subStringChinese(String str, int startIndex, int endIndex) { + int length = 0; + int size = endIndex - startIndex; + List charList = new ArrayList(); + for (char c : str.toCharArray()) { + if (isChinese(c)) length += 2; + else length++; + charList.add(c); + if (length >= size) break; + } + StringBuilder builder = new StringBuilder(); + for (Character c : charList) { + builder.append(c); + } + return builder.toString(); + } + + /** + * regular expression matcher helper + * + * @param pattern regular expression + * @param str string to be matched + * @return + */ + public static boolean regMatch(String pattern, String str) { + Pattern p = Pattern.compile(pattern); + Matcher matcher = p.matcher(str); + return matcher.matches(); + } + + /** + * remove all characters except [0-9a-zA-Z_] and blank space + * + * @param o + * @return + */ + public static String removeIllegalCharacters(String o) { + return o.replaceAll(Patterns.ILLEGAL_NAME_CHAR, ""); + } + + public static boolean validateAccount(String str) { + if (str == null) return false; + if (str.length() < SystemConstant.ACCOUNT_LENGTH_MIN || str.length() > SystemConstant.ACCOUNT_LENGTH_MAX) { + return false; + } + return str.matches(Patterns.LEGAL_ACCOUNT_CHAR + "*"); + } + + public static boolean validateName(String str) { + if (str == null) return false; + if (str.length() < SystemConstant.NAME_LENGTH_MIN || str.length() > SystemConstant.NAME_LENGTH_MAX) { + return false; + } + + for (int i = 0; i < str.length(); i++) { + char c = str.charAt(i); + if (!isChinese(c) && !String.valueOf(c).matches(Patterns.LEGAL_NAME_CHAR)) { + return false; + } + } + + return true; + } + + /** + * similar to JavaScript's String.prototype.join + * + * @param strs + * @param seperator + * @return + */ + public static String join(String [] strs, String seperator) { + String rv = ""; + + for (int i = 0; i < strs.length; i++) { + rv += (i == 0) ? strs[i] : seperator + strs[i]; + } + + return rv; + } +} diff --git a/src/com/taobao/rigel/rap/common/SystemVisitorLog.java b/src/main/java/com/taobao/rigel/rap/common/utils/SystemVisitorLog.java similarity index 88% rename from src/com/taobao/rigel/rap/common/SystemVisitorLog.java rename to src/main/java/com/taobao/rigel/rap/common/utils/SystemVisitorLog.java index ab60b3b64..2ed212d17 100644 --- a/src/com/taobao/rigel/rap/common/SystemVisitorLog.java +++ b/src/main/java/com/taobao/rigel/rap/common/utils/SystemVisitorLog.java @@ -1,9 +1,11 @@ -package com.taobao.rigel.rap.common; +package com.taobao.rigel.rap.common.utils; import com.taobao.rigel.rap.account.bo.User; +import com.taobao.rigel.rap.common.bo.Item; import com.taobao.rigel.rap.project.bo.Project; import com.taobao.rigel.rap.project.service.ProjectMgr; -import org.apache.logging.log4j.*; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; import java.util.*; @@ -11,19 +13,18 @@ * Created by Bosn on 14-9-2. */ public class SystemVisitorLog { + private static final int MAX_LOG_LENGTH = 10; + private static final int REALTIME_TIME_SPAN = 60; + private static final Logger logger = LogManager.getFormatterLogger(SystemVisitorLog.class); private static Map ipMap = new HashMap(); private static Map userMap = new HashMap(); private static List> mockMapList = new ArrayList>(); private static Map mockMap = new HashMap(); private static Map realtimeMap = new HashMap(); - private static final int MAX_LOG_LENGTH = 10; - private static final int REALTIME_TIME_SPAN = 60; private static int mockTotalNum = 0; private static Date mockTotalNumDate = new Date(); - private static Map cacheIdMap = new HashMap(); // key = actionId, value = projectId - private static int counter = 1; - - + // private static Map cacheIdMap = new HashMap(); // key = actionId, value = projectId + // private static int counter = 1; public static List mock(int projectId, String methodName, String pattern, String account) { Date now = new Date(); @@ -54,8 +55,6 @@ public static int getMockNumToday() { return mockTotalNum; } - private static final org.apache.logging.log4j.Logger logger = LogManager.getFormatterLogger(SystemVisitorLog.class.getName()); - public static List getIpLog() { return getLogMap(ipMap, MAX_LOG_LENGTH); } @@ -72,12 +71,14 @@ public static List getAllUserLog() { return getLogMap(userMap, 0); } - public static List> getMockMapList() {return mockMapList;} + public static List> getMockMapList() { + return mockMapList; + } - public static List> getRealtimeMap(Long limitTime) { + public static List> getRealtimeMap(int limitTime) { List> result = new ArrayList>(); - if (limitTime == null) { - limitTime = Long.MIN_VALUE; + if (limitTime == 0) { + limitTime = Integer.MIN_VALUE; } Calendar c = Calendar.getInstance(); @@ -119,7 +120,7 @@ private static List getLogMap(Map map, int max) { } Collections.sort(list, new Comparator() { - @Override + public int compare(Item o1, Item o2) { return Integer.parseInt(o2.getValue()) - Integer.parseInt(o1.getValue()); } @@ -214,7 +215,7 @@ public static List> getMockNumByProjectToday(ProjectMgr proj List> results = new ArrayList>(); for (Integer id : mockMap.keySet()) { if (id == null) continue; - Project p = projectMgr.getProject(id); + Project p = projectMgr.getProjectSummary(id); if (p == null) continue; String name = p.getName(); Map row = new HashMap(); @@ -224,9 +225,9 @@ public static List> getMockNumByProjectToday(ProjectMgr proj results.add(row); } Collections.sort(results, new Comparator>() { - @Override + public int compare(Map o1, Map o2) { - return (Integer)o2.get("mockNum") - (Integer)o1.get("mockNum"); + return (Integer) o2.get("mockNum") - (Integer) o1.get("mockNum"); } }); if (results.size() > 5) { diff --git a/src/com/taobao/rigel/rap/common/URLUtils.java b/src/main/java/com/taobao/rigel/rap/common/utils/URLUtils.java similarity index 91% rename from src/com/taobao/rigel/rap/common/URLUtils.java rename to src/main/java/com/taobao/rigel/rap/common/utils/URLUtils.java index 7cfeb21f7..787462f41 100644 --- a/src/com/taobao/rigel/rap/common/URLUtils.java +++ b/src/main/java/com/taobao/rigel/rap/common/utils/URLUtils.java @@ -1,4 +1,4 @@ -package com.taobao.rigel.rap.common; +package com.taobao.rigel.rap.common.utils; /** * Created by mashengbo on 14-9-5. @@ -8,7 +8,7 @@ public static boolean isStaticUrl(String url) { if (url == null) { return false; } - String [] extentions = new String[] { + String[] extentions = new String[]{ ".jpg", ".png", ".gif", ".js", ".css", ".font", ".woff" }; @@ -24,7 +24,7 @@ public static boolean isLogUrl(String url) { if (url == null) { return false; } - String [] keys = new String[] { + String[] keys = new String[]{ "logData.action", "getUnreadNotificationList.action" }; for (String key : keys) { @@ -39,7 +39,7 @@ public static boolean isMockServiceUrl(String url) { if (url == null) { return false; } - String [] keys = new String[] { + String[] keys = new String[]{ "/mockjs/", "/mock/", "/mockjsdata/" }; for (String key : keys) { @@ -95,7 +95,7 @@ public static String getRelativeUrl(String url) { } public static String removeParamsInUrl(String url) { - String result = url.replaceAll("/:[^/]*", "/:number"); + String result = url.replaceAll("/:[^/]*", "/:number"); if (!result.startsWith("/")) { result = "/" + result; } @@ -103,7 +103,7 @@ public static String removeParamsInUrl(String url) { } public static String removeRealParamsInUrl(String url) { - url = url.replaceAll("/[0-9]+[^\\$/]", "/:number"); + url = url.replaceAll("/[0-9]+[^\\$/]", "/:number"); String lastPart = url.substring(url.lastIndexOf("/") + 1); if (lastPart != null) { try { diff --git a/src/com/taobao/rigel/rap/mock/bo/Rule.java b/src/main/java/com/taobao/rigel/rap/mock/bo/Rule.java similarity index 94% rename from src/com/taobao/rigel/rap/mock/bo/Rule.java rename to src/main/java/com/taobao/rigel/rap/mock/bo/Rule.java index a6b3c79da..d42ea5283 100644 --- a/src/com/taobao/rigel/rap/mock/bo/Rule.java +++ b/src/main/java/com/taobao/rigel/rap/mock/bo/Rule.java @@ -2,9 +2,6 @@ import java.util.Date; -/** - * Created by Bosn on 15/7/17. - */ public class Rule { private int actionId; private String rules; diff --git a/src/com/taobao/rigel/rap/mock/dao/MockDao.java b/src/main/java/com/taobao/rigel/rap/mock/dao/MockDao.java similarity index 100% rename from src/com/taobao/rigel/rap/mock/dao/MockDao.java rename to src/main/java/com/taobao/rigel/rap/mock/dao/MockDao.java diff --git a/src/com/taobao/rigel/rap/mock/dao/impl/MockDaoImpl.java b/src/main/java/com/taobao/rigel/rap/mock/dao/impl/MockDaoImpl.java similarity index 77% rename from src/com/taobao/rigel/rap/mock/dao/impl/MockDaoImpl.java rename to src/main/java/com/taobao/rigel/rap/mock/dao/impl/MockDaoImpl.java index 94c30d726..590a5e413 100644 --- a/src/com/taobao/rigel/rap/mock/dao/impl/MockDaoImpl.java +++ b/src/main/java/com/taobao/rigel/rap/mock/dao/impl/MockDaoImpl.java @@ -3,17 +3,17 @@ import com.taobao.rigel.rap.mock.bo.Rule; import com.taobao.rigel.rap.mock.dao.MockDao; import org.hibernate.Session; -import org.springframework.orm.hibernate3.support.HibernateDaoSupport; +import org.springframework.orm.hibernate5.support.HibernateDaoSupport; /** * Created by Bosn on 15/7/17. */ public class MockDaoImpl extends HibernateDaoSupport implements MockDao { - @Override + public Rule getRule(int actionId) { Rule rule = null; try { - Session session = getSession(); + Session session = currentSession(); rule = (Rule) session.get(Rule.class, actionId); } catch (Exception ex) { ex.printStackTrace(); @@ -21,9 +21,9 @@ public Rule getRule(int actionId) { return rule; } - @Override + public int removeRule(int actionId) { - Session session = getSession(); + Session session = currentSession(); Object rule = session.get(Rule.class, actionId); if (rule != null) { session.delete((Rule) rule); @@ -33,16 +33,16 @@ public int removeRule(int actionId) { } } - @Override + public int updateRule(Rule rule) { - Session session = getSession(); + Session session = currentSession(); session.update(rule); return 0; } - @Override + public int addRule(Rule rule) { - Session session = getSession(); + Session session = currentSession(); session.save(rule); return 0; } diff --git a/src/main/java/com/taobao/rigel/rap/mock/service/MockMgr.java b/src/main/java/com/taobao/rigel/rap/mock/service/MockMgr.java new file mode 100644 index 000000000..c767e2a75 --- /dev/null +++ b/src/main/java/com/taobao/rigel/rap/mock/service/MockMgr.java @@ -0,0 +1,95 @@ +package com.taobao.rigel.rap.mock.service; + +import com.taobao.rigel.rap.mock.bo.Rule; +import com.taobao.rigel.rap.project.bo.Action; + +import java.io.UnsupportedEncodingException; +import java.util.Map; + +public interface MockMgr { + /** + * automatically generate testing data + * + * @param projectId + * @param pattern + * @param options + * @return JSON String + * @throws UnsupportedEncodingException + */ + String generateData(int projectId, String pattern, + Map options) throws UnsupportedEncodingException; + + /** + * modify mock data of parameters based on mockData + * + * @param actionId identifier of the action to be modified + * @param mockData mock data string example: + * response.param1.subParam=@format=x.xxxx_AND_response. + * param2=@value= + * 1_AND_response.param3.subParam.subSubParam=@length=7 + * @return number of rows affected + */ + int modify(int actionId, String mockData); + + /** + * clear all mock data of object in specified project + * + * @param projectId + * @return number of rows affected + */ + int reset(int projectId); + + /** + * generate mockjs rule + * + * @param id projectId, if both pattern and options are null, + * this id means actionId(used for OpenAPI) + * @param pattern + * @param options + * @return + * @throws UnsupportedEncodingException + */ + String generateRule(int id, String pattern, + Map options) throws UnsupportedEncodingException; + + /** + * generate mockjs data + * + * @param id + * @param pattern + * @param options + * @return + * @throws UnsupportedEncodingException + */ + String generateRuleData(int id, String pattern, + Map options) throws UnsupportedEncodingException; + + /** + * generate mockjs data by Action ID + * + * @param actionId + * @return + * @throws UnsupportedEncodingException + */ + // String generateRuleData(int actionId) throws UnsupportedEncodingException; + + /** + * validate API format + * + * @param projectId + * @param pattern + * @param options + * @param jsonToCompare + * @return + */ + String validateAPI(int projectId, String pattern, Map options, String jsonToCompare) throws UnsupportedEncodingException; + + /** + * get mock rule from action and action rule + * + * @param rule + * @param action + * @return + */ + String getMockRuleFromActionAndRule(Rule rule, Action action); +} diff --git a/src/com/taobao/rigel/rap/mock/service/impl/MockMgrImpl.java b/src/main/java/com/taobao/rigel/rap/mock/service/impl/MockMgrImpl.java similarity index 86% rename from src/com/taobao/rigel/rap/mock/service/impl/MockMgrImpl.java rename to src/main/java/com/taobao/rigel/rap/mock/service/impl/MockMgrImpl.java index 29c548761..70cc47571 100644 --- a/src/com/taobao/rigel/rap/mock/service/impl/MockMgrImpl.java +++ b/src/main/java/com/taobao/rigel/rap/mock/service/impl/MockMgrImpl.java @@ -1,28 +1,34 @@ package com.taobao.rigel.rap.mock.service.impl; -import java.io.UnsupportedEncodingException; -import java.net.URLDecoder; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - import com.google.gson.Gson; -import com.taobao.rigel.rap.common.*; +import com.taobao.rigel.rap.common.config.Patterns; +import com.taobao.rigel.rap.common.config.SystemSettings; +import com.taobao.rigel.rap.common.utils.*; import com.taobao.rigel.rap.mock.bo.Rule; import com.taobao.rigel.rap.mock.dao.MockDao; -import nl.flotsam.xeger.Xeger; - import com.taobao.rigel.rap.mock.service.MockMgr; import com.taobao.rigel.rap.project.bo.Action; import com.taobao.rigel.rap.project.bo.Parameter; import com.taobao.rigel.rap.project.dao.ProjectDao; import com.taobao.rigel.rap.project.service.ProjectMgr; +import nl.flotsam.xeger.Xeger; +import org.apache.logging.log4j.LogManager; +import sun.misc.Cache; + +import java.io.UnsupportedEncodingException; +import java.net.URLDecoder; +import java.util.*; +import java.util.concurrent.*; +import java.util.regex.Matcher; +import java.util.regex.Pattern; public class MockMgrImpl implements MockMgr { + + interface Callback { + void onSuccess(String result); + } + + private static final org.apache.logging.log4j.Logger logger = LogManager.getLogger(MockMgrImpl.class); private final String ERROR_PATTERN = "{\"isOk\":false,\"msg\":\"路径为空,请查看是否接口未填写URL.\"}"; private ProjectDao projectDao; private ProjectMgr projectMgr; @@ -34,13 +40,13 @@ public class MockMgrImpl implements MockMgr { * random seed */ private int _num = 1; - private String[] NAME_LIB = { "霍雍", "行列", "幻刺", "金台", "望天", "李牧", "三冰", + private String[] NAME_LIB = {"霍雍", "行列", "幻刺", "金台", "望天", "李牧", "三冰", "自勉", "思霏", "诚冉", "甘苦", "勇智", "墨汁老湿", "圣香", "定球", "征宇", "灵兮", "永盛", - "小婉", "紫丞", "少侠", "木谦", "周亮", "宝山", "张中", "晓哲", "夜沨" }; - private String[] LOCATION_LIB = { "北京 朝阳区", "北京 海淀区", "北京 昌平区", - "吉林 长春 绿园区", "吉林 吉林 丰满区" }; - private String[] PHONE_LIB = { "15813243928", "13884928343", "18611683243", - "18623432532", "18611582432" }; + "小婉", "紫丞", "少侠", "木谦", "周亮", "宝山", "张中", "晓哲", "夜沨"}; + private String[] LOCATION_LIB = {"北京 朝阳区", "北京 海淀区", "北京 昌平区", + "吉林 长春 绿园区", "吉林 吉林 丰满区"}; + private String[] PHONE_LIB = {"15813243928", "13884928343", "18611683243", + "18623432532", "18611582432"}; public static Map> getUrlParameters(String url) throws UnsupportedEncodingException { @@ -112,7 +118,7 @@ public void setProjectDao(ProjectDao projectDao) { this.projectDao = projectDao; } - @Override + public String generateData(int projectId, String pattern, Map options) throws UnsupportedEncodingException { @@ -187,23 +193,91 @@ public String generateData(int projectId, String pattern, return resultFilter(result); } - @Override - public String generateRuleData(int projectId, String pattern, + + public String generateRuleData(final int projectId, String pattern, Map options) throws UnsupportedEncodingException { - String result = generateRule(projectId, pattern, options); - result = MockjsRunner.renderMockjsRule(result); - result = StringUtils.chineseToUnicode(result); - return result; + final String mockRule = generateRule(projectId, pattern, options); + String returnValue = null; + ExecutorService executor = Executors.newSingleThreadExecutor(); + try { + Future task = executor.submit(new Callable() { + public String call() throws Exception { + return MockjsRunner.renderMockjsRule(mockRule); + } + }); + + int timeout = SystemSettings.MOCK_SERVICE_TIMEOUT; + while (true) { + if (task.isDone()) { + returnValue = task.get(); + break; + } else if (timeout <= 0){ + task.cancel(true); + logger.warn("Interrupted mock rule by pattern:" + pattern + ", projectId:" + projectId); + break; + } + + Thread.sleep(100); + timeout -= 100; + } + + + } catch (InterruptedException ex) { + + } catch (ExecutionException e) { + } finally { + executor.shutdownNow(); + } + + if (returnValue == null) { + return "{\"isOk\":false, \"errMsg\":\"运行超时," + SystemSettings.MOCK_SERVICE_TIMEOUT + "毫秒都跑不完,服务器HOLD不住啊,亲的自定义函数是不是写的太夸张了啊...\"}"; + } else { + return StringUtils.chineseToUnicode(returnValue); + } } public String generateRuleData(int actionId) throws UnsupportedEncodingException { - String result = generateRule(actionId, null, null); - result = MockjsRunner.renderMockjsRule(result); - result = StringUtils.chineseToUnicode(result); - return result; + final String mockRule = generateRule(actionId, null, null); + String returnValue = null; + ExecutorService executor = Executors.newSingleThreadExecutor(); + try { + Future task = executor.submit(new Callable() { + public String call() throws Exception { + return MockjsRunner.renderMockjsRule(mockRule); + } + }); + + int timeout = SystemSettings.MOCK_SERVICE_TIMEOUT; + while (true) { + if (task.isDone()) { + returnValue = task.get(); + break; + } else if (timeout <= 0){ + task.cancel(true); + logger.warn("Interrupted mock rule by actionId:" + actionId); + break; + } + + Thread.sleep(100); + timeout -= 100; + } + + } catch (InterruptedException ex) { + + } catch (ExecutionException e) { + } finally { + executor.shutdownNow(); + } + + + if (returnValue == null) { + return "{\"isOk\":false, \"errMsg\":\"运行超时,3秒都跑不完,服务器HOLD不住啊,亲的自定义函数是不是写的太夸张了啊...\"}"; + } else { + return StringUtils.chineseToUnicode(returnValue); + } } - @Override + public String validateAPI(int projectId, String pattern, Map options, String jsonToCompare) throws UnsupportedEncodingException { String mockjsData = generateRuleData(projectId, pattern, options); @@ -223,7 +297,7 @@ public String validateAPI(int projectId, String pattern, Map opt return new JSRunner().run(jsCode.toString()); } - @Override + public String generateRule(int projectId, String pattern, Map options) throws UnsupportedEncodingException { if (!isPatternLegal(pattern)) { @@ -232,7 +306,7 @@ public String generateRule(int projectId, String pattern, String originalPattern = pattern; boolean loadRule = false; Rule rule = null; - if (options.get("loadRule") != null && (Boolean)options.get("loadRule") == true) { + if (options.get("loadRule") != null && (Boolean) options.get("loadRule") == true) { loadRule = true; } int actionId = 0; @@ -264,7 +338,7 @@ public String generateRule(int projectId, String pattern, } if (action.getDisableCache() == 0 && loadRule == false) { - String ruleCache = CacheUtils.getRuleCache(action, originalPattern); + String ruleCache = CacheUtils.getRuleCache(action, originalPattern, false); if (ruleCache != null) { return ruleCache; } @@ -273,13 +347,13 @@ public String generateRule(int projectId, String pattern, } if (loadRule) { - rule = mockDao.getRule((int) action.getId()); + rule = mockDao.getRule(action.getId()); } String result = getMockRuleFromActionAndRule(rule, action); if (!loadRule) { - CacheUtils.setRuleCache(action.getId(), result); + CacheUtils.setRuleCache(action.getId(), result, false); } return result; } @@ -468,15 +542,12 @@ private void recursivelyLoadMockData(Parameter p, Parameter pMock) { /** * build JSON * - * @param json - * string builder - * @param para - * parameter to be parsed - * @param index - * available in array stands for index of array, used for - * special mode of tags like @format[3] which means the third - * record enabled only. Default value should be -1 which disabled - * the feature. + * @param json string builder + * @param para parameter to be parsed + * @param index available in array stands for index of array, used for + * special mode of tags like @format[3] which means the third + * record enabled only. Default value should be -1 which disabled + * the feature. */ private void buildJson(StringBuilder json, Parameter para, int index) { boolean isArrayObject = para.getDataType().equals("array"); @@ -533,15 +604,12 @@ private void buildJson(StringBuilder json, Parameter para, int index) { /** * build mock.js template * - * @param json - * string builder - * @param para - * parameter to be parsed - * @param index - * available in array stands for index of array, used for - * special mode of tags like @format[3] which means the third - * record enabled only. Default value should be -1 which disabled - * the feature. + * @param json string builder + * @param para parameter to be parsed + * @param index available in array stands for index of array, used for + * special mode of tags like @format[3] which means the third + * record enabled only. Default value should be -1 which disabled + * the feature. */ private void buildMockTemplate(StringBuilder json, Parameter para, int index) { boolean isArrayObject = para.getDataType().equals("array"); @@ -910,11 +978,9 @@ private String processMockValueWithParams(String mockValue) { /** * from tag string to tag map * - * @param tags - * tag string input by parsing whole string split by separator - * ";" - * @param tagMap - * tag map + * @param tags tag string input by parsing whole string split by separator + * ";" + * @param tagMap tag map * @param isMocking */ private void parseTags(String[] tags, Map tagMap, @@ -982,7 +1048,7 @@ private void parseTags(String[] tags, Map tagMap, } } - @Override + public int modify(int actionId, String mockData) { Action action = projectDao.getAction(actionId); if (action == null) @@ -1009,9 +1075,8 @@ public int modify(int actionId, String mockData) { * recursively locating parameter specified in the mock data * * @param pList - * @param snip - * request.a.b.c=@xxxx => a.b.c==@xxxx (namely request. or - * response. removed) + * @param snip request.a.b.c=@xxxx => a.b.c==@xxxx (namely request. or + * response. removed) * @return */ private Parameter locateParam(Set pList, String snip) { @@ -1028,7 +1093,7 @@ private Parameter locateParam(Set pList, String snip) { return null; } - @Override + public int reset(int projectId) { return projectDao.resetMockData(projectId); } diff --git a/src/main/java/com/taobao/rigel/rap/mock/web/action/MockAction.java b/src/main/java/com/taobao/rigel/rap/mock/web/action/MockAction.java new file mode 100644 index 000000000..93981feb2 --- /dev/null +++ b/src/main/java/com/taobao/rigel/rap/mock/web/action/MockAction.java @@ -0,0 +1,466 @@ +package com.taobao.rigel.rap.mock.web.action; + +import com.google.gson.Gson; +import com.taobao.rigel.rap.common.base.ActionBase; +import com.taobao.rigel.rap.common.utils.HTTPUtils; +import com.taobao.rigel.rap.common.utils.SystemVisitorLog; +import com.taobao.rigel.rap.mock.service.MockMgr; +import com.taobao.rigel.rap.project.bo.Action; +import com.taobao.rigel.rap.project.bo.Module; +import com.taobao.rigel.rap.project.bo.Page; +import com.taobao.rigel.rap.project.bo.Project; +import com.taobao.rigel.rap.project.service.ProjectMgr; +import org.apache.logging.log4j.LogManager; +import org.apache.struts2.ServletActionContext; + +import java.io.UnsupportedEncodingException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + + +public class MockAction extends ActionBase { + + private static final org.apache.logging.log4j.Logger logger = LogManager.getFormatterLogger(MockAction.class.getName()); + private int id; + private int __id__; + private String pattern; + private String mockData; + private int actionId; + private int projectId; + private String content; + private String callback; + private boolean enable = true; + private String _c; + private ProjectMgr projectMgr; + private List urlList; + private boolean seajs; + private boolean disableLog; + private String mode; + private MockMgr mockMgr; + private String actionData; + private String url; + + public String getActionData() { + return actionData; + } + + public void setActionData(String actionData) { + this.actionData = actionData; + } + + public String getUrl() { + return url; + } + + public void setUrl(String url) { + this.url = url; + } + + public boolean isDisableLog() { + return disableLog; + } + + public void setDisableLog(boolean disableLog) { + this.disableLog = disableLog; + } + + public List getUrlList() { + return urlList; + } + + public void setUrlList(List urlList) { + this.urlList = urlList; + } + + private String getMethod() { + return ServletActionContext.getRequest().getMethod(); + } + + public ProjectMgr getProjectMgr() { + return projectMgr; + } + + public void setProjectMgr(ProjectMgr projectMgr) { + this.projectMgr = projectMgr; + } + + public int getProjectId() { + return projectId; + } + + public void setProjectId(int projectId) { + this.projectId = projectId; + } + + public boolean isEnable() { + return enable; + } + + public void setEnable(boolean enable) { + this.enable = enable; + } + + public boolean isSeajs() { + return seajs; + } + + public void setSeajs(boolean seajs) { + this.seajs = seajs; + } + + public String getMode() { + return mode; + } + + public void setMode(String mode) { + this.mode = mode; + } + + public void setMockData(String mockData) { + this.mockData = mockData; + } + + public void setActionId(int actionId) { + this.actionId = actionId; + } + + public String get_c() { + return _c; + } + + public void set_c(String _c) { + this._c = _c; + } + + public String getCallback() { + return callback; + } + + public void setCallback(String callback) { + this.callback = callback; + } + + public MockMgr getMockMgr() { + return mockMgr; + } + + public void setMockMgr(MockMgr mockMgr) { + this.mockMgr = mockMgr; + } + + public String getContent() { + return content; + } + + public void setContent(String content) { + this.content = content; + } + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public String getPattern() { + return pattern; + } + + /** + * force callback or _c to be the last parameter + * + * @param pattern + */ + public void setPattern(String pattern) { + this.pattern = pattern; + } + + public String createData() throws UnsupportedEncodingException { + boolean isJSON = false; + updateProjectListMockNum(SystemVisitorLog.mock(__id__, "createData", pattern, getCurAccount())); + Map options = new HashMap(); + String _c = get_c(); + String result = mockMgr.generateData(__id__, pattern, options); + if (options.get("callback") != null) { + _c = (String) options.get("callback"); + callback = (String) options.get("callback"); + } + + if (callback != null && !callback.isEmpty()) { + setContent(callback + "(" + result + ")"); + } else if (_c != null && !_c.isEmpty()) { + setContent(_c + "(" + result + ")"); + } else { + isJSON = true; + setContent(result); + } + if (isJSON) { + return "json"; + } else { + return SUCCESS; + } + } + + public String createRule() throws UnsupportedEncodingException { + boolean isJSON = false; + updateProjectListMockNum(SystemVisitorLog.mock(__id__, "createRule", pattern, getCurAccount())); + Map options = new HashMap(); + String _c = get_c(); + options.put("method", getMethod()); + String result = mockMgr.generateRule(__id__, pattern, options); + if (options.get("callback") != null) { + _c = (String) options.get("callback"); + callback = (String) options.get("callback"); + } + if (callback != null && !callback.isEmpty()) { + setContent(callback + "(" + result + ")"); + } else if (_c != null && !_c.isEmpty()) { + setContent(_c + "(" + result + ")"); + } else { + isJSON = true; + setContent(result); + } + if (isJSON) { + return "json"; + } else { + return SUCCESS; + } + } + + public String createRuleAuto() throws UnsupportedEncodingException { + boolean isJSON = false; + updateProjectListMockNum(SystemVisitorLog.mock(__id__, "createRule", pattern, getCurAccount())); + Map options = new HashMap(); + String _c = get_c(); + options.put("method", getMethod()); + options.put("loadRule", true); // load rules set by Open API (tb_rule) + + String result = mockMgr.generateRule(__id__, pattern, options); + if (options.get("callback") != null) { + _c = (String) options.get("callback"); + callback = (String) options.get("callback"); + } + if (callback != null && !callback.isEmpty()) { + setContent(callback + "(" + result + ")"); + } else if (_c != null && !_c.isEmpty()) { + setContent(_c + "(" + result + ")"); + } else { + isJSON = true; + setContent(result); + } + if (isJSON) { + return "json"; + } else { + return SUCCESS; + } + } + + public String createRuleByActionData() throws UnsupportedEncodingException { + boolean isJSON = false; + updateProjectListMockNum(SystemVisitorLog.mock(id, "createRuleByActionData", pattern, getCurAccount())); + Map options = new HashMap(); + String _c = get_c(); + String result = mockMgr.generateRule(id, pattern, options); + if (options.get("callback") != null) { + _c = (String) options.get("callback"); + callback = (String) options.get("callback"); + } + if (callback != null && !callback.isEmpty()) { + setContent(callback + "(" + result + ")"); + } else if (_c != null && !_c.isEmpty()) { + setContent(_c + "(" + result + ")"); + } else { + isJSON = true; + setContent(result); + } + if (isJSON) { + return "json"; + } else { + return SUCCESS; + } + } + + public String modify() { + setNum(mockMgr.modify(actionId, mockData)); + return SUCCESS; + } + + public String reset() { + setNum(mockMgr.reset(projectId)); + return SUCCESS; + } + + public String createPluginScript() { + updateProjectListMockNum(SystemVisitorLog.mock(id, "createPluginScript", pattern, getCurAccount())); + Map _circleRefProtector = new HashMap(); + List list = new ArrayList(); + Project p = projectMgr.getProject(projectId); + + loadWhiteList(p, list, _circleRefProtector); + urlList = list; + return SUCCESS; + } + + public String getWhiteList() { + Map _circleRefProtector = new HashMap(); + List list = new ArrayList(); + Project p = projectMgr.getProject(projectId); + + loadWhiteList(p, list, _circleRefProtector); + urlList = list; + Gson g = new Gson(); + String json = g.toJson(urlList); + setJson(json); + + return SUCCESS; + } + + private void loadWhiteList(Project p, List list, Map map) { + // prevent circle reference + if (p == null || map.get(p.getId() + "") != null) { + return; + } else { + map.put(p.getId() + "", true); + } + if (p != null) { + for (Module m : p.getModuleList()) { + for (Page page : m.getPageList()) { + for (Action a : page.getActionList()) { + list.add(a.getRequestUrlRel()); + } + } + } + } + + String relatedIds = p.getRelatedIds(); + if (relatedIds != null && !relatedIds.isEmpty()) { + String[] relatedIdsArr = relatedIds.split(","); + for (String relatedId : relatedIdsArr) { + int rId = Integer.parseInt(relatedId); + Project rP = projectMgr.getProject(rId); + if (rP != null && rP.getId() > 0) + loadWhiteList(rP, list, map); + } + } + } + + public String createMockjsData() throws UnsupportedEncodingException { + boolean isJSON = false; + updateProjectListMockNum(SystemVisitorLog.mock(__id__, "createMockjsData", pattern, getCurAccount())); + String _c = get_c(); + Map options = new HashMap(); + options.put("method", getMethod()); + String result = mockMgr.generateRuleData(__id__, pattern, options); + if (options.get("callback") != null) { + _c = (String) options.get("callback"); + callback = (String) options.get("callback"); + } + if (callback != null && !callback.isEmpty()) { + setContent(callback + "(" + result + ")"); + } else if (_c != null && !_c.isEmpty()) { + setContent(_c + "(" + result + ")"); + } else { + isJSON = true; + setContent(result); + } + + if (isJSON) { + return "json"; + } else { + return SUCCESS; + } + } + + public String createMockjsDataAuto() throws UnsupportedEncodingException { + boolean isJSON = false; + updateProjectListMockNum(SystemVisitorLog.mock(__id__, "createMockjsData", pattern, getCurAccount())); + String _c = get_c(); + Map options = new HashMap(); + options.put("method", getMethod()); + options.put("loadRule", true); + String result = mockMgr.generateRuleData(__id__, pattern, options); + if (options.get("callback") != null) { + _c = (String) options.get("callback"); + callback = (String) options.get("callback"); + } + if (callback != null && !callback.isEmpty()) { + setContent(callback + "(" + result + ")"); + } else if (_c != null && !_c.isEmpty()) { + setContent(_c + "(" + result + ")"); + } else { + isJSON = true; + setContent(result); + } + + if (isJSON) { + return "json"; + } else { + return SUCCESS; + } + } + + public String validateAPI() throws UnsupportedEncodingException { + boolean isJSON = false; + updateProjectListMockNum(SystemVisitorLog.mock(id, "createRule", pattern, getCurAccount())); + Map options = new HashMap(); + String _c = get_c(); + options.put("method", getMethod()); + + String result = mockMgr.validateAPI(id, pattern, options, getJson()); + if (options.get("callback") != null) { + _c = (String) options.get("callback"); + callback = (String) options.get("callback"); + } + if (callback != null && !callback.isEmpty()) { + setContent(callback + "(" + result + ")"); + } else if (_c != null && !_c.isEmpty()) { + setContent(_c + "(" + result + ")"); + } else { + isJSON = true; + setContent(result); + } + if (isJSON) { + return "json"; + } else { + return SUCCESS; + } + } + + private void updateProjectListMockNum(List list) { + for (Project p : list) { + Project project = projectMgr.getProject(p.getId()); + if (project == null) continue; + project.setMockNum(p.getMockNum() + project.getMockNum()); + projectMgr.updateProjectNum(project); + } + } + + public int get__id__() { + return __id__; + } + + public void set__id__(int __id__) { + this.__id__ = __id__; + } + + public String requestOnServer() { + try { + setContent(HTTPUtils.sendGet(url)); + } catch (Exception e) { + setContent(e.getMessage()); + } + return SUCCESS; + } + + public String queryMockData() { + Gson gson = new Gson(); + Action action = gson.fromJson(actionData, Action.class); + setContent(mockMgr.getMockRuleFromActionAndRule(null, action)); + + return SUCCESS; + } +} diff --git a/src/com/taobao/rigel/rap/organization/bo/Corporation.java b/src/main/java/com/taobao/rigel/rap/organization/bo/Corporation.java similarity index 65% rename from src/com/taobao/rigel/rap/organization/bo/Corporation.java rename to src/main/java/com/taobao/rigel/rap/organization/bo/Corporation.java index 0a2e1142b..428067a6c 100644 --- a/src/com/taobao/rigel/rap/organization/bo/Corporation.java +++ b/src/main/java/com/taobao/rigel/rap/organization/bo/Corporation.java @@ -1,20 +1,25 @@ package com.taobao.rigel.rap.organization.bo; -import com.taobao.rigel.rap.common.StringUtils; +import com.taobao.rigel.rap.common.utils.StringUtils; +import java.util.HashMap; import java.util.List; +import java.util.Map; public class Corporation { - private int id; - private String logoUrl; - private long userId; - private String name; + public static final int PUBLIC_ACCESS = 20; + public static final int PRIVATE_ACCESS = 10; + public final int NAME_STR_MAX_LENGTH = 20; + private int id; + private String logoUrl; + private int userId; + private String name; private List accountList; private long memberNum; private String creatorName; - public final int NAME_STR_MAX_LENGTH = 20; - public static final int PUBLIC_ACCESS = 20; - public static final int PRIVATE_ACCESS = 10; + private String desc; + private short accessType; + private boolean hasAccess; public List getAccountList() { return accountList; @@ -32,8 +37,6 @@ public void setDesc(String desc) { this.desc = desc; } - private String desc; - public short getAccessType() { return accessType; } @@ -46,35 +49,37 @@ public void setAccessType(short accessType) { } } - private short accessType; + public int getId() { + return id; + } - public int getId() { - return id; - } + public void setId(int id) { + this.id = id; + } - public void setId(int id) { - this.id = id; - } + public String getLogoUrl() { + return logoUrl; + } - public String getLogoUrl() { - return logoUrl; - } + public void setLogoUrl(String logoUrl) { + this.logoUrl = logoUrl; + } - public void setLogoUrl(String logoUrl) { - this.logoUrl = logoUrl; - } + public int getUserId() { + return userId; + } - public long getUserId() { - return userId; - } + public void setUserId(int userId) { + this.userId = userId; + } - public void setUserId(long userId) { - this.userId = userId; - } + public String getName() { + return name; + } - public String getName() { - return name; - } + public void setName(String name) { + this.name = name; + } public String getNameStr() { if (StringUtils.getLengthOfStringChinese(name) > NAME_STR_MAX_LENGTH) { @@ -83,10 +88,6 @@ public String getNameStr() { return name; } - public void setName(String name) { - this.name = name; - } - public long getMemberNum() { return memberNum; } @@ -95,8 +96,6 @@ public void setMemberNum(long memberNum) { this.memberNum = memberNum; } - private boolean hasAccess; - public boolean isHasAccess() { return hasAccess; } @@ -116,4 +115,15 @@ public void setCreatorName(String creatorName) { public boolean isPublic() { return this.accessType == PUBLIC_ACCESS; } + + public Map toMap() { + Map map = new HashMap(); + + map.put("id", getId()); + map.put("nameStr", getNameStr()); + map.put("accessType", getAccessType()); + map.put("name", getName()); + + return map; + } } diff --git a/src/main/java/com/taobao/rigel/rap/organization/bo/Group.java b/src/main/java/com/taobao/rigel/rap/organization/bo/Group.java new file mode 100644 index 000000000..50a300373 --- /dev/null +++ b/src/main/java/com/taobao/rigel/rap/organization/bo/Group.java @@ -0,0 +1,40 @@ +package com.taobao.rigel.rap.organization.bo; + +public class Group { + private int id; + private String name; + private int productionLineId; + private int userId; + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public int getProductionLineId() { + return productionLineId; + } + + public void setProductionLineId(int productionLineId) { + this.productionLineId = productionLineId; + } + + public int getUserId() { + return userId; + } + + public void setUserId(int userId) { + this.userId = userId; + } +} diff --git a/src/main/java/com/taobao/rigel/rap/organization/bo/ProductionLine.java b/src/main/java/com/taobao/rigel/rap/organization/bo/ProductionLine.java new file mode 100644 index 000000000..063d67750 --- /dev/null +++ b/src/main/java/com/taobao/rigel/rap/organization/bo/ProductionLine.java @@ -0,0 +1,50 @@ +package com.taobao.rigel.rap.organization.bo; + + +public class ProductionLine { + private int id; + private String name; + private int projectNum; + private int corporationId; + private int userId; + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public int getProjectNum() { + return projectNum; + } + + public void setProjectNum(int projectNum) { + this.projectNum = projectNum; + } + + public int getCorporationId() { + return corporationId; + } + + public void setCorporationId(int corporationId) { + this.corporationId = corporationId; + } + + public int getUserId() { + return userId; + } + + public void setUserId(int userId) { + this.userId = userId; + } +} diff --git a/src/com/taobao/rigel/rap/organization/dao/OrganizationDao.java b/src/main/java/com/taobao/rigel/rap/organization/dao/OrganizationDao.java similarity index 52% rename from src/com/taobao/rigel/rap/organization/dao/OrganizationDao.java rename to src/main/java/com/taobao/rigel/rap/organization/dao/OrganizationDao.java index 34dfdfee0..62d042f6a 100644 --- a/src/com/taobao/rigel/rap/organization/dao/OrganizationDao.java +++ b/src/main/java/com/taobao/rigel/rap/organization/dao/OrganizationDao.java @@ -1,105 +1,105 @@ package com.taobao.rigel.rap.organization.dao; -import java.util.List; - import com.taobao.rigel.rap.account.bo.User; import com.taobao.rigel.rap.organization.bo.Corporation; import com.taobao.rigel.rap.organization.bo.Group; import com.taobao.rigel.rap.organization.bo.ProductionLine; +import java.util.List; + public interface OrganizationDao { - /** - * get corporation list - * - * @return - */ - List getCorporationList(); - - /** - * get group list - * - * @return - */ - List getGroupList(int productionLineId); - - /** - * get production line list - * - * @return - */ - List getProductionLineList(int corpId); - - /** - * add group - * - * @param group - */ - int addGroup(Group group); - - /** - * add production line - * - * @param productionLine - */ - int addProductionLine(ProductionLine productionLine); - - /** - * remove group - * - * @param groupId - */ - void removeGroup(int groupId); - - /** - * remove production line - * - * @param productionLineId - */ - void removeProductionLine(int productionLineId); - - /** - * update group - * - * @param group - */ - void updateGroup(Group group); - - /** - * update production line - * - * @param productionLine - */ - void updateProductionLine(ProductionLine productionLine); - - /** - * get group - * - * @param id - * @return - */ - Group getGroup(int id); - - /** - * get production line - * - * @param id - * @return - */ - ProductionLine getProductionLine(int id); - - /** - * get corporation - * - * @param id - * @return - */ - Corporation getCorporation(int id); - - /** - * update ProductionLine.projectNum - * - * @param productionLineId - */ + /** + * get corporation list + * + * @return + */ + List getCorporationList(); + + /** + * get group list + * + * @return + */ + List getGroupList(int productionLineId); + + /** + * get production line list + * + * @return + */ + List getProductionLineList(int corpId); + + /** + * add group + * + * @param group + */ + int addGroup(Group group); + + /** + * add production line + * + * @param productionLine + */ + int addProductionLine(ProductionLine productionLine); + + /** + * remove group + * + * @param groupId + */ + void removeGroup(int groupId); + + /** + * remove production line + * + * @param productionLineId + */ + void removeProductionLine(int productionLineId); + + /** + * update group + * + * @param group + */ + void updateGroup(Group group); + + /** + * update production line + * + * @param productionLine + */ + void updateProductionLine(ProductionLine productionLine); + + /** + * get group + * + * @param id + * @return + */ + Group getGroup(int id); + + /** + * get production line + * + * @param id + * @return + */ + ProductionLine getProductionLine(int id); + + /** + * get corporation + * + * @param id + * @return + */ + Corporation getCorporation(int id); + + /** + * update ProductionLine.projectNum + * + * @param productionLineId + */ void updateCountersInProductionLine(int productionLineId); /** @@ -118,7 +118,7 @@ public interface OrganizationDao { * @param userId * @param roleId */ - void addUserToCorp(int corpId, long userId, int roleId); + void addUserToCorp(int corpId, int userId, int roleId); /** * check if user in corporation @@ -127,7 +127,7 @@ public interface OrganizationDao { * @param corpId * @return */ - boolean isUserInCorp(long userId, int corpId); + boolean isUserInCorp(int userId, int corpId); /** * get user role in corporation @@ -136,7 +136,7 @@ public interface OrganizationDao { * @param corpId * @return roleId */ - int getUserRoleInCorp(long userId, int corpId); + int getUserRoleInCorp(int userId, int corpId); /** * set user role in corporation @@ -145,7 +145,7 @@ public interface OrganizationDao { * @param corpId * @param roleId */ - void setUserRoleInCorp(long userId, int corpId, int roleId); + void setUserRoleInCorp(int userId, int corpId, int roleId); /** * get corporation list @@ -159,7 +159,7 @@ public interface OrganizationDao { * * @return */ - long getCorporationListWithPagerNum (); + int getCorporationListWithPagerNum(); /** * get corporation list of user @@ -167,7 +167,7 @@ public interface OrganizationDao { * @param userId * @return */ - List getCorporationListWithPager(long userId, int pageNum, int pageSize); + List getCorporationListWithPager(int userId, int pageNum, int pageSize); /** * get corporation list of user num @@ -175,7 +175,7 @@ public interface OrganizationDao { * @param userId * @return */ - long getCorporationListWithPagerNum(long userId); + int getCorporationListWithPagerNum(int userId); /** * add new corporation @@ -190,7 +190,7 @@ public interface OrganizationDao { * @param corpId * @return */ - long getMemberNumOfCorporation(int corpId); + int getMemberNumOfCorporation(int corpId); /** * delete all membership from team @@ -200,7 +200,7 @@ public interface OrganizationDao { * @param userId * @param corpId */ - void deleteMembershipFromCorp(long curUserId, long userId, int corpId); + void deleteMembershipFromCorp(int curUserId, int userId, int corpId); /** * update corporation diff --git a/src/com/taobao/rigel/rap/organization/dao/impl/OrganizationDaoImpl.java b/src/main/java/com/taobao/rigel/rap/organization/dao/impl/OrganizationDaoImpl.java similarity index 50% rename from src/com/taobao/rigel/rap/organization/dao/impl/OrganizationDaoImpl.java rename to src/main/java/com/taobao/rigel/rap/organization/dao/impl/OrganizationDaoImpl.java index 8bac5f79b..1f875a4a7 100644 --- a/src/com/taobao/rigel/rap/organization/dao/impl/OrganizationDaoImpl.java +++ b/src/main/java/com/taobao/rigel/rap/organization/dao/impl/OrganizationDaoImpl.java @@ -9,14 +9,16 @@ import com.taobao.rigel.rap.project.dao.ProjectDao; import org.hibernate.Query; import org.hibernate.Session; -import org.springframework.orm.hibernate3.support.HibernateDaoSupport; +import org.springframework.orm.hibernate5.support.HibernateDaoSupport; -import java.math.BigInteger; import java.util.ArrayList; import java.util.List; public class OrganizationDaoImpl extends HibernateDaoSupport implements - OrganizationDao { + OrganizationDao { + + private AccountDao accountDao; + private ProjectDao projectDao; public AccountDao getAccountDao() { return accountDao; @@ -26,8 +28,6 @@ public void setAccountDao(AccountDao accountDao) { this.accountDao = accountDao; } - private AccountDao accountDao; - public ProjectDao getProjectDao() { return projectDao; } @@ -36,110 +36,107 @@ public void setProjectDao(ProjectDao projectDao) { this.projectDao = projectDao; } - private ProjectDao projectDao; + @SuppressWarnings("unchecked") + + public List getCorporationList() { + return currentSession().createQuery("from Corporation").list(); + } + + @SuppressWarnings("unchecked") + + public List getGroupList(int productionLineId) { + Query query = currentSession().createQuery( + "from Group where productionLineId = :id"); + query.setInteger("id", productionLineId); + return query.list(); + } + + @SuppressWarnings("unchecked") + + public List getProductionLineList(int corpId) { + return currentSession() + .createQuery("from ProductionLine where corporation_id = :id") + .setInteger("id", corpId).list(); + } + + + public int addGroup(Group group) { + Object s = currentSession().save(group); + return (Integer) s; + } + + + public int addProductionLine(ProductionLine productionLine) { + Object s = currentSession().save(productionLine); + return (Integer) s; + } + + + public void removeGroup(int groupId) { + Session session = currentSession(); + Object group = session.get(Group.class, groupId); + if (group != null) { + session.delete((Group) group); + } + } + + + public void removeProductionLine(int productionLineId) { + Session session = currentSession(); + Object productionLine = session.get(ProductionLine.class, + productionLineId); + if (productionLine != null) { + session.delete((ProductionLine) productionLine); + } + } + + + public void updateGroup(Group group) { + Group g = getGroup(group.getId()); + if (g != null) { + g.setName(group.getName()); + currentSession().update(g); + } + } + + + public void updateProductionLine(ProductionLine line) { + ProductionLine p = getProductionLine(line.getId()); + p.setName(line.getName()); + currentSession().update(p); + } + + + public Group getGroup(int id) { + return (Group) currentSession().get(Group.class, id); + } + + + public ProductionLine getProductionLine(int id) { + return (ProductionLine) currentSession().get(ProductionLine.class, id); + } + + + public void updateCountersInProductionLine(int productionLineId) { + StringBuilder sql = new StringBuilder(); + sql.append("SELECT COUNT(*) FROM tb_project p ") + .append("JOIN tb_group g ON p.group_id = g.id ") + .append("JOIN tb_production_line pl ON pl.id = g.production_line_id ") + .append("WHERE g.production_line_id = :id"); + Query query = currentSession().createSQLQuery(sql.toString()); + query.setInteger("id", productionLineId); + int num = Integer.parseInt(query.uniqueResult().toString()); + sql = new StringBuilder(); + sql.append("UPDATE tb_production_line SET project_num = :num WHERE id = :id"); + query = currentSession().createSQLQuery(sql.toString()); + query.setInteger("num", num); + query.setInteger("id", productionLineId); + query.executeUpdate(); + } - @SuppressWarnings("unchecked") - @Override - public List getCorporationList() { - return getSession().createQuery("from Corporation").list(); - } - - @SuppressWarnings("unchecked") - @Override - public List getGroupList(int productionLineId) { - Query query = getSession().createQuery( - "from Group where productionLineId = :id"); - query.setInteger("id", productionLineId); - return query.list(); - } - - @SuppressWarnings("unchecked") - @Override - public List getProductionLineList(int corpId) { - return getSession() - .createQuery("from ProductionLine where corporation_id = :id") - .setInteger("id", corpId).list(); - } - - @Override - public int addGroup(Group group) { - Object s = getSession().save(group); - return (Integer)s; - } - - @Override - public int addProductionLine(ProductionLine productionLine) { - Object s = getSession().save(productionLine); - return (Integer)s; - } - - @Override - public void removeGroup(int groupId) { - Session session = getSession(); - Object group = session.get(Group.class, groupId); - if (group != null) { - session.delete((Group) group); - } - } - - @Override - public void removeProductionLine(int productionLineId) { - Session session = getSession(); - Object productionLine = session.get(ProductionLine.class, - productionLineId); - if (productionLine != null) { - session.delete((ProductionLine) productionLine); - } - } - - @Override - public void updateGroup(Group group) { - Group g = getGroup(group.getId()); - if (g != null) { - g.setName(group.getName()); - getSession().update(g); - } - } - - @Override - public void updateProductionLine(ProductionLine line) { - ProductionLine p = getProductionLine(line.getId()); - p.setName(line.getName()); - getSession().update(p); - } - - @Override - public Group getGroup(int id) { - return (Group) getSession().get(Group.class, id); - } - - @Override - public ProductionLine getProductionLine(int id) { - return (ProductionLine) getSession().get(ProductionLine.class, id); - } - - @Override - public void updateCountersInProductionLine(int productionLineId) { - StringBuilder sql = new StringBuilder(); - sql.append("SELECT COUNT(*) FROM tb_project p ") - .append("JOIN tb_group g ON p.group_id = g.id ") - .append("JOIN tb_production_line pl ON pl.id = g.production_line_id ") - .append("WHERE g.production_line_id = :id"); - Query query = getSession().createSQLQuery(sql.toString()); - query.setInteger("id", productionLineId); - int num = Integer.parseInt(query.uniqueResult().toString()); - sql = new StringBuilder(); - sql.append("UPDATE tb_production_line SET project_num = :num WHERE id = :id"); - query = getSession().createSQLQuery(sql.toString()); - query.setInteger("num", num); - query.setInteger("id", productionLineId); - query.executeUpdate(); - } - - @Override public List getUserLisOfCorp(int corpId) { - Query query = getSession().createSQLQuery("SELECT user_id FROM tb_corporation_and_user WHERE corporation_id = :corpId"); + Query query = currentSession().createSQLQuery("SELECT user_id FROM tb_corporation_and_user WHERE corporation_id = :corpId"); query.setInteger("corpId", corpId); List list = query.list(); List resultList = new ArrayList(); @@ -152,27 +149,27 @@ public List getUserLisOfCorp(int corpId) { return resultList; } - @Override - public void addUserToCorp(int corpId, long userId, int roleId) { - Query query = getSession().createSQLQuery("INSERT INTO tb_corporation_and_user (corporation_id, user_id, role_id) VALUES (:corpId, :userId, :roleId)"); + + public void addUserToCorp(int corpId, int userId, int roleId) { + Query query = currentSession().createSQLQuery("INSERT INTO tb_corporation_and_user (corporation_id, user_id, role_id) VALUES (:corpId, :userId, :roleId)"); query.setInteger("corpId", corpId) - .setLong("userId", userId) + .setInteger("userId", userId) .setInteger("roleId", roleId); query.executeUpdate(); } - @Override - public boolean isUserInCorp(long userId, int corpId) { - Query query = getSession().createSQLQuery("SELECT COUNT(*) FROM tb_corporation_and_user WHERE user_id = :userId AND corporation_id = :corpId"); - query.setLong("userId", userId).setInteger("corpId", corpId); + + public boolean isUserInCorp(int userId, int corpId) { + Query query = currentSession().createSQLQuery("SELECT COUNT(*) FROM tb_corporation_and_user WHERE user_id = :userId AND corporation_id = :corpId"); + query.setInteger("userId", userId).setInteger("corpId", corpId); int num = Integer.parseInt(query.uniqueResult().toString()); return num > 0; } - @Override - public int getUserRoleInCorp(long userId, int corpId) { - Query query = getSession().createSQLQuery("SELECT role_id FROM tb_corporation_and_user WHERE user_id = :userId AND corporation_id = :corpId"); - query.setLong("userId", userId).setInteger("corpId", corpId); + + public int getUserRoleInCorp(int userId, int corpId) { + Query query = currentSession().createSQLQuery("SELECT role_id FROM tb_corporation_and_user WHERE user_id = :userId AND corporation_id = :corpId"); + query.setInteger("userId", userId).setInteger("corpId", corpId); Object result = query.uniqueResult(); if (result == null) { return -1; @@ -180,25 +177,25 @@ public int getUserRoleInCorp(long userId, int corpId) { return Integer.parseInt(result.toString()); } - @Override - public void setUserRoleInCorp(long userId, int corpId, int roleId) { - Query query = getSession().createSQLQuery("UPDATE tb_corporation_and_user SET role_id = :roleId WHERE user_id = :userId AND corporation_id = :corpId"); + + public void setUserRoleInCorp(int userId, int corpId, int roleId) { + Query query = currentSession().createSQLQuery("UPDATE tb_corporation_and_user SET role_id = :roleId WHERE user_id = :userId AND corporation_id = :corpId"); query.setInteger("roleId", roleId); query.setInteger("corpId", corpId); - query.setLong("userId", userId); + query.setInteger("userId", userId); query.executeUpdate(); } - @Override + public List getCorporationListWithPager(int pageNum, int pageSize) { StringBuilder sql = new StringBuilder(); sql.append("SELECT c.id ") .append("FROM tb_corporation c ") .append("LIMIT :startIndex, :pageSize "); - Query query = getSession().createSQLQuery(sql.toString()); - query.setLong("startIndex", (pageNum - 1) * pageSize); - query.setLong("pageSize", pageSize); + Query query = currentSession().createSQLQuery(sql.toString()); + query.setInteger("startIndex", (pageNum - 1) * pageSize); + query.setInteger("pageSize", pageSize); List list = (List) query.list(); List resultList = new ArrayList(); @@ -209,19 +206,19 @@ public List getCorporationListWithPager(int pageNum, int pageSize) return resultList; } - @Override - public long getCorporationListWithPagerNum() { + + public int getCorporationListWithPagerNum() { StringBuilder sql = new StringBuilder(); sql.append("SELECT COUNT(*) ") .append("FROM tb_corporation c "); - Query query = getSession().createSQLQuery(sql.toString()); + Query query = currentSession().createSQLQuery(sql.toString()); - return Long.parseLong(query.uniqueResult().toString()); + return Integer.parseInt(query.uniqueResult().toString()); } - @Override - public List getCorporationListWithPager(long userId, int pageNum, int pageSize) { + + public List getCorporationListWithPager(int userId, int pageNum, int pageSize) { StringBuilder sql = new StringBuilder(); sql .append("SELECT DISTINCT cid FROM ( ") @@ -236,10 +233,10 @@ public List getCorporationListWithPager(long userId, int pageNum, i .append("ORDER BY cid DESC ") .append("LIMIT :startIndex, :pageSize "); - Query query = getSession().createSQLQuery(sql.toString()); - query.setLong("userId", userId); - query.setLong("startIndex", (pageNum - 1) * pageSize); - query.setLong("pageSize", pageSize); + Query query = currentSession().createSQLQuery(sql.toString()); + query.setInteger("userId", userId); + query.setInteger("startIndex", (pageNum - 1) * pageSize); + query.setInteger("pageSize", pageSize); List list = query.list(); List resultList = new ArrayList(); @@ -250,8 +247,8 @@ public List getCorporationListWithPager(long userId, int pageNum, i return resultList; } - @Override - public long getCorporationListWithPagerNum(long userId) { + + public int getCorporationListWithPagerNum(int userId) { StringBuilder sql = new StringBuilder(); sql .append("SELECT COUNT(DISTINCT cid) FROM ( ") @@ -264,18 +261,18 @@ public long getCorporationListWithPagerNum(long userId) { .append(" WHERE user_id = :userId or access_type = 20") .append(") AS TEMP "); - Query query = getSession().createSQLQuery(sql.toString()); - query.setLong("userId", userId); - return Long.parseLong(query.uniqueResult().toString()); + Query query = currentSession().createSQLQuery(sql.toString()); + query.setInteger("userId", userId); + return Integer.parseInt(query.uniqueResult().toString()); } - @Override + public int addCorporation(Corporation c) { - Session session = getSession(); + Session session = currentSession(); Query query = session.createSQLQuery("INSERT INTO tb_corporation (`name`, logo_url, user_id, access_type, `desc`) VALUES (:name, :logoUrl, :userId, :accessType, :desc)"); query.setString("name", c.getName()); query.setString("logoUrl", c.getLogoUrl()); - query.setLong("userId", c.getUserId()); + query.setInteger("userId", c.getUserId()); query.setShort("accessType", c.getAccessType()); query.setString("desc", c.getDesc()); query.executeUpdate(); @@ -283,17 +280,17 @@ public int addCorporation(Corporation c) { return Integer.parseInt(session.createSQLQuery("SELECT LAST_INSERT_ID()").uniqueResult().toString()); } - @Override - public long getMemberNumOfCorporation(int corpId) { - String sql = "SELECT COUNT(DISTINCT cu.user_id) FROM tb_corporation c JOIN tb_corporation_and_user cu ON cu.corporation_id = c.id WHERE c.id = :corpId"; - Query query = getSession().createSQLQuery(sql); + public int getMemberNumOfCorporation(int corpId) { + String sql = "SELECT COUNT(DISTINCT cu.user_id) FROM tb_corporation c JOIN tb_corporation_and_user cu ON cu.corporation_id = c.id WHERE c.id = :corpId"; + + Query query = currentSession().createSQLQuery(sql); query.setInteger("corpId", corpId); - return Long.parseLong(query.uniqueResult().toString()); + return Integer.parseInt(query.uniqueResult().toString()); } - private List getProjectIdsFromCorporation(long userId, int corpId) { + private List getProjectIdsFromCorporation(int userId, int corpId) { StringBuilder builder = new StringBuilder(); builder.append("SELECT DISTINCT p.id AS projectId ") .append("FROM tb_project p ") @@ -302,17 +299,17 @@ private List getProjectIdsFromCorporation(long userId, int corpId) { .append("JOIN tb_production_line pl ON pl.id = g.production_line_id ") .append("JOIN tb_corporation c ON c.id = pl.corporation_id ") .append("WHERE p.user_id = :userId AND c.id = :corpId"); - Query query = getSession().createSQLQuery(builder.toString()); - query.setLong("userId", userId); + Query query = currentSession().createSQLQuery(builder.toString()); + query.setInteger("userId", userId); query.setInteger("corpId", corpId); List idList = query.list(); return idList; } - @Override - public void deleteMembershipFromCorp(long curUserId, long userId, int corpId) { - Query query = getSession().createSQLQuery("DELETE FROM tb_corporation_and_user WHERE corporation_id = :corpId AND user_id = :userId"); - query.setLong("userId", userId); + + public void deleteMembershipFromCorp(int curUserId, int userId, int corpId) { + Query query = currentSession().createSQLQuery("DELETE FROM tb_corporation_and_user WHERE corporation_id = :corpId AND user_id = :userId"); + query.setInteger("userId", userId); query.setInteger("corpId", corpId); query.executeUpdate(); @@ -323,9 +320,9 @@ public void deleteMembershipFromCorp(long curUserId, long userId, int corpId) { } } - @Override + public void updateCorporation(Corporation c) { - Query query = getSession().createSQLQuery("UPDATE tb_corporation SET `name`=:name, `desc`=:desc, access_type=:accessType WHERE id=:id"); + Query query = currentSession().createSQLQuery("UPDATE tb_corporation SET `name`=:name, `desc`=:desc, access_type=:accessType WHERE id=:id"); query.setString("name", c.getName()); query.setString("desc", c.getDesc()); query.setShort("accessType", c.getAccessType()); @@ -333,7 +330,7 @@ public void updateCorporation(Corporation c) { query.executeUpdate(); } - @Override + public int getTeamIdByProjectId(int id) { StringBuilder sql = new StringBuilder(); @@ -344,13 +341,13 @@ public int getTeamIdByProjectId(int id) { sql.append(" JOIN tb_corporation c ON c.id = pl.corporation_id"); sql.append(" WHERE p.id = :id"); - Query query = getSession().createSQLQuery(sql.toString()); + Query query = currentSession().createSQLQuery(sql.toString()); query.setInteger("id", id); return (Integer) query.uniqueResult(); } - @Override - public Corporation getCorporation(int id) { - return (Corporation) getSession().get(Corporation.class, id); - } + + public Corporation getCorporation(int id) { + return currentSession().get(Corporation.class, id); + } } diff --git a/src/com/taobao/rigel/rap/organization/service/OrganizationMgr.java b/src/main/java/com/taobao/rigel/rap/organization/service/OrganizationMgr.java similarity index 51% rename from src/com/taobao/rigel/rap/organization/service/OrganizationMgr.java rename to src/main/java/com/taobao/rigel/rap/organization/service/OrganizationMgr.java index d850b200d..3336469a5 100644 --- a/src/com/taobao/rigel/rap/organization/service/OrganizationMgr.java +++ b/src/main/java/com/taobao/rigel/rap/organization/service/OrganizationMgr.java @@ -1,20 +1,20 @@ package com.taobao.rigel.rap.organization.service; -import java.util.List; - import com.taobao.rigel.rap.account.bo.User; -import com.taobao.rigel.rap.common.RapError; +import com.taobao.rigel.rap.common.bo.RapError; import com.taobao.rigel.rap.organization.bo.Corporation; import com.taobao.rigel.rap.organization.bo.Group; import com.taobao.rigel.rap.organization.bo.ProductionLine; +import java.util.List; + public interface OrganizationMgr { - /** - * get corporation list - * - * @return - */ - List getCorporationList(); + /** + * get corporation list + * + * @return + */ + List getCorporationList(); /** * get corporation list @@ -29,7 +29,7 @@ public interface OrganizationMgr { * * @return */ - long getCorporationListWithPagerNum (); + int getCorporationListWithPagerNum(); /** * get corporation list of user @@ -37,7 +37,7 @@ public interface OrganizationMgr { * @param userId * @return */ - List getCorporationListWithPager(long userId, int pageNum, int pageSize); + List getCorporationListWithPager(int userId, int pageNum, int pageSize); /** * get corporation list of user num @@ -45,79 +45,81 @@ public interface OrganizationMgr { * @param userId * @return */ - long getCorporationListWithPagerNum(long userId); - - /** - * get group list - * - * @return - */ - List getGroupList(int productionLineId); - - /** - * get production line list - * - * @return - */ - List getProductionLineList(int corpId); - - /** - * add group - * - * @param group - */ - int addGroup(Group group); - - /** - * add production line - * - * @param productionLine - */ - int addProductionLine(ProductionLine productionLine); - - /** - * remove group - * - * @param groupId - */ - RapError removeGroup(int groupId); - - /** - * remove production line - * - * @param productionLineId - */ - RapError removeProductionLine(int productionLineId); - - /** - * update group - * - * @param group - */ - void updateGroup(Group group); - - /** - * update production line - * - * @param productionLine - */ - void updateProductionLine(ProductionLine productionLine); - - /** - * get production line - * - * @param plid - * @return - */ - ProductionLine getProductionLine(int plid); - - /** - * get corporation - * - * @param id - * @return - */ - Corporation getCorporation(int id); + int getCorporationListWithPagerNum(int userId); + + /** + * get group list + * + * @return + * @param productionLineId + */ + List getGroupList(int productionLineId); + + /** + * get production line list + * + * @return + * @param corpId + */ + List getProductionLineList(int corpId); + + /** + * add group + * + * @param group + */ + int addGroup(Group group); + + /** + * add production line + * + * @param productionLine + */ + int addProductionLine(ProductionLine productionLine); + + /** + * remove group + * + * @param groupId + */ + RapError removeGroup(int groupId); + + /** + * remove production line + * + * @param productionLineId + */ + RapError removeProductionLine(int productionLineId); + + /** + * update group + * + * @param group + */ + void updateGroup(Group group); + + /** + * update production line + * + * @param productionLine + */ + void updateProductionLine(ProductionLine productionLine); + + /** + * get production line + * + * @param plid + * @return + */ + ProductionLine getProductionLine(int plid); + + /** + * get corporation + * + * @param id + * @return + */ + Corporation getCorporation(int id); /** @@ -127,7 +129,7 @@ public interface OrganizationMgr { * @param corpId * @return */ - boolean canUserAccessCorp(long userId, int corpId); + boolean canUserAccessCorp(int userId, int corpId); /** * can user manage corporation @@ -136,7 +138,7 @@ public interface OrganizationMgr { * @param corpId * @return */ - boolean canUserManageCorp(long userId, int corpId); + boolean canUserManageCorp(int userId, int corpId); /** * get user list of corporation @@ -148,12 +150,12 @@ public interface OrganizationMgr { /** * get user role in corporation - + * * @param userId * @param corpId * @return roleId */ - int getUserRoleInCorp(long userId, int corpId); + int getUserRoleInCorp(int userId, int corpId); /** * can user access project @@ -162,7 +164,7 @@ public interface OrganizationMgr { * @param projectId * @return */ - boolean canUserAccessProject(long userId, int projectId); + boolean canUserAccessProject(int userId, int projectId); /** * can user access page @@ -171,7 +173,7 @@ public interface OrganizationMgr { * @param pageId * @return */ - boolean canUserAccessPage(long userId, int pageId); + boolean canUserAccessPage(int userId, int pageId); /** @@ -181,7 +183,7 @@ public interface OrganizationMgr { * @param plId * @return */ - boolean canUserAccessProductionLine(long userId, int plId); + boolean canUserAccessProductionLine(int userId, int plId); /** * can user manage production line @@ -190,15 +192,16 @@ public interface OrganizationMgr { * @param plId * @return */ - boolean canUserManageProductionLine(long userId, int plId); + boolean canUserManageProductionLine(int userId, int plId); /** * can user access group * * @param userId + * @param groupId * @return */ - boolean canUserAccessGroup(long userId, int groupId); + boolean canUserAccessGroup(int userId, int groupId); /** * can user manage grup @@ -207,7 +210,7 @@ public interface OrganizationMgr { * @param groupId * @return */ - boolean canUserManageGroup(long userId, int groupId); + boolean canUserManageGroup(int userId, int groupId); /** * add new team @@ -221,12 +224,12 @@ public interface OrganizationMgr { * set user role in corporation * * @param curUserId user now proceeding the operation - * @param userId user to be processed + * @param userId user to be processed * @param corpId * @param roleId * @return if succeed */ - boolean setUserRoleInCorp(long curUserId, long userId, int corpId, int roleId); + boolean setUserRoleInCorp(int curUserId, int userId, int corpId, int roleId); /** * remove member from team @@ -236,7 +239,7 @@ public interface OrganizationMgr { * @param corpId * @return */ - boolean removeMemberFromCorp(long curUserId, long userId, int corpId); + boolean removeMemberFromCorp(int curUserId, int userId, int corpId); /** * add team members @@ -246,7 +249,7 @@ public interface OrganizationMgr { * @param accountList * @return */ - boolean addTeamMembers(long curUserId, int corpId, String accountList); + boolean addTeamMembers(int curUserId, int corpId, String accountList); /** * update corporation diff --git a/src/com/taobao/rigel/rap/organization/service/impl/OrganizationMgrImpl.java b/src/main/java/com/taobao/rigel/rap/organization/service/impl/OrganizationMgrImpl.java similarity index 60% rename from src/com/taobao/rigel/rap/organization/service/impl/OrganizationMgrImpl.java rename to src/main/java/com/taobao/rigel/rap/organization/service/impl/OrganizationMgrImpl.java index 412fdf227..ec6879dbe 100644 --- a/src/com/taobao/rigel/rap/organization/service/impl/OrganizationMgrImpl.java +++ b/src/main/java/com/taobao/rigel/rap/organization/service/impl/OrganizationMgrImpl.java @@ -1,11 +1,9 @@ package com.taobao.rigel.rap.organization.service.impl; -import java.util.List; - import com.taobao.rigel.rap.account.bo.User; import com.taobao.rigel.rap.account.service.AccountMgr; -import com.taobao.rigel.rap.common.CacheUtils; -import com.taobao.rigel.rap.common.RapError; +import com.taobao.rigel.rap.common.utils.CacheUtils; +import com.taobao.rigel.rap.common.bo.RapError; import com.taobao.rigel.rap.organization.bo.Corporation; import com.taobao.rigel.rap.organization.bo.Group; import com.taobao.rigel.rap.organization.bo.ProductionLine; @@ -15,11 +13,13 @@ import com.taobao.rigel.rap.project.bo.Page; import com.taobao.rigel.rap.project.bo.Project; import com.taobao.rigel.rap.project.service.ProjectMgr; -import sun.misc.Cache; + +import java.util.List; public class OrganizationMgrImpl implements OrganizationMgr { - private OrganizationDao organizationDao; - private ProjectMgr projectMgr; + private OrganizationDao organizationDao; + private ProjectMgr projectMgr; + private AccountMgr accountMgr; public AccountMgr getAccountMgr() { return accountMgr; @@ -29,76 +29,64 @@ public void setAccountMgr(AccountMgr accountMgr) { this.accountMgr = accountMgr; } - private AccountMgr accountMgr; - public ProjectMgr getProjectMgr() { - return projectMgr; - } + public ProjectMgr getProjectMgr() { + return projectMgr; + } + + public void setProjectMgr(ProjectMgr projectMgr) { + this.projectMgr = projectMgr; + } - public void setProjectMgr(ProjectMgr projectMgr) { - this.projectMgr = projectMgr; - } + public OrganizationDao getOrganizationDao() { + return organizationDao; + } - public OrganizationDao getOrganizationDao() { - return organizationDao; - } + public void setOrganizationDao(OrganizationDao organizationDao) { + this.organizationDao = organizationDao; + } - public void setOrganizationDao(OrganizationDao organizationDao) { - this.organizationDao = organizationDao; - } - @Override - public List getCorporationList() { - return organizationDao.getCorporationList(); - } + public List getCorporationList() { + return organizationDao.getCorporationList(); + } + - @Override public List getCorporationListWithPager(int pageNum, int pageSize) { - List cache = CacheUtils.getTeamCache(0L, pageNum, pageSize); - if(cache != null) { - return cache; - } List list = organizationDao.getCorporationListWithPager(pageNum, pageSize); for (Corporation c : list) { - long memberNum = organizationDao.getMemberNumOfCorporation(c.getId()); + int memberNum = organizationDao.getMemberNumOfCorporation(c.getId()); c.setMemberNum(memberNum + 1); // +1 project creator c.setHasAccess(true); c.setCreatorName(accountMgr.getUser(c.getUserId()).getName()); } - CacheUtils.setTeamCache(0L, pageNum, pageSize, list); return list; } - @Override - public long getCorporationListWithPagerNum() { - return organizationDao.getCorporationListWithPagerNum(); + + public int getCorporationListWithPagerNum() { + return organizationDao.getCorporationListWithPagerNum(); } - @Override - public List getCorporationListWithPager(long userId, int pageNum, int pageSize) { - List cache = CacheUtils.getTeamCache(userId, pageNum, pageSize); - if(cache != null) { - return cache; - } + public List getCorporationListWithPager(int userId, int pageNum, int pageSize) { User user = accountMgr.getUser(userId); if (user.isAdmin()) { return getCorporationListWithPager(pageNum, pageSize); } List list = organizationDao.getCorporationListWithPager(userId, pageNum, pageSize); for (Corporation c : list) { - long memberNum = organizationDao.getMemberNumOfCorporation(c.getId()); + int memberNum = organizationDao.getMemberNumOfCorporation(c.getId()); c.setMemberNum(memberNum + 1); // +1 project creator c.setHasAccess(canUserManageCorp(userId, c.getId())); c.setCreatorName(accountMgr.getUser(c.getUserId()).getName()); } - CacheUtils.setTeamCache(userId, pageNum, pageSize, list); return list; } - @Override - public long getCorporationListWithPagerNum(long userId) { + + public int getCorporationListWithPagerNum(int userId) { User user = accountMgr.getUser(userId); if (user.isAdmin()) { return getCorporationListWithPagerNum(); @@ -106,81 +94,81 @@ public long getCorporationListWithPagerNum(long userId) { return organizationDao.getCorporationListWithPagerNum(userId); } - @Override - public List getGroupList(int productionLineId) { - return organizationDao.getGroupList(productionLineId); - } - - @Override - public List getProductionLineList(int corpId) { - return organizationDao.getProductionLineList(corpId); - } - - @Override - public int addGroup(Group group) { - return organizationDao.addGroup(group); - } - - @Override - public int addProductionLine(ProductionLine productionLine) { - return organizationDao.addProductionLine(productionLine); - } - - @Override - public RapError removeGroup(int groupId) { - if (!groupCanBeDeleted(groupId)) { - return new RapError(RapError.ERR_HAS_CHILDREN, - "为确保您的数据安全,请先删除分组下的项目,再删除该分组。"); - } else { - organizationDao.removeGroup(groupId); - return new RapError(); - } - } - - private boolean groupCanBeDeleted(int groupId) { - List list = projectMgr.getProjectListByGroup(groupId); - - return list == null || list.size() == 0; - } - - @Override - public RapError removeProductionLine(int productionLineId) { - if (!productionLineCanBeDeleted(productionLineId)) { - return new RapError(RapError.ERR_HAS_CHILDREN, - "为确保您的数据安全,请先删除业务线下的分组及项目,再删除该业务线。"); - } else { - organizationDao.removeProductionLine(productionLineId); - return new RapError(); - } - } - - private boolean productionLineCanBeDeleted(int productionLineId) { - List list = this.getGroupList(productionLineId); - return list == null || list.size() == 0; - } - - @Override - public void updateGroup(Group group) { - organizationDao.updateGroup(group); - } - - @Override - public void updateProductionLine(ProductionLine productionLine) { - organizationDao.updateProductionLine(productionLine); - } - - @Override - public ProductionLine getProductionLine(int plid) { - return organizationDao.getProductionLine(plid); - } - - @Override - public Corporation getCorporation(int id) { - return organizationDao.getCorporation(id); - } - - @Override - public boolean canUserAccessCorp(long userId, int corpId) { + + public List getGroupList(int productionLineId) { + return organizationDao.getGroupList(productionLineId); + } + + + public List getProductionLineList(int corpId) { + return organizationDao.getProductionLineList(corpId); + } + + + public int addGroup(Group group) { + return organizationDao.addGroup(group); + } + + + public int addProductionLine(ProductionLine productionLine) { + return organizationDao.addProductionLine(productionLine); + } + + + public RapError removeGroup(int groupId) { + if (!groupCanBeDeleted(groupId)) { + return new RapError(RapError.ERR_HAS_CHILDREN, + "为确保您的数据安全,请先删除分组下的项目,再删除该分组。"); + } else { + organizationDao.removeGroup(groupId); + return new RapError(); + } + } + + private boolean groupCanBeDeleted(int groupId) { + List list = projectMgr.getProjectListByGroup(groupId); + + return list == null || list.size() == 0; + } + + + public RapError removeProductionLine(int productionLineId) { + if (!productionLineCanBeDeleted(productionLineId)) { + return new RapError(RapError.ERR_HAS_CHILDREN, + "为确保您的数据安全,请先删除业务线下的分组及项目,再删除该业务线。"); + } else { + organizationDao.removeProductionLine(productionLineId); + return new RapError(); + } + } + + private boolean productionLineCanBeDeleted(int productionLineId) { + List list = this.getGroupList(productionLineId); + return list == null || list.size() == 0; + } + + + public void updateGroup(Group group) { + organizationDao.updateGroup(group); + } + + + public void updateProductionLine(ProductionLine productionLine) { + organizationDao.updateProductionLine(productionLine); + } + + + public ProductionLine getProductionLine(int plid) { + return organizationDao.getProductionLine(plid); + } + + + public Corporation getCorporation(int id) { + return organizationDao.getCorporation(id); + } + + + public boolean canUserAccessCorp(int userId, int corpId) { Corporation c = getCorporation(corpId); if (c == null) return false; if (c.getUserId() == userId) return true; // team owner @@ -190,18 +178,19 @@ public boolean canUserAccessCorp(long userId, int corpId) { return organizationDao.isUserInCorp(userId, corpId); } - @Override - public boolean canUserManageCorp(long userId, int corpId) { + + public boolean canUserManageCorp(int userId, int corpId) { int roleId = organizationDao.getUserRoleInCorp(userId, corpId); - return (roleId >= 1 && roleId <= 2 || + Corporation corp = getCorporation(corpId); + return corp.getAccessType() == Corporation.PUBLIC_ACCESS || (roleId >= 1 && roleId <= 2 || userId == getCorporation(corpId).getUserId()) || accountMgr.getUser(userId).isAdmin(); } - @Override + public List getUserLisOfCorp(int corpId) { - List list = organizationDao.getUserLisOfCorp(corpId); + List list = organizationDao.getUserLisOfCorp(corpId); Corporation c = getCorporation(corpId); User u = accountMgr.getUser(c.getUserId()); list.add(u); @@ -217,13 +206,13 @@ public List getUserLisOfCorp(int corpId) { return list; } - @Override - public int getUserRoleInCorp(long userId, int corpId) { + + public int getUserRoleInCorp(int userId, int corpId) { return organizationDao.getUserRoleInCorp(userId, corpId); } - @Override - public boolean canUserAccessProject(long userId, int projectId) { + + public boolean canUserAccessProject(int userId, int projectId) { User u = accountMgr.getUser(userId); Project p = projectMgr.getProject(projectId); int teamId = organizationDao.getTeamIdByProjectId(projectId); @@ -233,8 +222,8 @@ public boolean canUserAccessProject(long userId, int projectId) { || canUserAccessCorp(userId, c.getId()) || p.getUser().getId() == userId; } - @Override - public boolean canUserAccessPage(long userId, int pageId) { + + public boolean canUserAccessPage(int userId, int pageId) { Page page = projectMgr.getPage(pageId); if (page != null) { Module module = page.getModule(); @@ -248,8 +237,8 @@ public boolean canUserAccessPage(long userId, int pageId) { return false; } - @Override - public boolean canUserAccessProductionLine(long userId, int plId) { + + public boolean canUserAccessProductionLine(int userId, int plId) { ProductionLine pl = this.getProductionLine(plId); int corpId = pl.getCorporationId(); Corporation team = getCorporation(corpId); @@ -259,15 +248,15 @@ public boolean canUserAccessProductionLine(long userId, int plId) { return canUserAccessCorp(userId, corpId); } - @Override - public boolean canUserManageProductionLine(long userId, int plId) { + + public boolean canUserManageProductionLine(int userId, int plId) { ProductionLine pl = this.getProductionLine(plId); int corpId = pl.getCorporationId(); return canUserManageCorp(userId, corpId); } - @Override - public boolean canUserAccessGroup(long userId, int groupId) { + + public boolean canUserAccessGroup(int userId, int groupId) { Group g = organizationDao.getGroup(groupId); ProductionLine pl = getProductionLine(g.getProductionLineId()); int corpId = pl.getCorporationId(); @@ -278,15 +267,15 @@ public boolean canUserAccessGroup(long userId, int groupId) { return canUserAccessCorp(userId, corpId); } - @Override - public boolean canUserManageGroup(long userId, int groupId) { + + public boolean canUserManageGroup(int userId, int groupId) { Group g = organizationDao.getGroup(groupId); ProductionLine pl = getProductionLine(g.getProductionLineId()); int corpId = pl.getCorporationId(); return canUserManageCorp(userId, corpId); } - @Override + public int addTeam(Corporation team) { int corpId = organizationDao.addCorporation(team); @@ -302,8 +291,8 @@ public int addTeam(Corporation team) { return corpId; } - @Override - public boolean setUserRoleInCorp(long curUserId, long userId, int corpId, int roleId) { + + public boolean setUserRoleInCorp(int curUserId, int userId, int corpId, int roleId) { if (canUserManageUserInCorp(curUserId, userId, corpId)) { organizationDao.setUserRoleInCorp(userId, corpId, roleId); return true; @@ -312,8 +301,8 @@ public boolean setUserRoleInCorp(long curUserId, long userId, int corpId, int ro } } - @Override - public boolean removeMemberFromCorp(long curUserId, long userId, int corpId) { + + public boolean removeMemberFromCorp(int curUserId, int userId, int corpId) { int roleId = getUserRoleInCorp(userId, corpId); // if user can't manage team, or the user to be deleted is super admin, failed @@ -326,8 +315,8 @@ public boolean removeMemberFromCorp(long curUserId, long userId, int corpId) { return true; } - @Override - public boolean addTeamMembers(long curUserId, int corpId, String accountList) { + + public boolean addTeamMembers(int curUserId, int corpId, String accountList) { if (!canUserManageCorp(curUserId, corpId)) return false; @@ -346,20 +335,20 @@ public boolean addTeamMembers(long curUserId, int corpId, String accountList) { return true; } - @Override + public void updateCorporation(Corporation c) { organizationDao.updateCorporation(c); } - private boolean canUserManageUserInCorp(long curUserId, long userId, int corpId) { + private boolean canUserManageUserInCorp(int curUserId, int userId, int corpId) { User curUser = accountMgr.getUser(curUserId); if (curUser.isAdmin()) { return true; } int roleId = getUserRoleInCorp(curUserId, corpId); - if (roleId >=1 || roleId <= 2) { - return true; + if (roleId >= 1 || roleId <= 2) { + return true; } return false; } diff --git a/src/main/java/com/taobao/rigel/rap/organization/web/action/GroupAction.java b/src/main/java/com/taobao/rigel/rap/organization/web/action/GroupAction.java new file mode 100644 index 000000000..b4b37c3d6 --- /dev/null +++ b/src/main/java/com/taobao/rigel/rap/organization/web/action/GroupAction.java @@ -0,0 +1,190 @@ +package com.taobao.rigel.rap.organization.web.action; + +import com.google.gson.Gson; +import com.taobao.rigel.rap.common.base.ActionBase; +import com.taobao.rigel.rap.common.bo.RapError; +import com.taobao.rigel.rap.organization.bo.Group; +import com.taobao.rigel.rap.organization.service.OrganizationMgr; +import com.taobao.rigel.rap.project.bo.Project; +import com.taobao.rigel.rap.project.service.ProjectMgr; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class GroupAction extends ActionBase { + + private OrganizationMgr organizationMgr; + private ProjectMgr projectMgr; + private int id; + private String name; + private int productLineId; + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public ProjectMgr getProjectMgr() { + return projectMgr; + } + + public void setProjectMgr(ProjectMgr projectMgr) { + this.projectMgr = projectMgr; + } + + public int getProductLineId() { + return productLineId; + } + + public void setProductLineId(int productLineId) { + this.productLineId = productLineId; + } + + public OrganizationMgr getOrganizationMgr() { + return organizationMgr; + } + + public void setOrganizationMgr(OrganizationMgr organizationMgr) { + this.organizationMgr = organizationMgr; + } + + public String all() { + if (!isUserLogined()) { + plsLogin(); + return JSON_ERROR; + } + if (!organizationMgr.canUserAccessProductionLine(getCurUserId(), productLineId)) { + setErrMsg(ACCESS_DENY); + return JSON_ERROR; + } + Gson gson = new Gson(); + Map result = new HashMap(); + List> groups = new ArrayList>(); + List groupModels = organizationMgr.getGroupList(productLineId); + for (Group groupModel : groupModels) { + Map group = new HashMap(); + group.put("id", groupModel.getId()); + group.put("name", groupModel.getName()); + List projectModelList = projectMgr + .getProjectListByGroup(groupModel.getId()); + List> projects = new ArrayList>(); + for (Project projectModel : projectModelList) { + if (getCurUser().isUserInRole("admin") + || getAccountMgr().canUserManageProject( + getCurUser().getId(), projectModel.getId())) { + projectModel.setIsManagable(true); + } + Map project = new HashMap(); + project.put("id", projectModel.getId()); + project.put("name", projectModel.getName()); + project.put("desc", projectModel.getIntroduction()); + project.put("status", projectModel.getLastUpdateStr()); + project.put("accounts", projectModel.getMemberAccountListStr()); + project.put("isManagable", projectModel.getIsManagable()); + project.put("creator", projectModel.getUser().getUserBaseInfo()); + project.put("teamId", projectModel.getTeamId()); + projects.add(project); + } + group.put("projects", projects); + groups.add(group); + } + + result.put("groups", groups); + + setJson(gson.toJson(result)); + return SUCCESS; + } + + public String groups() { + if (!isUserLogined()) { + plsLogin(); + return JSON_ERROR; + } + if (!organizationMgr.canUserAccessProductionLine(getCurUserId(), productLineId)) { + setErrMsg(ACCESS_DENY); + return JSON_ERROR; + } + Gson gson = new Gson(); + Map result = new HashMap(); + List> groups = new ArrayList>(); + List groupModels = organizationMgr.getGroupList(productLineId); + for (Group groupModel : groupModels) { + Map group = new HashMap(); + group.put("id", groupModel.getId()); + group.put("name", groupModel.getName()); + groups.add(group); + } + + result.put("groups", groups); + + setJson(gson.toJson(result)); + return SUCCESS; + } + + public String create() { + if (!isUserLogined()) { + plsLogin(); + return JSON_ERROR; + } + if (!organizationMgr.canUserManageProductionLine(getCurUserId(), productLineId)) { + setErrMsg(ACCESS_DENY); + return JSON_ERROR; + } + Gson gson = new Gson(); + Group group = new Group(); + group.setName(name); + group.setUserId((int) getCurUserId()); + group.setProductionLineId(productLineId); + int id = organizationMgr.addGroup(group); + Map g = new HashMap(); + g.put("id", id); + g.put("name", name); + setJson("{\"groups\":[" + gson.toJson(g) + "]}"); + return SUCCESS; + } + + public String delete() { + if (!isUserLogined()) { + plsLogin(); + return JSON_ERROR; + } + if (!organizationMgr.canUserManageGroup(getCurUserId(), id)) { + setErrMsg(ACCESS_DENY); + return JSON_ERROR; + } + RapError error = organizationMgr.removeGroup(id); + setJson(error.toString()); + return SUCCESS; + } + + public String update() { + if (!isUserLogined()) { + plsLogin(); + return JSON_ERROR; + } + if (!organizationMgr.canUserManageGroup(getCurUserId(), id)) { + setErrMsg(ACCESS_DENY); + return JSON_ERROR; + } + Group group = new Group(); + group.setId(id); + group.setName(name); + organizationMgr.updateGroup(group); + setJson("{\"isOk\":\"true\"}"); + return SUCCESS; + } + +} diff --git a/src/main/java/com/taobao/rigel/rap/organization/web/action/OrganizationAction.java b/src/main/java/com/taobao/rigel/rap/organization/web/action/OrganizationAction.java new file mode 100644 index 000000000..94c642e44 --- /dev/null +++ b/src/main/java/com/taobao/rigel/rap/organization/web/action/OrganizationAction.java @@ -0,0 +1,189 @@ +package com.taobao.rigel.rap.organization.web.action; + +import com.google.gson.Gson; +import com.taobao.rigel.rap.account.bo.User; +import com.taobao.rigel.rap.common.base.ActionBase; +import com.taobao.rigel.rap.common.utils.CacheUtils; +import com.taobao.rigel.rap.organization.bo.Corporation; +import com.taobao.rigel.rap.organization.bo.ProductionLine; +import com.taobao.rigel.rap.organization.service.OrganizationMgr; +import com.taobao.rigel.rap.project.bo.Project; +import com.taobao.rigel.rap.project.service.ProjectMgr; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class OrganizationAction extends ActionBase { + private OrganizationMgr organizationMgr; + private ProjectMgr projectMgr; + private int plid; + private int id; + private Corporation corporation; + private ProductionLine productline; + private Corporation team; + public Corporation getCorporation() { + return corporation; + } + + public void setCorporation(Corporation corporation) { + this.corporation = corporation; + } + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public int getPlid() { + return plid; + } + + public void setPlid(int plid) { + this.plid = plid; + } + + public ProductionLine getProductLine() { + return productline; + } + + public Corporation getTeam() { + return team; + } + + public ProjectMgr getProjectMgr() { + return projectMgr; + } + + public void setProjectMgr(ProjectMgr projectMgr) { + this.projectMgr = projectMgr; + } + + public OrganizationMgr getOrganizationMgr() { + return organizationMgr; + } + + public void setOrganizationMgr(OrganizationMgr organizationMgr) { + this.organizationMgr = organizationMgr; + } + + public String myHome() { + return SUCCESS; + } + + public String index() { + if (isUserLogined()) { + return SUCCESS; + } else { + return "public"; + } + + } + + public String group() { + if (!isUserLogined()) { + plsLogin(); + setRelativeReturnUrl("/org/group.do?plid=" + plid); + return LOGIN; + } + + if (!organizationMgr.canUserAccessProductionLine(getCurUserId(), plid)) { + setErrMsg(ACCESS_DENY); + return ERROR; + } + + productline = organizationMgr.getProductionLine(plid); + int corpId = productline.getCorporationId(); + team = organizationMgr.getCorporation(corpId); + return SUCCESS; + } + + public String productline() { + if (!isUserLogined()) { + plsLogin(); + setRelativeReturnUrl("/org/productline.do?id=" + id); + return LOGIN; + } + + if (!organizationMgr.canUserAccessCorp(getCurUserId(), id)) { + setErrMsg(ACCESS_DENY); + return ERROR; + } + + setCorporation(organizationMgr.getCorporation(id)); + return SUCCESS; + } + + public String projects() { + if (!isUserLogined()) { + plsLogin(); + return JSON_ERROR; + } + + int curUserId = getCurUserId(); + + String[] cacheKey = new String[]{CacheUtils.KEY_PROJECT_LIST, new Integer(curUserId).toString()}; + + String cacheResult = CacheUtils.get(cacheKey); + if (cacheResult != null) { + setJson(cacheResult); + } else { + + Gson gson = new Gson(); + + List> projects = new ArrayList>(); + + // int totalRecNum = projectMgr.getProjectListNum(getCurUser()); + User curUser = getAccountMgr().getUser(curUserId); + List projectList = projectMgr.getProjectList(curUser, 1, + Integer.MAX_VALUE); + + + for (Project p : projectList) { + if (curUser.isUserInRole("admin") + || getAccountMgr().canUserManageProject( + curUser.getId(), p.getId())) { + p.setIsManagable(true); + } + Map map = new HashMap(); + map.put("id", p.getId()); + map.put("name", p.getName()); + map.put("desc", p.getIntroduction()); + map.put("status", p.getLastUpdateStr()); + map.put("accounts", p.getMemberAccountListStr()); + map.put("isManagable", p.getIsManagable()); + map.put("creator", p.getUser().getUserBaseInfo()); + map.put("related", p.getUser().getId() != curUserId); + map.put("teamId", p.getTeamId()); + projects.add(map); + } + StringBuilder json = new StringBuilder(); + json.append("{"); + json.append(" \"groups\" : [{"); + json.append(" \"type\" : \"user\","); + json.append(" \"projects\" :"); + json.append(gson.toJson(projects)); + json.append(" }]"); + json.append("}"); + setJson(json.toString()); + CacheUtils.put(cacheKey, json.toString()); + } + return SUCCESS; + } + + public String corporationList() { + if (!isUserLogined()) { + plsLogin(); + return JSON_ERROR; + } + + Gson gson = new Gson(); + setJson(gson.toJson(organizationMgr.getCorporationListWithPager(getCurUserId(), 1, 1000))); + return SUCCESS; + } + +} diff --git a/src/main/java/com/taobao/rigel/rap/organization/web/action/ProductlineAction.java b/src/main/java/com/taobao/rigel/rap/organization/web/action/ProductlineAction.java new file mode 100644 index 000000000..eddfc6cf8 --- /dev/null +++ b/src/main/java/com/taobao/rigel/rap/organization/web/action/ProductlineAction.java @@ -0,0 +1,132 @@ +package com.taobao.rigel.rap.organization.web.action; + +import com.google.gson.Gson; +import com.taobao.rigel.rap.common.base.ActionBase; +import com.taobao.rigel.rap.organization.bo.ProductionLine; +import com.taobao.rigel.rap.organization.service.OrganizationMgr; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class ProductlineAction extends ActionBase { + + private OrganizationMgr organizationMgr; + private int corpId; + private int id; + private String name; + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public int getCorpId() { + return corpId; + } + + + public void setCorpId(int corpId) { + this.corpId = corpId; + } + + public OrganizationMgr getOrganizationMgr() { + return organizationMgr; + } + + public void setOrganizationMgr(OrganizationMgr organizationMgr) { + this.organizationMgr = organizationMgr; + } + + public String all() { + if (!isUserLogined()) { + plsLogin(); + return ERROR; + } + if (!organizationMgr.canUserAccessCorp(getCurUserId(), corpId)) { + setErrMsg(ACCESS_DENY); + return ERROR; + } + Map result = new HashMap(); + List> items = new ArrayList>(); + List lineModels = organizationMgr + .getProductionLineList(corpId); + for (ProductionLine lineModel : lineModels) { + Map line = new HashMap(); + line.put("id", lineModel.getId()); + line.put("name", lineModel.getName()); + line.put("count", lineModel.getProjectNum()); + items.add(line); + } + result.put("items", items); + + Gson gson = new Gson(); + setJson(gson.toJson(result)); + return SUCCESS; + } + + public String create() { + if (!isUserLogined()) { + plsLogin(); + return JSON_ERROR; + } + if (!organizationMgr.canUserManageCorp(getCurUserId(), corpId)) { + setErrMsg(ACCESS_DENY); + return JSON_ERROR; + } + ProductionLine line = new ProductionLine(); + Gson gson = new Gson(); + line.setName(name); + line.setUserId((int) getCurUserId()); + line.setCorporationId(corpId); + int id = organizationMgr.addProductionLine(line); + Map p = new HashMap(); + p.put("id", id); + p.put("name", name); + setJson("{\"items\":[" + gson.toJson(p) + "]}"); + return SUCCESS; + } + + public String delete() { + if (!isUserLogined()) { + plsLogin(); + return JSON_ERROR; + } + if (!organizationMgr.canUserManageProductionLine(getCurUserId(), id)) { + setErrMsg(ACCESS_DENY); + return JSON_ERROR; + } + setJson(organizationMgr.removeProductionLine(id).toString()); + return SUCCESS; + } + + public String update() { + if (!isUserLogined()) { + plsLogin(); + return JSON_ERROR; + } + if (!organizationMgr.canUserManageProductionLine(getCurUserId(), id)) { + setErrMsg(ACCESS_DENY); + return JSON_ERROR; + } + + ProductionLine line = new ProductionLine(); + line.setId(id); + line.setName(name); + organizationMgr.updateProductionLine(line); + setJson("{\"isOk\":\"true\"}"); + return SUCCESS; + } +} diff --git a/src/com/taobao/rigel/rap/organization/web/action/TeamAction.java b/src/main/java/com/taobao/rigel/rap/organization/web/action/TeamAction.java similarity index 92% rename from src/com/taobao/rigel/rap/organization/web/action/TeamAction.java rename to src/main/java/com/taobao/rigel/rap/organization/web/action/TeamAction.java index da57cda42..2b29fff39 100644 --- a/src/com/taobao/rigel/rap/organization/web/action/TeamAction.java +++ b/src/main/java/com/taobao/rigel/rap/organization/web/action/TeamAction.java @@ -1,10 +1,10 @@ package com.taobao.rigel.rap.organization.web.action; import com.taobao.rigel.rap.account.bo.User; -import com.taobao.rigel.rap.common.ActionBase; -import com.taobao.rigel.rap.common.CacheUtils; -import com.taobao.rigel.rap.common.StringUtils; -import com.taobao.rigel.rap.common.SystemConstant; +import com.taobao.rigel.rap.common.base.ActionBase; +import com.taobao.rigel.rap.common.utils.CacheUtils; +import com.taobao.rigel.rap.common.utils.StringUtils; +import com.taobao.rigel.rap.common.config.SystemConstant; import com.taobao.rigel.rap.organization.bo.Corporation; import com.taobao.rigel.rap.organization.service.OrganizationMgr; @@ -16,20 +16,24 @@ */ public class TeamAction extends ActionBase { + private static final org.apache.logging.log4j.Logger logger = org.apache.logging.log4j.LogManager.getFormatterLogger(TeamAction.class.getName()); private int id; private String name; private String accountList; - private long teamListNum; + private int teamListNum; private List userList; private int userId; - private static final org.apache.logging.log4j.Logger logger = org.apache.logging.log4j.LogManager.getFormatterLogger(TeamAction.class.getName()); + private Corporation team; + private int pageNum; + private List teamList; + private short accessType; + private OrganizationMgr organizationMgr; + private String desc; public Corporation getTeam() { return team; } - private Corporation team; - public int getPageNum() { if (pageNum > 0) return pageNum; @@ -37,14 +41,14 @@ public int getPageNum() { return 1; } - private int pageNum; + public void setPageNum(int pageNum) { + this.pageNum = pageNum; + } public List getTeamList() { return teamList; } - private List teamList; - public short getAccessType() { return accessType; } @@ -53,9 +57,6 @@ public void setAccessType(short accessType) { this.accessType = accessType; } - private short accessType; - private OrganizationMgr organizationMgr; - public OrganizationMgr getOrganizationMgr() { return organizationMgr; } @@ -72,8 +73,6 @@ public void setDesc(String desc) { this.desc = desc; } - private String desc; - public String getName() { return name; } @@ -95,13 +94,11 @@ public void setAccountList(String accountList) { this.accountList = accountList; } - public String create() { if (!isUserLogined()) { plsLogin(); return JSON_ERROR; } - CacheUtils.removeTeamCache(getCurUserId()); Corporation team = new Corporation(); team.setName(getName()); team.setUserId(getCurUserId()); @@ -120,23 +117,19 @@ public String teams() { setRelativeReturnUrl("/org/team/teams.do"); return LOGIN; } - long userId = getCurUserId(); + int userId = getCurUserId(); teamList = organizationMgr.getCorporationListWithPager(userId, getPageNum(), SystemConstant.DEFAULT_PAGE_SIZE); teamListNum = organizationMgr.getCorporationListWithPagerNum(userId); return SUCCESS; } - public void setPageNum(int pageNum) { - this.pageNum = pageNum; - } - - public long getTeamListNum() { + public int getTeamListNum() { return teamListNum; } - public long getTeamListPageInTotal() { - double result = Math.ceil((double)teamListNum / (double)SystemConstant.DEFAULT_PAGE_SIZE); - return (long) result; + public int getTeamListPageInTotal() { + double result = Math.ceil((double) teamListNum / (double) SystemConstant.DEFAULT_PAGE_SIZE); + return (int) result; } public String manage() { diff --git a/src/com/taobao/rigel/rap/platform/dao/DataDao.java b/src/main/java/com/taobao/rigel/rap/platform/dao/DataDao.java similarity index 100% rename from src/com/taobao/rigel/rap/platform/dao/DataDao.java rename to src/main/java/com/taobao/rigel/rap/platform/dao/DataDao.java diff --git a/src/com/taobao/rigel/rap/platform/dao/impl/DataDaoImpl.java b/src/main/java/com/taobao/rigel/rap/platform/dao/impl/DataDaoImpl.java similarity index 75% rename from src/com/taobao/rigel/rap/platform/dao/impl/DataDaoImpl.java rename to src/main/java/com/taobao/rigel/rap/platform/dao/impl/DataDaoImpl.java index f559ac713..729e6290a 100644 --- a/src/com/taobao/rigel/rap/platform/dao/impl/DataDaoImpl.java +++ b/src/main/java/com/taobao/rigel/rap/platform/dao/impl/DataDaoImpl.java @@ -2,7 +2,7 @@ import com.taobao.rigel.rap.platform.dao.DataDao; import org.hibernate.Query; -import org.springframework.orm.hibernate3.support.HibernateDaoSupport; +import org.springframework.orm.hibernate5.support.HibernateDaoSupport; import java.util.ArrayList; import java.util.HashMap; @@ -13,17 +13,17 @@ * Created by Bosn on 14-9-5. */ public class DataDaoImpl extends HibernateDaoSupport implements DataDao { - @Override + public List> getUserTrendByMonth() { StringBuilder sql = new StringBuilder(); sql - .append("SELECT MONTH(create_date) AS month, COUNT(id) as num, create_date ") - .append("FROM tb_user ") - .append("WHERE create_date BETWEEN DATE_ADD(NOW(), INTERVAL -1 YEAR) AND NOW() ") - .append("GROUP BY MONTH(create_date) ") - .append("ORDER BY create_date"); - Query query = getSession().createSQLQuery(sql.toString()); - List list = query.list(); + .append("SELECT MONTH(create_date) AS month, COUNT(id) as num, create_date ") + .append("FROM tb_user ") + .append("WHERE create_date BETWEEN DATE_ADD(NOW(), INTERVAL -1 YEAR) AND NOW() ") + .append("GROUP BY MONTH(create_date) ") + .append("ORDER BY create_date"); + Query query = currentSession().createSQLQuery(sql.toString()); + List list = query.list(); List> result = new ArrayList>(); for (Object[] row : list) { Map map = new HashMap(); @@ -32,7 +32,7 @@ public List> getUserTrendByMonth() { result.add(map); } - Object count = getSession().createSQLQuery("SELECT COUNT(*) FROM tb_user WHERE create_date < DATE_ADD(NOW(), INTERVAL -1 YEAR)") + Object count = currentSession().createSQLQuery("SELECT COUNT(*) FROM tb_user WHERE create_date < DATE_ADD(NOW(), INTERVAL -1 YEAR)") .uniqueResult(); Map mapCount = new HashMap(); mapCount.put("startValue", count); @@ -42,7 +42,7 @@ public List> getUserTrendByMonth() { return result; } - @Override + public List> getProjectTrendByMonth() { StringBuilder sql = new StringBuilder(); sql @@ -51,8 +51,8 @@ public List> getProjectTrendByMonth() { .append("WHERE create_date BETWEEN DATE_ADD(NOW(), INTERVAL -1 YEAR) AND NOW() ") .append("GROUP BY MONTH(create_date) ") .append("ORDER BY create_date"); - Query query = getSession().createSQLQuery(sql.toString()); - List list = query.list(); + Query query = currentSession().createSQLQuery(sql.toString()); + List list = query.list(); List> result = new ArrayList>(); for (Object[] row : list) { Map map = new HashMap(); @@ -61,7 +61,7 @@ public List> getProjectTrendByMonth() { result.add(map); } - Object count = getSession().createSQLQuery("SELECT COUNT(*) FROM tb_project WHERE create_date < DATE_ADD(NOW(), INTERVAL -1 YEAR)") + Object count = currentSession().createSQLQuery("SELECT COUNT(*) FROM tb_project WHERE create_date < DATE_ADD(NOW(), INTERVAL -1 YEAR)") .uniqueResult(); Map mapCount = new HashMap(); mapCount.put("startValue", count); @@ -70,7 +70,7 @@ public List> getProjectTrendByMonth() { return result; } - @Override + public List> getCheckInTrendByMonth() { StringBuilder sql = new StringBuilder(); sql @@ -79,8 +79,8 @@ public List> getCheckInTrendByMonth() { .append("WHERE create_date BETWEEN DATE_ADD(NOW(), INTERVAL -1 YEAR) AND NOW() ") .append("GROUP BY MONTH(create_date) ") .append("ORDER BY create_date"); - Query query = getSession().createSQLQuery(sql.toString()); - List list = query.list(); + Query query = currentSession().createSQLQuery(sql.toString()); + List list = query.list(); List> result = new ArrayList>(); for (Object[] row : list) { Map map = new HashMap(); @@ -89,8 +89,8 @@ public List> getCheckInTrendByMonth() { result.add(map); } - Object count = getSession().createSQLQuery("SELECT COUNT(*) FROM tb_check_in WHERE create_date < DATE_ADD(NOW(), INTERVAL -1 YEAR)") - .uniqueResult(); + Object count = currentSession().createSQLQuery("SELECT COUNT(*) FROM tb_check_in WHERE create_date < DATE_ADD(NOW(), INTERVAL -1 YEAR)") + .uniqueResult(); Map mapCount = new HashMap(); mapCount.put("startValue", count); result.add(mapCount); @@ -98,7 +98,7 @@ public List> getCheckInTrendByMonth() { return result; } - @Override + public List> getActionNumByTeam() { StringBuilder sql = new StringBuilder(); sql @@ -115,8 +115,8 @@ public List> getActionNumByTeam() { .append("ORDER BY COUNT(a.id) DESC "); - Query query = getSession().createSQLQuery(sql.toString()); - List list = query.list(); + Query query = currentSession().createSQLQuery(sql.toString()); + List list = query.list(); List> result = new ArrayList>(); for (Object[] row : list) { Map map = new HashMap(); diff --git a/src/com/taobao/rigel/rap/platform/service/DataMgr.java b/src/main/java/com/taobao/rigel/rap/platform/service/DataMgr.java similarity index 100% rename from src/com/taobao/rigel/rap/platform/service/DataMgr.java rename to src/main/java/com/taobao/rigel/rap/platform/service/DataMgr.java diff --git a/src/com/taobao/rigel/rap/platform/service/impl/DataMgrImpl.java b/src/main/java/com/taobao/rigel/rap/platform/service/impl/DataMgrImpl.java similarity index 96% rename from src/com/taobao/rigel/rap/platform/service/impl/DataMgrImpl.java rename to src/main/java/com/taobao/rigel/rap/platform/service/impl/DataMgrImpl.java index bfdeca7da..1dda99108 100644 --- a/src/com/taobao/rigel/rap/platform/service/impl/DataMgrImpl.java +++ b/src/main/java/com/taobao/rigel/rap/platform/service/impl/DataMgrImpl.java @@ -17,14 +17,14 @@ public class DataMgrImpl implements DataMgr { private DataDao dataDao; private ProjectMgr projectMgr; - public void setDataDao(DataDao dataDao) { - this.dataDao = dataDao; - } - public DataDao getDataDao() { return dataDao; } + public void setDataDao(DataDao dataDao) { + this.dataDao = dataDao; + } + public ProjectMgr getProjectMgr() { return projectMgr; } @@ -33,27 +33,27 @@ public void setProjectMgr(ProjectMgr projectMgr) { this.projectMgr = projectMgr; } - @Override + public List> getUserTrendByMonth() { return dataDao.getUserTrendByMonth(); } - @Override + public List> getProjectTrendByMonth() { return dataDao.getProjectTrendByMonth(); } - @Override + public List> getCheckInTrendByMonth() { return dataDao.getCheckInTrendByMonth(); } - @Override + public List> getActionNumByTeam() { return dataDao.getActionNumByTeam(); } - @Override + public List> getMockNumByProject() { List list = projectMgr.selectMockNumTopNProjectList(5); List> results = new ArrayList>(); diff --git a/src/com/taobao/rigel/rap/platform/web/action/PlatformAction.java b/src/main/java/com/taobao/rigel/rap/platform/web/action/PlatformAction.java similarity index 67% rename from src/com/taobao/rigel/rap/platform/web/action/PlatformAction.java rename to src/main/java/com/taobao/rigel/rap/platform/web/action/PlatformAction.java index 1eed1471c..4ba96f9c8 100644 --- a/src/com/taobao/rigel/rap/platform/web/action/PlatformAction.java +++ b/src/main/java/com/taobao/rigel/rap/platform/web/action/PlatformAction.java @@ -1,48 +1,40 @@ package com.taobao.rigel.rap.platform.web.action; -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStreamReader; - import com.google.gson.Gson; -import com.opensymphony.xwork2.ActionContext; -import com.taobao.rigel.rap.common.Item; -import com.taobao.rigel.rap.common.SystemVisitorLog; +import com.taobao.rigel.rap.common.base.ActionBase; +import com.taobao.rigel.rap.common.bo.Item; +import com.taobao.rigel.rap.common.utils.SystemVisitorLog; import com.taobao.rigel.rap.platform.service.DataMgr; import com.taobao.rigel.rap.project.service.ProjectMgr; -import org.apache.commons.io.IOUtils; - -import com.taobao.rigel.rap.common.ActionBase; -import com.taobao.rigel.rap.common.SystemConstant; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; public class PlatformAction extends ActionBase { + private static final Logger logger = LogManager.getFormatterLogger(PlatformAction.class.getName()); private Gson gson = new Gson(); + private int time; + private Map>> trends = new HashMap>>(); + private Map>> statistics = new HashMap>>(); + private int tabIndex; + private ProjectMgr projectMgr; + private List modelLog = new ArrayList(); + private Map modelLogMap = new HashMap(); + private DataMgr dataMgr; + private String text; - private long time; - - public void setTime(long time) { + public void setTime(int time) { this.time = time; } - private static final Logger logger = LogManager.getFormatterLogger(PlatformAction.class.getName()); - - private static final long serialVersionUID = 1L; - - private Map>> trends = new HashMap>>(); - public Map>> getTrends() { return trends; } - private Map>> statistics = new HashMap>>(); - public Map>> getStatistics() { return statistics; } @@ -56,17 +48,13 @@ public String getStatisticsJSON() { } public String getRealtimeJSON() { - return gson.toJson(SystemVisitorLog.getRealtimeMap(null)); + return gson.toJson(SystemVisitorLog.getRealtimeMap(0)); } - public String getRealtimeJSONByTime(long time) { + public String getRealtimeJSONByTime(int time) { return gson.toJson(SystemVisitorLog.getRealtimeMap(time)); } - - - private int tabIndex; - public int getTabIndex() { return tabIndex; } @@ -75,11 +63,6 @@ public void setTabIndex(int tabIndex) { this.tabIndex = tabIndex; } - private ProjectMgr projectMgr; - private List modelLog = new ArrayList(); - - private Map modelLogMap = new HashMap(); - public Map getModelLogMap() { return modelLogMap; } @@ -88,15 +71,13 @@ public List getModelLog() { return modelLog; } - public void setProjectMgr(ProjectMgr projectMgr) { - this.projectMgr = projectMgr; - } - public ProjectMgr getProjectMgr() { return projectMgr; } - private DataMgr dataMgr; + public void setProjectMgr(ProjectMgr projectMgr) { + this.projectMgr = projectMgr; + } public DataMgr getDataMgr() { return dataMgr; @@ -106,34 +87,32 @@ public void setDataMgr(DataMgr dataMgr) { this.dataMgr = dataMgr; } - private String text; - - public String getText() { - return text; - } + public String getText() { + return text; + } - public void setText(String text) { - this.text = text; - } + public void setText(String text) { + this.text = text; + } - public String home() { - return SUCCESS; - } + public String home() { + return SUCCESS; + } - public String test() { - return SUCCESS; - } + public String test() { + return SUCCESS; + } public String log() { // statistics for RAP models - modelLog.add(new Item("用户数", new Long(getAccountMgr().getUserNum()).toString())); - modelLog.add(new Item("项目数", new Long(projectMgr.getProjectNum()).toString())); - modelLog.add(new Item("接口数", new Long(projectMgr.getActionNum()).toString())); - //modelLog.add(new Item("TAB数", new Long(projectMgr.getModuleNum()).toString())); - //modelLog.add(new Item("页面数", new Long(projectMgr.getPageNum()).toString())); - //modelLog.add(new Item("参数数", new Long(projectMgr.getParametertNum()).toString())); - modelLog.add(new Item("文档提交数", new Long(projectMgr.getCheckInNum()).toString())); - modelLog.add(new Item("MOCK服务调用次数", new Long(projectMgr.getMockNumInTotal()).toString(), "该信息自2014年10月底开始记录")); + modelLog.add(new Item("用户数", new Integer(getAccountMgr().getUserNum()).toString())); + modelLog.add(new Item("项目数", new Integer(projectMgr.getProjectNum()).toString())); + modelLog.add(new Item("接口数", new Integer(projectMgr.getActionNum()).toString())); + //modelLog.add(new Item("TAB数", new Integer(projectMgr.getModuleNum()).toString())); + //modelLog.add(new Item("页面数", new Integer(projectMgr.getPageNum()).toString())); + //modelLog.add(new Item("参数数", new Integer(projectMgr.getParametertNum()).toString())); + modelLog.add(new Item("文档提交数", new Integer(projectMgr.getCheckInNum()).toString())); + modelLog.add(new Item("MOCK服务调用次数", new Integer(projectMgr.getMockNumInTotal()).toString(), "该信息自2014年10月底开始记录")); for (Item item : modelLog) { modelLogMap.put(item.getKey(), item); @@ -145,7 +124,6 @@ public String log() { trends.put("checkIn", dataMgr.getCheckInTrendByMonth()); - // statistics data statistics.put("actionNumByTeam", dataMgr.getActionNumByTeam()); statistics.put("mockNumByProject", dataMgr.getMockNumByProject()); diff --git a/src/main/java/com/taobao/rigel/rap/project/bo/Action.java b/src/main/java/com/taobao/rigel/rap/project/bo/Action.java new file mode 100644 index 000000000..926adb5e0 --- /dev/null +++ b/src/main/java/com/taobao/rigel/rap/project/bo/Action.java @@ -0,0 +1,287 @@ +package com.taobao.rigel.rap.project.bo; + +import com.taobao.rigel.rap.common.utils.StringUtils; + +import java.util.*; + +public class Action implements java.io.Serializable { + + private int id; + private int disableCache; + private String name; + private String description; + private String requestType = "1"; + private String requestUrl; + private Set requestParameterList = new HashSet(); + private Set responseParameterList = new HashSet(); + private String responseTemplate; + private Set pageList = new HashSet(); + private String remarks; + + public static List loadList(List> result) { + List list = new ArrayList(); + for (Map row : result) { + Action obj = new Action(); + obj.setDescription((String) row.get("description")); + obj.setId((Integer) row.get("id")); + obj.setName((String) row.get("name")); + obj.setRemarks((String) row.get("remarks")); + obj.setRequestType((String) row.get("request_type")); + obj.setRequestUrl((String) row.get("request_url")); + list.add(obj); + } + return list; + } + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public int getDisableCache() { + return disableCache; + } + + public void setDisableCache(int disableCache) { + this.disableCache = disableCache; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description == null ? "" : description; + } + + public String getRequestType() { + return requestType; + } + + public void setRequestType(String requestType) { + if (requestType == null || requestType == "") + return; + this.requestType = requestType; + } + + public String getMethod() { + if (this.requestType.equals("2")) { + return "POST"; + } else if (this.requestType.equals("3")) { + return "PUT"; + } else if (this.requestType.equals("4")) { + return "DELETE"; + } else { + return "GET"; // in default + } + } + + public String getRequestUrl() { + return requestUrl; + } + + public void setRequestUrl(String requestUrl) { + this.requestUrl = requestUrl == null ? "" : requestUrl; + } + + public void addParameter(Parameter parameter, boolean isRequest) { + if (isRequest) { + getRequestParameterList().add(parameter); + parameter.getActionRequestList().add(this); + } else { + getResponseParameterList().add(parameter); + parameter.getActionResponseList().add(this); + } + } + + public Set getRequestParameterList() { + return requestParameterList; + } + + public void setRequestParameterList(Set requestParameterList) { + this.requestParameterList = requestParameterList; + } + + public Set getResponseParameterList() { + return responseParameterList; + } + + public void setResponseParameterList(Set responseParameterList) { + this.responseParameterList = responseParameterList; + } + + public List getRequestParameterListOrdered() { + Set parameterList = getRequestParameterList(); + List parameterListOrdered = new ArrayList(); + parameterListOrdered.addAll(parameterList); + Collections.sort(parameterListOrdered, new ParameterComparator()); + return parameterListOrdered; + } + + public List getResponseParameterListOrdered() { + Set parameterList = getResponseParameterList(); + List parameterListOrdered = new ArrayList(); + parameterListOrdered.addAll(parameterList); + Collections.sort(parameterListOrdered, new ParameterComparator()); + return parameterListOrdered; + } + + public String getResponseTemplate() { + return responseTemplate; + } + + public void setResponseTemplate(String responseTemplate) { + this.responseTemplate = responseTemplate == null ? "" + : responseTemplate; + } + + public Set getPageList() { + return pageList; + } + + public void setPageList(Set pageList) { + this.pageList = pageList; + } + + public void update(Action action) { + setDescription(action.getDescription()); + setName(action.getName()); + setRequestType(action.getRequestType()); + setRequestUrl(action.getRequestUrl()); + setResponseTemplate(action.getResponseTemplate()); + } + + public String toString() { + StringBuilder stringBuilder = new StringBuilder(); + + stringBuilder.append("{\"id\":" + getId() + ","); + stringBuilder.append("\"name\":\"" + StringUtils.escapeInJ(getName()) + + "\","); + stringBuilder.append("\"description\":\"" + + StringUtils.escapeInJ(getDescription()) + "\","); + stringBuilder.append("\"requestType\":\"" + getRequestType() + "\","); + stringBuilder.append("\"requestUrl\":\"" + + StringUtils.escapeInJ(getRequestUrl()) + "\","); + stringBuilder.append("\"responseTemplate\":\"" + + StringUtils.escapeInJ(getResponseTemplate()) + "\","); + stringBuilder.append("\"requestParameterList\":"); + + stringBuilder.append("["); + Iterator iterator = getRequestParameterListOrdered() + .iterator(); + while (iterator.hasNext()) { + stringBuilder.append(iterator.next()); + if (iterator.hasNext()) { + stringBuilder.append(","); + } + } + stringBuilder.append("],"); + + stringBuilder.append("\"responseParameterList\":"); + + stringBuilder.append("["); + iterator = getResponseParameterListOrdered().iterator(); + while (iterator.hasNext()) { + stringBuilder.append(iterator.next()); + if (iterator.hasNext()) { + stringBuilder.append(","); + } + } + stringBuilder.append("]}"); + return stringBuilder.toString(); + } + + public String getRemarks() { + return remarks; + } + + public void setRemarks(String remarks) { + this.remarks = remarks; + } + + /** + * get request parameter list HTML for file exporting reason: velocity + * doesn't support macro recursion. + * + * @return + */ + public String getRequestParameterListHTML() { + return getParameterListHTML(requestParameterList); + } + + public String getResponseParameterListHTML() { + return getParameterListHTML(responseParameterList); + } + + private String getParameterListHTML(Set list) { + StringBuilder html = new StringBuilder(); + html + .append("") + .append("") + .append("") + .append("") + .append("") + .append("") + .append(""); + getParameterListHTMLSub(html, list, (short) 1); + html.append("
    NameIdentifierTypeRemark
    "); + return html.toString(); + } + + private void getParameterListHTMLSub(StringBuilder html, Set list, short level) { + for (Parameter p : list) { + html + .append("") + .append("" + levelMark(level) + StringUtils.escapeInH(p.getName()) + "") + .append("" + StringUtils.escapeInH(p.getIdentifier()) + "") + .append("" + StringUtils.escapeInH(p.getDataType()) + "") + .append("" + StringUtils.escapeInH(p.getRemark()) + "") + .append(""); + if (p.getParameterList() != null || p.getParameterList().size() > 0) { + getParameterListHTMLSub(html, p.getParameterList(), (short) (level + 1)); + } + } + + } + + /** + * level 1: level 2:--- level 3:------ ... + * + * @param level started from 1 + * @return + */ + private String levelMark(short level) { + StringBuilder sb = new StringBuilder(); + for (short i = 1; i < level; i++) { + sb.append("---"); + } + return sb.toString(); + } + + public String getRequestUrlRel() { + String url = this.requestUrl; + if (url == null || url.isEmpty()) { + return "xxxxxxxxxxxxxxxxEMPTY URLxxxxxxxxxxxxxxxxx"; + } + if (url.contains("https://")) { + url = url.substring(url.indexOf("/", 7)); + } else if (url.contains("http://")) { + url = url.substring(url.indexOf("/", 8)); + } + return url; + } + + public enum TYPE {REQUEST, RESPONSE} + +} diff --git a/src/main/java/com/taobao/rigel/rap/project/bo/ActionComparator.java b/src/main/java/com/taobao/rigel/rap/project/bo/ActionComparator.java new file mode 100644 index 000000000..5332cebf3 --- /dev/null +++ b/src/main/java/com/taobao/rigel/rap/project/bo/ActionComparator.java @@ -0,0 +1,11 @@ +package com.taobao.rigel.rap.project.bo; + +import java.util.Comparator; + +public class ActionComparator implements Comparator { + + public int compare(Action o1, Action o2) { + return o1.getId() < o2.getId() ? 0 : 1; + } + +} diff --git a/src/main/java/com/taobao/rigel/rap/project/bo/CheckInComparator.java b/src/main/java/com/taobao/rigel/rap/project/bo/CheckInComparator.java new file mode 100644 index 000000000..79bae64eb --- /dev/null +++ b/src/main/java/com/taobao/rigel/rap/project/bo/CheckInComparator.java @@ -0,0 +1,14 @@ +package com.taobao.rigel.rap.project.bo; + +import com.taobao.rigel.rap.workspace.bo.CheckIn; + +import java.util.Comparator; + +public class CheckInComparator implements Comparator { + + + public int compare(CheckIn o1, CheckIn o2) { + return o1.getId() > o2.getId() ? -1 : 1; + } + +} diff --git a/src/main/java/com/taobao/rigel/rap/project/bo/Module.java b/src/main/java/com/taobao/rigel/rap/project/bo/Module.java new file mode 100644 index 000000000..3c626aa6a --- /dev/null +++ b/src/main/java/com/taobao/rigel/rap/project/bo/Module.java @@ -0,0 +1,125 @@ +package com.taobao.rigel.rap.project.bo; + +import com.taobao.rigel.rap.common.utils.StringUtils; + +import java.util.*; + +public class Module implements java.io.Serializable { + + private int id; + private int projectId; + private String name; + private String introduction; + private Project project; + private Set pageList = new HashSet(); + + public int getId() { + return this.id; + } + + public void setId(int id) { + this.id = id; + } + + public int getProjectId() { + return this.projectId; + } + + public void setProjectId(int projectId) { + this.projectId = projectId; + } + + public String getName() { + return this.name; + } + + public void setName(String name) { + this.name = name; + } + + public String getIntroduction() { + return this.introduction; + } + + public void setIntroduction(String introduction) { + this.introduction = (introduction == null ? "" : introduction); + } + + public Project getProject() { + return this.project; + } + + public void setProject(Project project) { + this.project = project; + } + + public void addPage(Page page) { + getPageList().add(page); + page.setModule(this); + } + + public Set getPageList() { + return this.pageList; + } + + public void setPageList(Set pageList) { + this.pageList = pageList; + } + + public List getPageListOrdered() { + Set pageList = getPageList(); + List pageListOrdered = new ArrayList(); + pageListOrdered.addAll(pageList); + Collections.sort(pageListOrdered, new PageComparator()); + return pageListOrdered; + } + + public void update(Module module) { + setIntroduction(module.getIntroduction()); + setName(module.getName()); + } + + public String toString() { + + StringBuilder stringBuilder = new StringBuilder(); + + stringBuilder.append("{\"id\":" + getId() + ","); + stringBuilder.append("\"introduction\":\"" + StringUtils.escapeInJ(getIntroduction()) + "\","); + stringBuilder.append("\"name\":\"" + StringUtils.escapeInJ(getName()) + "\","); + stringBuilder.append("\"pageList\":"); + + stringBuilder.append("["); + Iterator iterator = getPageListOrdered().iterator(); + while (iterator.hasNext()) { + stringBuilder.append(iterator.next()); + if (iterator.hasNext()) { + stringBuilder.append(","); + } + } + stringBuilder.append("]}"); + + return stringBuilder.toString(); + } + + public String toString(Project.TO_STRING_TYPE type) { + + StringBuilder stringBuilder = new StringBuilder(); + + stringBuilder.append("{\"id\":" + getId() + ","); + stringBuilder.append("\"introduction\":\"" + StringUtils.escapeInJ(getIntroduction()) + "\","); + stringBuilder.append("\"name\":\"" + StringUtils.escapeInJ(getName()) + "\","); + stringBuilder.append("\"pageList\":"); + + stringBuilder.append("["); + Iterator iterator = getPageListOrdered().iterator(); + while (iterator.hasNext()) { + stringBuilder.append(iterator.next().toString(type)); + if (iterator.hasNext()) { + stringBuilder.append(","); + } + } + stringBuilder.append("]}"); + + return stringBuilder.toString(); + } +} diff --git a/src/main/java/com/taobao/rigel/rap/project/bo/ModuleComparator.java b/src/main/java/com/taobao/rigel/rap/project/bo/ModuleComparator.java new file mode 100644 index 000000000..d0f72a334 --- /dev/null +++ b/src/main/java/com/taobao/rigel/rap/project/bo/ModuleComparator.java @@ -0,0 +1,11 @@ +package com.taobao.rigel.rap.project.bo; + +import java.util.Comparator; + +public class ModuleComparator implements Comparator { + + public int compare(Module o1, Module o2) { + return o1.getId() < o2.getId() ? 0 : 1; + } + +} diff --git a/src/main/java/com/taobao/rigel/rap/project/bo/ObjectItem.java b/src/main/java/com/taobao/rigel/rap/project/bo/ObjectItem.java new file mode 100644 index 000000000..5f314ff4d --- /dev/null +++ b/src/main/java/com/taobao/rigel/rap/project/bo/ObjectItem.java @@ -0,0 +1,23 @@ +package com.taobao.rigel.rap.project.bo; + +public class ObjectItem implements java.io.Serializable { + + public String className; + private int id; + + public String getClassName() { + return className; + } + + public void setClassName(String className) { + this.className = className; + } + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } +} diff --git a/src/main/java/com/taobao/rigel/rap/project/bo/Page.java b/src/main/java/com/taobao/rigel/rap/project/bo/Page.java new file mode 100644 index 000000000..8f296cbc0 --- /dev/null +++ b/src/main/java/com/taobao/rigel/rap/project/bo/Page.java @@ -0,0 +1,126 @@ +package com.taobao.rigel.rap.project.bo; + +import com.taobao.rigel.rap.common.utils.StringUtils; + +import java.util.*; + +public class Page implements java.io.Serializable { + + private int id; + private String name; + private String introduction; + private Module module; + private Set actionList = new HashSet(); + private String template; + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getIntroduction() { + return introduction; + } + + public void setIntroduction(String introduction) { + this.introduction = (introduction == null ? "" : introduction); + } + + public Module getModule() { + return module; + } + + public void setModule(Module module) { + this.module = module; + } + + public Set getActionList() { + return actionList; + } + + public void setActionList(Set actionList) { + this.actionList = actionList; + } + + public List getActionListOrdered() { + Set actionList = getActionList(); + List actionListOrdered = new ArrayList(); + actionListOrdered.addAll(actionList); + Collections.sort(actionListOrdered, new ActionComparator()); + return actionListOrdered; + } + + public String getTemplate() { + return template; + } + + public void setTemplate(String template) { + this.template = template; + } + + public void addAction(Action action) { + getActionList().add(action); + //action.getPageList().add(this); + } + + public void update(Page page) { + setIntroduction(page.getIntroduction()); + setName(page.getName()); + setTemplate(page.getTemplate()); + } + + public String toString() { + StringBuilder stringBuilder = new StringBuilder(); + + stringBuilder.append("{\"id\":" + getId() + ","); + stringBuilder.append("\"introduction\":\"" + StringUtils.escapeInJ(getIntroduction()) + "\","); + stringBuilder.append("\"name\":\"" + StringUtils.escapeInJ(getName()) + "\","); + stringBuilder.append("\"actionList\":"); + + stringBuilder.append("["); + Iterator iterator = getActionListOrdered().iterator(); + while (iterator.hasNext()) { + stringBuilder.append(iterator.next()); + if (iterator.hasNext()) { + stringBuilder.append(","); + } + } + stringBuilder.append("]}"); + + return stringBuilder.toString(); + } + + public String toString(Project.TO_STRING_TYPE type) { + StringBuilder stringBuilder = new StringBuilder(); + + stringBuilder.append("{\"id\":" + getId() + ","); + stringBuilder.append("\"introduction\":\"" + StringUtils.escapeInJ(getIntroduction()) + "\","); + stringBuilder.append("\"name\":\"" + StringUtils.escapeInJ(getName()) + "\""); + if (type == Project.TO_STRING_TYPE.TO_PAGE) { + stringBuilder.append("}"); + } else { + stringBuilder.append(",\"actionList\":"); + stringBuilder.append("["); + Iterator iterator = getActionListOrdered().iterator(); + while (iterator.hasNext()) { + stringBuilder.append(iterator.next()); + if (iterator.hasNext()) { + stringBuilder.append(","); + } + } + stringBuilder.append("]}"); + } + return stringBuilder.toString(); + } +} diff --git a/src/main/java/com/taobao/rigel/rap/project/bo/PageComparator.java b/src/main/java/com/taobao/rigel/rap/project/bo/PageComparator.java new file mode 100644 index 000000000..9c1f63a6e --- /dev/null +++ b/src/main/java/com/taobao/rigel/rap/project/bo/PageComparator.java @@ -0,0 +1,11 @@ +package com.taobao.rigel.rap.project.bo; + +import java.util.Comparator; + +public class PageComparator implements Comparator { + + public int compare(Page o1, Page o2) { + return o1.getId() < o2.getId() ? 0 : 1; + } + +} diff --git a/src/main/java/com/taobao/rigel/rap/project/bo/Parameter.java b/src/main/java/com/taobao/rigel/rap/project/bo/Parameter.java new file mode 100644 index 000000000..44feec02d --- /dev/null +++ b/src/main/java/com/taobao/rigel/rap/project/bo/Parameter.java @@ -0,0 +1,255 @@ +package com.taobao.rigel.rap.project.bo; + +import com.taobao.rigel.rap.common.utils.StringUtils; + +import java.util.*; + +public class Parameter implements java.io.Serializable { + + private int id; + private String mockData; + private String name; + private String identifier; + private String identifierChange; + private String remarkChange; + private String dataType; + private String remark; + private Set actionRequestList = new HashSet(); + private Set actionResponseList = new HashSet(); + private String validator = ""; + private Set parameterList = new HashSet(); + private Set complexParamerterList = new HashSet(); + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public String getMockData() { + return mockData; + } + + public void setMockData(String mockData) { + this.mockData = mockData; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = (name == null ? "" : name); + } + + public String getIdentifier() { + if (identifierChange != null) { + return identifierChange; + } else { + return identifier; + } + } + + public void setIdentifier(String identifier) { + this.identifier = (identifier == null ? "" : identifier); + } + + public String getIdentifierChange() { + + return identifierChange; + } + + public void setIdentifierChange(String identifierChange) { + this.identifierChange = identifierChange; + } + + public String getRemarkChange() { + return remarkChange; + } + + public void setRemarkChange(String remarkChange) { + this.remarkChange = remarkChange; + } + + public String getMockIdentifier() { + String rv = ""; + if (identifier == null || identifier.isEmpty()) { + return "\"emptyIdentifier\""; + } + + rv = identifier; + if (rv != null && !rv.isEmpty()) { + int index = rv.indexOf("|"); + if (index > -1) { + rv = rv.substring(0, index); + } + } + return "\"" + rv + "\""; + } + + public String getIdentifierWithoutMockjsRule() { + String rv; + if (identifier == null || identifier.isEmpty()) { + return "emptyIdentifier"; + } + + rv = identifier; + if (rv != null && !rv.isEmpty()) { + int index = rv.indexOf("|"); + if (index > -1) { + rv = rv.substring(0, index); + } + } + return rv; + } + + public String getMockJSIdentifier() { + String rv = ""; + if (identifier == null || identifier.isEmpty()) { + return "\"emptyIdentifier\""; + } + rv = identifier; + return "\"" + rv + "\""; + } + + public String getDataType() { + if (this.dataType == null || this.dataType.trim().isEmpty()) { + return ""; + } + return dataType; + } + + public void setDataType(String dataType) { + this.dataType = (dataType == null ? "" : dataType); + } + + public String getRemark() { + if (remarkChange != null) { + return remarkChange; + } + return (remark == null ? "" : remark); + } + + public void setRemark(String remark) { + this.remark = remark; + } + + public Set getActionRequestList() { + return actionRequestList; + } + + public void setActionRequestList(Set actionRequestList) { + this.actionRequestList = actionRequestList; + } + + public Set getActionResponseList() { + return actionResponseList; + } + + public void setActionResponseList(Set actionResponseList) { + this.actionResponseList = actionResponseList; + } + + public String getValidator() { + return validator; + } + + public void setValidator(String validator) { + this.validator = validator; + } + + public Set getParameterList() { + return parameterList; + } + + public void setParameterList(Set parameterList) { + this.parameterList = parameterList; + } + + public void update(Parameter parameter) { + setDataType(parameter.getDataType()); + setIdentifier(parameter.getIdentifier()); + setName(parameter.getName()); + setRemark(parameter.getRemark()); + setValidator(parameter.getValidator()); + } + + public List getParameterListOrdered() { + Set parameterList = getParameterList(); + List parameterListOrdered = new ArrayList(); + parameterListOrdered.addAll(parameterList); + Collections.sort(parameterListOrdered, new ParameterComparator()); + return parameterListOrdered; + } + + public Set getComplexParameterList() { + return complexParamerterList; + } + + public void setComplexParameterList(Set complexParameterList) { + this.complexParamerterList = complexParameterList; + } + + public void addChild(Parameter parameter) { + getParameterList().add(parameter); + parameter.getComplexParameterList().add(this); + } + + public String toString() { + StringBuilder stringBuilder = new StringBuilder(); + stringBuilder.append("{\"id\":" + getId() + ","); + stringBuilder.append("\"identifier\":\"" + + StringUtils.escapeInJ(getIdentifier()) + "\","); + stringBuilder.append("\"name\":\"" + StringUtils.escapeInJ(getName()) + + "\","); + stringBuilder.append("\"remark\":\"" + + StringUtils.escapeInJ(getRemark()) + "\","); + stringBuilder.append("\"parameterList\":"); + stringBuilder.append("["); + Iterator iterator = getParameterListOrdered().iterator(); + while (iterator.hasNext()) { + stringBuilder.append(iterator.next()); + if (iterator.hasNext()) { + stringBuilder.append(","); + } + } + stringBuilder.append("],"); + stringBuilder.append("\"validator\":\"" + + StringUtils.escapeInJ(getValidator()) + "\","); + stringBuilder.append("\"dataType\":\"" + + StringUtils.escapeInJ(getDataType()) + "\"}"); + return stringBuilder.toString(); + } + + public String getRemarkWithoutMockjsRule() { + if (remark != null && remark.contains("@mock=")) { + return remark.substring(0, remark.indexOf("@mock=")); + } else { + return remark; + } + } + + public String getMockJsRules() { + if (remark == null || remark.isEmpty() || (!remark.contains("@mock="))) { + return null; + } + return remark.substring(remark.indexOf("@mock=") + 6); + + } + + + public String getJSONSchemaDataType() { + if (dataType != null && dataType.contains("array")) { + return "array"; + } + return this.dataType; + } + + public boolean hasMockJSData() { + return this.getMockJsRules() != null; + } + + +} diff --git a/src/main/java/com/taobao/rigel/rap/project/bo/ParameterComparator.java b/src/main/java/com/taobao/rigel/rap/project/bo/ParameterComparator.java new file mode 100644 index 000000000..9bfc26752 --- /dev/null +++ b/src/main/java/com/taobao/rigel/rap/project/bo/ParameterComparator.java @@ -0,0 +1,11 @@ +package com.taobao.rigel.rap.project.bo; + +import java.util.Comparator; + +public class ParameterComparator implements Comparator { + + public int compare(Parameter o1, Parameter o2) { + return o1.getId() < o2.getId() ? 0 : 1; + } + +} diff --git a/src/main/java/com/taobao/rigel/rap/project/bo/Project.java b/src/main/java/com/taobao/rigel/rap/project/bo/Project.java new file mode 100644 index 000000000..49faf249f --- /dev/null +++ b/src/main/java/com/taobao/rigel/rap/project/bo/Project.java @@ -0,0 +1,543 @@ +package com.taobao.rigel.rap.project.bo; + +import com.taobao.rigel.rap.account.bo.User; +import com.taobao.rigel.rap.common.utils.ArrayUtils; +import com.taobao.rigel.rap.common.utils.DateUtils; +import com.taobao.rigel.rap.common.utils.StringUtils; +import com.taobao.rigel.rap.workspace.bo.CheckIn; +import com.taobao.rigel.rap.workspace.bo.Workspace; +import com.taobao.rigel.rap.workspace.bo.Workspace.ModeType; +import org.hibernate.Session; +import org.ocpsoft.prettytime.PrettyTime; + +import java.text.ParseException; +import java.util.*; + +public class Project implements java.io.Serializable { + + public static final int PRIVATE_ACCESS = 0; + public static final int DEFAULT_ACCESS = 10; + private int id; + private int userId; + private String name; + private Date createDate; + private Date updateTime; + private String introduction; + private User user; + private int workspaceModeInt; + private String relatedIds = ""; + private int groupId; + private int mockNum; + private int teamId; + private short accessType; + private Set userList = new HashSet(); + private Set moduleList = new HashSet(); + private String projectData; + private List memberAccountList; + private Set workspaceList = new HashSet(); + private String version; + private boolean isManagable; + private Set checkInList = new HashSet(); + + public Project() { + + } + + public int getTeamId() { + return teamId; + } + + public void setTeamId(int teamId) { + this.teamId = teamId; + } + + public short getAccessType() { + return accessType; + } + + + public void setAccessType(short accessType) { + this.accessType = accessType; + } + + public int getMockNum() { + return mockNum; + } + + public void setMockNum(int mockNum) { + this.mockNum = mockNum; + } + + public int getGroupId() { + return groupId; + } + + public void setGroupId(int groupId) { + this.groupId = groupId; + } + + public String getRelatedIds() { + return relatedIds; + } + + public void setRelatedIds(String relatedIds) { + String[] ids = relatedIds.split(","); + List idsArr = new ArrayList(); + for (String id : ids) { + try { + int integerId = Integer.parseInt(id); + idsArr.add(integerId); + } catch(Exception ex) { + + } + } + this.relatedIds = ArrayUtils.join(idsArr, ","); + } + + public int getWorkspaceModeInt() { + return workspaceModeInt; + } + + public void setWorkspaceModeInt(int workspaceModeInt) { + this.workspaceModeInt = workspaceModeInt; + } + + public Date getUpdateTime() { + return updateTime; + } + + public void setUpdateTime(Date updateTime) { + this.updateTime = updateTime; + } + + public ModeType getWorkspaceMode() { + if (workspaceModeInt == 1) { + return ModeType.VSS; + } else if (workspaceModeInt == 2) { + return ModeType.SVN; + } else { + return ModeType.VSS; + } + } + + public User getUser() { + return user; + } + + public void setUser(User user) { + this.user = user; + } + + public int getUserId() { + return userId; + } + + public void setUserId(int userId) { + this.userId = userId; + } + + public Set getUserList() { + return userList; + } + + public void setUserList(Set userList) { + this.userList = userList; + } + + public Set getModuleList() { + return moduleList; + } + + public void setModuleList(Set moduleList) { + this.moduleList = moduleList; + } + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public Date getCreateDate() { + return createDate; + } + + public void setCreateDate(Date createDate) { + this.createDate = createDate; + } + + public String getIntroduction() { + return introduction; + } + + public void setIntroduction(String introduction) { + this.introduction = (introduction == null ? "" : introduction); + } + + public String getProjectData() { + return projectData; + } + + public void setProjectData(String projectData) { + this.projectData = projectData; + } + + public List getModuleListOrdered() { + Set moduleList = getModuleList(); + List moduleListOrdered = new ArrayList(); + moduleListOrdered.addAll(moduleList); + Collections.sort(moduleListOrdered, new ModuleComparator()); + return moduleListOrdered; + } + + public void addModule(Module module) { + getModuleList().add(module); + module.setProject(this); + } + + public String getMemberAccountListStr() { + StringBuilder stringBuilder = new StringBuilder(); + for (User user : getUserList()) { + stringBuilder.append(user.getAccount() + "(" + user.getName() + "), "); + } + return stringBuilder.toString(); + } + + public List getMemberAccountList() { + return memberAccountList; + } + + public void setMemberAccountList(List memberAccountList) { + this.memberAccountList = memberAccountList; + } + + public Set getWorkspaceList() { + return workspaceList; + } + + public void setWorkspaceList(Set workspaceList) { + this.workspaceList = workspaceList; + } + + public String getVersion() { + return version; + } + + public void setVersion(String version) { + this.version = version; + } + + public String toString(TO_STRING_TYPE type) { + StringBuilder stringBuilder = new StringBuilder(); + stringBuilder.append("{\"createDateStr\":\"" + getCreateDateStr() + "\","); + stringBuilder.append("\"user\":" + getUser() + ","); + stringBuilder.append("\"id\":" + getId() + ","); + stringBuilder.append("\"version\":\"" + getVersion() + "\","); + stringBuilder.append("\"introduction\":\"" + StringUtils.escapeInJ(getIntroduction()) + "\","); + stringBuilder.append("\"name\":\"" + StringUtils.escapeInJ(getName()) + "\","); + stringBuilder.append("\"moduleList\":"); + + stringBuilder.append("["); + Iterator iterator = getModuleListOrdered().iterator(); + while (iterator.hasNext()) { + stringBuilder.append(iterator.next().toString(type)); + if (iterator.hasNext()) { + stringBuilder.append(","); + } + } + stringBuilder.append("]}"); + return stringBuilder.toString(); + } + + public String toString() { + return "{}"; + } + + public void update(Project project) { + setIntroduction(project.getIntroduction()); + setName(project.getName()); + } + + public boolean getIsManagable() { + return isManagable; + } + + public void setIsManagable(boolean isManagable) { + this.isManagable = isManagable; + } + + public String getCreateDateStr() { + return getCreateDate() == null ? "" : DateUtils.DATE_FORMAT.format(getCreateDate()); + } + + public void setCreateDateStr(String createDateStr) throws ParseException { + setCreateDate((createDateStr == null || createDateStr.equals("")) ? + null : DateUtils.DATE_FORMAT.parse(createDateStr)); + } + + public String getUserListStr() { + StringBuilder stringBuilder = new StringBuilder(); + Iterator iterator = getUserList().iterator(); + while (iterator.hasNext()) { + User user = iterator.next(); + // remove the creator + if (user.getId() == getUser().getId()) continue; + stringBuilder.append(user.getName() + "(" + user.getWorkRole() + ")"); + if (iterator.hasNext()) { + stringBuilder.append(", "); + } + } + return stringBuilder.toString(); + } + + public String getUserListStrShort() { + StringBuilder stringBuilder = new StringBuilder(); + Iterator iterator = getUserList().iterator(); + int count = 1; + while (iterator.hasNext()) { + User user = iterator.next(); + // remove the creator + if (user.getId() == getUser().getId()) continue; + stringBuilder.append(user.getName() + "(" + user.getWorkRole() + ")"); + if (iterator.hasNext()) { + stringBuilder.append(", "); + } + if (++count > 5) { + stringBuilder.append(iterator.hasNext() ? "etc." : ""); + break; + } + } + return stringBuilder.toString(); + } + + public Set getCheckInList() { + return checkInList; + } + + public void setCheckInList(Set checkInList) { + this.checkInList = checkInList; + } + + public List getCheckInListOrdered() { + Set checkInList = getCheckInList(); + List checkInListOrdered = new ArrayList(); + checkInListOrdered.addAll(checkInList); + Collections.sort(checkInListOrdered, new CheckInComparator()); + return checkInListOrdered; + } + + public Module findModule(int moduleId) { + for (Module i : getModuleList()) { + if (i.getId() == moduleId) + return i; + } + return null; + } + + public Page findPage(int pageId) { + for (Module module : getModuleList()) { + for (Page page : module.getPageList()) { + if (page.getId() == pageId) + return page; + } + } + return null; + } + + public Action findAction(int actionId) { + for (Module module : getModuleList()) { + for (Page page : module.getPageList()) { + for (Action action : page.getActionList()) { + if (action.getId() == actionId) + return action; + } + } + } + return null; + } + + public Parameter findParameter(int parameterId, boolean isRequestType) { + for (Module module : getModuleList()) { + for (Page page : module.getPageList()) { + for (Action action : page.getActionList()) { + for (Parameter parameter : (isRequestType ? + action.getRequestParameterList() : action.getResponseParameterList())) { + if (parameter.getId() == parameterId) { + return parameter; + } + } + } + } + } + return null; + } + + public Parameter findChildParameter(int parameterId) { + for (Module module : getModuleList()) { + for (Page page : module.getPageList()) { + for (Action action : page.getActionList()) { + for (Parameter parameter : action.getRequestParameterList()) { + Parameter pRecur = findParameterRecursively(parameter, parameterId); + if (pRecur != null) { + return pRecur; + } + } + + for (Parameter parameter : action.getResponseParameterList()) { + Parameter pRecur = findParameterRecursively(parameter, parameterId); + if (pRecur != null) { + return pRecur; + } + } + } + } + } + return null; + } + + /** + * find parameter recursively + * recursive: + * p.parameterList[0].parameterList[0]..... + * + * @param p + * @param id + * @return return the object found, other wise return null + */ + private Parameter findParameterRecursively(Parameter p, int id) { + Iterator iterator = p.getParameterList().iterator(); + while (iterator.hasNext()) { + Parameter parameter = iterator.next(); + if (parameter.getId() == id) { + return parameter; + } + parameter = findParameterRecursively(parameter, id); + if (parameter != null) { + return parameter; + } + } + return null; + } + + public void removeModule(int id, Session session) { + Module module = findModule(id); + if (module != null && moduleList != null) { + moduleList.remove(module); + session.delete(module); + } + } + + public void removePage(int id, Session session) { + Page page = findPage(id); + if (page != null && page.getModule() != null && page.getModule().getPageList() != null) { + page.getModule().getPageList().remove(page); + session.delete(page); + } + } + + public void removeAction(int id, Session session) { + Action action = findAction(id); + if (action == null) return; + Set pageList = action.getPageList(); + if (pageList == null) return; + Iterator iterator = pageList.iterator(); + while (iterator.hasNext()) { + iterator.next().getActionList().remove(action); + session.delete(action); + } + } + + public void removeParameter(int id, Session session) { + Parameter parameter = findParameter(id, true); + + // if parameter == null, it maybe response parameter + if (parameter == null) { + parameter = findParameter(id, false); + + // if parameter == null still, it must be child parameter of a complex parameter + if (parameter == null) { + parameter = findChildParameter(id); + if (parameter != null && parameter.getComplexParameterList() != null) { + for (Parameter pComplex : parameter.getComplexParameterList()) { + pComplex.getParameterList().remove(parameter); + session.delete(parameter); + } + } + return; + } + Iterator iterator = parameter.getActionResponseList().iterator(); + while (iterator.hasNext()) { + iterator.next().getResponseParameterList().remove(parameter); + session.delete(parameter); + } + } else { + Iterator iterator = parameter.getActionRequestList().iterator(); + while (iterator.hasNext()) { + iterator.next().getRequestParameterList().remove(parameter); + session.delete(parameter); + } + } + } + + public boolean addMember(User user) { + // if member added is the creator, ignore + if (user.getId() == getUser().getId()) + return false; + // if member already exists, ignore + boolean exist = false; + for (User item : getUserList()) { + if (item.getId() == user.getId()) { + exist = true; + } + } + if (exist) return false; + // validation complete, add this user + getUserList().add(user); + user.getJoinedProjectList().add(this); + return true; + } + + public void removeMember(User user) { + getUserList().remove(user); + user.getJoinedProjectList().remove(this); + } + + public String getLastUpdateStr() { + PrettyTime p = new PrettyTime(new Locale("zh")); + return p.format(this.updateTime) + "更新"; + } + + public List getAllAction() { + List list = new ArrayList(); + for (Module m : this.moduleList) { + for (Page p : m.getPageList()) { + for (Action a : p.getActionList()) { + list.add(a); + } + } + } + return list; + } + + public boolean isUserMember(int userId) { + if (getUserId() == userId) return true; + for (User u : getUserList()) { + if (u.getId() == userId) return true; + } + return false; + } + + public enum TO_STRING_TYPE {TO_MODULE, TO_PAGE, TO_ACTION, TO_PARAMETER} + + public enum STAGE_TYPE {DESIGNING, DEVELOPING, DEBUGING} +} diff --git a/src/main/java/com/taobao/rigel/rap/project/bo/Validator.java b/src/main/java/com/taobao/rigel/rap/project/bo/Validator.java new file mode 100644 index 000000000..c20ff4453 --- /dev/null +++ b/src/main/java/com/taobao/rigel/rap/project/bo/Validator.java @@ -0,0 +1,32 @@ +package com.taobao.rigel.rap.project.bo; + +public class Validator implements java.io.Serializable { + + private int id; + private int type; + private String rule; + + public int getId() { + return this.id; + } + + public void setId(int id) { + this.id = id; + } + + public int getType() { + return this.type; + } + + public void setType(int type) { + this.type = type; + } + + public String getRule() { + return this.rule; + } + + public void setRule(String rule) { + this.rule = rule; + } +} diff --git a/src/main/java/com/taobao/rigel/rap/project/dao/ProjectDao.java b/src/main/java/com/taobao/rigel/rap/project/dao/ProjectDao.java new file mode 100644 index 000000000..bfcf65014 --- /dev/null +++ b/src/main/java/com/taobao/rigel/rap/project/dao/ProjectDao.java @@ -0,0 +1,178 @@ +package com.taobao.rigel.rap.project.dao; + +import com.taobao.rigel.rap.account.bo.User; +import com.taobao.rigel.rap.project.bo.Action; +import com.taobao.rigel.rap.project.bo.Module; +import com.taobao.rigel.rap.project.bo.Page; +import com.taobao.rigel.rap.project.bo.Project; + +import java.util.List; +import java.util.Map; + +public interface ProjectDao { + + /** + * get project list + * + * @param user + * @param curPageNum + * @param pageSize + * @return + */ + List getProjectList(User user, int curPageNum, int pageSize); + + /** + * get new project + * + * @param project + * @return always 0 + */ + int addProject(Project project); + + /** + * update project + * + * @param id + * @param projectData + * @param deletedObjectListData + * @return + */ + String updateProject(int id, String projectData, + String deletedObjectListData, Map actionIdMap); + + /** + * update project + * + * @param project + * @return + */ + int updateProject(Project project); + + /** + * remove project + * + * @param id + * @return + */ + int removeProject(int id); + + /** + * get project + * + * @param id + * @return + */ + Project getProjectSummary(int id); + + /** + * get module + * + * @param id + * @return + */ + Module getModule(int id); + + /** + * get page + * + * @param id + * @return + */ + Object getPage(int id); + + + /** + * get action + * + * @param id + * @return + */ + Action getAction(int id); + + /** + * save project + * + * @param project + * @return + */ + int saveProject(Project project); + + /** + * get project list number + * + * @param user + * @return + */ + int getProjectListNum(User user); + + /** + * get matched action list based on URL pattern + * + * @param projectId + * @param pattern + * @return + */ + List getMatchedActionList(int projectId, String pattern); + + /** + * clear all mock data of objects in specified project + * + * @param projectId project id + * @return affected rows num + */ + public int resetMockData(int projectId); + + /** + * get project list by group + * + * @param id + * @return + */ + List getProjectListByGroup(int id); + + /** + * search all projects (for admin use) + * + * @param key + * @return + */ + List search(String key); + + List getProjectList(); + + int getProjectListNum(); + + int getModuleNum(); + + int getPageNum(); + + int getActionNum(); + + int getParametertNum(); + + int getCheckInNum(); + + int getMockNumInTotal(); + + List selectMockNumTopNProjectList(int limit); + + /** + * get project id by action id + * + * @param actionId + * @return + */ + Integer getProjectIdByActionId(int actionId); + + void updateProjectNum(Project project); + + + /** + * transfer a project to another user + * @param projectId + * @param creatorId + */ + void updateCreatorId(int projectId, int creatorId); + + Project getProject(int id); +} diff --git a/src/main/java/com/taobao/rigel/rap/project/dao/impl/ProjectDaoImpl.java b/src/main/java/com/taobao/rigel/rap/project/dao/impl/ProjectDaoImpl.java new file mode 100644 index 000000000..b4b8f8c5a --- /dev/null +++ b/src/main/java/com/taobao/rigel/rap/project/dao/impl/ProjectDaoImpl.java @@ -0,0 +1,575 @@ +package com.taobao.rigel.rap.project.dao.impl; + +import com.google.gson.Gson; +import com.taobao.rigel.rap.account.bo.User; +import com.taobao.rigel.rap.common.utils.ArrayUtils; +import com.taobao.rigel.rap.common.utils.CacheUtils; +import com.taobao.rigel.rap.common.utils.StringUtils; +import com.taobao.rigel.rap.common.utils.URLUtils; +import com.taobao.rigel.rap.project.bo.*; +import com.taobao.rigel.rap.project.dao.ProjectDao; +import org.hibernate.*; +import org.hibernate.criterion.Projections; +import org.hibernate.criterion.Restrictions; +import org.hibernate.transform.Transformers; +import org.springframework.orm.hibernate5.support.HibernateDaoSupport; + +import java.util.ArrayList; +import java.util.Date; +import java.util.List; +import java.util.Map; + +public class ProjectDaoImpl extends HibernateDaoSupport implements ProjectDao { + + public List getProjectList(User user, int curPageNum, int pageSize) { + StringBuilder sql = new StringBuilder(); + sql + .append("SELECT project_id ") + .append("FROM tb_project_and_user ") + .append("WHERE user_id = :userId ") + .append("UNION ") + .append("SELECT id ") + .append("FROM tb_project ") + .append("WHERE user_id = :userId "); + Query query = currentSession().createSQLQuery(sql.toString()).setInteger("userId", + user.getId()); + + List list = query.list(); + List resultList = new ArrayList(); + for (Integer id : list) { + Project p = this.getProject(id); + if (p != null && p.getId() > 0) { + resultList.add(p); + } + } + return resultList; + } + + public List getProjectList() { + String hqlByUser = "from Project"; + Query query = currentSession().createQuery(hqlByUser); + return query.list(); + } + + + public int addProject(Project project) { + Session session = currentSession(); + project.getUser().addCreatedProject(project); + project.setVersion("0.0.0.1"); // default version + int modeInt = project.getWorkspaceModeInt(); + if (modeInt <= 0 || modeInt >= 3) { + project.setWorkspaceModeInt(1); + } + session.save(project); + project = session.load(Project.class, project.getId()); + project.setProjectData(project + .toString(Project.TO_STRING_TYPE.TO_PARAMETER)); + return project.getId(); + } + + + public int removeProject(int id) { + Session session = currentSession(); + Object project = session.get(Project.class, id); + if (project != null) { + session.delete(project); + return 0; + } else { + return -1; + } + + } + + + public int updateProject(Project project) { + Session session = currentSession(); + session.update(project); + return 0; + } + + + public Project getProjectSummary(int id) { + + Project project = (Project) currentSession().createCriteria(Project.class) + .setProjection(Projections.projectionList() + .add(Projections.property("id"), "id") + .add(Projections.property("name"), "name") + .add(Projections.property("userId"), "userId") + .add(Projections.property("updateTime"), "updateTime") + .add(Projections.property("introduction"), "introduction") + .add(Projections.property("createDate"), "createDate") + .add(Projections.property("version"), "version") + .add(Projections.property("groupId"), "groupId") + .add(Projections.property("relatedIds"), "relatedIds") + .add(Projections.property("accessType"), "accessType") + ) + .add(Restrictions.eq("id", id)) + .setResultTransformer(Transformers.aliasToBean(Project.class)) + .uniqueResult(); + + return project; + + + // return (Project) currentSession().createQuery("from Project where id = :id").setint("id", id).uniqueResult(); + } + + + public Module getModule(int id) { + Module m = null; + try { + Session session = currentSession(); + m = (Module) session.get(Module.class, id); + } catch (ObjectNotFoundException ex) { + ex.printStackTrace(); + } catch (Exception ex) { + ex.printStackTrace(); + } + return m; + } + + + public Page getPage(int id) { + return (Page) currentSession().get(Page.class, id); + } + + + public Action getAction(int id) { + return (Action) currentSession().get(Action.class, id); + } + + private Parameter getParameter(int id) { + return (Parameter) currentSession().get(Parameter.class, id); + } + + + public int saveProject(Project project) { + Session session = currentSession(); + session.saveOrUpdate(project); + return 0; + } + + + public String updateProject(int id, String projectData, + String deletedObjectListData, Map actionIdMap) { + Session session = currentSession(); + + Gson gson = new Gson(); + + Project projectClient = gson.fromJson(projectData, Project.class); + + ObjectItem[] deletedObjectList = gson.fromJson(deletedObjectListData, + ObjectItem[].class); + + Project projectServer = session.load(Project.class, id); + projectServer.setUpdateTime(new Date()); + + // performing deleting + for (ObjectItem item : deletedObjectList) { + if (item.getClassName().equals("Module")) { + projectServer.removeModule(item.getId(), session); + } else if (item.getClassName().equals("Page")) { + projectServer.removePage(item.getId(), session); + } else if (item.getClassName().equals("Action")) { + projectServer.removeAction(item.getId(), session); + } else if (item.getClassName().equals("Parameter")) { + projectServer.removeParameter(item.getId(), session); + } + } + + // performing adding & updating + for (Module module : projectClient.getModuleList()) { + Module moduleServer = projectServer.findModule(module.getId()); + if (moduleServer == null) { + addModule(session, projectServer, module); + continue; + } + moduleServer.update(module); + for (Page page : module.getPageList()) { + Page pageServer = projectServer.findPage(page.getId()); + if (pageServer == null) { + addPage(session, module, page); + continue; + } + pageServer.update(page); + for (Action action : page.getActionList()) { + Action actionServer = projectServer.findAction(action + .getId()); + if (actionServer == null) { + int oldActionId = action.getId(); + int createdActionId = addAction(session, page, action); + actionIdMap.put(oldActionId, createdActionId); + continue; + } + actionServer.update(action); + CacheUtils.removeCacheByActionId(action.getId()); + for (Parameter parameter : action.getRequestParameterList()) { + Parameter parameterServer = projectServer + .findParameter(parameter.getId(), true); + if (parameterServer == null) { + addParameter(session, action, parameter, true); + continue; + } + parameterServer.update(parameter); + for (Parameter childParameter : parameter + .getParameterList()) { + processParameterRecursively(session, projectServer, + parameter, childParameter); + } + } + + for (Parameter parameter : action + .getResponseParameterList()) { + Parameter parameterServer = projectServer + .findParameter(parameter.getId(), false); + if (parameterServer == null) { + addParameter(session, action, parameter, false); + continue; + } + parameterServer.update(parameter); + for (Parameter childParameter : parameter + .getParameterList()) { + processParameterRecursively(session, projectServer, + parameter, childParameter); + } + } + } + } + } + return ""; + } + + private void processParameterRecursively(Session session, + Project projectServer, Parameter parameter, Parameter childParameter) { + Parameter childParameterServer = projectServer + .findChildParameter(childParameter.getId()); + if (childParameterServer == null) { + addParameterRecursively(session, parameter, childParameter); + } else { + childParameterServer.update(childParameter); + } + for (Parameter childOfChildParameter : childParameter + .getParameterList()) { + processParameterRecursively(session, projectServer, childParameter, + childOfChildParameter); + } + } + + private void addModule(Session session, Project project, Module module) { + project.addModule(module); + session.save(module); + for (Page page : module.getPageList()) { + addPage(session, module, page); + } + } + + private void addPage(Session session, Module module, Page page) { + module = (Module) session.load(Module.class, module.getId()); + module.addPage(page); + session.save(page); + for (Action action : page.getActionList()) { + addAction(session, page, action); + } + } + + private int addAction(Session session, Page page, Action action) { + page = session.load(Page.class, page.getId()); + page.addAction(action); + int createdId = (Integer) session.save(action); + for (Parameter parameter : action.getRequestParameterList()) { + addParameter(session, action, parameter, true); + } + for (Parameter parameter : action.getResponseParameterList()) { + addParameter(session, action, parameter, false); + } + return createdId; + } + + private void addParameter(Session session, Action action, + Parameter parameter, boolean isRequest) { + action = session.load(Action.class, action.getId()); + action.addParameter(parameter, isRequest); + session.save(parameter); + for (Parameter childParameter : parameter.getParameterList()) { + addParameterRecursively(session, parameter, childParameter); + } + } + + /** + * add parameter recursively + * + * @param session session object + * @param parameter parent parameter + * @param childParameter child parameter + */ + private void addParameterRecursively(Session session, Parameter parameter, + Parameter childParameter) { + parameter = session + .load(Parameter.class, parameter.getId()); + parameter.addChild(childParameter); + session.save(childParameter); + for (Parameter childOfChildParameter : childParameter + .getParameterList()) { + addParameterRecursively(session, childParameter, + childOfChildParameter); + } + } + + @SuppressWarnings("unchecked") + + public int getProjectListNum(User user) { + String hql = "select count(p) from Project as p order by p.id desc"; + String hqlByUser = "select count(p) from Project as p left join p.userList as u where p.user.id = :userId or u.id = :userId order by p.id desc"; + Query query = user == null ? currentSession().createQuery(hql) + : currentSession().createQuery(hqlByUser).setInteger("userId", + user.getId()); + List list = query.list(); + return list.get(0); + } + + + public int getProjectListNum() { + String sql = "SELECT COUNT(*) FROM tb_project"; + Query query = currentSession().createSQLQuery(sql); + return Integer.parseInt(query.uniqueResult().toString()); + } + + + public int getModuleNum() { + String sql = "SELECT COUNT(*) FROM tb_module"; + Query query = currentSession().createSQLQuery(sql); + return Integer.parseInt(query.uniqueResult().toString()); + } + + + public int getPageNum() { + String sql = "SELECT COUNT(*) FROM tb_page"; + Query query = currentSession().createSQLQuery(sql); + return Integer.parseInt(query.uniqueResult().toString()); + } + + + public int getActionNum() { + String sql = "SELECT COUNT(*) FROM tb_action"; + Query query = currentSession().createSQLQuery(sql); + return Integer.parseInt(query.uniqueResult().toString()); + } + + + public int getMockNumInTotal() { + String sql = "SELECT SUM(mock_num) FROM tb_project"; + Query query = currentSession().createSQLQuery(sql); + Object queryResult = query.uniqueResult(); + return queryResult != null ? Integer.parseInt(queryResult.toString()) : 0; + } + + + public int getParametertNum() { + String sql = "SELECT COUNT(*) FROM tb_parameter"; + Query query = currentSession().createSQLQuery(sql); + return Integer.parseInt(query.uniqueResult().toString()); + } + + + public int getCheckInNum() { + String sql = "SELECT COUNT(*) FROM tb_check_in"; + Query query = currentSession().createSQLQuery(sql); + return Integer.parseInt(query.uniqueResult().toString()); + } + + + public List getMatchedActionList(int projectId, String pattern) { + List list = getActionListOfProject(projectId); + List result = new ArrayList(); + for (Action action : list) { + String url = action.getRequestUrl(); + url = URLUtils.getRelativeUrl(url); + if (url.startsWith("reg:")) { // regular pattern + if (StringUtils.regMatch(url.substring(4), pattern)) { + result.add(action); + } + } else if (url.contains(":")) { + String urlParamRemoved = URLUtils.removeParamsInUrl(url); + String realUrlParamRemoved = URLUtils + .removeRealParamsInUrl(pattern); + if (realUrlParamRemoved.equals(urlParamRemoved)) { + result.add(action); + } + } else { // normal pattern + if (url.contains(pattern)) { + result.add(action); + } + } + } + + return result; + + // process /:id/ cases + // boolean urlParalized = false; + // String patternOrignial = pattern; + // if (pattern.contains(":")) { + // urlParalized = true; + // pattern = pattern.substring(0, pattern.indexOf(":")); + // } + + /** + * StringBuilder sb = new StringBuilder(); + * sb.append("SELECT a.id FROM tb_action a ") + * .append("JOIN tb_action_and_page ap ON ap.action_id = a.id ") + * .append("JOIN tb_page p ON p.id = ap.page_id ") + * .append("JOIN tb_module m ON m.id = p.module_id ") .append( + * "WHERE LOCATE(:pattern, a.request_url) != 0 AND m.project_id = :projectId " + * ); + * + * String sql = sb.toString(); Query query = + * currentSession().createSQLQuery(sql); query.setString("pattern", + * pattern); query.setInteger("projectId", projectId); List + * list = query.list(); List actionList = new + * ArrayList(); for (int id : list) { + * actionList.add(getAction(id)); } + */ + + // URL parameters filter + /** + * if (urlParalized) { List filteredActionList = new + * ArrayList(); for (Action a : actionList) { String u = + * a.getRequestUrl(); if (u.contains("?")) { u = u.substring(0, + * u.indexOf("?")); } u = StringUtils.removeParamsInUrl(u); + * patternOrignial = StringUtils .removeParamsInUrl(patternOrignial); if + * (u != null && patternOrignial != null && u.equals(patternOrignial)) { + * filteredActionList.add(a); } } actionList = filteredActionList; } + */ + // return actionList; + } + + private List getParameterIdList(int projectId) { + StringBuilder sql = new StringBuilder(); + sql.append(" SELECT DISTINCT p.id") + .append(" FROM tb_parameter p") + .append(" JOIN tb_response_parameter_list_mapping rplm ON p.id = rplm.parameter_id") + .append(" JOIN tb_action_and_page ap ON ap.action_id = rplm.action_id") + .append(" JOIN tb_page p2 ON p2.id = ap.page_id") + .append(" JOIN tb_module m ON m.id = p2.module_id") + .append(" WHERE m.project_id = :projectId"); + Query query = currentSession().createSQLQuery(sql.toString()); + query.setInteger("projectId", projectId); + List list = query.list(); + + StringBuilder sql2 = new StringBuilder(); + sql2.append(" SELECT DISTINCT p.id") + .append(" FROM tb_parameter p") + .append(" JOIN tb_request_parameter_list_mapping rplm ON p.id = rplm.parameter_id") + .append(" JOIN tb_action_and_page ap ON ap.action_id = rplm.action_id") + .append(" JOIN tb_page p2 ON p2.id = ap.page_id") + .append(" JOIN tb_module m ON m.id = p2.module_id") + .append(" WHERE m.project_id = :projectId"); + Query query2 = currentSession().createSQLQuery(sql2.toString()); + query2.setInteger("projectId", projectId); + list.addAll(query2.list()); + List paramList = new ArrayList(); + for (int pId : list) { + paramList.add(getParameter(pId)); + } + for (Parameter p : paramList) { + recursivelyAddSubParamList(list, p); + } + return list; + } + + private void recursivelyAddSubParamList(List list, Parameter p) { + list.add(p.getId()); + if (p.getParameterList() == null) + return; + for (Parameter subP : p.getParameterList()) { + recursivelyAddSubParamList(list, subP); + } + } + + public int resetMockData(int projectId) { + List pIdList = getParameterIdList(projectId); + String sql = "UPDATE tb_parameter SET mock_data = NULL where id in (" + + ArrayUtils.join(pIdList, ",") + ")"; + Query query = currentSession().createSQLQuery(sql); + return query.executeUpdate(); + } + + @SuppressWarnings("unchecked") + + public List getProjectListByGroup(int id) { + String hql = "from Project where groupId = :id"; + Query query = currentSession().createQuery(hql); + query.setInteger("id", id); + return query.list(); + } + + + public List search(String key) { + String hql = "from Project where name LIKE :key"; + Query query = currentSession().createQuery(hql); + query.setString("key", "%" + key + "%"); + return query.list(); + } + + @SuppressWarnings({"rawtypes"}) + private List getActionListOfProject(int projectId) { + List list = new ArrayList(); + StringBuilder sql = new StringBuilder(); + sql.append("SELECT a.id "); + sql.append("FROM tb_project p "); + sql.append("JOIN tb_module m ON m.project_id = p.id "); + sql.append("JOIN tb_page ON tb_page.module_id = m.id "); + sql.append("JOIN tb_action_and_page anp ON anp.page_id = tb_page.id "); + sql.append("JOIN tb_action a ON a.id = anp.action_id "); + sql.append("WHERE p.id = :projectId "); + Query query = currentSession().createSQLQuery(sql.toString()); + query.setInteger("projectId", projectId); + + List result = query.list(); + List ids = new ArrayList(); + for (Object r : result) { + ids.add((Integer) r); + } + for (Integer id : ids) { + list.add(this.getAction(id)); + } + return list; + } + + + public List selectMockNumTopNProjectList(int limit) { + String hqlByUser = "from Project order by mockNum desc"; + Query query = currentSession().createQuery(hqlByUser); + return query.setMaxResults(limit).list(); + } + + + public Integer getProjectIdByActionId(int actionId) { + StringBuilder sql = new StringBuilder(); + sql.append("SELECT p.id FROM tb_project p "); + sql.append("JOIN tb_module m ON m.project_id = p.id "); + sql.append("JOIN tb_page page ON page.module_id = m.id "); + sql.append("JOIN tb_action_and_page anp ON anp.page_id = page.id "); + sql.append("where action_id = :actionId"); + Query query = currentSession().createSQLQuery(sql.toString()); + query.setInteger("actionId", actionId); + return (Integer) query.uniqueResult(); + } + + + public void updateProjectNum(Project project) { + String sql = "UPDATE tb_project SET mock_num = :mockNum WHERE id = :projectId"; + currentSession().createSQLQuery(sql).setInteger("mockNum", project.getMockNum()).setInteger("projectId", project.getId()).executeUpdate(); + } + + + public void updateCreatorId(int projectId, int creatorId) { + Query query = currentSession().createSQLQuery("UPDATE tb_project SET user_id = :userId WHERE id = :id"); + query.setInteger("userId", creatorId); + query.setInteger("id", projectId); + query.executeUpdate(); + } + + public Project getProject(int id) { + return currentSession().get(Project.class, id); + } + +} diff --git a/src/main/java/com/taobao/rigel/rap/project/service/ProjectMgr.java b/src/main/java/com/taobao/rigel/rap/project/service/ProjectMgr.java new file mode 100644 index 000000000..e93fc5748 --- /dev/null +++ b/src/main/java/com/taobao/rigel/rap/project/service/ProjectMgr.java @@ -0,0 +1,219 @@ +package com.taobao.rigel.rap.project.service; + +import com.taobao.rigel.rap.account.bo.User; +import com.taobao.rigel.rap.project.bo.Action; +import com.taobao.rigel.rap.project.bo.Module; +import com.taobao.rigel.rap.project.bo.Page; +import com.taobao.rigel.rap.project.bo.Project; + +import java.util.List; +import java.util.Map; + +public interface ProjectMgr { + + /** + * get project list + * + * @param user + * @param curPageNum + * @param pageSize + * @return + */ + List getProjectList(User user, int curPageNum, int pageSize); + + /** + * add new project + * + * @param project + * @return + */ + int addProject(Project project); + + /** + * remove project + * + * @param id + * @return + */ + int removeProject(int id); + + /** + * update project + * + * @param project + * @return + */ + int updateProject(Project project); + + /** + * get project by id + * + * @param id + * @return + */ + Project getProjectSummary(int id); + + Project getProject(int id, String ver); + + /** + * with project data + * + * @param id + * @return + */ + Project getProject(int id); + + /** + * get module by id + * + * @param id + * @return + */ + Module getModule(int id); + + /** + * get page by id + * + * @param id + * @return + */ + Page getPage(int id); + + /** + * update project + * + * @param id + * @param projectData + * @param deletedObjectListData + * @return + */ + String updateProject(int id, String projectData, + String deletedObjectListData, Map actionIdMap); + + /** + * get number of project list usually used for pager + * + * @param user + * @return + */ + int getProjectListNum(User user); + + /** + * set action.remarks as paramIdList eg-> action.remarks = "id,name,age"; + * used for parameter identifier spelling validation [*caution*] only + * calculating response parameters + * + * @param action action to be filled with paramIdList info + */ + void loadParamIdListForAction(Action action); + + /** + * load paramIdList for page + * + * @param page + */ + void loadParamIdListForPage(Page page); + + /** + * get matched action list based on URL pattern + * + * @param projectId + * @param pattern + * @return + */ + List getMatchedActionList(int projectId, String pattern); + + /** + * get project list by group id + * + * @param id + * @return + */ + List getProjectListByGroup(int id); + + /** + * search all projects (for admin) + * + * @param key + * @return + */ + List search(String key); + + /** + * search project by user + * + * @param key + * @param curUserId + * @return + */ + List search(String key, int curUserId); + + /** + * get action + * + * @param id + * @return + */ + Action getAction(int id); + + Action getAction(int id, String ver, int projectId); + + /** + * update doc + * + * @param projectId + */ + void updateDoc(int projectId); + + List getProjectList(); + + int getProjectNum(); + + int getModuleNum(); + + int getPageNum(); + + int getActionNum(); + + int getParametertNum(); + + int getCheckInNum(); + + int getMockNumInTotal(); + + List selectMockNumTopNProjectList(int limit); + + /** + * update Action.disableCache + * + * @param projectId + */ + void updateCache(int projectId); + + /** + * get project id by action id + * + * @param actionId + * @return + */ + Integer getProjectIdByActionId(int actionId); + + void updateProjectNum(Project project); + + /** + * clear project model cache(without project data) by projectId + * influence projects list + * + * @param projectId + */ + void clearProjectInfoCache(int projectId); + + /** + * clear project data cache + * influence workspace + * + * @param projectId + */ + void clearProjectDocCache(int projectId); + +} diff --git a/src/main/java/com/taobao/rigel/rap/project/service/impl/ProjectMgrImpl.java b/src/main/java/com/taobao/rigel/rap/project/service/impl/ProjectMgrImpl.java new file mode 100644 index 000000000..f57cdbae5 --- /dev/null +++ b/src/main/java/com/taobao/rigel/rap/project/service/impl/ProjectMgrImpl.java @@ -0,0 +1,460 @@ +package com.taobao.rigel.rap.project.service.impl; + +import com.google.gson.Gson; +import com.taobao.rigel.rap.account.bo.Notification; +import com.taobao.rigel.rap.account.bo.User; +import com.taobao.rigel.rap.account.dao.AccountDao; +import com.taobao.rigel.rap.account.service.AccountMgr; +import com.taobao.rigel.rap.common.utils.ArrayUtils; +import com.taobao.rigel.rap.common.utils.CacheUtils; +import com.taobao.rigel.rap.common.utils.HTTPUtils; +import com.taobao.rigel.rap.common.config.SystemConstant; +import com.taobao.rigel.rap.organization.bo.Group; +import com.taobao.rigel.rap.organization.dao.OrganizationDao; +import com.taobao.rigel.rap.organization.service.OrganizationMgr; +import com.taobao.rigel.rap.project.bo.*; +import com.taobao.rigel.rap.project.dao.ProjectDao; +import com.taobao.rigel.rap.project.service.ProjectMgr; +import com.taobao.rigel.rap.workspace.bo.CheckIn; +import com.taobao.rigel.rap.workspace.dao.WorkspaceDao; + +import java.util.*; + +public class ProjectMgrImpl implements ProjectMgr { + + private ProjectDao projectDao; + private OrganizationDao organizationDao; + private AccountMgr accountMgr; + private WorkspaceDao workspaceDao; + private OrganizationMgr organizationMgr; + private AccountDao accountDao; + + public OrganizationMgr getOrganizationMgr() { + return organizationMgr; + } + + public void setOrganizationMgr(OrganizationMgr organizationMgr) { + this.organizationMgr = organizationMgr; + } + + public void setWorkspaceDao(WorkspaceDao workspaceDao) { + this.workspaceDao = workspaceDao; + } + + public AccountMgr getAccountMgr() { + return accountMgr; + } + + public void setAccountMgr(AccountMgr accountMgr) { + this.accountMgr = accountMgr; + } + + public OrganizationDao getOrganizationDao() { + return organizationDao; + } + + public void setOrganizationDao(OrganizationDao organizationDao) { + this.organizationDao = organizationDao; + } + + public ProjectDao getProjectDao() { + return this.projectDao; + } + + public void setProjectDao(ProjectDao projectDao) { + this.projectDao = projectDao; + } + + public AccountDao getAccountDao() { + return accountDao; + } + + public void setAccountDao(AccountDao accountDao) { + this.accountDao = accountDao; + } + + + public List getProjectList(User user, int curPageNum, int pageSize) { + + List projectList = projectDao.getProjectList(user, curPageNum, + pageSize); + for (Project p : projectList) { + if (user.isUserInRole("admin") + || p.getUserId() == user.getId()) { + p.setIsManagable(true); + } + p.setTeamId(organizationDao.getTeamIdByProjectId(p.getId())); + p.setUser(accountDao.getUser(p.getUserId())); + } + return projectList; + } + + + public int addProject(Project project) { + project.setUpdateTime(new Date()); + project.setCreateDate(new Date()); + List usersInformed = new ArrayList(); + + for (String account : project.getMemberAccountList()) { + User user = accountDao.getUser(account); + if (user != null) { + boolean addSuccess = project.addMember(user); + if (addSuccess) { + usersInformed.add(user); + } + } + } + + int result = projectDao.addProject(project); + for (User u : usersInformed) { + Notification o = new Notification(); + o.setTypeId((short) 2); + o.setTargetUser(project.getUser()); + o.setUser(u); + o.setParam1(new Integer(result).toString()); + o.setParam2(project.getName()); + accountMgr.addNotification(o); + } + + Group g = organizationDao.getGroup(project.getGroupId()); + if (g.getProductionLineId() > 0) { + organizationDao.updateCountersInProductionLine(g + .getProductionLineId()); + } + clearProjectInfoCache(result); + return result; + } + + + public int removeProject(int id) { + clearProjectDocCache(id); + clearProjectInfoCache(id); + Project p = getProject(id); + Group g = organizationDao.getGroup(p.getGroupId()); + int result = projectDao.removeProject(id); + if (g != null) { + int pId = g.getProductionLineId(); + if (pId > 0) { + organizationDao.updateCountersInProductionLine(pId); + } + } + return result; + } + + + public int updateProject(Project outerProject) { + // first clear, for existed members + clearProjectInfoCache(outerProject.getId()); + + Project project = getProject(outerProject.getId()); + project.setName(outerProject.getName()); + project.setIntroduction(outerProject.getIntroduction()); + project.setUpdateTime(new Date()); + project.setRelatedIds(outerProject.getRelatedIds()); + + if (outerProject.getMemberAccountList() != null) { + // adding new ones + for (String account : outerProject.getMemberAccountList()) { + User user = accountDao.getUser(account); + if (user != null) { + boolean addSuccess = project.addMember(user); + if (addSuccess) { + Notification o = new Notification(); + o.setTypeId((short) 2); + o.setTargetUser(outerProject.getUser()); + o.setUser(user); + o.setParam1(new Integer(outerProject.getId()).toString()); + o.setParam2(outerProject.getName()); + accountMgr.addNotification(o); + } + } + } + + if (project.getUserList() != null) { + // remove old ones + List userListToBeRemoved = new ArrayList(); + for (User user : project.getUserList()) { + if (!outerProject.getMemberAccountList().contains( + user.getAccount())) { + userListToBeRemoved.add(user); + } + } + + for (User user : userListToBeRemoved) { + project.removeMember(user); + } + } + + } + + int returnVal = projectDao.updateProject(project); + + // duplex clear, for added new members + clearProjectInfoCache(project.getId()); + clearProjectDocCache(project.getId()); + + return returnVal; + } + + + public Project getProjectSummary(int id) { + Project p = projectDao.getProjectSummary(id); + if (p != null) + p.setUser(accountMgr.getUser(p.getUserId())); + return p; + } + + + public Project getProject(int id, String ver) { + CheckIn check = workspaceDao.getVersion(id, ver); + String projectData = check.getProjectData(); + + Gson gson = new Gson(); + Project p = gson.fromJson(projectData, Project.class); + p.setVersion(check.getVersion()); + return p; + } + + public Project getProject(int id) { + Project p = projectDao.getProject(id); + return p; + } + + + public Module getModule(int id) { + return projectDao.getModule(id); + } + + + public Page getPage(int id) { + return (Page) projectDao.getPage(id); + } + + + public String updateProject(int id, String projectData, + String deletedObjectListData, Map actionIdMap) { + clearProjectDocCache(id); + return projectDao.updateProject(id, projectData, deletedObjectListData, actionIdMap); + } + + + public int getProjectListNum(User user) { + if (user != null && user.isUserInRole("admin")) { + user = null; + } + return projectDao.getProjectListNum(user); + } + + + public void loadParamIdListForAction(Action action) { + List paramIdList = new ArrayList(); + recursivelyLoadParamIdList(paramIdList, + action.getResponseParameterList()); + action.setRemarks(ArrayUtils.join(paramIdList, ",")); + } + + + public void loadParamIdListForPage(Page page) { + for (Action action : page.getActionList()) { + loadParamIdListForAction(action); + } + } + + /** + * sub method of loadParamIdListForAction for recursively load paramIdList + * for complex parameters + * + * @param paramIdList + * @param paramList + */ + private void recursivelyLoadParamIdList(List paramIdList, + Set paramList) { + for (Parameter p : paramList) { + if (p.getIdentifier() != null || !p.getIdentifier().isEmpty()) { + paramIdList.add(p.getIdentifier()); + } + if (p.getParameterList() != null && p.getParameterList().size() > 0) { + recursivelyLoadParamIdList(paramIdList, p.getParameterList()); + } + } + } + + + public List getMatchedActionList(int projectId, String pattern) { + List actionList = projectDao.getMatchedActionList(projectId, + pattern); + if (actionList == null || actionList.size() == 0) { + Project project = projectDao.getProjectSummary(projectId); + if (project != null) { + String ids = project.getRelatedIds(); + if (ids != null && !ids.isEmpty()) { + String[] arr = ids.split(","); + for (String id : arr) { + actionList = projectDao.getMatchedActionList( + Integer.parseInt(id), pattern); + if (actionList != null && actionList.size() != 0) { + return actionList; + } + } + } + } + } + return actionList; + } + + + public List getProjectListByGroup(int id) { + return projectDao.getProjectListByGroup(id); + } + + + public List search(String key) { + return projectDao.search(key); + } + + + public List search(String key, int userId) { + List list = projectDao.search(key); + List result = new ArrayList(); + + for (Project p : list) { + if (organizationMgr.canUserAccessProject(userId, p.getId())) { + result.add(p); + } + } + return result; + } + + + public Action getAction(int id) { + return projectDao.getAction(id); + } + + + public Action getAction(int id, String ver, int projectId) { + CheckIn check = workspaceDao.getVersion(projectId, ver); + Gson gson = new Gson(); + Project p = gson.fromJson(check.getProjectData(), Project.class); + return p.findAction(id); + } + + + public void updateDoc(int projectId) { + try { + HTTPUtils.sendGet("http://" + SystemConstant.NODE_SERVER + "/api/generateDoc?projectId=" + projectId); + } catch (Exception e) { + e.printStackTrace(); + } + } + + + public List getProjectList() { + return projectDao.getProjectList(); + } + + + public int getProjectNum() { + return projectDao.getProjectListNum(); + } + + + public int getModuleNum() { + return projectDao.getModuleNum(); + } + + + public int getPageNum() { + return projectDao.getPageNum(); + } + + + public int getActionNum() { + return projectDao.getActionNum(); + } + + + public int getParametertNum() { + return projectDao.getParametertNum(); + } + + + public int getCheckInNum() { + return projectDao.getCheckInNum(); + } + + + public int getMockNumInTotal() { + return projectDao.getMockNumInTotal(); + } + + + public List selectMockNumTopNProjectList(int limit) { + return projectDao.selectMockNumTopNProjectList(limit); + } + + + public void updateCache(int projectId) { + Project project = getProject(projectId); + for (Module module : project.getModuleList()) { + for (Page page : module.getPageList()) { + for (Action action : page.getActionList()) { + updateActionCache(action); + } + } + } + } + + + public Integer getProjectIdByActionId(int actionId) { + return projectDao.getProjectIdByActionId(actionId); + } + + + public void updateProjectNum(Project project) { + projectDao.updateProjectNum(project); + } + + public void clearProjectInfoCache(int projectId) { + Project p = getProject(projectId); + List ids = new ArrayList(); + ids.add(p.getUserId()); + + Set members = p.getUserList(); + for (User member : members) { + ids.add(member.getId()); + } + + for (int userId : ids) { + String[] cacheKey = new String[]{CacheUtils.KEY_PROJECT_LIST, new Integer(userId).toString()}; + CacheUtils.del(cacheKey); + } + } + + public void clearProjectDocCache(int projectId) { + String[] cacheKey = new String[]{CacheUtils.KEY_WORKSPACE, new Integer(projectId).toString()}; + CacheUtils.del(cacheKey); + } + + private void updateActionCache(Action action) { + action.setDisableCache(0); + for (Parameter param : action.getResponseParameterList()) { + clearParameterCache(param, action); + } + } + + private void clearParameterCache(Parameter param, Action action) { + String rules = param.getMockJsRules(); + if (rules != null && rules.contains("${") && rules.contains("}")) { + action.setDisableCache(1); + return; // over + } + Set children = param.getParameterList(); + if (children != null && children.size() != 0) { + for (Parameter child : children) { + clearParameterCache(child, action); + } + } + } + + +} diff --git a/src/main/java/com/taobao/rigel/rap/project/web/action/ProjectAction.java b/src/main/java/com/taobao/rigel/rap/project/web/action/ProjectAction.java new file mode 100644 index 000000000..b93ecd49a --- /dev/null +++ b/src/main/java/com/taobao/rigel/rap/project/web/action/ProjectAction.java @@ -0,0 +1,371 @@ +package com.taobao.rigel.rap.project.web.action; + +import com.google.gson.Gson; +import com.taobao.rigel.rap.account.bo.User; +import com.taobao.rigel.rap.auto.generate.bo.VelocityTemplateGenerator; +import com.taobao.rigel.rap.auto.generate.contract.Generator; +import com.taobao.rigel.rap.common.base.ActionBase; +import com.taobao.rigel.rap.common.bo.RapError; +import com.taobao.rigel.rap.project.bo.Page; +import com.taobao.rigel.rap.project.bo.Project; +import com.taobao.rigel.rap.project.service.ProjectMgr; +import com.taobao.rigel.rap.workspace.service.WorkspaceMgr; + +import java.io.ByteArrayInputStream; +import java.io.FileNotFoundException; +import java.io.InputStream; +import java.io.UnsupportedEncodingException; +import java.util.*; + +public class ProjectAction extends ActionBase { + + private int id; + + private List searchResult; + + private String ids; + private String key; + private String desc; + private int groupId; + private String accounts; + private String memberAccountListStr; + private String name; + private Date createDate; + private String introduction; + private List projectList; + private Project project; + private ProjectMgr projectMgr; + private WorkspaceMgr workspaceMgr; + private int pageId; + private String projectData; + private String result; + private InputStream outputStream; + + public String getIds() { + if (ids == null || ids.isEmpty()) { + return ""; + } + + String[] idList = ids.split(","); + String returnVal = ""; + Integer num = 0; + int counter = 0; + for (String id : idList) { + try { + num = Integer.parseInt(id); + counter++; + if (counter > 1) { + returnVal += ","; + } + returnVal += num.toString(); + + } catch (Exception ex) { + + } + } + return returnVal; + } + + public void setIds(String ids) { + this.ids = ids; + } + + public List getSearchResult() { + return searchResult; + } + + public String getKey() { + return key; + } + + public void setKey(String key) { + this.key = key; + } + + public int getId() { + return this.id; + } + + public void setId(int id) { + this.id = id; + } + + public int getGroupId() { + return groupId; + } + + public void setGroupId(int groupId) { + this.groupId = groupId; + } + + public String getDesc() { + return desc; + } + + public void setDesc(String desc) { + this.desc = desc; + } + + public String getAccounts() { + if (accounts == null) + return ""; + return accounts; + } + + public void setAccounts(String accounts) { + this.accounts = accounts; + } + + public List getMemberAccountList() { + List memberList = new ArrayList(); + for (User user : super.getAccountMgr().getUserList()) { + memberList.add(user.getAccount() + "(" + user.getName() + ")"); + } + return memberList; + } + + public String getMemberAccountListStr() { + return memberAccountListStr; + } + + public void setMemberAccountListStr(String memberAccountListStr) { + this.memberAccountListStr = memberAccountListStr; + } + + public String getName() { + return this.name; + } + + public void setName(String name) { + this.name = name; + } + + public Date getCreateDate() { + return this.createDate; + } + + public void setCreateDate(Date createDate) { + this.createDate = createDate; + } + + public String getIntroduction() { + return this.introduction; + } + + public void setIntroduction(String introduction) { + this.introduction = introduction; + } + + public List getProjectList() { + return this.projectList; + } + + public void setProjectList(List projectList) { + this.projectList = projectList; + } + + public Project getProject() { + return this.project; + } + + public void setProject(Project project) { + this.project = project; + } + + public ProjectMgr getProjectMgr() { + return projectMgr; + } + + public void setProjectMgr(ProjectMgr projectMgr) { + this.projectMgr = projectMgr; + } + + public WorkspaceMgr getWorkspaceMgr() { + return workspaceMgr; + } + + public void setWorkspaceMgr(WorkspaceMgr workspaceMgr) { + this.workspaceMgr = workspaceMgr; + } + + public int getPageId() { + return pageId; + } + + public void setPageId(int pageId) { + this.pageId = pageId; + } + + public String getProjectData() { + return projectData; + } + + public void setProjectData(String projectData) { + this.projectData = projectData; + } + + public String delete() { + if (!isUserLogined()) + return LOGIN; + if (!getAccountMgr().canUserManageProject(getCurUserId(), getId())) { + setErrMsg("您没有管理该项目的权限"); + return ERROR; + } + projectMgr.removeProject(getId()); + return SUCCESS; + } + + public String create() { + if (!isUserLogined()) + return LOGIN; + Gson gson = new Gson(); + + Project project = new Project(); + project.setCreateDate(new Date()); + project.setUser(getCurUser()); + project.setUserId(getCurUserId()); + project.setIntroduction(getDesc()); + project.setName(getName()); + project.setGroupId(groupId); + List memberAccountList = new ArrayList(); + String[] list = getAccounts().split(","); + // format: mashengbo(大灰狼堡森), linpanhui(林攀辉), + for (String item : list) { + String account = item.contains("(") ? item.substring(0, + item.indexOf("(")).trim() : item.trim(); + if (!account.equals("")) + memberAccountList.add(account); + } + project.setMemberAccountList(memberAccountList); + int projectId = projectMgr.addProject(project); + project = projectMgr.getProject(projectId); + Map result = new HashMap(); + result.put("id", project.getId()); + result.put("name", project.getName()); + result.put("desc", project.getIntroduction()); + result.put("accounts", project.getMemberAccountListStr()); + result.put("groupId", project.getGroupId()); + result.put("isManagable", "true"); + result.put("creator", project.getUser().getUserBaseInfo()); + setJson(new RapError(gson.toJson(result)).toString()); + return SUCCESS; + } + + public String update() { + if (!isUserLogined()) + return LOGIN; + if (!getAccountMgr().canUserManageProject(getCurUserId(), getId())) { + setErrMsg("您没有管理该项目的权限"); + return ERROR; + } + Project project = new Project(); + project.setId(getId()); + project.setIntroduction(getDesc()); + project.setName(getName()); + project.setUser(getCurUser()); + List memberAccountList = new ArrayList(); + String[] list = getAccounts().split(","); + // format: mashengbo(大灰狼堡森), linpanhui(林攀辉), + for (String item : list) { + String account = item.contains("(") ? item.substring(0, + item.indexOf("(")).trim() : item.trim(); + if (!account.equals("")) + memberAccountList.add(account); + } + Gson gson = new Gson(); + project.setMemberAccountList(memberAccountList); + projectMgr.updateProject(project); + + project = projectMgr.getProject(project.getId()); + + if (getCurUser().isUserInRole("admin") + || getCurUser().getId() == project.getUser().getId()) { + project.setIsManagable(true); + } + + Map result = new HashMap(); + result.put("id", project.getId()); + result.put("name", project.getName()); + result.put("desc", project.getIntroduction()); + result.put("accounts", project.getMemberAccountListStr()); + result.put("groupId", project.getGroupId()); + result.put("isManagable", project.getIsManagable()); + setJson(new RapError(gson.toJson(result)).toString()); + + return SUCCESS; + } + + public String updateReleatedIds() { + if (!isUserLogined()) + return LOGIN; + if (!getAccountMgr().canUserManageProject(getCurUserId(), getId())) { + setErrMsg("您没有管理该项目的权限"); + return ERROR; + } + + Project project = projectMgr.getProjectSummary(getId()); + project.setRelatedIds(getIds()); + projectMgr.updateProject(project); + + + return SUCCESS; + } + + public String getResult() { + return result; + } + + public void setResult(String result) { + this.result = result; + } + + public InputStream getOutputStream() { + return outputStream; + } + + public void setOutputStream(InputStream outputStream) { + this.outputStream = outputStream; + } + + public String autoGenerate() throws FileNotFoundException, + UnsupportedEncodingException { + Generator generator = new VelocityTemplateGenerator(); + Page page = projectMgr.getPage(getPageId()); + generator.setObject(page); + String exportFileString = generator.doGenerate(); + outputStream = new ByteArrayInputStream( + exportFileString.getBytes("UTF8")); + return SUCCESS; + } + + public String getGeneratedFileName() { + return projectMgr.getPage(getPageId()).getTemplate(); + } + + public String search() { + + if (!isUserLogined()) { + plsLogin(); + return JSON_ERROR; + } + + User curUser = getCurUser(); + if (curUser.isAdmin()) { + searchResult = projectMgr.search(key); + } else { + searchResult = projectMgr.search(key, getCurUserId()); + } + + List> list = new ArrayList>(); + for (Project p : searchResult) { + Map item = new HashMap(); + item.put("id", p.getId()); + item.put("name", p.getName()); + list.add(item); + } + Gson gson = new Gson(); + setJson(gson.toJson(list)); + return SUCCESS; + } + +} diff --git a/src/com/taobao/rigel/rap/tester/bo/SSOUser.java b/src/main/java/com/taobao/rigel/rap/tester/bo/SSOUser.java similarity index 100% rename from src/com/taobao/rigel/rap/tester/bo/SSOUser.java rename to src/main/java/com/taobao/rigel/rap/tester/bo/SSOUser.java index 7075f48b3..9f771f8ce 100644 --- a/src/com/taobao/rigel/rap/tester/bo/SSOUser.java +++ b/src/main/java/com/taobao/rigel/rap/tester/bo/SSOUser.java @@ -1,11 +1,11 @@ package com.taobao.rigel.rap.tester.bo; public class SSOUser { - public SSOUser() { - - } public String empId; public String nickNameCn; public String firstName; public String lastName; + public SSOUser() { + + } } diff --git a/src/com/taobao/rigel/rap/tester/bo/SSOUserRes.java b/src/main/java/com/taobao/rigel/rap/tester/bo/SSOUserRes.java similarity index 100% rename from src/com/taobao/rigel/rap/tester/bo/SSOUserRes.java rename to src/main/java/com/taobao/rigel/rap/tester/bo/SSOUserRes.java index 5cd093f46..d1591e623 100644 --- a/src/com/taobao/rigel/rap/tester/bo/SSOUserRes.java +++ b/src/main/java/com/taobao/rigel/rap/tester/bo/SSOUserRes.java @@ -4,12 +4,12 @@ * Created by Bosn on 14-9-23. */ public class SSOUserRes { + public SSOUser content; + public SSOUserRes() { } - public SSOUser content; - } diff --git a/src/main/java/com/taobao/rigel/rap/tester/web/action/TesterAction.java b/src/main/java/com/taobao/rigel/rap/tester/web/action/TesterAction.java new file mode 100644 index 000000000..c036f3d3d --- /dev/null +++ b/src/main/java/com/taobao/rigel/rap/tester/web/action/TesterAction.java @@ -0,0 +1,97 @@ +package com.taobao.rigel.rap.tester.web.action; + +import com.taobao.rigel.rap.common.base.ActionBase; +import com.taobao.rigel.rap.organization.service.OrganizationMgr; +import com.taobao.rigel.rap.project.bo.Page; +import com.taobao.rigel.rap.project.service.ProjectMgr; + + +public class TesterAction extends ActionBase { + + private ProjectMgr projectMgr; + private int id; + private Page page; + private int projectId; + private String url; + private OrganizationMgr organizationMgr; + + public String getUrl() { + return url; + } + + public void setUrl(String url) { + this.url = url; + } + + public OrganizationMgr getOrganizationMgr() { + return organizationMgr; + } + + public void setOrganizationMgr(OrganizationMgr organizationMgr) { + this.organizationMgr = organizationMgr; + } + + public int getProjectId() { + return projectId; + } + + public Page getPage() { + return page; + } + + public ProjectMgr getProjectMgr() { + return projectMgr; + } + + public void setProjectMgr(ProjectMgr projectMgr) { + this.projectMgr = projectMgr; + } + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public String pageTester() { + + if (!isUserLogined()) { + plsLogin(); + setRelativeReturnUrl("/tester/pageTester.do?id=" + + id); + return LOGIN; + } + + if (!organizationMgr.canUserAccessPage(getCurUserId(), id)) { + setErrMsg(ACCESS_DENY); + return ERROR; + } + + page = projectMgr.getPage(id); + projectMgr.loadParamIdListForPage(page); + projectId = page.getModule().getProject().getId(); + return SUCCESS; + } + + public String test() { + /** + SystemVisitorLog.clear(projectMgr); + System.out.println("Clear complete!"); + setJson("clear complete"); + */ + return SUCCESS; + } + + /** + * used for system configuration when new version deployed + * + * @return + */ + public String ___init___() throws Exception { + + + return SUCCESS; + } +} diff --git a/src/main/java/com/taobao/rigel/rap/workspace/bo/CheckIn.java b/src/main/java/com/taobao/rigel/rap/workspace/bo/CheckIn.java new file mode 100644 index 000000000..012d99431 --- /dev/null +++ b/src/main/java/com/taobao/rigel/rap/workspace/bo/CheckIn.java @@ -0,0 +1,178 @@ +package com.taobao.rigel.rap.workspace.bo; + +import com.taobao.rigel.rap.account.bo.User; +import com.taobao.rigel.rap.common.utils.DateUtils; +import com.taobao.rigel.rap.common.utils.StringUtils; +import com.taobao.rigel.rap.project.bo.Project; +import com.taobao.rigel.rap.workspace.bo.Workspace.ModeType; + +import java.util.Date; + +public class CheckIn implements java.io.Serializable { + + private int id; + private Date createDate; + private String tag; + private User user; + private Project project; + private String description; + private String version; + private String projectData; + private int workspaceModeInt; + private String log; + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public Date getCreateDate() { + return createDate; + } + + public void setCreateDate(Date createDate) { + this.createDate = createDate; + } + + public String getCreateDateStr() { + return getCreateDate() == null ? "" : DateUtils.TIME_FORMAT.format(getCreateDate()); + } + + public String getTag() { + return tag; + } + + public void setTag(String tag) { + this.tag = tag; + } + + public User getUser() { + return user; + } + + public void setUser(User user) { + this.user = user; + } + + public Project getProject() { + return project; + } + + public void setProject(Project project) { + this.project = project; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public String getVersion() { + return version; + } + + public void setVersion(String version) { + this.version = version; + } + + public String getProjectData() { + return projectData; + } + + public void setProjectData(String projectData) { + this.projectData = projectData; + } + + public int getWorkspaceModeInt() { + return workspaceModeInt; + } + + public void setWorkspaceModeInt(int workspaceModeInt) { + this.workspaceModeInt = workspaceModeInt; + } + + public ModeType getWorkspaceMode() { + if (workspaceModeInt == 1) { + return ModeType.VSS; + } else if (workspaceModeInt == 2) { + return ModeType.SVN; + } else { + // default + return ModeType.VSS; + } + } + + public void setWorkspaceMode(ModeType workspaceModeType) { + if (workspaceModeType == ModeType.VSS) { + workspaceModeInt = 1; + } else if (workspaceModeType == ModeType.SVN) { + workspaceModeInt = 2; + } else { + // default + workspaceModeInt = 1; + } + } + + public String getLog() { + return log; + } + + public void setLog(String log) { + this.log = log; + } + + public void versionUpgrade(int versionPosition) throws Exception { + if (versionPosition > 4 || versionPosition < 1) { + throw new Exception("illegal version position: " + versionPosition); + } + String[] versionList = getVersion().split("\\."); + if (versionList.length != 4) { + throw new Exception("illegal version format: " + getVersion()); + } + Integer integer = Integer.parseInt(versionList[versionPosition - 1]) + 1; + versionList[versionPosition - 1] = integer.toString(); + String newVersion = ""; + for (int i = 0; i < versionList.length; i++) { + newVersion += versionList[i]; + if (i < versionList.length - 1) { + newVersion += "."; + } + } + setVersion(newVersion); + } + + public String toString() { + return this.toString(ToStringType.NORMAL); + } + + public String toString(ToStringType type) { + if (type == ToStringType.NORMAL) { + StringBuilder stringBuilder = new StringBuilder(); + stringBuilder.append("{\"id\":" + getId() + ","); + stringBuilder.append("\"version\":\"" + getVersion() + "\","); + stringBuilder.append("\"userName\":\"" + getUser().getName() + "\","); + stringBuilder.append("\"createDateStr\":\"" + getCreateDateStr() + "\","); + stringBuilder.append("\"description\":\"" + StringUtils.escapeInJ(getDescription()) + "\"}"); + return stringBuilder.toString(); + } else if (type == ToStringType.COMPLETED) { + StringBuilder stringBuilder = new StringBuilder(); + stringBuilder.append("{\"id\":" + getId() + ","); + stringBuilder.append("\"version\":\"" + getVersion() + "\","); + stringBuilder.append("\"userName\":\"" + getUser().getName() + "\","); + stringBuilder.append("\"projectData\":" + getProjectData() + ","); + stringBuilder.append("\"createDateStr\":\"" + getCreateDateStr() + "\","); + stringBuilder.append("\"description\":\"" + StringUtils.escapeInJ(getDescription()) + "\"}"); + return stringBuilder.toString(); + } else { + return this.toString(); + } + } + + public enum ToStringType {COMPLETED, NORMAL} +} \ No newline at end of file diff --git a/src/main/java/com/taobao/rigel/rap/workspace/bo/Workspace.java b/src/main/java/com/taobao/rigel/rap/workspace/bo/Workspace.java new file mode 100644 index 000000000..8c806409b --- /dev/null +++ b/src/main/java/com/taobao/rigel/rap/workspace/bo/Workspace.java @@ -0,0 +1,114 @@ +package com.taobao.rigel.rap.workspace.bo; + +import com.taobao.rigel.rap.account.bo.User; +import com.taobao.rigel.rap.project.bo.Project; + +import java.util.Date; +import java.util.Iterator; +import java.util.List; + +public class Workspace implements java.io.Serializable { + + private int id; + private Project project; + private User user; + private Date createDate; + private Date updateDate; + private String projectData; + private String projectDataOriginal; + + public boolean isAccessable() { + return accessable; + } + + public void setAccessable(boolean accessable) { + this.accessable = accessable; + } + + private boolean accessable; + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public int getModeInt() { + return project.getWorkspaceModeInt(); + } + + public ModeType getModeType() { + return project.getWorkspaceMode(); + } + + public Project getProject() { + return project; + } + + public void setProject(Project project) { + this.project = project; + } + + public User getUser() { + return user; + } + + public void setUser(User user) { + this.user = user; + } + + public Date getCreateDate() { + return createDate; + } + + public void setCreateDate(Date createDate) { + this.createDate = createDate; + } + + public Date getUpdateDate() { + return updateDate; + } + + public void setUpdateDate(Date updateDate) { + this.updateDate = updateDate; + } + + public String getProjectData() { + return projectData; + } + + public void setProjectData(String projectData) { + this.projectData = projectData; + } + + public String getProjectDataOriginal() { + return projectDataOriginal; + } + + public void setProjectDataOriginal(String projectDataOriginal) { + this.projectDataOriginal = projectDataOriginal; + } + + public String toString() { + StringBuilder stringBuilder = new StringBuilder(); + stringBuilder.append("{\"projectData\":" + getProject().getProjectData() + ","); + stringBuilder.append("\"relatedIds\":\"" + getProject().getRelatedIds() + "\","); + stringBuilder.append("\"checkList\":["); + List checkList = getProject().getCheckInListOrdered(); + if (checkList != null) { + Iterator iterator = checkList.iterator(); + while (iterator.hasNext()) { + stringBuilder.append(iterator.next().toString()); + if (iterator.hasNext()) { + stringBuilder.append(", "); + } + } + } + stringBuilder.append("]}"); + return stringBuilder.toString(); + } + + public enum ModeType {VSS, SVN} +} diff --git a/src/main/java/com/taobao/rigel/rap/workspace/dao/WorkspaceDao.java b/src/main/java/com/taobao/rigel/rap/workspace/dao/WorkspaceDao.java new file mode 100644 index 000000000..da904b505 --- /dev/null +++ b/src/main/java/com/taobao/rigel/rap/workspace/dao/WorkspaceDao.java @@ -0,0 +1,21 @@ +package com.taobao.rigel.rap.workspace.dao; + +import com.taobao.rigel.rap.workspace.bo.CheckIn; +import com.taobao.rigel.rap.workspace.bo.Workspace; + +public interface WorkspaceDao { + + Workspace getWorkspace(int projectId, int userId); + + void updateWorkspace(Workspace workspace); + + Workspace getWorkspace(int id); + + void addCheckIn(CheckIn checkIn); + + CheckIn getVersion(int versionId); + + CheckIn getVersion(int projectId, String version); + + void prepareForVersionSwitch(CheckIn check); +} diff --git a/src/main/java/com/taobao/rigel/rap/workspace/dao/impl/WorkspaceDaoImpl.java b/src/main/java/com/taobao/rigel/rap/workspace/dao/impl/WorkspaceDaoImpl.java new file mode 100644 index 000000000..1bfd4d868 --- /dev/null +++ b/src/main/java/com/taobao/rigel/rap/workspace/dao/impl/WorkspaceDaoImpl.java @@ -0,0 +1,112 @@ +package com.taobao.rigel.rap.workspace.dao.impl; + +import com.taobao.rigel.rap.account.bo.User; +import com.taobao.rigel.rap.account.dao.AccountDao; +import com.taobao.rigel.rap.project.bo.Module; +import com.taobao.rigel.rap.project.bo.Project; +import com.taobao.rigel.rap.project.dao.ProjectDao; +import com.taobao.rigel.rap.workspace.bo.CheckIn; +import com.taobao.rigel.rap.workspace.bo.Workspace; +import com.taobao.rigel.rap.workspace.dao.WorkspaceDao; +import org.hibernate.HibernateException; +import org.hibernate.Query; +import org.hibernate.Session; +import org.springframework.orm.hibernate5.support.HibernateDaoSupport; + +import java.util.Date; +import java.util.Iterator; + +public class WorkspaceDaoImpl extends HibernateDaoSupport implements WorkspaceDao { + + private AccountDao accountDao; + private ProjectDao projectDao; + + public AccountDao getAccountDao() { + return accountDao; + } + + public void setAccountDao(AccountDao accountDao) { + this.accountDao = accountDao; + } + + public ProjectDao getProjectDao() { + return projectDao; + } + + public void setProjectDao(ProjectDao projectDao) { + this.projectDao = projectDao; + } + + + public Workspace getWorkspace(int projectId, int userId) throws HibernateException { + Session session = currentSession(); + Query q = session.createQuery("from Workspace where user.id = :userId and project.id = :projectId"); + q.setInteger("projectId", projectId); + q.setInteger("userId", userId); + Workspace workspace = (Workspace) q.uniqueResult(); + if (workspace == null) { + return addWorkspace(projectId, userId); + } else { + return workspace; + } + } + + private Workspace addWorkspace(int projectId, int userId) { + Session session = currentSession(); + Project project = (Project) session.get(Project.class, projectId); + if (project == null) { + throw new RuntimeException("project you requested doesn't exist."); + } + Workspace workspace = new Workspace(); + workspace.setUser((User) session.load(User.class, userId)); + workspace.setProject(project); + workspace.setProjectData(project.toString(Project.TO_STRING_TYPE.TO_PARAMETER)); + workspace.setProjectDataOriginal(workspace.getProjectData()); + workspace.setUpdateDate(new Date()); + int id = (Integer) session.save(workspace); + return getWorkspace(id); + } + + public void updateWorkspace(Workspace workspace) { + workspace.setUpdateDate(new Date()); + currentSession().save(workspace); + } + + + public Workspace getWorkspace(int id) { + Session session = currentSession(); + Workspace workspace = session.load(Workspace.class, id); + return workspace; + } + + public void addCheckIn(CheckIn checkIn) { + currentSession().save(checkIn); + } + + + public CheckIn getVersion(int versionId) { + return currentSession().load(CheckIn.class, versionId); + } + + + public CheckIn getVersion(int projectId, String version) { + Session session = currentSession(); + Query query = session.createQuery("from CheckIn obj where obj.project.id = :projectId and obj.version = :version"); + query.setInteger("projectId", projectId); + query.setString("version", version); + return (CheckIn) query.uniqueResult(); + } + + + public void prepareForVersionSwitch(CheckIn check) { + Session session = currentSession(); + Project project = check.getProject(); + Iterator iterator = project.getModuleList().iterator(); + while (iterator.hasNext()) { + Module next = iterator.next(); + session.delete(next); + } + project.getModuleList().clear(); + } + +} diff --git a/src/main/java/com/taobao/rigel/rap/workspace/service/WorkspaceMgr.java b/src/main/java/com/taobao/rigel/rap/workspace/service/WorkspaceMgr.java new file mode 100644 index 000000000..844dfcdc5 --- /dev/null +++ b/src/main/java/com/taobao/rigel/rap/workspace/service/WorkspaceMgr.java @@ -0,0 +1,74 @@ +package com.taobao.rigel.rap.workspace.service; + +import com.taobao.rigel.rap.workspace.bo.CheckIn; +import com.taobao.rigel.rap.workspace.bo.Workspace; + +public interface WorkspaceMgr { + + /** + * get workspace obj + * + * @param projectId + * @param userId + * @return + */ + Workspace getWorkspace(int projectId, int userId); + + /** + * update workspace + * + * @param workspace + */ + void updateWorkspace(Workspace workspace); + + /** + * get workspace + * + * @param id + * @return + */ + Workspace getWorkspace(int id); + + + /*** + * workspace check out + * + * @param jsonList [0]:projectData, [1]: projectDataOriginal + * @param userId + * @param projectId + * @return + */ + String checkOut(String[] jsonList, int userId, int projectId); + + /*** + * workspace check in + * + * @param jsonList [0]:projectData [1]: projectDataOriginal + * @param userId + * @param projectId + * @return + */ + String checkIn(String[] jsonList, int userId, int projectId); + + /** + * add new check in log + * + * @param checkIn + */ + void addCheckIn(CheckIn checkIn); + + /** + * get {@link CheckIn} obj + * + * @param versionId + * @return + */ + CheckIn getVersion(int versionId); + + /** + * do sth. preparing for version switch + * + * @param check + */ + void prepareForVersionSwitch(CheckIn check); +} diff --git a/src/main/java/com/taobao/rigel/rap/workspace/service/impl/WorkspaceMgrImpl.java b/src/main/java/com/taobao/rigel/rap/workspace/service/impl/WorkspaceMgrImpl.java new file mode 100644 index 000000000..c07ef753c --- /dev/null +++ b/src/main/java/com/taobao/rigel/rap/workspace/service/impl/WorkspaceMgrImpl.java @@ -0,0 +1,645 @@ +package com.taobao.rigel.rap.workspace.service.impl; + +import com.google.gson.Gson; +import com.taobao.rigel.rap.project.bo.*; +import com.taobao.rigel.rap.project.dao.ProjectDao; +import com.taobao.rigel.rap.workspace.bo.CheckIn; +import com.taobao.rigel.rap.workspace.bo.Workspace; +import com.taobao.rigel.rap.workspace.dao.WorkspaceDao; +import com.taobao.rigel.rap.workspace.service.WorkspaceMgr; +import java.util.Iterator; + +public class WorkspaceMgrImpl implements WorkspaceMgr { + + private WorkspaceDao workspaceDao; + private ProjectDao projectDao; + + public WorkspaceDao getWorkspaceDao() { + return this.workspaceDao; + } + + public void setWorkspaceDao(WorkspaceDao workspaceDao) { + this.workspaceDao = workspaceDao; + } + + public ProjectDao getProjectDao() { + return projectDao; + } + + public void setProjectDao(ProjectDao projectDao) { + this.projectDao = projectDao; + } + + public Workspace getWorkspace(int projectId, int userId) { + Workspace workspace = workspaceDao.getWorkspace(projectId, userId); + return workspace; + } + + public void updateWorkspace(Workspace workspace) { + workspaceDao.updateWorkspace(workspace); + + } + + public Workspace getWorkspace(int id) { + return workspaceDao.getWorkspace(id); + } + + public String checkIn(String[] jsonList, int userId, int projectId) { + //[TODO] does user has access? + StringBuilder log = new StringBuilder(); + Project projectClient, projectOriginal, projectServer; + Gson gson = new Gson(); + // get server workspace + projectServer = projectDao.getProjectSummary(projectId); + // parse client workspace + projectClient = gson.fromJson(jsonList[0], Project.class); + // parse original client workspace + projectOriginal = gson.fromJson(jsonList[1], Project.class); + + /** + * start processing ... + * update a(client) => b(server) compared with o (Original) + */ + + // search moduleList + Iterator moduleIterator = projectClient.getModuleList().iterator(); + while (moduleIterator.hasNext()) { + Module moduleA = moduleIterator.next(); + // scan module + Module moduleB = findModule(projectServer, moduleA.getId()); + if (moduleB == null) { + log.append(logTemplate(moduleA.getId(), "module", "add", null, null, null)); + projectServer.getModuleList().add(moduleA); + continue; + } + Module moduleO = findModule(projectOriginal, moduleA.getId()); + if (!moduleA.getName().equals(moduleB.getName())) { + boolean aChanged = (!moduleA.getName().equals(moduleO.getName())); + boolean bChanged = (!moduleB.getName().equals(moduleO.getName())); + + if (aChanged && bChanged) { + // [TODO] conflict! + } else if (aChanged && !bChanged) { + // update + log.append(logTemplate(moduleB.getId(), "module", "update", + moduleA.getName(), moduleB.getName(), "name")); + moduleB.setName(moduleA.getName()); + } else if (!aChanged && bChanged) { + // ignore + } + } + if (!moduleA.getIntroduction().equals(moduleB.getIntroduction())) { + boolean aChanged = (!moduleA.getIntroduction().equals(moduleO.getIntroduction())); + boolean bChanged = (!moduleB.getIntroduction().equals(moduleO.getIntroduction())); + + if (aChanged && bChanged) { + // [TODO] conflict! + } else if (aChanged && !bChanged) { + // update + log.append(logTemplate(moduleB.getId(), "module", "update", + moduleA.getIntroduction(), moduleB.getIntroduction(), "introduction")); + moduleB.setIntroduction(moduleA.getIntroduction()); + } else if (!aChanged && bChanged) { + // ignore + } + } + // search pageList + Iterator pageIterator = moduleA.getPageList().iterator(); + while (pageIterator.hasNext()) { + Page pageA = pageIterator.next(); + // scan page + Page pageB = findPage(projectServer, pageA.getId()); + if (pageB == null) { + moduleB.getPageList().add(pageA); + continue; + } + Page pageO = findPage(projectOriginal, pageA.getId()); + if (!pageA.getName().equals(pageB.getName())) { + boolean aChanged = (!pageA.getName().equals(pageO.getName())); + boolean bChanged = (!pageB.getName().equals(pageO.getName())); + + if (aChanged && bChanged) { + // [TODO] conflict! + } else if (aChanged && !bChanged) { + // update + log.append(logTemplate(pageB.getId(), "page", "update", + pageA.getName(), pageB.getName(), "name")); + pageB.setName(pageA.getName()); + } else if (!aChanged && bChanged) { + // ignore + } + } + if (!pageA.getIntroduction().equals(pageB.getIntroduction())) { + boolean aChanged = (!pageA.getIntroduction().equals(pageO.getIntroduction())); + boolean bChanged = (!pageB.getIntroduction().equals(pageO.getIntroduction())); + + if (aChanged && bChanged) { + // [TODO] conflict! + } else if (aChanged && !bChanged) { + // update + log.append(logTemplate(pageB.getId(), "page", "update", + pageA.getIntroduction(), pageB.getIntroduction(), "introduction")); + pageB.setIntroduction(pageA.getIntroduction()); + } else if (!aChanged && bChanged) { + // ignore + } + } + // search actionList + Iterator actionIterator = pageA.getActionList().iterator(); + while (actionIterator.hasNext()) { + Action actionA = actionIterator.next(); + // scan action + Action actionB = findAction(projectServer, actionA.getId()); + if (actionB == null) { + pageB.getActionList().add(actionA); + continue; + } + + Action actionO = findAction(projectOriginal, actionA.getId()); + if (!actionA.getName().equals(actionB.getName())) { + boolean aChanged = (!actionA.getName().equals(actionO.getName())); + boolean bChanged = (!actionB.getName().equals(actionO.getName())); + + if (aChanged && bChanged) { + // [TODO] conflict! + } else if (aChanged && !bChanged) { + // update + log.append(logTemplate(Integer.parseInt(new Integer(actionB.getId()).toString()), "action", "update", + actionA.getName(), actionB.getName(), "name")); + actionB.setName(actionA.getName()); + } else if (!aChanged && bChanged) { + // ignore + } + } + if (!actionA.getDescription().equals(actionB.getDescription())) { + boolean aChanged = (!actionA.getDescription().equals(actionO.getDescription())); + boolean bChanged = (!actionB.getDescription().equals(actionO.getDescription())); + + if (aChanged && bChanged) { + // [TODO] conflict! + } else if (aChanged && !bChanged) { + // update + log.append(logTemplate(Integer.parseInt(new Integer(actionB.getId()).toString()), "action", "update", + actionA.getDescription(), actionB.getDescription(), "description")); + actionB.setDescription(actionA.getDescription()); + } else if (!aChanged && bChanged) { + // ignore + } + } + if (!actionA.getRequestType().equals(actionB.getRequestType())) { + boolean aChanged = (!actionA.getRequestType().equals(actionO.getRequestType())); + boolean bChanged = (!actionB.getRequestType().equals(actionO.getRequestType())); + + if (aChanged && bChanged) { + // [TODO] conflict! + } else if (aChanged && !bChanged) { + // update + log.append(logTemplate(Integer.parseInt(new Integer(actionB.getId()).toString()), "action", "update", + actionA.getRequestType(), actionB.getRequestType(), "requestType")); + actionB.setRequestType(actionA.getRequestType()); + } else if (!aChanged && bChanged) { + // ignore + } + } + if (!actionA.getRequestUrl().equals(actionB.getRequestUrl())) { + boolean aChanged = (!actionA.getRequestUrl().equals(actionO.getRequestUrl())); + boolean bChanged = (!actionB.getRequestUrl().equals(actionO.getRequestUrl())); + + if (aChanged && bChanged) { + // [TODO] conflict! + } else if (aChanged && !bChanged) { + // update + log.append(logTemplate(Integer.parseInt(new Integer(actionB.getId()).toString()), "action", "update", + actionA.getRequestUrl(), actionB.getRequestUrl(), "requestUrl")); + actionB.setRequestUrl(actionA.getRequestUrl()); + } else if (!aChanged && bChanged) { + // ignore + } + } + if (!actionA.getResponseTemplate().equals(actionB.getResponseTemplate())) { + boolean aChanged = (!actionA.getResponseTemplate().equals(actionO.getResponseTemplate())); + boolean bChanged = (!actionB.getResponseTemplate().equals(actionO.getResponseTemplate())); + + if (aChanged && bChanged) { + // [TODO] conflict! + } else if (aChanged && !bChanged) { + // update + log.append(logTemplate(Integer.parseInt(new Integer(actionB.getId()).toString()), "action", "update", + actionA.getResponseTemplate(), actionB.getResponseTemplate(), "responseTemplate")); + actionB.setResponseTemplate(actionA.getResponseTemplate()); + } else if (!aChanged && bChanged) { + // ignore + } + } + // search requestParameterList + Iterator requestParameterIterator = actionA.getRequestParameterList().iterator(); + while (requestParameterIterator.hasNext()) { + Parameter parameterA = requestParameterIterator.next(); + // scan request parameter + Parameter parameterB = findParameter(projectServer, parameterA.getId(), true); + if (parameterB == null) { + actionB.getRequestParameterList().add(parameterA); + continue; + } + Parameter parameterO = findParameter(projectOriginal, parameterA.getId(), true); + processParameter(parameterA, parameterB, parameterO, log); + } + + // search responseParameterList + Iterator responseParameterIterator = actionA.getResponseParameterList().iterator(); + while (responseParameterIterator.hasNext()) { + Parameter parameterA = responseParameterIterator.next(); + // scan response parameter + Parameter parameterB = findParameter(projectClient, parameterA.getId(), false); + if (parameterB == null) { + actionB.getResponseParameterList().add(parameterA); + continue; + } + Parameter parameterO = findParameter(projectOriginal, parameterA.getId(), false); + processParameter(parameterA, parameterB, parameterO, log); + } + } + } + + } + projectDao.updateProject(projectServer); + projectServer = projectDao.getProjectSummary(projectId); + return "{\"projectData\":" + projectServer.toString() + ", \"log\":\"" + log + + "\", \"projectDataOriginal\":" + projectServer.toString() + "}"; + } + + + public String checkOut(String[] jsonList, int userId, int projectId) { + //[TODO] does user has access? + + StringBuilder log = new StringBuilder(); + Project projectClient, projectOriginal, projectServer; + Gson gson = new Gson(); + // get server workspace + projectServer = projectDao.getProjectSummary(projectId); + // parse client workspace + projectClient = gson.fromJson(jsonList[0], Project.class); + // parse original client workspace + projectOriginal = gson.fromJson(jsonList[1], Project.class); + + /** + * start processing ... + * update a(Server) => b(client) compared with o (Original) + */ + + // search moduleList + Iterator moduleIterator = projectServer.getModuleList().iterator(); + while (moduleIterator.hasNext()) { + Module moduleA = moduleIterator.next(); + // scan module + Module moduleB = findModule(projectClient, moduleA.getId()); + if (moduleB == null) { + log.append(logTemplate(moduleA.getId(), "module", "add", null, null, null)); + projectClient.getModuleList().add(moduleA); + continue; + } + Module moduleO = findModule(projectOriginal, moduleA.getId()); + if (!moduleA.getName().equals(moduleB.getName())) { + boolean aChanged = (!moduleA.getName().equals(moduleO.getName())); + boolean bChanged = (!moduleB.getName().equals(moduleO.getName())); + + if (aChanged && bChanged) { + // [TODO] conflict! + } else if (aChanged && !bChanged) { + // update + log.append(logTemplate(moduleB.getId(), "module", "update", + moduleA.getName(), moduleB.getName(), "name")); + moduleB.setName(moduleA.getName()); + } else if (!aChanged && bChanged) { + // ignore + } + } + if (!moduleA.getIntroduction().equals(moduleB.getIntroduction())) { + boolean aChanged = (!moduleA.getIntroduction().equals(moduleO.getIntroduction())); + boolean bChanged = (!moduleB.getIntroduction().equals(moduleO.getIntroduction())); + + if (aChanged && bChanged) { + // [TODO] conflict! + } else if (aChanged && !bChanged) { + // update + log.append(logTemplate(moduleB.getId(), "module", "update", + moduleA.getIntroduction(), moduleB.getIntroduction(), "introduction")); + moduleB.setIntroduction(moduleA.getIntroduction()); + } else if (!aChanged && bChanged) { + // ignore + } + } + // search pageList + Iterator pageIterator = moduleA.getPageList().iterator(); + while (pageIterator.hasNext()) { + Page pageA = pageIterator.next(); + // scan page + Page pageB = findPage(projectClient, pageA.getId()); + if (pageB == null) { + moduleB.getPageList().add(pageA); + continue; + } + Page pageO = findPage(projectOriginal, pageA.getId()); + if (!pageA.getName().equals(pageB.getName())) { + boolean aChanged = (!pageA.getName().equals(pageO.getName())); + boolean bChanged = (!pageB.getName().equals(pageO.getName())); + + if (aChanged && bChanged) { + // [TODO] conflict! + } else if (aChanged && !bChanged) { + // update + log.append(logTemplate(pageB.getId(), "page", "update", + pageA.getName(), pageB.getName(), "name")); + pageB.setName(pageA.getName()); + } else if (!aChanged && bChanged) { + // ignore + } + } + if (!pageA.getIntroduction().equals(pageB.getIntroduction())) { + boolean aChanged = (!pageA.getIntroduction().equals(pageO.getIntroduction())); + boolean bChanged = (!pageB.getIntroduction().equals(pageO.getIntroduction())); + + if (aChanged && bChanged) { + // [TODO] conflict! + } else if (aChanged && !bChanged) { + // update + log.append(logTemplate(pageB.getId(), "page", "update", + pageA.getIntroduction(), pageB.getIntroduction(), "introduction")); + pageB.setIntroduction(pageA.getIntroduction()); + } else if (!aChanged && bChanged) { + // ignore + } + } + // search actionList + Iterator actionIterator = pageA.getActionList().iterator(); + while (actionIterator.hasNext()) { + Action actionA = actionIterator.next(); + // scan action + Action actionB = findAction(projectClient, actionA.getId()); + if (actionB == null) { + pageB.getActionList().add(actionA); + continue; + } + + Action actionO = findAction(projectOriginal, actionA.getId()); + if (!actionA.getName().equals(actionB.getName())) { + boolean aChanged = (!actionA.getName().equals(actionO.getName())); + boolean bChanged = (!actionB.getName().equals(actionO.getName())); + + if (aChanged && bChanged) { + // [TODO] conflict! + } else if (aChanged && !bChanged) { + // update + log.append(logTemplate(Integer.parseInt(new Integer(actionB.getId()).toString()), "action", "update", + actionA.getName(), actionB.getName(), "name")); + actionB.setName(actionA.getName()); + } else if (!aChanged && bChanged) { + // ignore + } + } + if (!actionA.getDescription().equals(actionB.getDescription())) { + boolean aChanged = (!actionA.getDescription().equals(actionO.getDescription())); + boolean bChanged = (!actionB.getDescription().equals(actionO.getDescription())); + + if (aChanged && bChanged) { + // [TODO] conflict! + } else if (aChanged && !bChanged) { + // update + log.append(logTemplate(Integer.parseInt(new Integer(actionB.getId()).toString()), "action", "update", + actionA.getDescription(), actionB.getDescription(), "description")); + actionB.setDescription(actionA.getDescription()); + } else if (!aChanged && bChanged) { + // ignore + } + } + if (!actionA.getRequestType().equals(actionB.getRequestType())) { + boolean aChanged = (!actionA.getRequestType().equals(actionO.getRequestType())); + boolean bChanged = (!actionB.getRequestType().equals(actionO.getRequestType())); + + if (aChanged && bChanged) { + // [TODO] conflict! + } else if (aChanged && !bChanged) { + // update + log.append(logTemplate(Integer.parseInt(new Integer(actionB.getId()).toString()), "action", "update", + actionA.getRequestType(), actionB.getRequestType(), "requestType")); + actionB.setRequestType(actionA.getRequestType()); + } else if (!aChanged && bChanged) { + // ignore + } + } + if (!actionA.getRequestUrl().equals(actionB.getRequestUrl())) { + boolean aChanged = (!actionA.getRequestUrl().equals(actionO.getRequestUrl())); + boolean bChanged = (!actionB.getRequestUrl().equals(actionO.getRequestUrl())); + + if (aChanged && bChanged) { + // [TODO] conflict! + } else if (aChanged && !bChanged) { + // update + log.append(logTemplate(Integer.parseInt(new Integer(actionB.getId()).toString()), "action", "update", + actionA.getRequestUrl(), actionB.getRequestUrl(), "requestUrl")); + actionB.setRequestUrl(actionA.getRequestUrl()); + } else if (!aChanged && bChanged) { + // ignore + } + } + if (!actionA.getResponseTemplate().equals(actionB.getResponseTemplate())) { + boolean aChanged = (!actionA.getResponseTemplate().equals(actionO.getResponseTemplate())); + boolean bChanged = (!actionB.getResponseTemplate().equals(actionO.getResponseTemplate())); + + if (aChanged && bChanged) { + // [TODO] conflict! + } else if (aChanged && !bChanged) { + // update + log.append(logTemplate(Integer.parseInt(new Integer(actionB.getId()).toString()), "action", "update", + actionA.getResponseTemplate(), actionB.getResponseTemplate(), "responseTemplate")); + actionB.setResponseTemplate(actionA.getResponseTemplate()); + } else if (!aChanged && bChanged) { + // ignore + } + } + // search requestParameterList + Iterator requestParameterIterator = actionA.getRequestParameterList().iterator(); + while (requestParameterIterator.hasNext()) { + Parameter parameterA = requestParameterIterator.next(); + // scan request parameter + Parameter parameterB = findParameter(projectClient, parameterA.getId(), true); + if (parameterB == null) { + actionB.getRequestParameterList().add(parameterA); + continue; + } + Parameter parameterO = findParameter(projectOriginal, parameterA.getId(), true); + processParameter(parameterA, parameterB, parameterO, log); + } + + // search responseParameterList + Iterator responseParameterIterator = actionA.getResponseParameterList().iterator(); + while (responseParameterIterator.hasNext()) { + Parameter parameterA = responseParameterIterator.next(); + // scan response parameter + Parameter parameterB = findParameter(projectClient, parameterA.getId(), false); + if (parameterB == null) { + actionB.getResponseParameterList().add(parameterA); + continue; + } + Parameter parameterO = findParameter(projectOriginal, parameterA.getId(), false); + processParameter(parameterA, parameterB, parameterO, log); + } + } + } + + } + return "{\"projectData\":" + projectClient.toString() + ", \"log\":\"" + + log + "\", \"projectDataOriginal\":" + projectClient.toString() + "}"; + } + + + private void processParameter(Parameter parameterA, Parameter parameterB, + Parameter parameterO, StringBuilder log) { + if (!parameterA.getName().equals(parameterB.getName())) { + boolean aChanged = (!parameterA.getName().equals(parameterO.getName())); + boolean bChanged = (!parameterB.getName().equals(parameterO.getName())); + + if (aChanged && bChanged) { + // [TODO] conflict! + } else if (aChanged && !bChanged) { + // update + log.append(logTemplate(parameterB.getId(), "parameter", "update", + parameterA.getName(), parameterB.getName(), "name")); + parameterB.setName(parameterA.getName()); + } else if (!aChanged && bChanged) { + // ignore + } + } + if (!parameterA.getDataType().equals(parameterB.getDataType())) { + boolean aChanged = (!parameterA.getDataType().equals(parameterO.getDataType())); + boolean bChanged = (!parameterB.getDataType().equals(parameterO.getDataType())); + + if (aChanged && bChanged) { + // [TODO] conflict! + } else if (aChanged && !bChanged) { + // update + log.append(logTemplate(parameterB.getId(), "parameter", "update", + parameterA.getDataType(), parameterB.getDataType(), "dataType")); + parameterB.setDataType(parameterA.getDataType()); + } else if (!aChanged && bChanged) { + // ignore + } + } + if (!parameterA.getIdentifier().equals(parameterB.getIdentifier())) { + boolean aChanged = (!parameterA.getIdentifier().equals(parameterO.getIdentifier())); + boolean bChanged = (!parameterB.getIdentifier().equals(parameterO.getIdentifier())); + + if (aChanged && bChanged) { + // [TODO] conflict! + } else if (aChanged && !bChanged) { + // update + log.append(logTemplate(parameterB.getId(), "parameter", "update", + parameterA.getIdentifier(), parameterB.getIdentifier(), "identifier")); + parameterB.setIdentifier(parameterA.getIdentifier()); + } else if (!aChanged && bChanged) { + // ignore + } + } + if (!parameterA.getRemark().equals(parameterB.getRemark())) { + boolean aChanged = (!parameterA.getRemark().equals(parameterO.getRemark())); + boolean bChanged = (!parameterB.getRemark().equals(parameterO.getRemark())); + + if (aChanged && bChanged) { + // [TODO] conflict! + } else if (aChanged && !bChanged) { + // update + log.append(logTemplate(parameterB.getId(), "parameter", "update", + parameterA.getRemark(), parameterB.getRemark(), "remark")); + parameterB.setRemark(parameterA.getRemark()); + } else if (!aChanged && bChanged) { + // ignore + } + } + if (!parameterA.getValidator().equals(parameterB.getValidator())) { + boolean aChanged = (!parameterA.getValidator().equals(parameterO.getValidator())); + boolean bChanged = (!parameterB.getValidator().equals(parameterO.getValidator())); + + if (aChanged && bChanged) { + // [TODO] conflict! + } else if (aChanged && !bChanged) { + // update + log.append(logTemplate(parameterB.getId(), "parameter", "update", + parameterA.getValidator(), parameterB.getValidator(), "validator")); + parameterB.setValidator(parameterA.getValidator()); + } else if (!aChanged && bChanged) { + // ignore + } + } + } + + private Module findModule(Project p, int moduleId) { + for (Module i : p.getModuleList()) { + if (i.getId() == moduleId) + return i; + } + return null; + } + + private Page findPage(Project p, int pageId) { + for (Module module : p.getModuleList()) { + for (Page page : module.getPageList()) { + if (page.getId() == pageId) + return page; + } + } + return null; + } + + private Action findAction(Project p, int actionId) { + for (Module module : p.getModuleList()) { + for (Page page : module.getPageList()) { + for (Action action : page.getActionList()) { + if (action.getId() == actionId) + return action; + } + } + } + return null; + } + + private Parameter findParameter(Project p, int parameterId, boolean isRequestType) { + for (Module module : p.getModuleList()) { + for (Page page : module.getPageList()) { + for (Action action : page.getActionList()) { + for (Parameter parameter : (isRequestType ? + action.getRequestParameterList() : action.getResponseParameterList())) { + if (parameter.getId() == parameterId) + return parameter; + } + } + } + } + return null; + } + + + private String logTemplate(int objectId, String className, + String operationName, String newValue, String oldValue, String property) { + return operationName == "add" ? + "
    " + operationName + " " + className + " [" + objectId + + "]
    " + : "
    " + operationName + " " + className + " [" + objectId + + "]." + property + " from [" + oldValue + "] to [" + newValue + "]
    "; + } + + + public void addCheckIn(CheckIn checkIn) { + workspaceDao.addCheckIn(checkIn); + } + + + public CheckIn getVersion(int versionId) { + return workspaceDao.getVersion(versionId); + } + + + public void prepareForVersionSwitch(CheckIn check) { + workspaceDao.prepareForVersionSwitch(check); + + } +} diff --git a/src/main/java/com/taobao/rigel/rap/workspace/web/action/WorkspaceAction.java b/src/main/java/com/taobao/rigel/rap/workspace/web/action/WorkspaceAction.java new file mode 100644 index 000000000..963697a5d --- /dev/null +++ b/src/main/java/com/taobao/rigel/rap/workspace/web/action/WorkspaceAction.java @@ -0,0 +1,569 @@ +package com.taobao.rigel.rap.workspace.web.action; + +import com.google.gson.Gson; +import com.taobao.rigel.rap.account.bo.Notification; +import com.taobao.rigel.rap.account.bo.User; +import com.taobao.rigel.rap.common.base.ActionBase; +import com.taobao.rigel.rap.common.config.SystemConstant; +import com.taobao.rigel.rap.common.service.impl.ContextManager; +import com.taobao.rigel.rap.common.utils.CacheUtils; +import com.taobao.rigel.rap.common.utils.MapUtils; +import com.taobao.rigel.rap.organization.service.OrganizationMgr; +import com.taobao.rigel.rap.project.bo.Module; +import com.taobao.rigel.rap.project.bo.Project; +import com.taobao.rigel.rap.project.service.ProjectMgr; +import com.taobao.rigel.rap.workspace.bo.CheckIn; +import com.taobao.rigel.rap.workspace.bo.Workspace; +import com.taobao.rigel.rap.workspace.service.WorkspaceMgr; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.apache.velocity.Template; +import org.apache.velocity.VelocityContext; +import org.apache.velocity.app.VelocityEngine; +import org.apache.velocity.exception.MethodInvocationException; +import org.apache.velocity.exception.ParseErrorException; +import org.apache.velocity.exception.ResourceNotFoundException; + +import java.io.ByteArrayInputStream; +import java.io.InputStream; +import java.io.StringWriter; +import java.util.*; + +public class WorkspaceAction extends ActionBase { + + private static final Logger logger = LogManager.getFormatterLogger(WorkspaceAction.class); + public Module module; + private OrganizationMgr organizationMgr; + + private boolean accessable; + private boolean mock; + private int actionId; + private int id; + private String workspaceJsonString; + private Workspace workspace; + private VelocityEngine velocityEngine; + private int projectId; + private Project project; + private String projectData; + private String projectDataOriginal; + private String saveListJson; + private int saveId = -1; + private int versionId; + private String deletedObjectListData; + private String tag; + /** + * from 1 to 4, version position + */ + private int versionPosition; + private String description; + private boolean isLocked; + private InputStream fileInputStream; + + private WorkspaceMgr workspaceMgr; + private ProjectMgr projectMgr; + + public OrganizationMgr getOrganizationMgr() { + return organizationMgr; + } + + public void setOrganizationMgr(OrganizationMgr organizationMgr) { + this.organizationMgr = organizationMgr; + } + + public boolean isAccessable() { + return accessable; + } + + public void setAccessable(boolean accessable) { + this.accessable = accessable; + } + + public int getActionId() { + return actionId; + } + + public void setActionId(int actionId) { + this.actionId = actionId; + } + + public boolean isMock() { + return mock; + } + + public void setMock(boolean mock) { + this.mock = mock; + } + + public int getId() { + return this.id; + } + + public void setId(int id) { + this.id = id; + } + + public String getWorkspaceJsonString() { + return this.workspaceJsonString; + } + + public void setWorkspaceJsonString(String workspaceJsonString) { + this.workspaceJsonString = workspaceJsonString; + } + + public Workspace getWorkspace() { + return this.workspace; + } + + public void setWorkspace(Workspace workspace) { + this.workspace = workspace; + } + + public Module getModule() { + return this.module; + } + + public void setModule(Module module) { + this.module = module; + } + + public VelocityEngine getVelocityEngine() { + return velocityEngine; + } + + public void setVelocityEngine(VelocityEngine velocityEngine) { + this.velocityEngine = velocityEngine; + } + + public Project getProject() { + return project; + } + + public void setProject(Project project) { + this.project = project; + } + + public int getProjectId() { + return this.projectId; + } + + public void setProjectId(int projectId) { + this.projectId = projectId; + } + + public String getProjectData() { + return projectData; + } + + public void setProjectData(String projectData) { + this.projectData = projectData; + } + + public String getProjectDataOriginal() { + return projectDataOriginal; + } + + public void setProjectDataOriginal(String projectDataOriginal) { + this.projectDataOriginal = projectDataOriginal; + } + + public String getSaveListJson() { + return saveListJson; + } + + public void setSaveListJson(String saveListJson) { + this.saveListJson = saveListJson; + } + + public int getSaveId() { + return saveId; + } + + public void setSaveId(int saveId) { + this.saveId = saveId; + } + + public int getVersionId() { + return versionId; + } + + public void setVersionId(int versionId) { + this.versionId = versionId; + } + + public String getDeletedObjectListData() { + return deletedObjectListData; + } + + public void setDeletedObjectListData(String deletedObjectListData) { + this.deletedObjectListData = deletedObjectListData; + } + + public String getTag() { + return tag; + } + + public void setTag(String tag) { + this.tag = tag; + } + + public int getVersionPosition() { + return versionPosition; + } + + public void setVersionPosition(int versionPosition) { + this.versionPosition = versionPosition; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public boolean getIsLocked() { + return isLocked; + } + + public void setIsLocked(boolean isLocked) { + this.isLocked = isLocked; + } + + public String myWorkspace() { + if (!isUserLogined()) { + plsLogin(); + setRelativeReturnUrl("/workspace/myWorkspace.do?projectId=" + + projectId); + return LOGIN; + } + setAccessable(getAccountMgr().canUserManageProject(getCurUserId(), getProjectId())); + return SUCCESS; + } + + public String loadWorkspace() { + if (!isUserLogined()) { + plsLogin(); + return JSON_ERROR; + } + String[] cacheKey = new String[]{CacheUtils.KEY_WORKSPACE, new Integer(getProjectId()).toString()}; + String cache = CacheUtils.get(cacheKey); + if (cache != null) { + setJson(cache); + } else { + Project p = projectMgr.getProject(getProjectId()); + + if (p == null || p.getId() <= 0) { + setErrMsg("该项目不存在或已被删除,会不会是亲这个链接保存的太久了呢?0 .0"); + logger.error("Unexpected project id=%d", getProjectId()); + return JSON_ERROR; + } + + if (!organizationMgr.canUserAccessProject(getCurUserId(), getProjectId())) { + setErrMsg(ACCESS_DENY); + return JSON_ERROR; + } + + Workspace workspace = new Workspace(); + workspace.setProject(p); + + String json = workspace.toString(); + setJson(json); + + CacheUtils.put(cacheKey, json); + } + return SUCCESS; + } + + /** + * load save, saveId must be significant, or operation failed + * + * @return the save object loaded + */ + /* + * public String querySave() { + * setJson(workspaceMgr.getSave(getSaveId()).getProjectData()); return + * SUCCESS; } + */ + public InputStream getFileInputStream() { + return fileInputStream; + } + + public WorkspaceMgr getworkspaceMgr() { + return workspaceMgr; + } + + public void setWorkspaceMgr(WorkspaceMgr workspaceMgr) { + this.workspaceMgr = workspaceMgr; + } + + public ProjectMgr projectMgr() { + return this.projectMgr; + } + + public void setProjectMgr(ProjectMgr projectMgr) { + this.projectMgr = projectMgr; + } + + public String ping() { + setJson("{\"isOk\":true}"); + return SUCCESS; + } + + public String queryVersion() { + setJson(workspaceMgr.getVersion(getVersionId()).toString( + CheckIn.ToStringType.COMPLETED)); + return SUCCESS; + } + + public String switchVersion() { + CheckIn check = workspaceMgr.getVersion(getVersionId()); + workspaceMgr.prepareForVersionSwitch(check); + projectMgr.updateProject(check.getProject().getId(), + check.getProjectData(), "[]", new HashMap()); + Project project = projectMgr.getProject(check.getProject().getId()); + String projectData = project + .toString(Project.TO_STRING_TYPE.TO_PARAMETER); + setJson("{\"projectData\":" + projectData + ", \"isOk\":true}"); + project.setProjectData(projectData); + projectMgr.updateProject(project); + return SUCCESS; + } + + public String checkIn() throws Exception { + User curUser = getCurUser(); + if (curUser == null) { + setErrMsg(LOGIN_WARN_MSG); + logger.error("Unlogined user trying to checkin and failed."); + return JSON_ERROR; + } + + if (!getAccountMgr().canUserManageProject(getCurUserId(), getId())) { + setErrMsg("access deny"); + logger.error("User %s trying to checkedin project(id=$d) and denied.", getCurAccount(), getId()); + return JSON_ERROR; + } + + // update project + Map actionIdMap = new HashMap(); + projectMgr.updateProject(getId(), getProjectData(), + getDeletedObjectListData(), actionIdMap); + + + project = projectMgr.getProject(getId()); + + // generate one check-in of VSS mode submit + CheckIn checkIn = new CheckIn(); + checkIn.setCreateDate(new Date()); + checkIn.setDescription(getDescription()); + checkIn.setProject(project); + checkIn.setProjectData(project + .toString(Project.TO_STRING_TYPE.TO_PARAMETER)); + checkIn.setTag(getTag()); + checkIn.setUser(curUser); + checkIn.setVersion(project.getVersion()); + checkIn.versionUpgrade(getVersionPosition()); + + // after version upgrade, set back to project + project.setVersion(checkIn.getVersion()); + checkIn.setWorkspaceMode(Workspace.ModeType.VSS); + workspaceMgr.addCheckIn(checkIn); + + // calculate JSON string for client + project = projectMgr.getProject(getId()); + StringBuilder stringBuilder = new StringBuilder(); + stringBuilder.append("{\"projectData\":" + checkIn.getProjectData()); + stringBuilder.append(",\"checkList\":["); + Iterator iterator = project.getCheckInListOrdered().iterator(); + while (iterator.hasNext()) { + stringBuilder.append(iterator.next()); + if (iterator.hasNext()) { + stringBuilder.append(","); + } + } + Gson g = new Gson(); + stringBuilder + .append("],\"actionIdMap\":") + .append(g.toJson(actionIdMap)) + .append(",\"isOk\":true}"); + setJson(stringBuilder.toString()); + + // update project data + project.setProjectData(checkIn.getProjectData()); + projectMgr.updateProject(project); + + // unlock the workspace + unlock(); + + // notification for doc change + for (User user : project.getUserList()) { + Notification notification = new Notification(); + notification.setParam1(new Integer(id).toString()); + notification.setParam2(project.getName()); + notification.setTypeId((short) 1); + notification.setTargetUser(getCurUser()); + notification.setUser(user); + if (notification.getUser().getId() != getCurUserId()) + getAccountMgr().addNotification(notification); + } + + Notification notification = new Notification(); + notification.setParam1(new Integer(id).toString()); + notification.setParam2(project.getName()); + notification.setTypeId((short) 1); + notification.setTargetUser(getCurUser()); + notification.setUser(project.getUser()); + if (notification.getUser().getId() != getCurUserId()) + getAccountMgr().addNotification(notification); + + // unfinished + +// Callable taskSub = new Callable() { +// +// public String call() throws Exception { +// try { +// // async update doc +// // projectMgr.updateDoc(id); +// // async update disableCache +// projectMgr.updateCache(id); +// } catch (Exception ex) { +// ex.printStackTrace(); +// } +// +// return null; +// } +// }; +// +// FutureTask futureTask = new FutureTask(taskSub); +// Thread asyncThread = new Thread(futureTask); +// asyncThread.start(); +// logger.info("Future task CHECK_IN running..."); + + return SUCCESS; + } + + public String lock() { + int curUserId = getCurUserId(); + if (curUserId <= 0) { + setIsOk(false); + setErrMsg(LOGIN_WARN_MSG); + return JSON_ERROR; + } + + boolean isOk = false; + if (isLocked(getId())) { + // if the project is locked, find the locker + User user = getLocker(getId()); + if (!user.getAccount().equals(getCurAccount())) { + setJson("{\"isOk\":false, \"errMsg\":\"该项目目前正被" + + user.getName() + "锁定.\"}"); + } else { + // user request lock a locked project + // which is locked by himself, so let him go + isOk = true; + } + + } else { + // else, lock the project, than let him go. + Map app = ContextManager.getApplication(); + if (app.get(ContextManager.KEY_PROJECT_LOCK_LIST) == null) { + app.put(ContextManager.KEY_PROJECT_LOCK_LIST, new HashMap()); + } + Map projectLockList = (Map) app + .get(ContextManager.KEY_PROJECT_LOCK_LIST); + if (projectLockList.get(curUserId) == null) { + projectLockList.put(curUserId, getId()); + // System.out.println("user[" + curUserId + "] locked project["+ + // getId() + "]"); + } + isOk = true; + } + if (isOk) { + setJson("{\"isOk\":true, \"projectData\":" + + projectMgr.getProject(getId()).getProjectData() + "}"); + } + return SUCCESS; + } + + public String unlock() { + if (isLocked(getId())) { + Map app = ContextManager.getApplication(); + Map projectLockList = (Map) app + .get(ContextManager.KEY_PROJECT_LOCK_LIST); + if (projectLockList == null) + return SUCCESS; + int userId = super.getCurUserId(); + int projectId = (Integer) projectLockList.get(userId); + projectLockList.remove(userId); + logger.info("user[%d] unlock project[%d]", userId, projectId); + } + return SUCCESS; + } + + /** + * caution: no authentication so far + * + * @return + * @throws Exception + */ + public String export() throws Exception { + project = projectMgr.getProject(projectId); + velocityEngine.init(); + VelocityContext context = new VelocityContext(); + context.put("project", project); + Template template = null; + try { + template = velocityEngine.getTemplate("resource/export.vm", "UTF8"); + } catch (ResourceNotFoundException rnfe) { + rnfe.printStackTrace(); + } catch (ParseErrorException pee) { + pee.printStackTrace(); + } catch (MethodInvocationException mie) { + mie.printStackTrace(); + } catch (Exception e) { + e.printStackTrace(); + } + StringWriter sw = new StringWriter(); + template.merge(context, sw); + fileInputStream = new ByteArrayInputStream(sw.toString().getBytes( + "UTF8")); + return SUCCESS; + } + + private boolean isLocked(int projectId) { + Map app = ContextManager.getApplication(); + Map projectLockList = (Map) app + .get(ContextManager.KEY_PROJECT_LOCK_LIST); + return projectLockList != null + && projectLockList.containsValue(projectId); + } + + private User getLocker(int projectId) { + Map app = ContextManager.getApplication(); + Map projectLockList = (Map) app + .get(ContextManager.KEY_PROJECT_LOCK_LIST); + if (projectLockList != null) { + int userId = (Integer) MapUtils.getKeyByValue(projectLockList, + projectId); + User user = getAccountMgr().getUser(userId); + return user; + } + return null; + } + + public String __init__() { + // prevent repeated intialization of servcie + if (SystemConstant.serviceInitialized) { + return SUCCESS; + } + + SystemConstant.serviceInitialized = true; + + List list = projectMgr.getProjectList(); + for (Project p : list) { + projectMgr.updateDoc(p.getId()); + } + return SUCCESS; + } + +} diff --git a/src/main/java/database/initialize.sql b/src/main/java/database/initialize.sql new file mode 100644 index 000000000..1cd841956 --- /dev/null +++ b/src/main/java/database/initialize.sql @@ -0,0 +1,562 @@ +CREATE DATABASE IF NOT EXISTS rap_db + DEFAULT CHARSET utf8 + COLLATE utf8_general_ci; + +USE rap_db; + + +/************************************************** + * * + * account module * + * * + **************************************************/ + + +/** + * user table + */ +CREATE TABLE tb_user +( + id INT(10) AUTO_INCREMENT NOT NULL + PRIMARY KEY, + account VARCHAR(32) NOT NULL + COMMENT '账户名 account name', + password VARCHAR(128) NOT NULL + COMMENT '密码 password', + name VARCHAR(256) NOT NULL + COMMENT '名字/昵称 name/nickname', + email VARCHAR(256) NOT NULL + COMMENT 'email', + create_date TIMESTAMP NOT NULL + COMMENT '创建日期 create date' + DEFAULT now(), + is_locked_out INT(1) NOT NULL + COMMENT '用户是否锁定 is the user locked out' + DEFAULT 0, + is_hint_enabled INT(1) NOT NULL + COMMENT '是否开启新手引导 is user hint enabled' + DEFAULT 1, + last_login_date DATETIME NOT NULL + COMMENT '最近登录 last login date', + incorrect_login_attempt INT(10) NOT NULL + COMMENT '错误登录次数,登录成功后会重置为0 count of incorrect login attempts, will be set to 0 after any succesful login' + DEFAULT 0, + realname VARCHAR(128) NOT NULL + COMMENT '真实姓名' + DEFAULT '', + emp_id VARCHAR(45) NULL + COMMENT '工号,可选', + mock_num INT(10) NOT NULL + COMMENT 'mock次数,用于记录该用户所创建的接口被调用的mock次数。 mock num, used for record mock API invokation count' + DEFAULT 0 +) + ENGINE = InnoDB + DEFAULT CHARSET = utf8; + +/** + * role table + * roles instruction: + * user - every registered shuold have this role + * rd - research and development engineering + * qa - quality engineering + * pm - project manager + * op - operation manager + * admin - administrator + * god - super admin + */ +CREATE TABLE tb_role +( + id INT(10) AUTO_INCREMENT NOT NULL + PRIMARY KEY, + name VARCHAR(16) NOT NULL + COMMENT '角色名称 role name' +) + ENGINE = InnoDB + DEFAULT CHARSET = utf8; + +/** + * user role table + */ +CREATE TABLE tb_role_and_user +( + user_id INT(10) NOT NULL, + role_id INT(10) NOT NULL, + + PRIMARY KEY (user_id, role_id), + FOREIGN KEY (user_id) REFERENCES tb_user (id), + FOREIGN KEY (role_id) REFERENCES tb_role (id) +) + ENGINE = InnoDB + DEFAULT CHARSET = utf8; + + +/************************************************** + * * + * project module * + * * + **************************************************/ + + + +/** + * parameter table + */ +CREATE TABLE tb_parameter +( + id INT(10) AUTO_INCREMENT NOT NULL + PRIMARY KEY, + name VARCHAR(256) NULL + COMMENT '参数含义 parameter name', + identifier VARCHAR(256) NULL + COMMENT '变量名/参数标识符 parameter identifier', + data_type VARCHAR(32) NULL + COMMENT '数据类型 data type', + remark TEXT NULL + COMMENT '备注/mock数据等 remark/mock data', + expression VARCHAR(128) NULL + COMMENT '备用字段:表达式 backup column:expression', + mock_data TEXT NULL + COMMENT '备用字段:mock数据 backup column:mock data' +) + ENGINE = InnoDB + DEFAULT CHARSET = utf8; + +/** + * project table + * workspace_mode 1-vss(default) 2-svn + * stage 1-design 2-developing 3-debug + */ +CREATE TABLE tb_project +( + id INT(10) AUTO_INCREMENT NOT NULL + PRIMARY KEY, + `version` VARCHAR(128) NOT NULL + COMMENT '版本号 version no.' + DEFAULT '0.0.0.1', + name VARCHAR(128) NOT NULL + COMMENT '项目名称 project name', + create_date TIMESTAMP NOT NULL + COMMENT '创建日期 create date' + DEFAULT now(), + user_id INT(10) NOT NULL + COMMENT '创建人ID, project author id', + introduction TEXT NULL + COMMENT '项目描述 project introduction', + workspace_mode INT(10) NOT NULL + COMMENT '工作区提交模式(类VSS or SVN),暂时弃用了。 Workspace submit mode, deprecated.' + DEFAULT 1, + stage INT(10) NOT NULL + COMMENT '项目阶段,暂时废弃;project stage, temply deprecated. 1-design 2-developing 3-debug' + DEFAULT 1, + project_data LONGTEXT NULL + COMMENT '项目JSON数据,存放当前最新的版本。 project JSON data, saved the newest version of the project', + group_id INT(10) NULL + COMMENT '分组ID group id', + related_ids VARCHAR(128) NOT NULL + COMMENT '路由ID,用于指定与哪些项目共享mock数据; router id, used for specify sharing data with which projects.' + DEFAULT '', + update_time DATETIME NOT NULL + COMMENT '更新时间 update time', + mock_num INT NOT NULL + COMMENT 'mock次数 mock num' + DEFAULT 0, + access_type TINYINT NOT NULL + COMMENT '权限控制, 10普通, 0私有' + DEFAULT 10, + + FOREIGN KEY (user_id) REFERENCES tb_user (id) +) + ENGINE = InnoDB + DEFAULT CHARSET = utf8; + +/** + * user list and user table + * used for creating multiple to multiple mapping + * access_level: + * 1 - read + * 2 - read&write + * 3 - read&write&manage + */ +CREATE TABLE tb_project_and_user +( + project_id INT(10) NOT NULL, + user_id INT(10) NOT NULL, + access_level INT NOT NULL + DEFAULT 1, + + PRIMARY KEY (project_id, user_id), + FOREIGN KEY (project_id) REFERENCES tb_project (id), + FOREIGN KEY (user_id) REFERENCES tb_user (id) +) + ENGINE = InnoDB + DEFAULT CHARSET = utf8; + +/** + * module table + */ +CREATE TABLE tb_module +( + id INT(10) AUTO_INCREMENT NOT NULL + PRIMARY KEY, + project_id INT(10) NOT NULL, + name VARCHAR(256) NOT NULL, + introduction VARCHAR(128) NULL, + + FOREIGN KEY (project_id) REFERENCES tb_project (id) +) + ENGINE = InnoDB + DEFAULT CHARSET = utf8; + +/** + * page table + */ +CREATE TABLE tb_page +( + id INT(10) AUTO_INCREMENT NOT NULL + PRIMARY KEY, + name VARCHAR(56) NOT NULL, + module_id INT(10) NOT NULL, + introduction TEXT NULL, + template VARCHAR(128) NULL, + + FOREIGN KEY (module_id) REFERENCES tb_module (id) +) + ENGINE = InnoDB + DEFAULT CHARSET = utf8; + +/** + * action table + * request_type: + * 1 - get + * 2 - post + * 3 - ajax get + * 4 - ajax post + */ +CREATE TABLE tb_action +( + id INT(10) AUTO_INCREMENT NOT NULL + PRIMARY KEY, + name VARCHAR(256) NOT NULL, + description TEXT NULL, + + /* request block */ + request_type INT NOT NULL + COMMENT '请求类型get/post/put/delete等等 request type' + DEFAULT 1, /** request_type = 99, mount type **/ + request_url TEXT NULL, + + disable_cache TINYINT NOT NULL + COMMENT '禁用Mock缓存 disable mock cache' + DEFAULT 0, + + /* response block */ + response_template TEXT NULL + COMMENT '响应模板地址, 暂时弃用。 response template address, temply deprecated.' + +) + ENGINE = InnoDB + DEFAULT CHARSET = utf8; + +/** + * action and page table + * used for creating multiple to multiple mapping + */ +CREATE TABLE tb_action_and_page +( + action_id INT(10) NOT NULL, + page_id INT(10) NOT NULL, + + FOREIGN KEY (action_id) REFERENCES tb_action (id), + FOREIGN KEY (page_id) REFERENCES tb_page (id), + PRIMARY KEY (action_id, page_id) +) + ENGINE = InnoDB + DEFAULT CHARSET = utf8; + + +/** + * parameter and parameter mapping + * complex_parameter has so many parameters(List or Map) + */ +CREATE TABLE tb_complex_parameter_list_mapping +( + complex_parameter_id INT(10) NOT NULL, + parameter_id INT(10) NOT NULL, + + PRIMARY KEY (complex_parameter_id, parameter_id), + FOREIGN KEY (complex_parameter_id) REFERENCES tb_parameter (id), + FOREIGN KEY (parameter_id) REFERENCES tb_parameter (id) +) + ENGINE = InnoDB + DEFAULT CHARSET = utf8; + +/** + * parameter and action's request mapping + */ +CREATE TABLE tb_request_parameter_list_mapping +( + action_id INT(10) NOT NULL, + parameter_id INT(10) NOT NULL, + + PRIMARY KEY (action_id, parameter_id), + FOREIGN KEY (action_id) REFERENCES tb_action (id), + FOREIGN KEY (parameter_id) REFERENCES tb_parameter (id) +) + ENGINE = InnoDB + DEFAULT CHARSET = utf8; + +/** + * parameter and action's response mapping + */ +CREATE TABLE tb_response_parameter_list_mapping +( + action_id INT(10) NOT NULL, + parameter_id INT(10) NOT NULL, + + PRIMARY KEY (action_id, parameter_id), + FOREIGN KEY (action_id) REFERENCES tb_action (id), + FOREIGN KEY (parameter_id) REFERENCES tb_parameter (id) +) + ENGINE = InnoDB + DEFAULT CHARSET = utf8; + + +/************************************************** + * * + * workspace module * + * * + **************************************************/ + + +/** + * workspace, deprecated 工作区,暂时未使用 + */ +CREATE TABLE tb_workspace +( + id INT(10) AUTO_INCREMENT NOT NULL + PRIMARY KEY, + project_id INT(10) NOT NULL, + user_id INT NOT NULL, + create_date TIMESTAMP NOT NULL + DEFAULT now(), + update_date DATETIME NOT NULL, + project_data LONGTEXT NOT NULL, + project_data_original LONGTEXT NOT NULL, + + FOREIGN KEY (project_id) REFERENCES tb_project (id), + FOREIGN KEY (user_id) REFERENCES tb_user (id) +) + ENGINE = InnoDB + DEFAULT CHARSET = utf8; + +/** + * workspace save, deprecated 工作区保存草稿,暂时未使用 + */ +CREATE TABLE tb_workspace_save +( + id INT(10) AUTO_INCREMENT NOT NULL + PRIMARY KEY, + workspace_id INT(10) NOT NULL, + update_date DATETIME NOT NULL, + project_data LONGTEXT NOT NULL, + + FOREIGN KEY (workspace_id) REFERENCES tb_workspace (id) +) + ENGINE = InnoDB + DEFAULT CHARSET = utf8; + +/** + * check in table + * every API document submit saved here, used for version control. + * 每一次提交记录在这里,用于版本管理和回滚控制 + * workspaceMode 1-VSS 2-SVN + */ +CREATE TABLE tb_check_in +( + id INT(10) AUTO_INCREMENT NOT NULL + PRIMARY KEY, + create_date TIMESTAMP NOT NULL + DEFAULT now(), + tag VARCHAR(128) NULL + COMMENT 'tag标签 暂时未使用 deprecated', + user_id INT(10) NOT NULL + COMMENT '提交人 submit user id', + project_id INT(10) NOT NULL + COMMENT '提交的项目ID submit project id', + description TEXT NULL + COMMENT '提交描述 submit description', + version VARCHAR(128) NOT NULL + COMMENT '版本号 version no.', + project_data LONGTEXT NOT NULL + COMMENT '项目JSON数据 project json data', + workspace_mode INT(10) NOT NULL + COMMENT '工作区模式(弃用) workspace mode(deprecated)', + log TEXT NULL + COMMENT '更新日志,用于存储与最近一个版本的对比差异。暂时未使用。update log, used for calculate versions differences. Deprecated.', + + FOREIGN KEY (user_id) REFERENCES tb_user (id), + FOREIGN KEY (project_id) REFERENCES tb_project (id) +) + ENGINE = InnoDB + DEFAULT CHARSET = utf8; + +/** + * user settings table + * 用户配置表 + */ +CREATE TABLE tb_user_settings +( + user_id INT(10) NOT NULL, + `key` VARCHAR(128) NOT NULL + COMMENT '配置KEY config key', + `value` VARCHAR(128) NOT NULL + COMMENT '配置VALUE config value', + + PRIMARY KEY (user_id, `key`), + FOREIGN KEY (user_id) REFERENCES tb_user (id) +) + ENGINE = InnoDB + DEFAULT CHARSET = utf8; + +/** + * user notification table + * 用户通知表 + */ + +CREATE TABLE tb_notification +( + id INT(10) AUTO_INCREMENT NOT NULL + PRIMARY KEY, + user_id INT(10) NOT NULL + COMMENT '接受通知的用户id; user id to be notified.', + target_user_id INT(10) NOT NULL + COMMENT '上下文用户id; context user id', + type_id SMALLINT NOT NULL + COMMENT '1-文档修改,2-被加入新项目', + param1 VARCHAR(128) NULL + COMMENT '1,2-项目id', + param2 VARCHAR(128) NULL + COMMENT ' 1,2-项目名称', + param3 TEXT NULL + COMMENT '备用预留 reserved', + create_time TIMESTAMP NOT NULL + COMMENT '创建时间 create time' + DEFAULT now(), + + is_read SMALLINT NOT NULL + COMMENT '是否已读 is notification read' + DEFAULT 0, + + FOREIGN KEY (user_id) REFERENCES tb_user (id), + FOREIGN KEY (target_user_id) REFERENCES tb_user (id) +) + ENGINE = InnoDB + DEFAULT CHARSET = utf8; + +/** + * corporation table + * 公司表 + */ +CREATE TABLE tb_corporation +( + id INT(10) AUTO_INCREMENT NOT NULL + PRIMARY KEY, + name VARCHAR(256) NOT NULL, + logo_url VARCHAR(256) NULL, + user_id INT(10) NULL, + access_type TINYINT NOT NULL + COMMENT '权限控制, 10普通, 20公开' + DEFAULT 10, + `desc` TEXT NOT NULL + COMMENT '备注', + + FOREIGN KEY (user_id) REFERENCES tb_user (id) +) + ENGINE = InnoDB + DEFAULT CHARSET = utf8; + + +/** + * product line table + * 生产线表 + */ +CREATE TABLE tb_production_line +( + id INT(10) AUTO_INCREMENT NOT NULL + PRIMARY KEY, + name VARCHAR(256) NOT NULL, + project_num INT(10) NOT NULL + DEFAULT 0, + corporation_id INT(10) NOT NULL, + user_id INT(10) NOT NULL, + + FOREIGN KEY (user_id) REFERENCES tb_user (id), + FOREIGN KEY (corporation_id) REFERENCES tb_corporation (id) +) + ENGINE = InnoDB + DEFAULT CHARSET = utf8; + +/** + * project group table + * 项目分组表 + */ +CREATE TABLE tb_group +( + id INT(10) AUTO_INCREMENT NOT NULL + PRIMARY KEY, + name VARCHAR(256) NOT NULL, + production_line_id INT(10) NOT NULL, + user_id INT(10) NOT NULL, + + FOREIGN KEY (user_id) REFERENCES tb_user (id), + FOREIGN KEY (production_line_id) REFERENCES tb_production_line (id) +) + ENGINE = InnoDB + DEFAULT CHARSET = utf8; + +/** + * 规则表,存储通过Open API设置的Mock规则 + * Stored mock rules set by Open API + */ +CREATE TABLE tb_rule ( + action_id INT(10) NOT NULL + PRIMARY KEY, + rules TEXT NOT NULL, -- JSON规则 + update_time DATETIME NOT NULL + DEFAULT NOW(), -- 最近更新时间 + + FOREIGN KEY (action_id) REFERENCES tb_action (id) +) + ENGINE = InnoDB + DEFAULT CHARSET = utf8; + +CREATE TABLE tb_corporation_and_user +( + user_id INT(10) NOT NULL, + corporation_id INT(10) NOT NULL, + role_id INT(10) NOT NULL, + + PRIMARY KEY (user_id, corporation_id), + FOREIGN KEY (user_id) REFERENCES tb_user (id), + FOREIGN KEY (corporation_id) REFERENCES tb_corporation (id), + FOREIGN KEY (role_id) REFERENCES tb_role (id) +) + ENGINE = InnoDB + DEFAULT CHARSET = utf8; + + +-- required base data +INSERT INTO tb_role (name) VALUES ('god'); +INSERT INTO tb_role (name) VALUES ('admin'); +INSERT INTO tb_role (name) VALUES ('user'); +-- removed unused qa/pm/rd roles + + +INSERT INTO tb_user (account, password, email, create_date, last_login_date, name) VALUES + ('admin', 'RESERVED', 'admin@example.com', NOW(), NOW(), 'admin'); + +INSERT INTO tb_role_and_user (user_id, role_id) VALUES (1, 1); + +-- INSERT INTO tb_corporation (name, logo_url, user_id) VALUES ('MyTeam', 'empty', 1); +-- 新版RAP可以自建团队,不需要插入默认团队了。 +-- RAP v0.11.5+ users can create teams by their own, so there's no need to set default team. diff --git a/src/main/java/database/scripts.sql b/src/main/java/database/scripts.sql new file mode 100644 index 000000000..3f0e58923 --- /dev/null +++ b/src/main/java/database/scripts.sql @@ -0,0 +1,56 @@ +-- recent projects + +SELECT + p.name projectName, + u.name userName, + p.create_date projectCreateTime, + p.introduction +FROM tb_project p + JOIN tb_user u ON p.user_id = u.id +ORDER BY p.id DESC + +-- recent users + +SELECT * +FROM tb_user +ORDER BY id DESC + +-- counters +SELECT COUNT(*) userNum +FROM tb_user; +SELECT COUNT(*) projectNum +FROM tb_project; + + +-- counting projects (actions >= 5) +SELECT + p.id, + p.name, + COUNT(a.id) +FROM tb_project p + JOIN tb_module m ON m.project_id = p.id + JOIN tb_page p2 ON p2.module_id = m.id + JOIN tb_action_and_page ap ON ap.page_id = p2.id + JOIN tb_action a ON a.id = ap.action_id +GROUP BY p.id +HAVING COUNT(a.id) > 5 +ORDER BY count(a.id) DESC + + +-- search request_url +SELECT + a.name actionName, + m.project_id projectId +FROM tb_action a + JOIN tb_action_and_page ap ON ap.action_id = a.id + JOIN tb_page p ON p.id = ap.page_id + JOIN tb_module m ON m.id = p.module_id +WHERE request_url LIKE '%key%' + +-- search organization info by projectId +SELECT CONCAT(c.name, '-', pl.name, '-', g.name, '-', p.name) AS info +FROM tb_project p + JOIN tb_group g ON g.id = p.group_id + JOIN tb_production_line pl ON pl.id = g.production_line_id + JOIN tb_corporation c ON c.id = pl.corporation_id +WHERE p.id = {projectId} \ No newline at end of file diff --git a/src/database/v0.11.0_to_v0.11.1.sql b/src/main/java/database/v0.11.0_to_v0.11.1.sql similarity index 51% rename from src/database/v0.11.0_to_v0.11.1.sql rename to src/main/java/database/v0.11.0_to_v0.11.1.sql index 906591012..9033403fc 100644 --- a/src/database/v0.11.0_to_v0.11.1.sql +++ b/src/main/java/database/v0.11.0_to_v0.11.1.sql @@ -2,9 +2,10 @@ USE rap_db; -- 缓存优化,智能判断接口是否应用缓存 ALTER TABLE tb_action - ADD COLUMN disable_cache TINYINT NOT NULL - DEFAULT 0; +ADD COLUMN disable_cache TINYINT NOT NULL + DEFAULT 0; -- 默认先全部disable_cache -UPDATE tb_action SET disable_cache = 1 - WHERE id != 0 \ No newline at end of file +UPDATE tb_action +SET disable_cache = 1 +WHERE id != 0 \ No newline at end of file diff --git a/src/main/java/org/apache/struts2/views/velocity/RapVelocityResult.java b/src/main/java/org/apache/struts2/views/velocity/RapVelocityResult.java new file mode 100644 index 000000000..70f448a7b --- /dev/null +++ b/src/main/java/org/apache/struts2/views/velocity/RapVelocityResult.java @@ -0,0 +1,16 @@ +package org.apache.struts2.views.velocity; + +import org.apache.struts2.dispatcher.VelocityResult; + +public class RapVelocityResult extends VelocityResult { + + private String contentType = "text/html"; + + public void setContentType(String contentType) { + this.contentType = contentType; + } + + protected String getContentType(String templateLocation) { + return contentType; + } +} diff --git a/src/org/apache/struts2/views/velocity/VelocityManager.java b/src/main/java/org/apache/struts2/views/velocity/VelocityManager.java similarity index 97% rename from src/org/apache/struts2/views/velocity/VelocityManager.java rename to src/main/java/org/apache/struts2/views/velocity/VelocityManager.java index ec4322312..ad065659c 100644 --- a/src/org/apache/struts2/views/velocity/VelocityManager.java +++ b/src/main/java/org/apache/struts2/views/velocity/VelocityManager.java @@ -27,6 +27,9 @@ import com.opensymphony.xwork2.util.ValueStack; import com.opensymphony.xwork2.util.logging.Logger; import com.opensymphony.xwork2.util.logging.LoggerFactory; +import com.taobao.rigel.rap.common.config.SystemConstant; +import com.taobao.rigel.rap.common.utils.DateUtils; +import com.taobao.rigel.rap.common.utils.SystemVisitorLog; import org.apache.commons.lang3.StringUtils; import org.apache.struts2.ServletActionContext; import org.apache.struts2.StrutsConstants; @@ -51,43 +54,30 @@ import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; -import java.util.ArrayList; -import java.util.Collections; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.Properties; -import java.util.Set; -import java.util.StringTokenizer; +import java.util.*; /** * Manages the environment for Velocity result types - * */ public class VelocityManager { - private static final Logger LOG = LoggerFactory.getLogger(VelocityManager.class); public static final String STRUTS = "struts"; - private ObjectFactory objectFactory; - public static final String KEY_VELOCITY_STRUTS_CONTEXT = ".KEY_velocity.struts2.context"; - /** * the parent JSP tag */ public static final String PARENT = "parent"; - /** * the current JSP tag */ public static final String TAG = "tag"; - - private VelocityEngine velocityEngine; - + private static final Logger LOG = LoggerFactory.getLogger(VelocityManager.class); /** * A reference to the toolbox manager. */ protected ToolboxManager toolboxManager = null; + private ObjectFactory objectFactory; + private VelocityEngine velocityEngine; private String toolBoxLocation; @@ -103,6 +93,37 @@ public class VelocityManager { private List tagLibraries; private List oldTagLibraries; + private static final String replace(String string, String oldString, String newString) { + if (string == null) { + return null; + } + // If the newString is null, just return the string since there's nothing to replace. + if (newString == null) { + return string; + } + int i = 0; + // Make sure that oldString appears at least once before doing any processing. + if ((i = string.indexOf(oldString, i)) >= 0) { + // Use char []'s, as they are more efficient to deal with. + char[] string2 = string.toCharArray(); + char[] newString2 = newString.toCharArray(); + int oLength = oldString.length(); + StringBuilder buf = new StringBuilder(string2.length); + buf.append(string2, 0, i).append(newString2); + i += oLength; + int j = i; + // Replace all remaining instances of oldString with newString. + while ((i = string.indexOf(oldString, i)) > 0) { + buf.append(string2, j, i - j).append(newString2); + i += oLength; + j = i; + } + buf.append(string2, j, string2.length - j); + return buf.toString(); + } + return string; + } + @Inject public void setObjectFactory(ObjectFactory fac) { this.objectFactory = fac; @@ -127,7 +148,7 @@ public void setContainer(Container container) { /** * @return a reference to the VelocityEngine used by all struts velocity thingies with the exception of - * directly accessed *.vm pages + * directly accessed *.vm pages */ public VelocityEngine getVelocityEngine() { return velocityEngine; @@ -153,16 +174,16 @@ public Context createContext(ValueStack stack, HttpServletRequest req, HttpServl VelocityContext[] chainedContexts = prepareChainedContexts(req, res, stack.getContext()); StrutsVelocityContext context = new StrutsVelocityContext(chainedContexts, stack); Map standardMap = ContextUtil.getStandardContext(stack, req, res); - for (Iterator iterator = standardMap.entrySet().iterator(); iterator.hasNext();) { + for (Iterator iterator = standardMap.entrySet().iterator(); iterator.hasNext(); ) { Map.Entry entry = (Map.Entry) iterator.next(); context.put((String) entry.getKey(), entry.getValue()); } - context.put("utils", new com.taobao.rigel.rap.common.StringUtils()); - context.put("dateUtils", new com.taobao.rigel.rap.common.DateUtils()); - context.put("consts", new com.taobao.rigel.rap.common.SystemConstant()); - context.put("logger", new com.taobao.rigel.rap.common.SystemVisitorLog()); + context.put("utils", new com.taobao.rigel.rap.common.utils.StringUtils()); + context.put("dateUtils", new DateUtils()); + context.put("consts", new SystemConstant()); + context.put("logger", new SystemVisitorLog()); context.put(STRUTS, new VelocityStrutsUtil(velocityEngine, context, stack, req, res)); @@ -361,7 +382,7 @@ public Properties loadConfiguration(ServletContext context) { LOG.debug("Initializing Velocity with the following properties ..."); for (Iterator iter = properties.keySet().iterator(); - iter.hasNext();) { + iter.hasNext(); ) { String key = (String) iter.next(); String value = properties.getProperty(key); @@ -424,9 +445,6 @@ protected void initToolbox(ServletContext context) { } } - - - /** *

    * Instantiates a new VelocityEngine. @@ -569,37 +587,6 @@ private void addDirective(StringBuilder sb, Class clazz) { sb.append(clazz.getName()).append(","); } - private static final String replace(String string, String oldString, String newString) { - if (string == null) { - return null; - } - // If the newString is null, just return the string since there's nothing to replace. - if (newString == null) { - return string; - } - int i = 0; - // Make sure that oldString appears at least once before doing any processing. - if ((i = string.indexOf(oldString, i)) >= 0) { - // Use char []'s, as they are more efficient to deal with. - char[] string2 = string.toCharArray(); - char[] newString2 = newString.toCharArray(); - int oLength = oldString.length(); - StringBuilder buf = new StringBuilder(string2.length); - buf.append(string2, 0, i).append(newString2); - i += oLength; - int j = i; - // Replace all remaining instances of oldString with newString. - while ((i = string.indexOf(oldString, i)) > 0) { - buf.append(string2, j, i - j).append(newString2); - i += oLength; - j = i; - } - buf.append(string2, j, string2.length - j); - return buf.toString(); - } - return string; - } - /** * @return the velocityProperties */ diff --git a/src/main/resources/com/taobao/rigel/rap/account/applicationContext.xml b/src/main/resources/com/taobao/rigel/rap/account/applicationContext.xml new file mode 100644 index 000000000..9696f8505 --- /dev/null +++ b/src/main/resources/com/taobao/rigel/rap/account/applicationContext.xml @@ -0,0 +1,17 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/main/resources/com/taobao/rigel/rap/account/mapping/Notification.hbm.xml b/src/main/resources/com/taobao/rigel/rap/account/mapping/Notification.hbm.xml new file mode 100644 index 000000000..fd20174d1 --- /dev/null +++ b/src/main/resources/com/taobao/rigel/rap/account/mapping/Notification.hbm.xml @@ -0,0 +1,31 @@ + + + + + + + + + + + + + 项目相关ID + + + + + 项目相关ID + + + + + 创建时间 + + + + + + diff --git a/src/main/resources/com/taobao/rigel/rap/account/mapping/Role.hbm.xml b/src/main/resources/com/taobao/rigel/rap/account/mapping/Role.hbm.xml new file mode 100644 index 000000000..6f9276cc7 --- /dev/null +++ b/src/main/resources/com/taobao/rigel/rap/account/mapping/Role.hbm.xml @@ -0,0 +1,12 @@ + + + + + + + + + + diff --git a/src/main/resources/com/taobao/rigel/rap/account/mapping/User.hbm.xml b/src/main/resources/com/taobao/rigel/rap/account/mapping/User.hbm.xml new file mode 100644 index 000000000..f927bcbab --- /dev/null +++ b/src/main/resources/com/taobao/rigel/rap/account/mapping/User.hbm.xml @@ -0,0 +1,62 @@ + + + + + + + + + + + 工号 + + + + + + + + + 是否启用提示 + + + + + 创建时间 + + + + + 最近登录时间 + + + + + 锁定状态 + + + + + 错误登录次数 + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/resources/com/taobao/rigel/rap/account/web/action/struts.xml b/src/main/resources/com/taobao/rigel/rap/account/web/action/struts.xml new file mode 100644 index 000000000..d325d3abf --- /dev/null +++ b/src/main/resources/com/taobao/rigel/rap/account/web/action/struts.xml @@ -0,0 +1,86 @@ + + + + + + /bcom/json.cb.vm + + + /account/login.vm + + + /bcom/json.cb.vm + + + + index + /org + + /account/login.vm + + + /platform/home.vm + + + /account/register.vm + + + /platform/home.vm + /account/register.vm + + + /account/myAccount.vm + /account/login.vm + + + /account/mySetting.vm + /account/login.vm + + + + /account/myAccount.vm + + + /account/myAccount.vm + + + /bcom/json.cb.vm + + + /bcom/json.cb.vm + + + /bcom/json.cb.vm + + + /bcom/json.cb.vm + + + /bcom/json.cb.vm + + + + + /bcom/json.cb.vm + + + \ No newline at end of file diff --git a/src/main/resources/com/taobao/rigel/rap/api/applicationContext.xml b/src/main/resources/com/taobao/rigel/rap/api/applicationContext.xml new file mode 100644 index 000000000..c639bf15f --- /dev/null +++ b/src/main/resources/com/taobao/rigel/rap/api/applicationContext.xml @@ -0,0 +1,10 @@ + + + + + + + + \ No newline at end of file diff --git a/src/main/resources/com/taobao/rigel/rap/api/web/action/struts.xml b/src/main/resources/com/taobao/rigel/rap/api/web/action/struts.xml new file mode 100644 index 000000000..c3dc54ccc --- /dev/null +++ b/src/main/resources/com/taobao/rigel/rap/api/web/action/struts.xml @@ -0,0 +1,31 @@ + + + + + + + + + /bcom/json.cb.vm + + + /bcom/json.cb.vm + + + /bcom/json.cb.vm + + + /bcom/json.cb.vm + + + /bcom/json.cb.vm + + + diff --git a/src/main/resources/com/taobao/rigel/rap/common/applicationContext.xml b/src/main/resources/com/taobao/rigel/rap/common/applicationContext.xml new file mode 100644 index 000000000..a0dc63f47 --- /dev/null +++ b/src/main/resources/com/taobao/rigel/rap/common/applicationContext.xml @@ -0,0 +1,7 @@ + + + + + \ No newline at end of file diff --git a/src/main/resources/com/taobao/rigel/rap/mock/applicationContext.xml b/src/main/resources/com/taobao/rigel/rap/mock/applicationContext.xml new file mode 100644 index 000000000..96e1e3661 --- /dev/null +++ b/src/main/resources/com/taobao/rigel/rap/mock/applicationContext.xml @@ -0,0 +1,12 @@ + + + + + + + + + + \ No newline at end of file diff --git a/src/main/resources/com/taobao/rigel/rap/mock/mapping/Rule.hbm.xml b/src/main/resources/com/taobao/rigel/rap/mock/mapping/Rule.hbm.xml new file mode 100644 index 000000000..41e658f5d --- /dev/null +++ b/src/main/resources/com/taobao/rigel/rap/mock/mapping/Rule.hbm.xml @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/main/resources/com/taobao/rigel/rap/mock/web/action/struts.xml b/src/main/resources/com/taobao/rigel/rap/mock/web/action/struts.xml new file mode 100644 index 000000000..c5cde8941 --- /dev/null +++ b/src/main/resources/com/taobao/rigel/rap/mock/web/action/struts.xml @@ -0,0 +1,139 @@ + + + + + + + + + + /bcom/isOkWithNum.cb.vm + + + + + /bcom/isOkWithNum.cb.vm + + + + + /bcom/contentWithoutEscape.cb.vm + + /bcom/contentWithoutEscape.cb.vm + + + application/json + /bcom/contentWithoutEscape.cb.vm + + + + + /bcom/contentWithoutEscape.cb.vm + + /bcom/contentWithoutEscape.cb.vm + + + application/json + /bcom/contentWithoutEscape.cb.vm + + + + + /bcom/contentWithoutEscape.cb.vm + + /bcom/contentWithoutEscape.cb.vm + + + application/json + /bcom/contentWithoutEscape.cb.vm + + + + + /bcom/contentWithoutEscape.cb.vm + + /bcom/contentWithoutEscape.cb.vm + + + application/json + /bcom/contentWithoutEscape.cb.vm + + + + + /bcom/contentWithoutEscape.cb.vm + + /bcom/contentWithoutEscape.cb.vm + + + application/json + /bcom/contentWithoutEscape.cb.vm + + + + + /bcom/contentWithoutEscape.cb.vm + + /bcom/contentWithoutEscape.cb.vm + + + application/json + /bcom/contentWithoutEscape.cb.vm + + + + + /bcom/contentWithoutEscape.cb.vm + + /bcom/contentWithoutEscape.cb.vm + + + application/json + /bcom/contentWithoutEscape.cb.vm + + + + + + text/javascript + /mock/createPluginScript.vm + + + + + /bcom/json.cb.vm + + + + + /bcom/contentWithoutEscape.cb.vm + + + + + /bcom/contentWithoutEscape.cb.vm + + /bcom/contentWithoutEscape.cb.vm + + + application/json + /bcom/contentWithoutEscape.cb.vm + + + + \ No newline at end of file diff --git a/src/main/resources/com/taobao/rigel/rap/organization/applicationContext.xml b/src/main/resources/com/taobao/rigel/rap/organization/applicationContext.xml new file mode 100644 index 000000000..fb2e1262d --- /dev/null +++ b/src/main/resources/com/taobao/rigel/rap/organization/applicationContext.xml @@ -0,0 +1,14 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/main/resources/com/taobao/rigel/rap/organization/mapping/Corporation.hbm.xml b/src/main/resources/com/taobao/rigel/rap/organization/mapping/Corporation.hbm.xml new file mode 100644 index 000000000..b8872873f --- /dev/null +++ b/src/main/resources/com/taobao/rigel/rap/organization/mapping/Corporation.hbm.xml @@ -0,0 +1,31 @@ + + + + + + + + + + + + + + + + + creator id + + + + + + + + access type + + + + \ No newline at end of file diff --git a/src/main/resources/com/taobao/rigel/rap/organization/mapping/Group.hbm.xml b/src/main/resources/com/taobao/rigel/rap/organization/mapping/Group.hbm.xml new file mode 100644 index 000000000..692296fee --- /dev/null +++ b/src/main/resources/com/taobao/rigel/rap/organization/mapping/Group.hbm.xml @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/main/resources/com/taobao/rigel/rap/organization/mapping/ProductionLine.hbm.xml b/src/main/resources/com/taobao/rigel/rap/organization/mapping/ProductionLine.hbm.xml new file mode 100644 index 000000000..a65047078 --- /dev/null +++ b/src/main/resources/com/taobao/rigel/rap/organization/mapping/ProductionLine.hbm.xml @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/com/taobao/rigel/rap/organization/web/action/struts.xml b/src/main/resources/com/taobao/rigel/rap/organization/web/action/struts.xml similarity index 96% rename from src/com/taobao/rigel/rap/organization/web/action/struts.xml rename to src/main/resources/com/taobao/rigel/rap/organization/web/action/struts.xml index 7166ebcc9..bc6d6d7b3 100644 --- a/src/com/taobao/rigel/rap/organization/web/action/struts.xml +++ b/src/main/resources/com/taobao/rigel/rap/organization/web/action/struts.xml @@ -33,10 +33,12 @@ /org/team/manage.vm - + /bcom/json.cb.vm - + /bcom/json.cb.vm diff --git a/src/main/resources/com/taobao/rigel/rap/platform/applicationContext.xml b/src/main/resources/com/taobao/rigel/rap/platform/applicationContext.xml new file mode 100644 index 000000000..00546a7c4 --- /dev/null +++ b/src/main/resources/com/taobao/rigel/rap/platform/applicationContext.xml @@ -0,0 +1,10 @@ + + + + + + + + + \ No newline at end of file diff --git a/src/com/taobao/rigel/rap/platform/web/action/struts.xml b/src/main/resources/com/taobao/rigel/rap/platform/web/action/struts.xml similarity index 58% rename from src/com/taobao/rigel/rap/platform/web/action/struts.xml rename to src/main/resources/com/taobao/rigel/rap/platform/web/action/struts.xml index 6759ba5b5..ef25d4cad 100644 --- a/src/com/taobao/rigel/rap/platform/web/action/struts.xml +++ b/src/main/resources/com/taobao/rigel/rap/platform/web/action/struts.xml @@ -1,14 +1,14 @@ + "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN" + "http://struts.apache.org/dtds/struts-2.0.dtd"> - - - /platform/home.vm + + + /platform/home.vm - /platform/test.vm + /platform/test.vm /platform/log.vm @@ -16,8 +16,9 @@ /platform/monitor.vm - + /bcom/json.cb.vm - + diff --git a/src/main/resources/com/taobao/rigel/rap/project/applicationContext.xml b/src/main/resources/com/taobao/rigel/rap/project/applicationContext.xml new file mode 100644 index 000000000..898a55ecd --- /dev/null +++ b/src/main/resources/com/taobao/rigel/rap/project/applicationContext.xml @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/main/resources/com/taobao/rigel/rap/project/mapping/Action.hbm.xml b/src/main/resources/com/taobao/rigel/rap/project/mapping/Action.hbm.xml new file mode 100644 index 000000000..772179306 --- /dev/null +++ b/src/main/resources/com/taobao/rigel/rap/project/mapping/Action.hbm.xml @@ -0,0 +1,48 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/main/resources/com/taobao/rigel/rap/project/mapping/Module.hbm.xml b/src/main/resources/com/taobao/rigel/rap/project/mapping/Module.hbm.xml new file mode 100644 index 000000000..e0f568f4b --- /dev/null +++ b/src/main/resources/com/taobao/rigel/rap/project/mapping/Module.hbm.xml @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/resources/com/taobao/rigel/rap/project/mapping/Page.hbm.xml b/src/main/resources/com/taobao/rigel/rap/project/mapping/Page.hbm.xml new file mode 100644 index 000000000..215c26182 --- /dev/null +++ b/src/main/resources/com/taobao/rigel/rap/project/mapping/Page.hbm.xml @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/resources/com/taobao/rigel/rap/project/mapping/Parameter.hbm.xml b/src/main/resources/com/taobao/rigel/rap/project/mapping/Parameter.hbm.xml new file mode 100644 index 000000000..3271bafdc --- /dev/null +++ b/src/main/resources/com/taobao/rigel/rap/project/mapping/Parameter.hbm.xml @@ -0,0 +1,43 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/main/resources/com/taobao/rigel/rap/project/mapping/Project.hbm.xml b/src/main/resources/com/taobao/rigel/rap/project/mapping/Project.hbm.xml new file mode 100644 index 000000000..f6f23fe76 --- /dev/null +++ b/src/main/resources/com/taobao/rigel/rap/project/mapping/Project.hbm.xml @@ -0,0 +1,89 @@ + + + + + + + + + + + 项目名称 + + + + + 项目相关ID + + + + + 分组ID + + + + + MOCK调用次数 + + + + + 当前版本 + + + + + 创建时间 + + + + + 更新时间 + + + + + 项目简介 + + + + + 共享模式 + + + + + 项目数据(json),用于VSS同步模式 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/resources/com/taobao/rigel/rap/project/web/action/struts.xml b/src/main/resources/com/taobao/rigel/rap/project/web/action/struts.xml new file mode 100644 index 000000000..66f82a312 --- /dev/null +++ b/src/main/resources/com/taobao/rigel/rap/project/web/action/struts.xml @@ -0,0 +1,37 @@ + + + + + + + + + /bcom/json.cb.vm + + + + /bcom/json.cb.vm + + + + /bcom/json.cb.vm + + + + /bcom/json.cb.vm + + + + /bcom/json.cb.vm + + + + + diff --git a/src/main/resources/com/taobao/rigel/rap/tester/web/action/struts.xml b/src/main/resources/com/taobao/rigel/rap/tester/web/action/struts.xml new file mode 100644 index 000000000..2bdaaf642 --- /dev/null +++ b/src/main/resources/com/taobao/rigel/rap/tester/web/action/struts.xml @@ -0,0 +1,23 @@ + + + + + + + + /tester/pageTester.vm + + + /bcom/isOk.cb.vm + + + /bcom/content.cb.vm + + + + diff --git a/src/main/resources/com/taobao/rigel/rap/workspace/applicationContext.xml b/src/main/resources/com/taobao/rigel/rap/workspace/applicationContext.xml new file mode 100644 index 000000000..01e963521 --- /dev/null +++ b/src/main/resources/com/taobao/rigel/rap/workspace/applicationContext.xml @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + + + + resource.loader=class + class.resource.loader.class=org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader + + + + + + \ No newline at end of file diff --git a/src/main/resources/com/taobao/rigel/rap/workspace/mapping/CheckIn.hbm.xml b/src/main/resources/com/taobao/rigel/rap/workspace/mapping/CheckIn.hbm.xml new file mode 100644 index 000000000..7a641c0bc --- /dev/null +++ b/src/main/resources/com/taobao/rigel/rap/workspace/mapping/CheckIn.hbm.xml @@ -0,0 +1,35 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/main/resources/com/taobao/rigel/rap/workspace/mapping/Workspace.hbm.xml b/src/main/resources/com/taobao/rigel/rap/workspace/mapping/Workspace.hbm.xml new file mode 100644 index 000000000..19d12b1f9 --- /dev/null +++ b/src/main/resources/com/taobao/rigel/rap/workspace/mapping/Workspace.hbm.xml @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/main/resources/com/taobao/rigel/rap/workspace/web/action/struts.xml b/src/main/resources/com/taobao/rigel/rap/workspace/web/action/struts.xml new file mode 100644 index 000000000..74771d937 --- /dev/null +++ b/src/main/resources/com/taobao/rigel/rap/workspace/web/action/struts.xml @@ -0,0 +1,70 @@ + + + + + + + + + /workspace/myWorkspace.vm + + + /bcom/json.cb.vm + + + /bcom/json.cb.vm + + + /bcom/json.cb.vm + + + + /bcom/json.cb.vm + + + /bcom/json.cb.vm + + + + /bcom/json.cb.vm + + + /bcom/json.cb.vm + + + + /bcom/json.cb.vm + + + + attachment;filename=export.html + text/html + fileInputStream + 1024 + + + + + diff --git a/src/main/resources/database/initialize.sql b/src/main/resources/database/initialize.sql new file mode 100644 index 000000000..1cd841956 --- /dev/null +++ b/src/main/resources/database/initialize.sql @@ -0,0 +1,562 @@ +CREATE DATABASE IF NOT EXISTS rap_db + DEFAULT CHARSET utf8 + COLLATE utf8_general_ci; + +USE rap_db; + + +/************************************************** + * * + * account module * + * * + **************************************************/ + + +/** + * user table + */ +CREATE TABLE tb_user +( + id INT(10) AUTO_INCREMENT NOT NULL + PRIMARY KEY, + account VARCHAR(32) NOT NULL + COMMENT '账户名 account name', + password VARCHAR(128) NOT NULL + COMMENT '密码 password', + name VARCHAR(256) NOT NULL + COMMENT '名字/昵称 name/nickname', + email VARCHAR(256) NOT NULL + COMMENT 'email', + create_date TIMESTAMP NOT NULL + COMMENT '创建日期 create date' + DEFAULT now(), + is_locked_out INT(1) NOT NULL + COMMENT '用户是否锁定 is the user locked out' + DEFAULT 0, + is_hint_enabled INT(1) NOT NULL + COMMENT '是否开启新手引导 is user hint enabled' + DEFAULT 1, + last_login_date DATETIME NOT NULL + COMMENT '最近登录 last login date', + incorrect_login_attempt INT(10) NOT NULL + COMMENT '错误登录次数,登录成功后会重置为0 count of incorrect login attempts, will be set to 0 after any succesful login' + DEFAULT 0, + realname VARCHAR(128) NOT NULL + COMMENT '真实姓名' + DEFAULT '', + emp_id VARCHAR(45) NULL + COMMENT '工号,可选', + mock_num INT(10) NOT NULL + COMMENT 'mock次数,用于记录该用户所创建的接口被调用的mock次数。 mock num, used for record mock API invokation count' + DEFAULT 0 +) + ENGINE = InnoDB + DEFAULT CHARSET = utf8; + +/** + * role table + * roles instruction: + * user - every registered shuold have this role + * rd - research and development engineering + * qa - quality engineering + * pm - project manager + * op - operation manager + * admin - administrator + * god - super admin + */ +CREATE TABLE tb_role +( + id INT(10) AUTO_INCREMENT NOT NULL + PRIMARY KEY, + name VARCHAR(16) NOT NULL + COMMENT '角色名称 role name' +) + ENGINE = InnoDB + DEFAULT CHARSET = utf8; + +/** + * user role table + */ +CREATE TABLE tb_role_and_user +( + user_id INT(10) NOT NULL, + role_id INT(10) NOT NULL, + + PRIMARY KEY (user_id, role_id), + FOREIGN KEY (user_id) REFERENCES tb_user (id), + FOREIGN KEY (role_id) REFERENCES tb_role (id) +) + ENGINE = InnoDB + DEFAULT CHARSET = utf8; + + +/************************************************** + * * + * project module * + * * + **************************************************/ + + + +/** + * parameter table + */ +CREATE TABLE tb_parameter +( + id INT(10) AUTO_INCREMENT NOT NULL + PRIMARY KEY, + name VARCHAR(256) NULL + COMMENT '参数含义 parameter name', + identifier VARCHAR(256) NULL + COMMENT '变量名/参数标识符 parameter identifier', + data_type VARCHAR(32) NULL + COMMENT '数据类型 data type', + remark TEXT NULL + COMMENT '备注/mock数据等 remark/mock data', + expression VARCHAR(128) NULL + COMMENT '备用字段:表达式 backup column:expression', + mock_data TEXT NULL + COMMENT '备用字段:mock数据 backup column:mock data' +) + ENGINE = InnoDB + DEFAULT CHARSET = utf8; + +/** + * project table + * workspace_mode 1-vss(default) 2-svn + * stage 1-design 2-developing 3-debug + */ +CREATE TABLE tb_project +( + id INT(10) AUTO_INCREMENT NOT NULL + PRIMARY KEY, + `version` VARCHAR(128) NOT NULL + COMMENT '版本号 version no.' + DEFAULT '0.0.0.1', + name VARCHAR(128) NOT NULL + COMMENT '项目名称 project name', + create_date TIMESTAMP NOT NULL + COMMENT '创建日期 create date' + DEFAULT now(), + user_id INT(10) NOT NULL + COMMENT '创建人ID, project author id', + introduction TEXT NULL + COMMENT '项目描述 project introduction', + workspace_mode INT(10) NOT NULL + COMMENT '工作区提交模式(类VSS or SVN),暂时弃用了。 Workspace submit mode, deprecated.' + DEFAULT 1, + stage INT(10) NOT NULL + COMMENT '项目阶段,暂时废弃;project stage, temply deprecated. 1-design 2-developing 3-debug' + DEFAULT 1, + project_data LONGTEXT NULL + COMMENT '项目JSON数据,存放当前最新的版本。 project JSON data, saved the newest version of the project', + group_id INT(10) NULL + COMMENT '分组ID group id', + related_ids VARCHAR(128) NOT NULL + COMMENT '路由ID,用于指定与哪些项目共享mock数据; router id, used for specify sharing data with which projects.' + DEFAULT '', + update_time DATETIME NOT NULL + COMMENT '更新时间 update time', + mock_num INT NOT NULL + COMMENT 'mock次数 mock num' + DEFAULT 0, + access_type TINYINT NOT NULL + COMMENT '权限控制, 10普通, 0私有' + DEFAULT 10, + + FOREIGN KEY (user_id) REFERENCES tb_user (id) +) + ENGINE = InnoDB + DEFAULT CHARSET = utf8; + +/** + * user list and user table + * used for creating multiple to multiple mapping + * access_level: + * 1 - read + * 2 - read&write + * 3 - read&write&manage + */ +CREATE TABLE tb_project_and_user +( + project_id INT(10) NOT NULL, + user_id INT(10) NOT NULL, + access_level INT NOT NULL + DEFAULT 1, + + PRIMARY KEY (project_id, user_id), + FOREIGN KEY (project_id) REFERENCES tb_project (id), + FOREIGN KEY (user_id) REFERENCES tb_user (id) +) + ENGINE = InnoDB + DEFAULT CHARSET = utf8; + +/** + * module table + */ +CREATE TABLE tb_module +( + id INT(10) AUTO_INCREMENT NOT NULL + PRIMARY KEY, + project_id INT(10) NOT NULL, + name VARCHAR(256) NOT NULL, + introduction VARCHAR(128) NULL, + + FOREIGN KEY (project_id) REFERENCES tb_project (id) +) + ENGINE = InnoDB + DEFAULT CHARSET = utf8; + +/** + * page table + */ +CREATE TABLE tb_page +( + id INT(10) AUTO_INCREMENT NOT NULL + PRIMARY KEY, + name VARCHAR(56) NOT NULL, + module_id INT(10) NOT NULL, + introduction TEXT NULL, + template VARCHAR(128) NULL, + + FOREIGN KEY (module_id) REFERENCES tb_module (id) +) + ENGINE = InnoDB + DEFAULT CHARSET = utf8; + +/** + * action table + * request_type: + * 1 - get + * 2 - post + * 3 - ajax get + * 4 - ajax post + */ +CREATE TABLE tb_action +( + id INT(10) AUTO_INCREMENT NOT NULL + PRIMARY KEY, + name VARCHAR(256) NOT NULL, + description TEXT NULL, + + /* request block */ + request_type INT NOT NULL + COMMENT '请求类型get/post/put/delete等等 request type' + DEFAULT 1, /** request_type = 99, mount type **/ + request_url TEXT NULL, + + disable_cache TINYINT NOT NULL + COMMENT '禁用Mock缓存 disable mock cache' + DEFAULT 0, + + /* response block */ + response_template TEXT NULL + COMMENT '响应模板地址, 暂时弃用。 response template address, temply deprecated.' + +) + ENGINE = InnoDB + DEFAULT CHARSET = utf8; + +/** + * action and page table + * used for creating multiple to multiple mapping + */ +CREATE TABLE tb_action_and_page +( + action_id INT(10) NOT NULL, + page_id INT(10) NOT NULL, + + FOREIGN KEY (action_id) REFERENCES tb_action (id), + FOREIGN KEY (page_id) REFERENCES tb_page (id), + PRIMARY KEY (action_id, page_id) +) + ENGINE = InnoDB + DEFAULT CHARSET = utf8; + + +/** + * parameter and parameter mapping + * complex_parameter has so many parameters(List or Map) + */ +CREATE TABLE tb_complex_parameter_list_mapping +( + complex_parameter_id INT(10) NOT NULL, + parameter_id INT(10) NOT NULL, + + PRIMARY KEY (complex_parameter_id, parameter_id), + FOREIGN KEY (complex_parameter_id) REFERENCES tb_parameter (id), + FOREIGN KEY (parameter_id) REFERENCES tb_parameter (id) +) + ENGINE = InnoDB + DEFAULT CHARSET = utf8; + +/** + * parameter and action's request mapping + */ +CREATE TABLE tb_request_parameter_list_mapping +( + action_id INT(10) NOT NULL, + parameter_id INT(10) NOT NULL, + + PRIMARY KEY (action_id, parameter_id), + FOREIGN KEY (action_id) REFERENCES tb_action (id), + FOREIGN KEY (parameter_id) REFERENCES tb_parameter (id) +) + ENGINE = InnoDB + DEFAULT CHARSET = utf8; + +/** + * parameter and action's response mapping + */ +CREATE TABLE tb_response_parameter_list_mapping +( + action_id INT(10) NOT NULL, + parameter_id INT(10) NOT NULL, + + PRIMARY KEY (action_id, parameter_id), + FOREIGN KEY (action_id) REFERENCES tb_action (id), + FOREIGN KEY (parameter_id) REFERENCES tb_parameter (id) +) + ENGINE = InnoDB + DEFAULT CHARSET = utf8; + + +/************************************************** + * * + * workspace module * + * * + **************************************************/ + + +/** + * workspace, deprecated 工作区,暂时未使用 + */ +CREATE TABLE tb_workspace +( + id INT(10) AUTO_INCREMENT NOT NULL + PRIMARY KEY, + project_id INT(10) NOT NULL, + user_id INT NOT NULL, + create_date TIMESTAMP NOT NULL + DEFAULT now(), + update_date DATETIME NOT NULL, + project_data LONGTEXT NOT NULL, + project_data_original LONGTEXT NOT NULL, + + FOREIGN KEY (project_id) REFERENCES tb_project (id), + FOREIGN KEY (user_id) REFERENCES tb_user (id) +) + ENGINE = InnoDB + DEFAULT CHARSET = utf8; + +/** + * workspace save, deprecated 工作区保存草稿,暂时未使用 + */ +CREATE TABLE tb_workspace_save +( + id INT(10) AUTO_INCREMENT NOT NULL + PRIMARY KEY, + workspace_id INT(10) NOT NULL, + update_date DATETIME NOT NULL, + project_data LONGTEXT NOT NULL, + + FOREIGN KEY (workspace_id) REFERENCES tb_workspace (id) +) + ENGINE = InnoDB + DEFAULT CHARSET = utf8; + +/** + * check in table + * every API document submit saved here, used for version control. + * 每一次提交记录在这里,用于版本管理和回滚控制 + * workspaceMode 1-VSS 2-SVN + */ +CREATE TABLE tb_check_in +( + id INT(10) AUTO_INCREMENT NOT NULL + PRIMARY KEY, + create_date TIMESTAMP NOT NULL + DEFAULT now(), + tag VARCHAR(128) NULL + COMMENT 'tag标签 暂时未使用 deprecated', + user_id INT(10) NOT NULL + COMMENT '提交人 submit user id', + project_id INT(10) NOT NULL + COMMENT '提交的项目ID submit project id', + description TEXT NULL + COMMENT '提交描述 submit description', + version VARCHAR(128) NOT NULL + COMMENT '版本号 version no.', + project_data LONGTEXT NOT NULL + COMMENT '项目JSON数据 project json data', + workspace_mode INT(10) NOT NULL + COMMENT '工作区模式(弃用) workspace mode(deprecated)', + log TEXT NULL + COMMENT '更新日志,用于存储与最近一个版本的对比差异。暂时未使用。update log, used for calculate versions differences. Deprecated.', + + FOREIGN KEY (user_id) REFERENCES tb_user (id), + FOREIGN KEY (project_id) REFERENCES tb_project (id) +) + ENGINE = InnoDB + DEFAULT CHARSET = utf8; + +/** + * user settings table + * 用户配置表 + */ +CREATE TABLE tb_user_settings +( + user_id INT(10) NOT NULL, + `key` VARCHAR(128) NOT NULL + COMMENT '配置KEY config key', + `value` VARCHAR(128) NOT NULL + COMMENT '配置VALUE config value', + + PRIMARY KEY (user_id, `key`), + FOREIGN KEY (user_id) REFERENCES tb_user (id) +) + ENGINE = InnoDB + DEFAULT CHARSET = utf8; + +/** + * user notification table + * 用户通知表 + */ + +CREATE TABLE tb_notification +( + id INT(10) AUTO_INCREMENT NOT NULL + PRIMARY KEY, + user_id INT(10) NOT NULL + COMMENT '接受通知的用户id; user id to be notified.', + target_user_id INT(10) NOT NULL + COMMENT '上下文用户id; context user id', + type_id SMALLINT NOT NULL + COMMENT '1-文档修改,2-被加入新项目', + param1 VARCHAR(128) NULL + COMMENT '1,2-项目id', + param2 VARCHAR(128) NULL + COMMENT ' 1,2-项目名称', + param3 TEXT NULL + COMMENT '备用预留 reserved', + create_time TIMESTAMP NOT NULL + COMMENT '创建时间 create time' + DEFAULT now(), + + is_read SMALLINT NOT NULL + COMMENT '是否已读 is notification read' + DEFAULT 0, + + FOREIGN KEY (user_id) REFERENCES tb_user (id), + FOREIGN KEY (target_user_id) REFERENCES tb_user (id) +) + ENGINE = InnoDB + DEFAULT CHARSET = utf8; + +/** + * corporation table + * 公司表 + */ +CREATE TABLE tb_corporation +( + id INT(10) AUTO_INCREMENT NOT NULL + PRIMARY KEY, + name VARCHAR(256) NOT NULL, + logo_url VARCHAR(256) NULL, + user_id INT(10) NULL, + access_type TINYINT NOT NULL + COMMENT '权限控制, 10普通, 20公开' + DEFAULT 10, + `desc` TEXT NOT NULL + COMMENT '备注', + + FOREIGN KEY (user_id) REFERENCES tb_user (id) +) + ENGINE = InnoDB + DEFAULT CHARSET = utf8; + + +/** + * product line table + * 生产线表 + */ +CREATE TABLE tb_production_line +( + id INT(10) AUTO_INCREMENT NOT NULL + PRIMARY KEY, + name VARCHAR(256) NOT NULL, + project_num INT(10) NOT NULL + DEFAULT 0, + corporation_id INT(10) NOT NULL, + user_id INT(10) NOT NULL, + + FOREIGN KEY (user_id) REFERENCES tb_user (id), + FOREIGN KEY (corporation_id) REFERENCES tb_corporation (id) +) + ENGINE = InnoDB + DEFAULT CHARSET = utf8; + +/** + * project group table + * 项目分组表 + */ +CREATE TABLE tb_group +( + id INT(10) AUTO_INCREMENT NOT NULL + PRIMARY KEY, + name VARCHAR(256) NOT NULL, + production_line_id INT(10) NOT NULL, + user_id INT(10) NOT NULL, + + FOREIGN KEY (user_id) REFERENCES tb_user (id), + FOREIGN KEY (production_line_id) REFERENCES tb_production_line (id) +) + ENGINE = InnoDB + DEFAULT CHARSET = utf8; + +/** + * 规则表,存储通过Open API设置的Mock规则 + * Stored mock rules set by Open API + */ +CREATE TABLE tb_rule ( + action_id INT(10) NOT NULL + PRIMARY KEY, + rules TEXT NOT NULL, -- JSON规则 + update_time DATETIME NOT NULL + DEFAULT NOW(), -- 最近更新时间 + + FOREIGN KEY (action_id) REFERENCES tb_action (id) +) + ENGINE = InnoDB + DEFAULT CHARSET = utf8; + +CREATE TABLE tb_corporation_and_user +( + user_id INT(10) NOT NULL, + corporation_id INT(10) NOT NULL, + role_id INT(10) NOT NULL, + + PRIMARY KEY (user_id, corporation_id), + FOREIGN KEY (user_id) REFERENCES tb_user (id), + FOREIGN KEY (corporation_id) REFERENCES tb_corporation (id), + FOREIGN KEY (role_id) REFERENCES tb_role (id) +) + ENGINE = InnoDB + DEFAULT CHARSET = utf8; + + +-- required base data +INSERT INTO tb_role (name) VALUES ('god'); +INSERT INTO tb_role (name) VALUES ('admin'); +INSERT INTO tb_role (name) VALUES ('user'); +-- removed unused qa/pm/rd roles + + +INSERT INTO tb_user (account, password, email, create_date, last_login_date, name) VALUES + ('admin', 'RESERVED', 'admin@example.com', NOW(), NOW(), 'admin'); + +INSERT INTO tb_role_and_user (user_id, role_id) VALUES (1, 1); + +-- INSERT INTO tb_corporation (name, logo_url, user_id) VALUES ('MyTeam', 'empty', 1); +-- 新版RAP可以自建团队,不需要插入默认团队了。 +-- RAP v0.11.5+ users can create teams by their own, so there's no need to set default team. diff --git a/src/main/resources/database/scripts.sql b/src/main/resources/database/scripts.sql new file mode 100644 index 000000000..3f0e58923 --- /dev/null +++ b/src/main/resources/database/scripts.sql @@ -0,0 +1,56 @@ +-- recent projects + +SELECT + p.name projectName, + u.name userName, + p.create_date projectCreateTime, + p.introduction +FROM tb_project p + JOIN tb_user u ON p.user_id = u.id +ORDER BY p.id DESC + +-- recent users + +SELECT * +FROM tb_user +ORDER BY id DESC + +-- counters +SELECT COUNT(*) userNum +FROM tb_user; +SELECT COUNT(*) projectNum +FROM tb_project; + + +-- counting projects (actions >= 5) +SELECT + p.id, + p.name, + COUNT(a.id) +FROM tb_project p + JOIN tb_module m ON m.project_id = p.id + JOIN tb_page p2 ON p2.module_id = m.id + JOIN tb_action_and_page ap ON ap.page_id = p2.id + JOIN tb_action a ON a.id = ap.action_id +GROUP BY p.id +HAVING COUNT(a.id) > 5 +ORDER BY count(a.id) DESC + + +-- search request_url +SELECT + a.name actionName, + m.project_id projectId +FROM tb_action a + JOIN tb_action_and_page ap ON ap.action_id = a.id + JOIN tb_page p ON p.id = ap.page_id + JOIN tb_module m ON m.id = p.module_id +WHERE request_url LIKE '%key%' + +-- search organization info by projectId +SELECT CONCAT(c.name, '-', pl.name, '-', g.name, '-', p.name) AS info +FROM tb_project p + JOIN tb_group g ON g.id = p.group_id + JOIN tb_production_line pl ON pl.id = g.production_line_id + JOIN tb_corporation c ON c.id = pl.corporation_id +WHERE p.id = {projectId} \ No newline at end of file diff --git a/src/main/resources/database/v0.11.0_to_v0.11.1.sql b/src/main/resources/database/v0.11.0_to_v0.11.1.sql new file mode 100644 index 000000000..9033403fc --- /dev/null +++ b/src/main/resources/database/v0.11.0_to_v0.11.1.sql @@ -0,0 +1,11 @@ +USE rap_db; + +-- 缓存优化,智能判断接口是否应用缓存 +ALTER TABLE tb_action +ADD COLUMN disable_cache TINYINT NOT NULL + DEFAULT 0; + +-- 默认先全部disable_cache +UPDATE tb_action +SET disable_cache = 1 +WHERE id != 0 \ No newline at end of file diff --git a/src/main/resources/ehcache.xml b/src/main/resources/ehcache.xml new file mode 100644 index 000000000..7456841eb --- /dev/null +++ b/src/main/resources/ehcache.xml @@ -0,0 +1,14 @@ + + + + + + + \ No newline at end of file diff --git a/src/main/resources/hibernate.cfg.xml b/src/main/resources/hibernate.cfg.xml new file mode 100644 index 000000000..9fe49db7b --- /dev/null +++ b/src/main/resources/hibernate.cfg.xml @@ -0,0 +1,141 @@ + + + + + + + *Mgr + *Service + *Proxy + + + + + transactionInterceptor + + + + + + + + + + + + + + + + + classpath:/mysql.local.properties + + + + + + + ${jdbc.driverClassName} + + + ${jdbc.url} + + + ${jdbc.username} + + + ${jdbc.password} + + + 5 + + + 30 + + + 10 + + + 60 + + + 60 + + + 5 + + + 0 + + + 1000 + + + 30 + + + true + + + + + + + + com/taobao/rigel/rap/project/mapping/Project.hbm.xml + com/taobao/rigel/rap/project/mapping/Module.hbm.xml + com/taobao/rigel/rap/project/mapping/Page.hbm.xml + com/taobao/rigel/rap/project/mapping/Action.hbm.xml + com/taobao/rigel/rap/project/mapping/Parameter.hbm.xml + com/taobao/rigel/rap/account/mapping/User.hbm.xml + com/taobao/rigel/rap/account/mapping/Role.hbm.xml + com/taobao/rigel/rap/account/mapping/Notification.hbm.xml + com/taobao/rigel/rap/workspace/mapping/Workspace.hbm.xml + com/taobao/rigel/rap/workspace/mapping/CheckIn.hbm.xml + com/taobao/rigel/rap/organization/mapping/Corporation.hbm.xml + com/taobao/rigel/rap/organization/mapping/Group.hbm.xml + com/taobao/rigel/rap/organization/mapping/ProductionLine.hbm.xml + com/taobao/rigel/rap/mock/mapping/Rule.hbm.xml + + + + + + org.hibernate.dialect.MySQLDialect + false + false + true + + + + + + + + + + + + + + + + + + + + + + + + + PROPAGATION_REQUIRED + + + + + diff --git a/src/log4j2.xml b/src/main/resources/log4j2.xml similarity index 65% rename from src/log4j2.xml rename to src/main/resources/log4j2.xml index f00c8f842..d01936843 100644 --- a/src/log4j2.xml +++ b/src/main/resources/log4j2.xml @@ -1,19 +1,19 @@ - + - - + - @@ -24,16 +24,14 @@ - - - - - + + + + + + + - - - - diff --git a/src/mysql.local.properties b/src/main/resources/mysql.local.properties similarity index 64% rename from src/mysql.local.properties rename to src/main/resources/mysql.local.properties index 15b7c2d89..e5cac9132 100644 --- a/src/mysql.local.properties +++ b/src/main/resources/mysql.local.properties @@ -1,9 +1,4 @@ -jdbc.driverClassName=com.mysql.jdbc.Driver -jdbc.url=jdbc\:mysql\://localhost\:3306/rap_db?useUnicode\=true&characterEncoding\=utf8&zeroDateTimeBehavior\=convertToNull&noAccessToProcedureBodies\=true -jdbc.username=root -jdbc.password= -jdbc.maxPoolSize=2 -jdbc.minPoolSize=1 -jdbc.initialPoolSize=1 -jdbc.idleConnectionTestPeriod=1800 -jdbc.maxIdleTime=3600 +jdbc.driverClassName=com.mysql.jdbc.Driver +jdbc.url=jdbc\:mysql\://localhost\:3306/rap_db?useUnicode\=true&characterEncoding\=utf8&zeroDateTimeBehavior\=convertToNull&noAccessToProcedureBodies\=true +jdbc.username=root +jdbc.password= diff --git a/src/main/resources/resource/export.vm b/src/main/resources/resource/export.vm new file mode 100644 index 000000000..e603a2135 --- /dev/null +++ b/src/main/resources/resource/export.vm @@ -0,0 +1,149 @@ + + + + + + + + +

    + #foreach($module in $project.moduleListOrdered) + #set($moduleNo = $velocityCount) +
    +

    $moduleNo $module.name

    + #foreach($page in $module.pageListOrdered) + #set($pageNo = $velocityCount) +
    +

    $moduleNo.$pageNo $page.name

    + #foreach($action in $page.actionListOrdered) + #set($actionNo = $velocityCount) +
    +

    $moduleNo.$pageNo.$actionNo $action.name

    + +

    Description

    + +
    $action.description
    +

    URL

    + +
    $action.requestUrl
    +

    Request Param List

    + $action.requestParameterListHTML +

    Response Param List

    + $action.responseParameterListHTML +
    + #end +
    + #end +
    + #end +
    + + diff --git a/src/struts.properties b/src/main/resources/struts.properties similarity index 97% rename from src/struts.properties rename to src/main/resources/struts.properties index bd5f62628..62e2ed71f 100644 --- a/src/struts.properties +++ b/src/main/resources/struts.properties @@ -1,10 +1,10 @@ -struts.objectFactory = spring -struts.locale=zh_CN -struts.enable.DynamicMethodInvocation=true -struts.devMode=false -struts.configuration.xml.reload=false -struts.custom.i18n.resources=ApplicationResources -struts.il8n.reload=true -struts.i18n.encoding=UTF-8 -struts.velocity.configfile = /WEB-INF/velocity.properties +struts.objectFactory = spring +struts.locale=zh_CN +struts.enable.DynamicMethodInvocation=true +struts.devMode=false +struts.configuration.xml.reload=false +struts.custom.i18n.resources=ApplicationResources +struts.il8n.reload=true +struts.i18n.encoding=UTF-8 +struts.velocity.configfile = /WEB-INF/velocity.properties struts.velocity.toolboxlocation =/WEB-INF/toolbox.xml \ No newline at end of file diff --git a/src/main/resources/struts.xml b/src/main/resources/struts.xml new file mode 100644 index 000000000..2ba82db3e --- /dev/null +++ b/src/main/resources/struts.xml @@ -0,0 +1,73 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + true + ERROR + + + + + + + /account/login.vm + /error.vm + /error.vm + /bcom/jsonError.cb.vm + /error.vm + /common/redirect.vm + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/WebContent/META-INF/MANIFEST.MF b/src/main/webapp/META-INF/MANIFEST.MF similarity index 100% rename from WebContent/META-INF/MANIFEST.MF rename to src/main/webapp/META-INF/MANIFEST.MF diff --git a/WebContent/WEB-INF/lib/xeger-1.0-SNAPSHOT.jar b/src/main/webapp/WEB-INF/lib/xeger-1.0-SNAPSHOT.jar similarity index 100% rename from WebContent/WEB-INF/lib/xeger-1.0-SNAPSHOT.jar rename to src/main/webapp/WEB-INF/lib/xeger-1.0-SNAPSHOT.jar diff --git a/src/main/webapp/WEB-INF/toolbox.xml b/src/main/webapp/WEB-INF/toolbox.xml new file mode 100644 index 000000000..4f442aa93 --- /dev/null +++ b/src/main/webapp/WEB-INF/toolbox.xml @@ -0,0 +1,23 @@ + + + + utils + application + com.taobao.rigel.rap.common.utils.StringUtils + + + dateUtils + application + com.taobao.rigel.rap.common.utils.DateUtils + + + consts + application + com.taobao.rigel.rap.common.config.SystemConstant + + + logger + application + com.taobao.rigel.rap.common.utils.SystemVisitorLog + + diff --git a/src/main/webapp/WEB-INF/urlrewrite.xml b/src/main/webapp/WEB-INF/urlrewrite.xml new file mode 100644 index 000000000..63f53a82b --- /dev/null +++ b/src/main/webapp/WEB-INF/urlrewrite.xml @@ -0,0 +1,79 @@ + + + + + + mock service + + ^/mock/(\d*?)/(.*)$ + /mock/createData.action?__id__=$1&pattern=/${escape:utf8:$2} + * + Origin, X-Requested-With, Content-Type, Accept + + + + + mockjs service + + ^/mockjs/(\d*?)/(.*)$ + /mock/createRule.action?__id__=$1&pattern=/${escape:utf8:$2} + * + Origin, X-Requested-With, Content-Type, Accept + + + + + mockjs auto service, use mock rules set by Open API + + ^/mockjsauto/(\d*?)/(.*)$ + /mock/createRuleAuto.action?__id__=$1&pattern=/${escape:utf8:$2} + * + Origin, X-Requested-With, Content-Type, Accept + + + + + mockjs result service + + ^/mockjsdata/(\d*?)/(.*)$ + /mock/createMockjsData.action?__id__=$1&pattern=/${escape:utf8:$2} + * + Origin, X-Requested-With, Content-Type, Accept + + + + + mockjs result service + + ^/mockjsdataauto/(\d*?)/(.*)$ + /mock/createMockjsDataAuto.action?__id__=$1&pattern=/${escape:utf8:$2} + * + Origin, X-Requested-With, Content-Type, Accept + + + + + validation API + + ^/validate/(\d*?)/(.*)$ + /mock/validateAPI.action?__id__=$1&pattern=/${escape:utf8:$2} + * + Origin, X-Requested-With, Content-Type, Accept + + + + + mockjs plugin generator + + ^/rap.plugin.js(.*)$ + /mock/createPluginScript.action$1 + + + + node doc service + + ^/doc/(\d*)$ + http://localhost:7429/doc/$1.html + + \ No newline at end of file diff --git a/WebContent/WEB-INF/velocity.properties b/src/main/webapp/WEB-INF/velocity.properties similarity index 98% rename from WebContent/WEB-INF/velocity.properties rename to src/main/webapp/WEB-INF/velocity.properties index e0903fb6f..92631596f 100644 --- a/WebContent/WEB-INF/velocity.properties +++ b/src/main/webapp/WEB-INF/velocity.properties @@ -112,5 +112,7 @@ runtime.interpolate.string.literals = true resource.manager.class=org.apache.velocity.runtime.resource.ResourceManagerImpl resource.manager.cache.class=org.apache.velocity.runtime.resource.ResourceCacheImpl +velocimacro.library.autoreload = true +velocimacro.permissions.allow.inline.to.replace.global=true runtime.log.logsystem.class=org.apache.velocity.runtime.log.NullLogSystem \ No newline at end of file diff --git a/src/main/webapp/WEB-INF/web.xml b/src/main/webapp/WEB-INF/web.xml new file mode 100644 index 000000000..56267db37 --- /dev/null +++ b/src/main/webapp/WEB-INF/web.xml @@ -0,0 +1,152 @@ + + + rap + + log4jConfigLocation + /WEB-INF/classes/log4j.properties + + + contextConfigLocation + classpath*:hibernate.cfg.xml + + + ssoFilter + com.alibaba.buc.sso.client.filter.SSOFilter + + APP_NAME + rapauto + + + SSO_CALLBACK_CLASS + com.alibaba.buc.sso.client.handler.impl.SimpleSSOCallback + + + SSO_SERVER_URL + https://login.alibaba-inc.com + + + CLIENT_KEY + 0e6f43d9-e380-4a7b-88ec-65b5568ce2ee + + + EXCLUSIONS + * + + + + UrlRewriteFilter + org.tuckey.web.filters.urlrewrite.UrlRewriteFilter + + confPath + /WEB-INF/urlrewrite.xml + + + + DelegatingFilterProxy + org.springframework.web.filter.DelegatingFilterProxy + + targetBeanName + authCheckFilter + + + targetFilterLifecycle + true + + + + authCheckFilter + com.taobao.rigel.rap.common.filter.AuthCheckFilter + + + openSessionInViewFilter + org.springframework.orm.hibernate5.support.OpenSessionInViewFilter + + + encodingFilter + org.springframework.web.filter.CharacterEncodingFilter + + encoding + UTF-8 + + + forceEncoding + true + + + + SetCharacterEncoding + com.taobao.rigel.rap.common.filter.SetCharacterEncodingFilter + + encoding + utf-8 + + + + ssoFilter + /* + + + DelegatingFilterProxy + /* + + + UrlRewriteFilter + /* + REQUEST + FORWARD + + + SetCharacterEncoding + /* + + + struts-cleanup + org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter + + + struts2 + org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter + + + openSessionInViewFilter + /* + + + struts-cleanup + /* + + + struts2 + /* + REQUEST + FORWARD + INCLUDE + + + org.springframework.web.context.ContextLoaderListener + + + DispatcherFilter + org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter + + + + DispatcherFilter + /* + + + com.taobao.rigel.rap.common.listener.SessionListener + + + + com.taobao.rigel.rap.common.listener.RapServletContextListener + + + + + 60 + + diff --git a/src/main/webapp/account/login.vm b/src/main/webapp/account/login.vm new file mode 100644 index 000000000..dd647cad4 --- /dev/null +++ b/src/main/webapp/account/login.vm @@ -0,0 +1,46 @@ + + + + + Login + #parse('/tcom/template.rap.vm') + #includeNewRapStatic + #if($returnUrlFirstSet) + #set($returnUrlEncoded = $!utils.escapeInU($returnUrl)) + #else + #set($returnUrlEncoded = $returnUrl) + #end + + + +
    + #bodyNewStart +
    + + +
    + + +
    +
    + + +
    + #if ($errMsg && $errMsg != "") +
    +
    + $!errMsg +
    +
    + #end +    + + 域账号登录 + +
    + #bodyEnd +
    + + diff --git a/src/main/webapp/account/myAccount.vm b/src/main/webapp/account/myAccount.vm new file mode 100644 index 000000000..f3e58ec8e --- /dev/null +++ b/src/main/webapp/account/myAccount.vm @@ -0,0 +1,135 @@ + + #parse('/tcom/template.rap.vm') + + + + + Manage Account + #includeNewRapStatic + + +#bodyNewStart +
    +
    +
    + + +
    +

    $!utils.escapeInH($user.account)

    +
    +
    +
    + + +
    +

    + #if($isEditMode) + + #else + $!utils.escapeInH($user.name) + #end +

    +
    +
    +
    + + +
    +

    + #if($isEditMode) + + #else + $!utils.escapeInH($user.email) + #end +

    +
    +
    + #if($isEditMode) +
    + + +
    +

    + * 若无需修改请忽略 +

    +
    +
    +
    + + +
    +

    + +

    +
    +
    +
    + + +
    +

    + +

    +
    +
    + #end +
    + + +
    +

    + $!utils.escapeInH($user.createDateStr) +

    +
    +
    +
    + + +
    +

    + #if($opSuccess) + 操作成功 + #else + + #end +

    +
    +
    +
    + + +
    +

    + #if($isEditMode) + + + #else + + #end +

    +
    +
    +
    +
    +#bodyEnd + + + diff --git a/src/main/webapp/account/mySetting.vm b/src/main/webapp/account/mySetting.vm new file mode 100644 index 000000000..e34f5e6ec --- /dev/null +++ b/src/main/webapp/account/mySetting.vm @@ -0,0 +1,156 @@ + + #parse('/tcom/template.rap.vm') + + + + + Manage Account #includeNewRapStatic + + + +#bodyNewStart + +
    +
    不要鸡冻,这个功能还木有做完,霍雍和思竹吃饭饭去了
    + + + +
    +
    +
    +
    + + +
    + +
    +
    +
    + + +
    +
    + +
    +
    + +
    +
    +
    + +
    + + +
    +
    + +
    +
    + +
    +
    +
    + +
    +
    + + +
    +
    +
    +
    +
    +
    + +
    + + +
    + +
    +
    + +
    + + +
    +
    + +
    +
    + +
    +
    +
    + +
    + + +
    +
    + +
    +
    + +
    +
    +
    + +
    +
    + + +
    +
    +
    +
    +
    更多功能,敬请期待~
    +
    +
    +#bodyEnd + + diff --git a/src/main/webapp/account/register.vm b/src/main/webapp/account/register.vm new file mode 100644 index 000000000..c8d8845e0 --- /dev/null +++ b/src/main/webapp/account/register.vm @@ -0,0 +1,95 @@ + + #parse('/tcom/template.rap.vm') + + + + 注册新的RAP账户 + #includeNewRapStatic + + +#bodyNewStart +
    +
    +
    + + +
    + +
    +
    +
    + + +
    +

    + +

    +
    +
    +
    + + +
    +

    + +

    +
    +
    +
    + + +
    +

    + +

    +
    +
    +
    + + +
    +

    + +

    +
    +
    +
    + + +
    +

    + +

    +
    +
    +
    + + +
    +

    + +

    +
    +
    +
    +
    +#bodyEnd + + + diff --git a/WebContent/bcom/ajaxRequest.cb.vm b/src/main/webapp/bcom/ajaxRequest.cb.vm similarity index 100% rename from WebContent/bcom/ajaxRequest.cb.vm rename to src/main/webapp/bcom/ajaxRequest.cb.vm diff --git a/WebContent/bcom/content.cb.vm b/src/main/webapp/bcom/content.cb.vm similarity index 100% rename from WebContent/bcom/content.cb.vm rename to src/main/webapp/bcom/content.cb.vm diff --git a/WebContent/bcom/contentAndId.cb.vm b/src/main/webapp/bcom/contentAndId.cb.vm similarity index 100% rename from WebContent/bcom/contentAndId.cb.vm rename to src/main/webapp/bcom/contentAndId.cb.vm diff --git a/WebContent/bcom/contentWithoutEscape.cb.vm b/src/main/webapp/bcom/contentWithoutEscape.cb.vm similarity index 100% rename from WebContent/bcom/contentWithoutEscape.cb.vm rename to src/main/webapp/bcom/contentWithoutEscape.cb.vm diff --git a/src/main/webapp/bcom/getModuleHtmlAjax.cb.vm b/src/main/webapp/bcom/getModuleHtmlAjax.cb.vm new file mode 100644 index 000000000..ae31c2a45 --- /dev/null +++ b/src/main/webapp/bcom/getModuleHtmlAjax.cb.vm @@ -0,0 +1,20 @@ +
    +
    + + #foreach ($page in $module.pageList) +
    + + #foreach ($action in $page.actionList) + + #end +
    add
    +
    + #end +
    +
    +
    +
    +
    diff --git a/WebContent/bcom/isOk.cb.vm b/src/main/webapp/bcom/isOk.cb.vm similarity index 100% rename from WebContent/bcom/isOk.cb.vm rename to src/main/webapp/bcom/isOk.cb.vm diff --git a/WebContent/bcom/isOkWithNum.cb.vm b/src/main/webapp/bcom/isOkWithNum.cb.vm similarity index 97% rename from WebContent/bcom/isOkWithNum.cb.vm rename to src/main/webapp/bcom/isOkWithNum.cb.vm index 57d777c0b..e7e4acdac 100644 --- a/WebContent/bcom/isOkWithNum.cb.vm +++ b/src/main/webapp/bcom/isOkWithNum.cb.vm @@ -1 +1 @@ -$!callback({"isOk":$!isOk, "num":$!num}) +$!callback({"isOk":$!isOk, "num":$!num}) diff --git a/WebContent/bcom/json.cb.vm b/src/main/webapp/bcom/json.cb.vm similarity index 100% rename from WebContent/bcom/json.cb.vm rename to src/main/webapp/bcom/json.cb.vm diff --git a/WebContent/bcom/jsonError.cb.vm b/src/main/webapp/bcom/jsonError.cb.vm similarity index 100% rename from WebContent/bcom/jsonError.cb.vm rename to src/main/webapp/bcom/jsonError.cb.vm diff --git a/WebContent/bcom/project.cb.vm b/src/main/webapp/bcom/project.cb.vm similarity index 100% rename from WebContent/bcom/project.cb.vm rename to src/main/webapp/bcom/project.cb.vm diff --git a/WebContent/bcom/saveWorkspace.cb.vm b/src/main/webapp/bcom/saveWorkspace.cb.vm similarity index 100% rename from WebContent/bcom/saveWorkspace.cb.vm rename to src/main/webapp/bcom/saveWorkspace.cb.vm diff --git a/src/main/webapp/common/blank.html b/src/main/webapp/common/blank.html new file mode 100644 index 000000000..ff34eec49 --- /dev/null +++ b/src/main/webapp/common/blank.html @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/src/main/webapp/common/redirect.vm b/src/main/webapp/common/redirect.vm new file mode 100644 index 000000000..3c7f8208c --- /dev/null +++ b/src/main/webapp/common/redirect.vm @@ -0,0 +1,14 @@ + + + + + RAP - 正在为您跳转 + + +正在为您跳转... + + + + diff --git a/src/main/webapp/demo/a.js b/src/main/webapp/demo/a.js new file mode 100644 index 000000000..ef47d9def --- /dev/null +++ b/src/main/webapp/demo/a.js @@ -0,0 +1,13 @@ +define(function (require, exports, module) { + var $ = require('jquery'); + exports.go = function () { + $.ajax({ + url: 'data.json', + dataType: 'json', + type: 'get', + success: function (data) { + $('body').html(JSON.stringify(data, null, 4)); + } + }); + } +}) \ No newline at end of file diff --git a/src/main/webapp/demo/mock.plugin/casebox/case1_seajs_jquery_preload.html b/src/main/webapp/demo/mock.plugin/casebox/case1_seajs_jquery_preload.html new file mode 100644 index 000000000..966895bb9 --- /dev/null +++ b/src/main/webapp/demo/mock.plugin/casebox/case1_seajs_jquery_preload.html @@ -0,0 +1,61 @@ + + + + + + + + + +
    +
    +

    + RAP plugin case1: seajs jquery preload issue. +

    + +

    LOG:

    +
    
    +
    + + + + + \ No newline at end of file diff --git a/src/main/webapp/demo/mock.plugin/data.json b/src/main/webapp/demo/mock.plugin/data.json new file mode 100644 index 000000000..8d6b85c7b --- /dev/null +++ b/src/main/webapp/demo/mock.plugin/data.json @@ -0,0 +1,3 @@ +{ + "a": 1 +} diff --git a/src/main/webapp/demo/mock.plugin/data1.js b/src/main/webapp/demo/mock.plugin/data1.js new file mode 100644 index 000000000..b07d8ddf3 --- /dev/null +++ b/src/main/webapp/demo/mock.plugin/data1.js @@ -0,0 +1,7 @@ +{ + "a" +: + 1, "b" +: + 2 +} \ No newline at end of file diff --git a/WebContent/demo/mock.plugin/index.htm b/src/main/webapp/demo/mock.plugin/index.htm similarity index 60% rename from WebContent/demo/mock.plugin/index.htm rename to src/main/webapp/demo/mock.plugin/index.htm index abec60a41..b0da4e314 100644 --- a/WebContent/demo/mock.plugin/index.htm +++ b/src/main/webapp/demo/mock.plugin/index.htm @@ -9,10 +9,10 @@ -
    
    -    
    +     */
    +
     
     
    diff --git a/src/main/webapp/demo/mock.plugin/jquery-2.0.3.min.js b/src/main/webapp/demo/mock.plugin/jquery-2.0.3.min.js
    new file mode 100644
    index 000000000..7ab438963
    --- /dev/null
    +++ b/src/main/webapp/demo/mock.plugin/jquery-2.0.3.min.js
    @@ -0,0 +1,2363 @@
    +/*! jQuery v2.0.3 | (c) 2005, 2013 jQuery Foundation, Inc. | jquery.org/license
    + //@ sourceMappingURL=jquery-2.0.3.min.map
    + */
    +(function (e, undefined) {
    +    var t, n, r = typeof undefined, i = e.location, o = e.document, s = o.documentElement, a = e.jQuery, u = e.$, l = {}, c = [], p = "2.0.3", f = c.concat, h = c.push, d = c.slice, g = c.indexOf, m = l.toString, y = l.hasOwnProperty, v = p.trim, x = function (e, n) {
    +        return new x.fn.init(e, n, t)
    +    }, b = /[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source, w = /\S+/g, T = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/, C = /^<(\w+)\s*\/?>(?:<\/\1>|)$/, k = /^-ms-/, N = /-([\da-z])/gi, E = function (e, t) {
    +        return t.toUpperCase()
    +    }, S = function () {
    +        o.removeEventListener("DOMContentLoaded", S, !1), e.removeEventListener("load", S, !1), x.ready()
    +    };
    +    x.fn = x.prototype = {
    +        jquery: p, constructor: x, init: function (e, t, n) {
    +            var r, i;
    +            if (!e)return this;
    +            if ("string" == typeof e) {
    +                if (r = "<" === e.charAt(0) && ">" === e.charAt(e.length - 1) && e.length >= 3 ? [null, e, null] : T.exec(e), !r || !r[1] && t)return !t || t.jquery ? (t || n).find(e) : this.constructor(t).find(e);
    +                if (r[1]) {
    +                    if (t = t instanceof x ? t[0] : t, x.merge(this, x.parseHTML(r[1], t && t.nodeType ? t.ownerDocument || t : o, !0)), C.test(r[1]) && x.isPlainObject(t))for (r in t)x.isFunction(this[r]) ? this[r](t[r]) : this.attr(r, t[r]);
    +                    return this
    +                }
    +                return i = o.getElementById(r[2]), i && i.parentNode && (this.length = 1, this[0] = i), this.context = o, this.selector = e, this
    +            }
    +            return e.nodeType ? (this.context = this[0] = e, this.length = 1, this) : x.isFunction(e) ? n.ready(e) : (e.selector !== undefined && (this.selector = e.selector, this.context = e.context), x.makeArray(e, this))
    +        }, selector: "", length: 0, toArray: function () {
    +            return d.call(this)
    +        }, get: function (e) {
    +            return null == e ? this.toArray() : 0 > e ? this[this.length + e] : this[e]
    +        }, pushStack: function (e) {
    +            var t = x.merge(this.constructor(), e);
    +            return t.prevObject = this, t.context = this.context, t
    +        }, each: function (e, t) {
    +            return x.each(this, e, t)
    +        }, ready: function (e) {
    +            return x.ready.promise().done(e), this
    +        }, slice: function () {
    +            return this.pushStack(d.apply(this, arguments))
    +        }, first: function () {
    +            return this.eq(0)
    +        }, last: function () {
    +            return this.eq(-1)
    +        }, eq: function (e) {
    +            var t = this.length, n = +e + (0 > e ? t : 0);
    +            return this.pushStack(n >= 0 && t > n ? [this[n]] : [])
    +        }, map: function (e) {
    +            return this.pushStack(x.map(this, function (t, n) {
    +                return e.call(t, n, t)
    +            }))
    +        }, end: function () {
    +            return this.prevObject || this.constructor(null)
    +        }, push: h, sort: [].sort, splice: [].splice
    +    }, x.fn.init.prototype = x.fn, x.extend = x.fn.extend = function () {
    +        var e, t, n, r, i, o, s = arguments[0] || {}, a = 1, u = arguments.length, l = !1;
    +        for ("boolean" == typeof s && (l = s, s = arguments[1] || {}, a = 2), "object" == typeof s || x.isFunction(s) || (s = {}), u === a && (s = this, --a); u > a; a++)if (null != (e = arguments[a]))for (t in e)n = s[t], r = e[t], s !== r && (l && r && (x.isPlainObject(r) || (i = x.isArray(r))) ? (i ? (i = !1, o = n && x.isArray(n) ? n : []) : o = n && x.isPlainObject(n) ? n : {}, s[t] = x.extend(l, o, r)) : r !== undefined && (s[t] = r));
    +        return s
    +    }, x.extend({
    +        expando: "jQuery" + (p + Math.random()).replace(/\D/g, ""), noConflict: function (t) {
    +            return e.$ === x && (e.$ = u), t && e.jQuery === x && (e.jQuery = a), x
    +        }, isReady: !1, readyWait: 1, holdReady: function (e) {
    +            e ? x.readyWait++ : x.ready(!0)
    +        }, ready: function (e) {
    +            (e === !0 ? --x.readyWait : x.isReady) || (x.isReady = !0, e !== !0 && --x.readyWait > 0 || (n.resolveWith(o, [x]), x.fn.trigger && x(o).trigger("ready").off("ready")))
    +        }, isFunction: function (e) {
    +            return "function" === x.type(e)
    +        }, isArray: Array.isArray, isWindow: function (e) {
    +            return null != e && e === e.window
    +        }, isNumeric: function (e) {
    +            return !isNaN(parseFloat(e)) && isFinite(e)
    +        }, type: function (e) {
    +            return null == e ? e + "" : "object" == typeof e || "function" == typeof e ? l[m.call(e)] || "object" : typeof e
    +        }, isPlainObject: function (e) {
    +            if ("object" !== x.type(e) || e.nodeType || x.isWindow(e))return !1;
    +            try {
    +                if (e.constructor && !y.call(e.constructor.prototype, "isPrototypeOf"))return !1
    +            } catch (t) {
    +                return !1
    +            }
    +            return !0
    +        }, isEmptyObject: function (e) {
    +            var t;
    +            for (t in e)return !1;
    +            return !0
    +        }, error: function (e) {
    +            throw Error(e)
    +        }, parseHTML: function (e, t, n) {
    +            if (!e || "string" != typeof e)return null;
    +            "boolean" == typeof t && (n = t, t = !1), t = t || o;
    +            var r = C.exec(e), i = !n && [];
    +            return r ? [t.createElement(r[1])] : (r = x.buildFragment([e], t, i), i && x(i).remove(), x.merge([], r.childNodes))
    +        }, parseJSON: JSON.parse, parseXML: function (e) {
    +            var t, n;
    +            if (!e || "string" != typeof e)return null;
    +            try {
    +                n = new DOMParser, t = n.parseFromString(e, "text/xml")
    +            } catch (r) {
    +                t = undefined
    +            }
    +            return (!t || t.getElementsByTagName("parsererror").length) && x.error("Invalid XML: " + e), t
    +        }, noop: function () {
    +        }, globalEval: function (e) {
    +            var t, n = eval;
    +            e = x.trim(e), e && (1 === e.indexOf("use strict") ? (t = o.createElement("script"), t.text = e, o.head.appendChild(t).parentNode.removeChild(t)) : n(e))
    +        }, camelCase: function (e) {
    +            return e.replace(k, "ms-").replace(N, E)
    +        }, nodeName: function (e, t) {
    +            return e.nodeName && e.nodeName.toLowerCase() === t.toLowerCase()
    +        }, each: function (e, t, n) {
    +            var r, i = 0, o = e.length, s = j(e);
    +            if (n) {
    +                if (s) {
    +                    for (; o > i; i++)if (r = t.apply(e[i], n), r === !1)break
    +                } else for (i in e)if (r = t.apply(e[i], n), r === !1)break
    +            } else if (s) {
    +                for (; o > i; i++)if (r = t.call(e[i], i, e[i]), r === !1)break
    +            } else for (i in e)if (r = t.call(e[i], i, e[i]), r === !1)break;
    +            return e
    +        }, trim: function (e) {
    +            return null == e ? "" : v.call(e)
    +        }, makeArray: function (e, t) {
    +            var n = t || [];
    +            return null != e && (j(Object(e)) ? x.merge(n, "string" == typeof e ? [e] : e) : h.call(n, e)), n
    +        }, inArray: function (e, t, n) {
    +            return null == t ? -1 : g.call(t, e, n)
    +        }, merge: function (e, t) {
    +            var n = t.length, r = e.length, i = 0;
    +            if ("number" == typeof n)for (; n > i; i++)e[r++] = t[i]; else while (t[i] !== undefined)e[r++] = t[i++];
    +            return e.length = r, e
    +        }, grep: function (e, t, n) {
    +            var r, i = [], o = 0, s = e.length;
    +            for (n = !!n; s > o; o++)r = !!t(e[o], o), n !== r && i.push(e[o]);
    +            return i
    +        }, map: function (e, t, n) {
    +            var r, i = 0, o = e.length, s = j(e), a = [];
    +            if (s)for (; o > i; i++)r = t(e[i], i, n), null != r && (a[a.length] = r); else for (i in e)r = t(e[i], i, n), null != r && (a[a.length] = r);
    +            return f.apply([], a)
    +        }, guid: 1, proxy: function (e, t) {
    +            var n, r, i;
    +            return "string" == typeof t && (n = e[t], t = e, e = n), x.isFunction(e) ? (r = d.call(arguments, 2), i = function () {
    +                return e.apply(t || this, r.concat(d.call(arguments)))
    +            }, i.guid = e.guid = e.guid || x.guid++, i) : undefined
    +        }, access: function (e, t, n, r, i, o, s) {
    +            var a = 0, u = e.length, l = null == n;
    +            if ("object" === x.type(n)) {
    +                i = !0;
    +                for (a in n)x.access(e, t, a, n[a], !0, o, s)
    +            } else if (r !== undefined && (i = !0, x.isFunction(r) || (s = !0), l && (s ? (t.call(e, r), t = null) : (l = t, t = function (e, t, n) {
    +                    return l.call(x(e), n)
    +                })), t))for (; u > a; a++)t(e[a], n, s ? r : r.call(e[a], a, t(e[a], n)));
    +            return i ? e : l ? t.call(e) : u ? t(e[0], n) : o
    +        }, now: Date.now, swap: function (e, t, n, r) {
    +            var i, o, s = {};
    +            for (o in t)s[o] = e.style[o], e.style[o] = t[o];
    +            i = n.apply(e, r || []);
    +            for (o in t)e.style[o] = s[o];
    +            return i
    +        }
    +    }), x.ready.promise = function (t) {
    +        return n || (n = x.Deferred(), "complete" === o.readyState ? setTimeout(x.ready) : (o.addEventListener("DOMContentLoaded", S, !1), e.addEventListener("load", S, !1))), n.promise(t)
    +    }, x.each("Boolean Number String Function Array Date RegExp Object Error".split(" "), function (e, t) {
    +        l["[object " + t + "]"] = t.toLowerCase()
    +    });
    +    function j(e) {
    +        var t = e.length, n = x.type(e);
    +        return x.isWindow(e) ? !1 : 1 === e.nodeType && t ? !0 : "array" === n || "function" !== n && (0 === t || "number" == typeof t && t > 0 && t - 1 in e)
    +    }
    +
    +    t = x(o), function (e, undefined) {
    +        var t, n, r, i, o, s, a, u, l, c, p, f, h, d, g, m, y, v = "sizzle" + -new Date, b = e.document, w = 0, T = 0, C = st(), k = st(), N = st(), E = !1, S = function (e, t) {
    +            return e === t ? (E = !0, 0) : 0
    +        }, j = typeof undefined, D = 1 << 31, A = {}.hasOwnProperty, L = [], q = L.pop, H = L.push, O = L.push, F = L.slice, P = L.indexOf || function (e) {
    +                var t = 0, n = this.length;
    +                for (; n > t; t++)if (this[t] === e)return t;
    +                return -1
    +            }, R = "checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped", M = "[\\x20\\t\\r\\n\\f]", W = "(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+", $ = W.replace("w", "w#"), B = "\\[" + M + "*(" + W + ")" + M + "*(?:([*^$|!~]?=)" + M + "*(?:(['\"])((?:\\\\.|[^\\\\])*?)\\3|(" + $ + ")|)|)" + M + "*\\]", I = ":(" + W + ")(?:\\(((['\"])((?:\\\\.|[^\\\\])*?)\\3|((?:\\\\.|[^\\\\()[\\]]|" + B.replace(3, 8) + ")*)|.*)\\)|)", z = RegExp("^" + M + "+|((?:^|[^\\\\])(?:\\\\.)*)" + M + "+$", "g"), _ = RegExp("^" + M + "*," + M + "*"), X = RegExp("^" + M + "*([>+~]|" + M + ")" + M + "*"), U = RegExp(M + "*[+~]"), Y = RegExp("=" + M + "*([^\\]'\"]*)" + M + "*\\]", "g"), V = RegExp(I), G = RegExp("^" + $ + "$"), J = {
    +            ID: RegExp("^#(" + W + ")"),
    +            CLASS: RegExp("^\\.(" + W + ")"),
    +            TAG: RegExp("^(" + W.replace("w", "w*") + ")"),
    +            ATTR: RegExp("^" + B),
    +            PSEUDO: RegExp("^" + I),
    +            CHILD: RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" + M + "*(even|odd|(([+-]|)(\\d*)n|)" + M + "*(?:([+-]|)" + M + "*(\\d+)|))" + M + "*\\)|)", "i"),
    +            bool: RegExp("^(?:" + R + ")$", "i"),
    +            needsContext: RegExp("^" + M + "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" + M + "*((?:-\\d)?\\d*)" + M + "*\\)|)(?=[^-]|$)", "i")
    +        }, Q = /^[^{]+\{\s*\[native \w/, K = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/, Z = /^(?:input|select|textarea|button)$/i, et = /^h\d$/i, tt = /'|\\/g, nt = RegExp("\\\\([\\da-f]{1,6}" + M + "?|(" + M + ")|.)", "ig"), rt = function (e, t, n) {
    +            var r = "0x" + t - 65536;
    +            return r !== r || n ? t : 0 > r ? String.fromCharCode(r + 65536) : String.fromCharCode(55296 | r >> 10, 56320 | 1023 & r)
    +        };
    +        try {
    +            O.apply(L = F.call(b.childNodes), b.childNodes), L[b.childNodes.length].nodeType
    +        } catch (it) {
    +            O = {
    +                apply: L.length ? function (e, t) {
    +                    H.apply(e, F.call(t))
    +                } : function (e, t) {
    +                    var n = e.length, r = 0;
    +                    while (e[n++] = t[r++]);
    +                    e.length = n - 1
    +                }
    +            }
    +        }
    +        function ot(e, t, r, i) {
    +            var o, s, a, u, l, f, g, m, x, w;
    +            if ((t ? t.ownerDocument || t : b) !== p && c(t), t = t || p, r = r || [], !e || "string" != typeof e)return r;
    +            if (1 !== (u = t.nodeType) && 9 !== u)return [];
    +            if (h && !i) {
    +                if (o = K.exec(e))if (a = o[1]) {
    +                    if (9 === u) {
    +                        if (s = t.getElementById(a), !s || !s.parentNode)return r;
    +                        if (s.id === a)return r.push(s), r
    +                    } else if (t.ownerDocument && (s = t.ownerDocument.getElementById(a)) && y(t, s) && s.id === a)return r.push(s), r
    +                } else {
    +                    if (o[2])return O.apply(r, t.getElementsByTagName(e)), r;
    +                    if ((a = o[3]) && n.getElementsByClassName && t.getElementsByClassName)return O.apply(r, t.getElementsByClassName(a)), r
    +                }
    +                if (n.qsa && (!d || !d.test(e))) {
    +                    if (m = g = v, x = t, w = 9 === u && e, 1 === u && "object" !== t.nodeName.toLowerCase()) {
    +                        f = gt(e), (g = t.getAttribute("id")) ? m = g.replace(tt, "\\$&") : t.setAttribute("id", m), m = "[id='" + m + "'] ", l = f.length;
    +                        while (l--)f[l] = m + mt(f[l]);
    +                        x = U.test(e) && t.parentNode || t, w = f.join(",")
    +                    }
    +                    if (w)try {
    +                        return O.apply(r, x.querySelectorAll(w)), r
    +                    } catch (T) {
    +                    } finally {
    +                        g || t.removeAttribute("id")
    +                    }
    +                }
    +            }
    +            return kt(e.replace(z, "$1"), t, r, i)
    +        }
    +
    +        function st() {
    +            var e = [];
    +
    +            function t(n, r) {
    +                return e.push(n += " ") > i.cacheLength && delete t[e.shift()], t[n] = r
    +            }
    +
    +            return t
    +        }
    +
    +        function at(e) {
    +            return e[v] = !0, e
    +        }
    +
    +        function ut(e) {
    +            var t = p.createElement("div");
    +            try {
    +                return !!e(t)
    +            } catch (n) {
    +                return !1
    +            } finally {
    +                t.parentNode && t.parentNode.removeChild(t), t = null
    +            }
    +        }
    +
    +        function lt(e, t) {
    +            var n = e.split("|"), r = e.length;
    +            while (r--)i.attrHandle[n[r]] = t
    +        }
    +
    +        function ct(e, t) {
    +            var n = t && e, r = n && 1 === e.nodeType && 1 === t.nodeType && (~t.sourceIndex || D) - (~e.sourceIndex || D);
    +            if (r)return r;
    +            if (n)while (n = n.nextSibling)if (n === t)return -1;
    +            return e ? 1 : -1
    +        }
    +
    +        function pt(e) {
    +            return function (t) {
    +                var n = t.nodeName.toLowerCase();
    +                return "input" === n && t.type === e
    +            }
    +        }
    +
    +        function ft(e) {
    +            return function (t) {
    +                var n = t.nodeName.toLowerCase();
    +                return ("input" === n || "button" === n) && t.type === e
    +            }
    +        }
    +
    +        function ht(e) {
    +            return at(function (t) {
    +                return t = +t, at(function (n, r) {
    +                    var i, o = e([], n.length, t), s = o.length;
    +                    while (s--)n[i = o[s]] && (n[i] = !(r[i] = n[i]))
    +                })
    +            })
    +        }
    +
    +        s = ot.isXML = function (e) {
    +            var t = e && (e.ownerDocument || e).documentElement;
    +            return t ? "HTML" !== t.nodeName : !1
    +        }, n = ot.support = {}, c = ot.setDocument = function (e) {
    +            var t = e ? e.ownerDocument || e : b, r = t.defaultView;
    +            return t !== p && 9 === t.nodeType && t.documentElement ? (p = t, f = t.documentElement, h = !s(t), r && r.attachEvent && r !== r.top && r.attachEvent("onbeforeunload", function () {
    +                c()
    +            }), n.attributes = ut(function (e) {
    +                return e.className = "i", !e.getAttribute("className")
    +            }), n.getElementsByTagName = ut(function (e) {
    +                return e.appendChild(t.createComment("")), !e.getElementsByTagName("*").length
    +            }), n.getElementsByClassName = ut(function (e) {
    +                return e.innerHTML = "
    ", e.firstChild.className = "i", 2 === e.getElementsByClassName("i").length + }), n.getById = ut(function (e) { + return f.appendChild(e).id = v, !t.getElementsByName || !t.getElementsByName(v).length + }), n.getById ? (i.find.ID = function (e, t) { + if (typeof t.getElementById !== j && h) { + var n = t.getElementById(e); + return n && n.parentNode ? [n] : [] + } + }, i.filter.ID = function (e) { + var t = e.replace(nt, rt); + return function (e) { + return e.getAttribute("id") === t + } + }) : (delete i.find.ID, i.filter.ID = function (e) { + var t = e.replace(nt, rt); + return function (e) { + var n = typeof e.getAttributeNode !== j && e.getAttributeNode("id"); + return n && n.value === t + } + }), i.find.TAG = n.getElementsByTagName ? function (e, t) { + return typeof t.getElementsByTagName !== j ? t.getElementsByTagName(e) : undefined + } : function (e, t) { + var n, r = [], i = 0, o = t.getElementsByTagName(e); + if ("*" === e) { + while (n = o[i++])1 === n.nodeType && r.push(n); + return r + } + return o + }, i.find.CLASS = n.getElementsByClassName && function (e, t) { + return typeof t.getElementsByClassName !== j && h ? t.getElementsByClassName(e) : undefined + }, g = [], d = [], (n.qsa = Q.test(t.querySelectorAll)) && (ut(function (e) { + e.innerHTML = "", e.querySelectorAll("[selected]").length || d.push("\\[" + M + "*(?:value|" + R + ")"), e.querySelectorAll(":checked").length || d.push(":checked") + }), ut(function (e) { + var n = t.createElement("input"); + n.setAttribute("type", "hidden"), e.appendChild(n).setAttribute("t", ""), e.querySelectorAll("[t^='']").length && d.push("[*^$]=" + M + "*(?:''|\"\")"), e.querySelectorAll(":enabled").length || d.push(":enabled", ":disabled"), e.querySelectorAll("*,:x"), d.push(",.*:") + })), (n.matchesSelector = Q.test(m = f.webkitMatchesSelector || f.mozMatchesSelector || f.oMatchesSelector || f.msMatchesSelector)) && ut(function (e) { + n.disconnectedMatch = m.call(e, "div"), m.call(e, "[s!='']:x"), g.push("!=", I) + }), d = d.length && RegExp(d.join("|")), g = g.length && RegExp(g.join("|")), y = Q.test(f.contains) || f.compareDocumentPosition ? function (e, t) { + var n = 9 === e.nodeType ? e.documentElement : e, r = t && t.parentNode; + return e === r || !(!r || 1 !== r.nodeType || !(n.contains ? n.contains(r) : e.compareDocumentPosition && 16 & e.compareDocumentPosition(r))) + } : function (e, t) { + if (t)while (t = t.parentNode)if (t === e)return !0; + return !1 + }, S = f.compareDocumentPosition ? function (e, r) { + if (e === r)return E = !0, 0; + var i = r.compareDocumentPosition && e.compareDocumentPosition && e.compareDocumentPosition(r); + return i ? 1 & i || !n.sortDetached && r.compareDocumentPosition(e) === i ? e === t || y(b, e) ? -1 : r === t || y(b, r) ? 1 : l ? P.call(l, e) - P.call(l, r) : 0 : 4 & i ? -1 : 1 : e.compareDocumentPosition ? -1 : 1 + } : function (e, n) { + var r, i = 0, o = e.parentNode, s = n.parentNode, a = [e], u = [n]; + if (e === n)return E = !0, 0; + if (!o || !s)return e === t ? -1 : n === t ? 1 : o ? -1 : s ? 1 : l ? P.call(l, e) - P.call(l, n) : 0; + if (o === s)return ct(e, n); + r = e; + while (r = r.parentNode)a.unshift(r); + r = n; + while (r = r.parentNode)u.unshift(r); + while (a[i] === u[i])i++; + return i ? ct(a[i], u[i]) : a[i] === b ? -1 : u[i] === b ? 1 : 0 + }, t) : p + }, ot.matches = function (e, t) { + return ot(e, null, null, t) + }, ot.matchesSelector = function (e, t) { + if ((e.ownerDocument || e) !== p && c(e), t = t.replace(Y, "='$1']"), !(!n.matchesSelector || !h || g && g.test(t) || d && d.test(t)))try { + var r = m.call(e, t); + if (r || n.disconnectedMatch || e.document && 11 !== e.document.nodeType)return r + } catch (i) { + } + return ot(t, p, null, [e]).length > 0 + }, ot.contains = function (e, t) { + return (e.ownerDocument || e) !== p && c(e), y(e, t) + }, ot.attr = function (e, t) { + (e.ownerDocument || e) !== p && c(e); + var r = i.attrHandle[t.toLowerCase()], o = r && A.call(i.attrHandle, t.toLowerCase()) ? r(e, t, !h) : undefined; + return o === undefined ? n.attributes || !h ? e.getAttribute(t) : (o = e.getAttributeNode(t)) && o.specified ? o.value : null : o + }, ot.error = function (e) { + throw Error("Syntax error, unrecognized expression: " + e) + }, ot.uniqueSort = function (e) { + var t, r = [], i = 0, o = 0; + if (E = !n.detectDuplicates, l = !n.sortStable && e.slice(0), e.sort(S), E) { + while (t = e[o++])t === e[o] && (i = r.push(o)); + while (i--)e.splice(r[i], 1) + } + return e + }, o = ot.getText = function (e) { + var t, n = "", r = 0, i = e.nodeType; + if (i) { + if (1 === i || 9 === i || 11 === i) { + if ("string" == typeof e.textContent)return e.textContent; + for (e = e.firstChild; e; e = e.nextSibling)n += o(e) + } else if (3 === i || 4 === i)return e.nodeValue + } else for (; t = e[r]; r++)n += o(t); + return n + }, i = ot.selectors = { + cacheLength: 50, + createPseudo: at, + match: J, + attrHandle: {}, + find: {}, + relative: { + ">": {dir: "parentNode", first: !0}, + " ": {dir: "parentNode"}, + "+": {dir: "previousSibling", first: !0}, + "~": {dir: "previousSibling"} + }, + preFilter: { + ATTR: function (e) { + return e[1] = e[1].replace(nt, rt), e[3] = (e[4] || e[5] || "").replace(nt, rt), "~=" === e[2] && (e[3] = " " + e[3] + " "), e.slice(0, 4) + }, CHILD: function (e) { + return e[1] = e[1].toLowerCase(), "nth" === e[1].slice(0, 3) ? (e[3] || ot.error(e[0]), e[4] = +(e[4] ? e[5] + (e[6] || 1) : 2 * ("even" === e[3] || "odd" === e[3])), e[5] = +(e[7] + e[8] || "odd" === e[3])) : e[3] && ot.error(e[0]), e + }, PSEUDO: function (e) { + var t, n = !e[5] && e[2]; + return J.CHILD.test(e[0]) ? null : (e[3] && e[4] !== undefined ? e[2] = e[4] : n && V.test(n) && (t = gt(n, !0)) && (t = n.indexOf(")", n.length - t) - n.length) && (e[0] = e[0].slice(0, t), e[2] = n.slice(0, t)), e.slice(0, 3)) + } + }, + filter: { + TAG: function (e) { + var t = e.replace(nt, rt).toLowerCase(); + return "*" === e ? function () { + return !0 + } : function (e) { + return e.nodeName && e.nodeName.toLowerCase() === t + } + }, CLASS: function (e) { + var t = C[e + " "]; + return t || (t = RegExp("(^|" + M + ")" + e + "(" + M + "|$)")) && C(e, function (e) { + return t.test("string" == typeof e.className && e.className || typeof e.getAttribute !== j && e.getAttribute("class") || "") + }) + }, ATTR: function (e, t, n) { + return function (r) { + var i = ot.attr(r, e); + return null == i ? "!=" === t : t ? (i += "", "=" === t ? i === n : "!=" === t ? i !== n : "^=" === t ? n && 0 === i.indexOf(n) : "*=" === t ? n && i.indexOf(n) > -1 : "$=" === t ? n && i.slice(-n.length) === n : "~=" === t ? (" " + i + " ").indexOf(n) > -1 : "|=" === t ? i === n || i.slice(0, n.length + 1) === n + "-" : !1) : !0 + } + }, CHILD: function (e, t, n, r, i) { + var o = "nth" !== e.slice(0, 3), s = "last" !== e.slice(-4), a = "of-type" === t; + return 1 === r && 0 === i ? function (e) { + return !!e.parentNode + } : function (t, n, u) { + var l, c, p, f, h, d, g = o !== s ? "nextSibling" : "previousSibling", m = t.parentNode, y = a && t.nodeName.toLowerCase(), x = !u && !a; + if (m) { + if (o) { + while (g) { + p = t; + while (p = p[g])if (a ? p.nodeName.toLowerCase() === y : 1 === p.nodeType)return !1; + d = g = "only" === e && !d && "nextSibling" + } + return !0 + } + if (d = [s ? m.firstChild : m.lastChild], s && x) { + c = m[v] || (m[v] = {}), l = c[e] || [], h = l[0] === w && l[1], f = l[0] === w && l[2], p = h && m.childNodes[h]; + while (p = ++h && p && p[g] || (f = h = 0) || d.pop())if (1 === p.nodeType && ++f && p === t) { + c[e] = [w, h, f]; + break + } + } else if (x && (l = (t[v] || (t[v] = {}))[e]) && l[0] === w)f = l[1]; else while (p = ++h && p && p[g] || (f = h = 0) || d.pop())if ((a ? p.nodeName.toLowerCase() === y : 1 === p.nodeType) && ++f && (x && ((p[v] || (p[v] = {}))[e] = [w, f]), p === t))break; + return f -= i, f === r || 0 === f % r && f / r >= 0 + } + } + }, PSEUDO: function (e, t) { + var n, r = i.pseudos[e] || i.setFilters[e.toLowerCase()] || ot.error("unsupported pseudo: " + e); + return r[v] ? r(t) : r.length > 1 ? (n = [e, e, "", t], i.setFilters.hasOwnProperty(e.toLowerCase()) ? at(function (e, n) { + var i, o = r(e, t), s = o.length; + while (s--)i = P.call(e, o[s]), e[i] = !(n[i] = o[s]) + }) : function (e) { + return r(e, 0, n) + }) : r + } + }, + pseudos: { + not: at(function (e) { + var t = [], n = [], r = a(e.replace(z, "$1")); + return r[v] ? at(function (e, t, n, i) { + var o, s = r(e, null, i, []), a = e.length; + while (a--)(o = s[a]) && (e[a] = !(t[a] = o)) + }) : function (e, i, o) { + return t[0] = e, r(t, null, o, n), !n.pop() + } + }), has: at(function (e) { + return function (t) { + return ot(e, t).length > 0 + } + }), contains: at(function (e) { + return function (t) { + return (t.textContent || t.innerText || o(t)).indexOf(e) > -1 + } + }), lang: at(function (e) { + return G.test(e || "") || ot.error("unsupported lang: " + e), e = e.replace(nt, rt).toLowerCase(), function (t) { + var n; + do if (n = h ? t.lang : t.getAttribute("xml:lang") || t.getAttribute("lang"))return n = n.toLowerCase(), n === e || 0 === n.indexOf(e + "-"); while ((t = t.parentNode) && 1 === t.nodeType); + return !1 + } + }), target: function (t) { + var n = e.location && e.location.hash; + return n && n.slice(1) === t.id + }, root: function (e) { + return e === f + }, focus: function (e) { + return e === p.activeElement && (!p.hasFocus || p.hasFocus()) && !!(e.type || e.href || ~e.tabIndex) + }, enabled: function (e) { + return e.disabled === !1 + }, disabled: function (e) { + return e.disabled === !0 + }, checked: function (e) { + var t = e.nodeName.toLowerCase(); + return "input" === t && !!e.checked || "option" === t && !!e.selected + }, selected: function (e) { + return e.parentNode && e.parentNode.selectedIndex, e.selected === !0 + }, empty: function (e) { + for (e = e.firstChild; e; e = e.nextSibling)if (e.nodeName > "@" || 3 === e.nodeType || 4 === e.nodeType)return !1; + return !0 + }, parent: function (e) { + return !i.pseudos.empty(e) + }, header: function (e) { + return et.test(e.nodeName) + }, input: function (e) { + return Z.test(e.nodeName) + }, button: function (e) { + var t = e.nodeName.toLowerCase(); + return "input" === t && "button" === e.type || "button" === t + }, text: function (e) { + var t; + return "input" === e.nodeName.toLowerCase() && "text" === e.type && (null == (t = e.getAttribute("type")) || t.toLowerCase() === e.type) + }, first: ht(function () { + return [0] + }), last: ht(function (e, t) { + return [t - 1] + }), eq: ht(function (e, t, n) { + return [0 > n ? n + t : n] + }), even: ht(function (e, t) { + var n = 0; + for (; t > n; n += 2)e.push(n); + return e + }), odd: ht(function (e, t) { + var n = 1; + for (; t > n; n += 2)e.push(n); + return e + }), lt: ht(function (e, t, n) { + var r = 0 > n ? n + t : n; + for (; --r >= 0;)e.push(r); + return e + }), gt: ht(function (e, t, n) { + var r = 0 > n ? n + t : n; + for (; t > ++r;)e.push(r); + return e + }) + } + }, i.pseudos.nth = i.pseudos.eq; + for (t in{radio: !0, checkbox: !0, file: !0, password: !0, image: !0})i.pseudos[t] = pt(t); + for (t in{submit: !0, reset: !0})i.pseudos[t] = ft(t); + function dt() { + } + + dt.prototype = i.filters = i.pseudos, i.setFilters = new dt; + function gt(e, t) { + var n, r, o, s, a, u, l, c = k[e + " "]; + if (c)return t ? 0 : c.slice(0); + a = e, u = [], l = i.preFilter; + while (a) { + (!n || (r = _.exec(a))) && (r && (a = a.slice(r[0].length) || a), u.push(o = [])), n = !1, (r = X.exec(a)) && (n = r.shift(), o.push({ + value: n, + type: r[0].replace(z, " ") + }), a = a.slice(n.length)); + for (s in i.filter)!(r = J[s].exec(a)) || l[s] && !(r = l[s](r)) || (n = r.shift(), o.push({ + value: n, + type: s, + matches: r + }), a = a.slice(n.length)); + if (!n)break + } + return t ? a.length : a ? ot.error(e) : k(e, u).slice(0) + } + + function mt(e) { + var t = 0, n = e.length, r = ""; + for (; n > t; t++)r += e[t].value; + return r + } + + function yt(e, t, n) { + var i = t.dir, o = n && "parentNode" === i, s = T++; + return t.first ? function (t, n, r) { + while (t = t[i])if (1 === t.nodeType || o)return e(t, n, r) + } : function (t, n, a) { + var u, l, c, p = w + " " + s; + if (a) { + while (t = t[i])if ((1 === t.nodeType || o) && e(t, n, a))return !0 + } else while (t = t[i])if (1 === t.nodeType || o)if (c = t[v] || (t[v] = {}), (l = c[i]) && l[0] === p) { + if ((u = l[1]) === !0 || u === r)return u === !0 + } else if (l = c[i] = [p], l[1] = e(t, n, a) || r, l[1] === !0)return !0 + } + } + + function vt(e) { + return e.length > 1 ? function (t, n, r) { + var i = e.length; + while (i--)if (!e[i](t, n, r))return !1; + return !0 + } : e[0] + } + + function xt(e, t, n, r, i) { + var o, s = [], a = 0, u = e.length, l = null != t; + for (; u > a; a++)(o = e[a]) && (!n || n(o, r, i)) && (s.push(o), l && t.push(a)); + return s + } + + function bt(e, t, n, r, i, o) { + return r && !r[v] && (r = bt(r)), i && !i[v] && (i = bt(i, o)), at(function (o, s, a, u) { + var l, c, p, f = [], h = [], d = s.length, g = o || Ct(t || "*", a.nodeType ? [a] : a, []), m = !e || !o && t ? g : xt(g, f, e, a, u), y = n ? i || (o ? e : d || r) ? [] : s : m; + if (n && n(m, y, a, u), r) { + l = xt(y, h), r(l, [], a, u), c = l.length; + while (c--)(p = l[c]) && (y[h[c]] = !(m[h[c]] = p)) + } + if (o) { + if (i || e) { + if (i) { + l = [], c = y.length; + while (c--)(p = y[c]) && l.push(m[c] = p); + i(null, y = [], l, u) + } + c = y.length; + while (c--)(p = y[c]) && (l = i ? P.call(o, p) : f[c]) > -1 && (o[l] = !(s[l] = p)) + } + } else y = xt(y === s ? y.splice(d, y.length) : y), i ? i(null, s, y, u) : O.apply(s, y) + }) + } + + function wt(e) { + var t, n, r, o = e.length, s = i.relative[e[0].type], a = s || i.relative[" "], l = s ? 1 : 0, c = yt(function (e) { + return e === t + }, a, !0), p = yt(function (e) { + return P.call(t, e) > -1 + }, a, !0), f = [function (e, n, r) { + return !s && (r || n !== u) || ((t = n).nodeType ? c(e, n, r) : p(e, n, r)) + }]; + for (; o > l; l++)if (n = i.relative[e[l].type])f = [yt(vt(f), n)]; else { + if (n = i.filter[e[l].type].apply(null, e[l].matches), n[v]) { + for (r = ++l; o > r; r++)if (i.relative[e[r].type])break; + return bt(l > 1 && vt(f), l > 1 && mt(e.slice(0, l - 1).concat({value: " " === e[l - 2].type ? "*" : ""})).replace(z, "$1"), n, r > l && wt(e.slice(l, r)), o > r && wt(e = e.slice(r)), o > r && mt(e)) + } + f.push(n) + } + return vt(f) + } + + function Tt(e, t) { + var n = 0, o = t.length > 0, s = e.length > 0, a = function (a, l, c, f, h) { + var d, g, m, y = [], v = 0, x = "0", b = a && [], T = null != h, C = u, k = a || s && i.find.TAG("*", h && l.parentNode || l), N = w += null == C ? 1 : Math.random() || .1; + for (T && (u = l !== p && l, r = n); null != (d = k[x]); x++) { + if (s && d) { + g = 0; + while (m = e[g++])if (m(d, l, c)) { + f.push(d); + break + } + T && (w = N, r = ++n) + } + o && ((d = !m && d) && v--, a && b.push(d)) + } + if (v += x, o && x !== v) { + g = 0; + while (m = t[g++])m(b, y, l, c); + if (a) { + if (v > 0)while (x--)b[x] || y[x] || (y[x] = q.call(f)); + y = xt(y) + } + O.apply(f, y), T && !a && y.length > 0 && v + t.length > 1 && ot.uniqueSort(f) + } + return T && (w = N, u = C), b + }; + return o ? at(a) : a + } + + a = ot.compile = function (e, t) { + var n, r = [], i = [], o = N[e + " "]; + if (!o) { + t || (t = gt(e)), n = t.length; + while (n--)o = wt(t[n]), o[v] ? r.push(o) : i.push(o); + o = N(e, Tt(i, r)) + } + return o + }; + function Ct(e, t, n) { + var r = 0, i = t.length; + for (; i > r; r++)ot(e, t[r], n); + return n + } + + function kt(e, t, r, o) { + var s, u, l, c, p, f = gt(e); + if (!o && 1 === f.length) { + if (u = f[0] = f[0].slice(0), u.length > 2 && "ID" === (l = u[0]).type && n.getById && 9 === t.nodeType && h && i.relative[u[1].type]) { + if (t = (i.find.ID(l.matches[0].replace(nt, rt), t) || [])[0], !t)return r; + e = e.slice(u.shift().value.length) + } + s = J.needsContext.test(e) ? 0 : u.length; + while (s--) { + if (l = u[s], i.relative[c = l.type])break; + if ((p = i.find[c]) && (o = p(l.matches[0].replace(nt, rt), U.test(u[0].type) && t.parentNode || t))) { + if (u.splice(s, 1), e = o.length && mt(u), !e)return O.apply(r, o), r; + break + } + } + } + return a(e, f)(o, t, !h, r, U.test(e)), r + } + + n.sortStable = v.split("").sort(S).join("") === v, n.detectDuplicates = E, c(), n.sortDetached = ut(function (e) { + return 1 & e.compareDocumentPosition(p.createElement("div")) + }), ut(function (e) { + return e.innerHTML = "", "#" === e.firstChild.getAttribute("href") + }) || lt("type|href|height|width", function (e, t, n) { + return n ? undefined : e.getAttribute(t, "type" === t.toLowerCase() ? 1 : 2) + }), n.attributes && ut(function (e) { + return e.innerHTML = "", e.firstChild.setAttribute("value", ""), "" === e.firstChild.getAttribute("value") + }) || lt("value", function (e, t, n) { + return n || "input" !== e.nodeName.toLowerCase() ? undefined : e.defaultValue + }), ut(function (e) { + return null == e.getAttribute("disabled") + }) || lt(R, function (e, t, n) { + var r; + return n ? undefined : (r = e.getAttributeNode(t)) && r.specified ? r.value : e[t] === !0 ? t.toLowerCase() : null + }), x.find = ot, x.expr = ot.selectors, x.expr[":"] = x.expr.pseudos, x.unique = ot.uniqueSort, x.text = ot.getText, x.isXMLDoc = ot.isXML, x.contains = ot.contains + }(e); + var D = {}; + + function A(e) { + var t = D[e] = {}; + return x.each(e.match(w) || [], function (e, n) { + t[n] = !0 + }), t + } + + x.Callbacks = function (e) { + e = "string" == typeof e ? D[e] || A(e) : x.extend({}, e); + var t, n, r, i, o, s, a = [], u = !e.once && [], l = function (p) { + for (t = e.memory && p, n = !0, s = i || 0, i = 0, o = a.length, r = !0; a && o > s; s++)if (a[s].apply(p[0], p[1]) === !1 && e.stopOnFalse) { + t = !1; + break + } + r = !1, a && (u ? u.length && l(u.shift()) : t ? a = [] : c.disable()) + }, c = { + add: function () { + if (a) { + var n = a.length; + (function s(t) { + x.each(t, function (t, n) { + var r = x.type(n); + "function" === r ? e.unique && c.has(n) || a.push(n) : n && n.length && "string" !== r && s(n) + }) + })(arguments), r ? o = a.length : t && (i = n, l(t)) + } + return this + }, remove: function () { + return a && x.each(arguments, function (e, t) { + var n; + while ((n = x.inArray(t, a, n)) > -1)a.splice(n, 1), r && (o >= n && o--, s >= n && s--) + }), this + }, has: function (e) { + return e ? x.inArray(e, a) > -1 : !(!a || !a.length) + }, empty: function () { + return a = [], o = 0, this + }, disable: function () { + return a = u = t = undefined, this + }, disabled: function () { + return !a + }, lock: function () { + return u = undefined, t || c.disable(), this + }, locked: function () { + return !u + }, fireWith: function (e, t) { + return !a || n && !u || (t = t || [], t = [e, t.slice ? t.slice() : t], r ? u.push(t) : l(t)), this + }, fire: function () { + return c.fireWith(this, arguments), this + }, fired: function () { + return !!n + } + }; + return c + }, x.extend({ + Deferred: function (e) { + var t = [["resolve", "done", x.Callbacks("once memory"), "resolved"], ["reject", "fail", x.Callbacks("once memory"), "rejected"], ["notify", "progress", x.Callbacks("memory")]], n = "pending", r = { + state: function () { + return n + }, always: function () { + return i.done(arguments).fail(arguments), this + }, then: function () { + var e = arguments; + return x.Deferred(function (n) { + x.each(t, function (t, o) { + var s = o[0], a = x.isFunction(e[t]) && e[t]; + i[o[1]](function () { + var e = a && a.apply(this, arguments); + e && x.isFunction(e.promise) ? e.promise().done(n.resolve).fail(n.reject).progress(n.notify) : n[s + "With"](this === r ? n.promise() : this, a ? [e] : arguments) + }) + }), e = null + }).promise() + }, promise: function (e) { + return null != e ? x.extend(e, r) : r + } + }, i = {}; + return r.pipe = r.then, x.each(t, function (e, o) { + var s = o[2], a = o[3]; + r[o[1]] = s.add, a && s.add(function () { + n = a + }, t[1 ^ e][2].disable, t[2][2].lock), i[o[0]] = function () { + return i[o[0] + "With"](this === i ? r : this, arguments), this + }, i[o[0] + "With"] = s.fireWith + }), r.promise(i), e && e.call(i, i), i + }, when: function (e) { + var t = 0, n = d.call(arguments), r = n.length, i = 1 !== r || e && x.isFunction(e.promise) ? r : 0, o = 1 === i ? e : x.Deferred(), s = function (e, t, n) { + return function (r) { + t[e] = this, n[e] = arguments.length > 1 ? d.call(arguments) : r, n === a ? o.notifyWith(t, n) : --i || o.resolveWith(t, n) + } + }, a, u, l; + if (r > 1)for (a = Array(r), u = Array(r), l = Array(r); r > t; t++)n[t] && x.isFunction(n[t].promise) ? n[t].promise().done(s(t, l, n)).fail(o.reject).progress(s(t, u, a)) : --i; + return i || o.resolveWith(l, n), o.promise() + } + }), x.support = function (t) { + var n = o.createElement("input"), r = o.createDocumentFragment(), i = o.createElement("div"), s = o.createElement("select"), a = s.appendChild(o.createElement("option")); + return n.type ? (n.type = "checkbox", t.checkOn = "" !== n.value, t.optSelected = a.selected, t.reliableMarginRight = !0, t.boxSizingReliable = !0, t.pixelPosition = !1, n.checked = !0, t.noCloneChecked = n.cloneNode(!0).checked, s.disabled = !0, t.optDisabled = !a.disabled, n = o.createElement("input"), n.value = "t", n.type = "radio", t.radioValue = "t" === n.value, n.setAttribute("checked", "t"), n.setAttribute("name", "t"), r.appendChild(n), t.checkClone = r.cloneNode(!0).cloneNode(!0).lastChild.checked, t.focusinBubbles = "onfocusin"in e, i.style.backgroundClip = "content-box", i.cloneNode(!0).style.backgroundClip = "", t.clearCloneStyle = "content-box" === i.style.backgroundClip, x(function () { + var n, r, s = "padding:0;margin:0;border:0;display:block;-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box", a = o.getElementsByTagName("body")[0]; + a && (n = o.createElement("div"), n.style.cssText = "border:0;width:0;height:0;position:absolute;top:0;left:-9999px;margin-top:1px", a.appendChild(n).appendChild(i), i.innerHTML = "", i.style.cssText = "-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;padding:1px;border:1px;display:block;width:4px;margin-top:1%;position:absolute;top:1%", x.swap(a, null != a.style.zoom ? {zoom: 1} : {}, function () { + t.boxSizing = 4 === i.offsetWidth + }), e.getComputedStyle && (t.pixelPosition = "1%" !== (e.getComputedStyle(i, null) || {}).top, t.boxSizingReliable = "4px" === (e.getComputedStyle(i, null) || {width: "4px"}).width, r = i.appendChild(o.createElement("div")), r.style.cssText = i.style.cssText = s, r.style.marginRight = r.style.width = "0", i.style.width = "1px", t.reliableMarginRight = !parseFloat((e.getComputedStyle(r, null) || {}).marginRight)), a.removeChild(n)) + }), t) : t + }({}); + var L, q, H = /(?:\{[\s\S]*\}|\[[\s\S]*\])$/, O = /([A-Z])/g; + + function F() { + Object.defineProperty(this.cache = {}, 0, { + get: function () { + return {} + } + }), this.expando = x.expando + Math.random() + } + + F.uid = 1, F.accepts = function (e) { + return e.nodeType ? 1 === e.nodeType || 9 === e.nodeType : !0 + }, F.prototype = { + key: function (e) { + if (!F.accepts(e))return 0; + var t = {}, n = e[this.expando]; + if (!n) { + n = F.uid++; + try { + t[this.expando] = {value: n}, Object.defineProperties(e, t) + } catch (r) { + t[this.expando] = n, x.extend(e, t) + } + } + return this.cache[n] || (this.cache[n] = {}), n + }, set: function (e, t, n) { + var r, i = this.key(e), o = this.cache[i]; + if ("string" == typeof t)o[t] = n; else if (x.isEmptyObject(o))x.extend(this.cache[i], t); else for (r in t)o[r] = t[r]; + return o + }, get: function (e, t) { + var n = this.cache[this.key(e)]; + return t === undefined ? n : n[t] + }, access: function (e, t, n) { + var r; + return t === undefined || t && "string" == typeof t && n === undefined ? (r = this.get(e, t), r !== undefined ? r : this.get(e, x.camelCase(t))) : (this.set(e, t, n), n !== undefined ? n : t) + }, remove: function (e, t) { + var n, r, i, o = this.key(e), s = this.cache[o]; + if (t === undefined)this.cache[o] = {}; else { + x.isArray(t) ? r = t.concat(t.map(x.camelCase)) : (i = x.camelCase(t), t in s ? r = [t, i] : (r = i, r = r in s ? [r] : r.match(w) || [])), n = r.length; + while (n--)delete s[r[n]] + } + }, hasData: function (e) { + return !x.isEmptyObject(this.cache[e[this.expando]] || {}) + }, discard: function (e) { + e[this.expando] && delete this.cache[e[this.expando]] + } + }, L = new F, q = new F, x.extend({ + acceptData: F.accepts, hasData: function (e) { + return L.hasData(e) || q.hasData(e) + }, data: function (e, t, n) { + return L.access(e, t, n) + }, removeData: function (e, t) { + L.remove(e, t) + }, _data: function (e, t, n) { + return q.access(e, t, n) + }, _removeData: function (e, t) { + q.remove(e, t) + } + }), x.fn.extend({ + data: function (e, t) { + var n, r, i = this[0], o = 0, s = null; + if (e === undefined) { + if (this.length && (s = L.get(i), 1 === i.nodeType && !q.get(i, "hasDataAttrs"))) { + for (n = i.attributes; n.length > o; o++)r = n[o].name, 0 === r.indexOf("data-") && (r = x.camelCase(r.slice(5)), P(i, r, s[r])); + q.set(i, "hasDataAttrs", !0) + } + return s + } + return "object" == typeof e ? this.each(function () { + L.set(this, e) + }) : x.access(this, function (t) { + var n, r = x.camelCase(e); + if (i && t === undefined) { + if (n = L.get(i, e), n !== undefined)return n; + if (n = L.get(i, r), n !== undefined)return n; + if (n = P(i, r, undefined), n !== undefined)return n + } else this.each(function () { + var n = L.get(this, r); + L.set(this, r, t), -1 !== e.indexOf("-") && n !== undefined && L.set(this, e, t) + }) + }, null, t, arguments.length > 1, null, !0) + }, removeData: function (e) { + return this.each(function () { + L.remove(this, e) + }) + } + }); + function P(e, t, n) { + var r; + if (n === undefined && 1 === e.nodeType)if (r = "data-" + t.replace(O, "-$1").toLowerCase(), n = e.getAttribute(r), "string" == typeof n) { + try { + n = "true" === n ? !0 : "false" === n ? !1 : "null" === n ? null : +n + "" === n ? +n : H.test(n) ? JSON.parse(n) : n + } catch (i) { + } + L.set(e, t, n) + } else n = undefined; + return n + } + + x.extend({ + queue: function (e, t, n) { + var r; + return e ? (t = (t || "fx") + "queue", r = q.get(e, t), n && (!r || x.isArray(n) ? r = q.access(e, t, x.makeArray(n)) : r.push(n)), r || []) : undefined + }, dequeue: function (e, t) { + t = t || "fx"; + var n = x.queue(e, t), r = n.length, i = n.shift(), o = x._queueHooks(e, t), s = function () { + x.dequeue(e, t) + }; + "inprogress" === i && (i = n.shift(), r--), i && ("fx" === t && n.unshift("inprogress"), delete o.stop, i.call(e, s, o)), !r && o && o.empty.fire() + }, _queueHooks: function (e, t) { + var n = t + "queueHooks"; + return q.get(e, n) || q.access(e, n, { + empty: x.Callbacks("once memory").add(function () { + q.remove(e, [t + "queue", n]) + }) + }) + } + }), x.fn.extend({ + queue: function (e, t) { + var n = 2; + return "string" != typeof e && (t = e, e = "fx", n--), n > arguments.length ? x.queue(this[0], e) : t === undefined ? this : this.each(function () { + var n = x.queue(this, e, t); + x._queueHooks(this, e), "fx" === e && "inprogress" !== n[0] && x.dequeue(this, e) + }) + }, dequeue: function (e) { + return this.each(function () { + x.dequeue(this, e) + }) + }, delay: function (e, t) { + return e = x.fx ? x.fx.speeds[e] || e : e, t = t || "fx", this.queue(t, function (t, n) { + var r = setTimeout(t, e); + n.stop = function () { + clearTimeout(r) + } + }) + }, clearQueue: function (e) { + return this.queue(e || "fx", []) + }, promise: function (e, t) { + var n, r = 1, i = x.Deferred(), o = this, s = this.length, a = function () { + --r || i.resolveWith(o, [o]) + }; + "string" != typeof e && (t = e, e = undefined), e = e || "fx"; + while (s--)n = q.get(o[s], e + "queueHooks"), n && n.empty && (r++, n.empty.add(a)); + return a(), i.promise(t) + } + }); + var R, M, W = /[\t\r\n\f]/g, $ = /\r/g, B = /^(?:input|select|textarea|button)$/i; + x.fn.extend({ + attr: function (e, t) { + return x.access(this, x.attr, e, t, arguments.length > 1) + }, removeAttr: function (e) { + return this.each(function () { + x.removeAttr(this, e) + }) + }, prop: function (e, t) { + return x.access(this, x.prop, e, t, arguments.length > 1) + }, removeProp: function (e) { + return this.each(function () { + delete this[x.propFix[e] || e] + }) + }, addClass: function (e) { + var t, n, r, i, o, s = 0, a = this.length, u = "string" == typeof e && e; + if (x.isFunction(e))return this.each(function (t) { + x(this).addClass(e.call(this, t, this.className)) + }); + if (u)for (t = (e || "").match(w) || []; a > s; s++)if (n = this[s], r = 1 === n.nodeType && (n.className ? (" " + n.className + " ").replace(W, " ") : " ")) { + o = 0; + while (i = t[o++])0 > r.indexOf(" " + i + " ") && (r += i + " "); + n.className = x.trim(r) + } + return this + }, removeClass: function (e) { + var t, n, r, i, o, s = 0, a = this.length, u = 0 === arguments.length || "string" == typeof e && e; + if (x.isFunction(e))return this.each(function (t) { + x(this).removeClass(e.call(this, t, this.className)) + }); + if (u)for (t = (e || "").match(w) || []; a > s; s++)if (n = this[s], r = 1 === n.nodeType && (n.className ? (" " + n.className + " ").replace(W, " ") : "")) { + o = 0; + while (i = t[o++])while (r.indexOf(" " + i + " ") >= 0)r = r.replace(" " + i + " ", " "); + n.className = e ? x.trim(r) : "" + } + return this + }, toggleClass: function (e, t) { + var n = typeof e; + return "boolean" == typeof t && "string" === n ? t ? this.addClass(e) : this.removeClass(e) : x.isFunction(e) ? this.each(function (n) { + x(this).toggleClass(e.call(this, n, this.className, t), t) + }) : this.each(function () { + if ("string" === n) { + var t, i = 0, o = x(this), s = e.match(w) || []; + while (t = s[i++])o.hasClass(t) ? o.removeClass(t) : o.addClass(t) + } else(n === r || "boolean" === n) && (this.className && q.set(this, "__className__", this.className), this.className = this.className || e === !1 ? "" : q.get(this, "__className__") || "") + }) + }, hasClass: function (e) { + var t = " " + e + " ", n = 0, r = this.length; + for (; r > n; n++)if (1 === this[n].nodeType && (" " + this[n].className + " ").replace(W, " ").indexOf(t) >= 0)return !0; + return !1 + }, val: function (e) { + var t, n, r, i = this[0]; + { + if (arguments.length)return r = x.isFunction(e), this.each(function (n) { + var i; + 1 === this.nodeType && (i = r ? e.call(this, n, x(this).val()) : e, null == i ? i = "" : "number" == typeof i ? i += "" : x.isArray(i) && (i = x.map(i, function (e) { + return null == e ? "" : e + "" + })), t = x.valHooks[this.type] || x.valHooks[this.nodeName.toLowerCase()], t && "set"in t && t.set(this, i, "value") !== undefined || (this.value = i)) + }); + if (i)return t = x.valHooks[i.type] || x.valHooks[i.nodeName.toLowerCase()], t && "get"in t && (n = t.get(i, "value")) !== undefined ? n : (n = i.value, "string" == typeof n ? n.replace($, "") : null == n ? "" : n) + } + } + }), x.extend({ + valHooks: { + option: { + get: function (e) { + var t = e.attributes.value; + return !t || t.specified ? e.value : e.text + } + }, select: { + get: function (e) { + var t, n, r = e.options, i = e.selectedIndex, o = "select-one" === e.type || 0 > i, s = o ? null : [], a = o ? i + 1 : r.length, u = 0 > i ? a : o ? i : 0; + for (; a > u; u++)if (n = r[u], !(!n.selected && u !== i || (x.support.optDisabled ? n.disabled : null !== n.getAttribute("disabled")) || n.parentNode.disabled && x.nodeName(n.parentNode, "optgroup"))) { + if (t = x(n).val(), o)return t; + s.push(t) + } + return s + }, set: function (e, t) { + var n, r, i = e.options, o = x.makeArray(t), s = i.length; + while (s--)r = i[s], (r.selected = x.inArray(x(r).val(), o) >= 0) && (n = !0); + return n || (e.selectedIndex = -1), o + } + } + }, attr: function (e, t, n) { + var i, o, s = e.nodeType; + if (e && 3 !== s && 8 !== s && 2 !== s)return typeof e.getAttribute === r ? x.prop(e, t, n) : (1 === s && x.isXMLDoc(e) || (t = t.toLowerCase(), i = x.attrHooks[t] || (x.expr.match.bool.test(t) ? M : R)), n === undefined ? i && "get"in i && null !== (o = i.get(e, t)) ? o : (o = x.find.attr(e, t), null == o ? undefined : o) : null !== n ? i && "set"in i && (o = i.set(e, n, t)) !== undefined ? o : (e.setAttribute(t, n + ""), n) : (x.removeAttr(e, t), undefined)) + }, removeAttr: function (e, t) { + var n, r, i = 0, o = t && t.match(w); + if (o && 1 === e.nodeType)while (n = o[i++])r = x.propFix[n] || n, x.expr.match.bool.test(n) && (e[r] = !1), e.removeAttribute(n) + }, attrHooks: { + type: { + set: function (e, t) { + if (!x.support.radioValue && "radio" === t && x.nodeName(e, "input")) { + var n = e.value; + return e.setAttribute("type", t), n && (e.value = n), t + } + } + } + }, propFix: {"for": "htmlFor", "class": "className"}, prop: function (e, t, n) { + var r, i, o, s = e.nodeType; + if (e && 3 !== s && 8 !== s && 2 !== s)return o = 1 !== s || !x.isXMLDoc(e), o && (t = x.propFix[t] || t, i = x.propHooks[t]), n !== undefined ? i && "set"in i && (r = i.set(e, n, t)) !== undefined ? r : e[t] = n : i && "get"in i && null !== (r = i.get(e, t)) ? r : e[t] + }, propHooks: { + tabIndex: { + get: function (e) { + return e.hasAttribute("tabindex") || B.test(e.nodeName) || e.href ? e.tabIndex : -1 + } + } + } + }), M = { + set: function (e, t, n) { + return t === !1 ? x.removeAttr(e, n) : e.setAttribute(n, n), n + } + }, x.each(x.expr.match.bool.source.match(/\w+/g), function (e, t) { + var n = x.expr.attrHandle[t] || x.find.attr; + x.expr.attrHandle[t] = function (e, t, r) { + var i = x.expr.attrHandle[t], o = r ? undefined : (x.expr.attrHandle[t] = undefined) != n(e, t, r) ? t.toLowerCase() : null; + return x.expr.attrHandle[t] = i, o + } + }), x.support.optSelected || (x.propHooks.selected = { + get: function (e) { + var t = e.parentNode; + return t && t.parentNode && t.parentNode.selectedIndex, null + } + }), x.each(["tabIndex", "readOnly", "maxLength", "cellSpacing", "cellPadding", "rowSpan", "colSpan", "useMap", "frameBorder", "contentEditable"], function () { + x.propFix[this.toLowerCase()] = this + }), x.each(["radio", "checkbox"], function () { + x.valHooks[this] = { + set: function (e, t) { + return x.isArray(t) ? e.checked = x.inArray(x(e).val(), t) >= 0 : undefined + } + }, x.support.checkOn || (x.valHooks[this].get = function (e) { + return null === e.getAttribute("value") ? "on" : e.value + }) + }); + var I = /^key/, z = /^(?:mouse|contextmenu)|click/, _ = /^(?:focusinfocus|focusoutblur)$/, X = /^([^.]*)(?:\.(.+)|)$/; + + function U() { + return !0 + } + + function Y() { + return !1 + } + + function V() { + try { + return o.activeElement + } catch (e) { + } + } + + x.event = { + global: {}, + add: function (e, t, n, i, o) { + var s, a, u, l, c, p, f, h, d, g, m, y = q.get(e); + if (y) { + n.handler && (s = n, n = s.handler, o = s.selector), n.guid || (n.guid = x.guid++), (l = y.events) || (l = y.events = {}), (a = y.handle) || (a = y.handle = function (e) { + return typeof x === r || e && x.event.triggered === e.type ? undefined : x.event.dispatch.apply(a.elem, arguments) + }, a.elem = e), t = (t || "").match(w) || [""], c = t.length; + while (c--)u = X.exec(t[c]) || [], d = m = u[1], g = (u[2] || "").split(".").sort(), d && (f = x.event.special[d] || {}, d = (o ? f.delegateType : f.bindType) || d, f = x.event.special[d] || {}, p = x.extend({ + type: d, + origType: m, + data: i, + handler: n, + guid: n.guid, + selector: o, + needsContext: o && x.expr.match.needsContext.test(o), + namespace: g.join(".") + }, s), (h = l[d]) || (h = l[d] = [], h.delegateCount = 0, f.setup && f.setup.call(e, i, g, a) !== !1 || e.addEventListener && e.addEventListener(d, a, !1)), f.add && (f.add.call(e, p), p.handler.guid || (p.handler.guid = n.guid)), o ? h.splice(h.delegateCount++, 0, p) : h.push(p), x.event.global[d] = !0); + e = null + } + }, + remove: function (e, t, n, r, i) { + var o, s, a, u, l, c, p, f, h, d, g, m = q.hasData(e) && q.get(e); + if (m && (u = m.events)) { + t = (t || "").match(w) || [""], l = t.length; + while (l--)if (a = X.exec(t[l]) || [], h = g = a[1], d = (a[2] || "").split(".").sort(), h) { + p = x.event.special[h] || {}, h = (r ? p.delegateType : p.bindType) || h, f = u[h] || [], a = a[2] && RegExp("(^|\\.)" + d.join("\\.(?:.*\\.|)") + "(\\.|$)"), s = o = f.length; + while (o--)c = f[o], !i && g !== c.origType || n && n.guid !== c.guid || a && !a.test(c.namespace) || r && r !== c.selector && ("**" !== r || !c.selector) || (f.splice(o, 1), c.selector && f.delegateCount--, p.remove && p.remove.call(e, c)); + s && !f.length && (p.teardown && p.teardown.call(e, d, m.handle) !== !1 || x.removeEvent(e, h, m.handle), delete u[h]) + } else for (h in u)x.event.remove(e, h + t[l], n, r, !0); + x.isEmptyObject(u) && (delete m.handle, q.remove(e, "events")) + } + }, + trigger: function (t, n, r, i) { + var s, a, u, l, c, p, f, h = [r || o], d = y.call(t, "type") ? t.type : t, g = y.call(t, "namespace") ? t.namespace.split(".") : []; + if (a = u = r = r || o, 3 !== r.nodeType && 8 !== r.nodeType && !_.test(d + x.event.triggered) && (d.indexOf(".") >= 0 && (g = d.split("."), d = g.shift(), g.sort()), c = 0 > d.indexOf(":") && "on" + d, t = t[x.expando] ? t : new x.Event(d, "object" == typeof t && t), t.isTrigger = i ? 2 : 3, t.namespace = g.join("."), t.namespace_re = t.namespace ? RegExp("(^|\\.)" + g.join("\\.(?:.*\\.|)") + "(\\.|$)") : null, t.result = undefined, t.target || (t.target = r), n = null == n ? [t] : x.makeArray(n, [t]), f = x.event.special[d] || {}, i || !f.trigger || f.trigger.apply(r, n) !== !1)) { + if (!i && !f.noBubble && !x.isWindow(r)) { + for (l = f.delegateType || d, _.test(l + d) || (a = a.parentNode); a; a = a.parentNode)h.push(a), u = a; + u === (r.ownerDocument || o) && h.push(u.defaultView || u.parentWindow || e) + } + s = 0; + while ((a = h[s++]) && !t.isPropagationStopped())t.type = s > 1 ? l : f.bindType || d, p = (q.get(a, "events") || {})[t.type] && q.get(a, "handle"), p && p.apply(a, n), p = c && a[c], p && x.acceptData(a) && p.apply && p.apply(a, n) === !1 && t.preventDefault(); + return t.type = d, i || t.isDefaultPrevented() || f._default && f._default.apply(h.pop(), n) !== !1 || !x.acceptData(r) || c && x.isFunction(r[d]) && !x.isWindow(r) && (u = r[c], u && (r[c] = null), x.event.triggered = d, r[d](), x.event.triggered = undefined, u && (r[c] = u)), t.result + } + }, + dispatch: function (e) { + e = x.event.fix(e); + var t, n, r, i, o, s = [], a = d.call(arguments), u = (q.get(this, "events") || {})[e.type] || [], l = x.event.special[e.type] || {}; + if (a[0] = e, e.delegateTarget = this, !l.preDispatch || l.preDispatch.call(this, e) !== !1) { + s = x.event.handlers.call(this, e, u), t = 0; + while ((i = s[t++]) && !e.isPropagationStopped()) { + e.currentTarget = i.elem, n = 0; + while ((o = i.handlers[n++]) && !e.isImmediatePropagationStopped())(!e.namespace_re || e.namespace_re.test(o.namespace)) && (e.handleObj = o, e.data = o.data, r = ((x.event.special[o.origType] || {}).handle || o.handler).apply(i.elem, a), r !== undefined && (e.result = r) === !1 && (e.preventDefault(), e.stopPropagation())) + } + return l.postDispatch && l.postDispatch.call(this, e), e.result + } + }, + handlers: function (e, t) { + var n, r, i, o, s = [], a = t.delegateCount, u = e.target; + if (a && u.nodeType && (!e.button || "click" !== e.type))for (; u !== this; u = u.parentNode || this)if (u.disabled !== !0 || "click" !== e.type) { + for (r = [], n = 0; a > n; n++)o = t[n], i = o.selector + " ", r[i] === undefined && (r[i] = o.needsContext ? x(i, this).index(u) >= 0 : x.find(i, this, null, [u]).length), r[i] && r.push(o); + r.length && s.push({elem: u, handlers: r}) + } + return t.length > a && s.push({elem: this, handlers: t.slice(a)}), s + }, + props: "altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "), + fixHooks: {}, + keyHooks: { + props: "char charCode key keyCode".split(" "), filter: function (e, t) { + return null == e.which && (e.which = null != t.charCode ? t.charCode : t.keyCode), e + } + }, + mouseHooks: { + props: "button buttons clientX clientY offsetX offsetY pageX pageY screenX screenY toElement".split(" "), + filter: function (e, t) { + var n, r, i, s = t.button; + return null == e.pageX && null != t.clientX && (n = e.target.ownerDocument || o, r = n.documentElement, i = n.body, e.pageX = t.clientX + (r && r.scrollLeft || i && i.scrollLeft || 0) - (r && r.clientLeft || i && i.clientLeft || 0), e.pageY = t.clientY + (r && r.scrollTop || i && i.scrollTop || 0) - (r && r.clientTop || i && i.clientTop || 0)), e.which || s === undefined || (e.which = 1 & s ? 1 : 2 & s ? 3 : 4 & s ? 2 : 0), e + } + }, + fix: function (e) { + if (e[x.expando])return e; + var t, n, r, i = e.type, s = e, a = this.fixHooks[i]; + a || (this.fixHooks[i] = a = z.test(i) ? this.mouseHooks : I.test(i) ? this.keyHooks : {}), r = a.props ? this.props.concat(a.props) : this.props, e = new x.Event(s), t = r.length; + while (t--)n = r[t], e[n] = s[n]; + return e.target || (e.target = o), 3 === e.target.nodeType && (e.target = e.target.parentNode), a.filter ? a.filter(e, s) : e + }, + special: { + load: {noBubble: !0}, focus: { + trigger: function () { + return this !== V() && this.focus ? (this.focus(), !1) : undefined + }, delegateType: "focusin" + }, blur: { + trigger: function () { + return this === V() && this.blur ? (this.blur(), !1) : undefined + }, delegateType: "focusout" + }, click: { + trigger: function () { + return "checkbox" === this.type && this.click && x.nodeName(this, "input") ? (this.click(), !1) : undefined + }, _default: function (e) { + return x.nodeName(e.target, "a") + } + }, beforeunload: { + postDispatch: function (e) { + e.result !== undefined && (e.originalEvent.returnValue = e.result) + } + } + }, + simulate: function (e, t, n, r) { + var i = x.extend(new x.Event, n, {type: e, isSimulated: !0, originalEvent: {}}); + r ? x.event.trigger(i, null, t) : x.event.dispatch.call(t, i), i.isDefaultPrevented() && n.preventDefault() + } + }, x.removeEvent = function (e, t, n) { + e.removeEventListener && e.removeEventListener(t, n, !1) + }, x.Event = function (e, t) { + return this instanceof x.Event ? (e && e.type ? (this.originalEvent = e, this.type = e.type, this.isDefaultPrevented = e.defaultPrevented || e.getPreventDefault && e.getPreventDefault() ? U : Y) : this.type = e, t && x.extend(this, t), this.timeStamp = e && e.timeStamp || x.now(), this[x.expando] = !0, undefined) : new x.Event(e, t) + }, x.Event.prototype = { + isDefaultPrevented: Y, + isPropagationStopped: Y, + isImmediatePropagationStopped: Y, + preventDefault: function () { + var e = this.originalEvent; + this.isDefaultPrevented = U, e && e.preventDefault && e.preventDefault() + }, + stopPropagation: function () { + var e = this.originalEvent; + this.isPropagationStopped = U, e && e.stopPropagation && e.stopPropagation() + }, + stopImmediatePropagation: function () { + this.isImmediatePropagationStopped = U, this.stopPropagation() + } + }, x.each({mouseenter: "mouseover", mouseleave: "mouseout"}, function (e, t) { + x.event.special[e] = { + delegateType: t, bindType: t, handle: function (e) { + var n, r = this, i = e.relatedTarget, o = e.handleObj; + return (!i || i !== r && !x.contains(r, i)) && (e.type = o.origType, n = o.handler.apply(this, arguments), e.type = t), n + } + } + }), x.support.focusinBubbles || x.each({focus: "focusin", blur: "focusout"}, function (e, t) { + var n = 0, r = function (e) { + x.event.simulate(t, e.target, x.event.fix(e), !0) + }; + x.event.special[t] = { + setup: function () { + 0 === n++ && o.addEventListener(e, r, !0) + }, teardown: function () { + 0 === --n && o.removeEventListener(e, r, !0) + } + } + }), x.fn.extend({ + on: function (e, t, n, r, i) { + var o, s; + if ("object" == typeof e) { + "string" != typeof t && (n = n || t, t = undefined); + for (s in e)this.on(s, t, n, e[s], i); + return this + } + if (null == n && null == r ? (r = t, n = t = undefined) : null == r && ("string" == typeof t ? (r = n, n = undefined) : (r = n, n = t, t = undefined)), r === !1)r = Y; else if (!r)return this; + return 1 === i && (o = r, r = function (e) { + return x().off(e), o.apply(this, arguments) + }, r.guid = o.guid || (o.guid = x.guid++)), this.each(function () { + x.event.add(this, e, r, n, t) + }) + }, one: function (e, t, n, r) { + return this.on(e, t, n, r, 1) + }, off: function (e, t, n) { + var r, i; + if (e && e.preventDefault && e.handleObj)return r = e.handleObj, x(e.delegateTarget).off(r.namespace ? r.origType + "." + r.namespace : r.origType, r.selector, r.handler), this; + if ("object" == typeof e) { + for (i in e)this.off(i, t, e[i]); + return this + } + return (t === !1 || "function" == typeof t) && (n = t, t = undefined), n === !1 && (n = Y), this.each(function () { + x.event.remove(this, e, n, t) + }) + }, trigger: function (e, t) { + return this.each(function () { + x.event.trigger(e, t, this) + }) + }, triggerHandler: function (e, t) { + var n = this[0]; + return n ? x.event.trigger(e, t, n, !0) : undefined + } + }); + var G = /^.[^:#\[\.,]*$/, J = /^(?:parents|prev(?:Until|All))/, Q = x.expr.match.needsContext, K = { + children: !0, + contents: !0, + next: !0, + prev: !0 + }; + x.fn.extend({ + find: function (e) { + var t, n = [], r = this, i = r.length; + if ("string" != typeof e)return this.pushStack(x(e).filter(function () { + for (t = 0; i > t; t++)if (x.contains(r[t], this))return !0 + })); + for (t = 0; i > t; t++)x.find(e, r[t], n); + return n = this.pushStack(i > 1 ? x.unique(n) : n), n.selector = this.selector ? this.selector + " " + e : e, n + }, has: function (e) { + var t = x(e, this), n = t.length; + return this.filter(function () { + var e = 0; + for (; n > e; e++)if (x.contains(this, t[e]))return !0 + }) + }, not: function (e) { + return this.pushStack(et(this, e || [], !0)) + }, filter: function (e) { + return this.pushStack(et(this, e || [], !1)) + }, is: function (e) { + return !!et(this, "string" == typeof e && Q.test(e) ? x(e) : e || [], !1).length + }, closest: function (e, t) { + var n, r = 0, i = this.length, o = [], s = Q.test(e) || "string" != typeof e ? x(e, t || this.context) : 0; + for (; i > r; r++)for (n = this[r]; n && n !== t; n = n.parentNode)if (11 > n.nodeType && (s ? s.index(n) > -1 : 1 === n.nodeType && x.find.matchesSelector(n, e))) { + n = o.push(n); + break + } + return this.pushStack(o.length > 1 ? x.unique(o) : o) + }, index: function (e) { + return e ? "string" == typeof e ? g.call(x(e), this[0]) : g.call(this, e.jquery ? e[0] : e) : this[0] && this[0].parentNode ? this.first().prevAll().length : -1 + }, add: function (e, t) { + var n = "string" == typeof e ? x(e, t) : x.makeArray(e && e.nodeType ? [e] : e), r = x.merge(this.get(), n); + return this.pushStack(x.unique(r)) + }, addBack: function (e) { + return this.add(null == e ? this.prevObject : this.prevObject.filter(e)) + } + }); + function Z(e, t) { + while ((e = e[t]) && 1 !== e.nodeType); + return e + } + + x.each({ + parent: function (e) { + var t = e.parentNode; + return t && 11 !== t.nodeType ? t : null + }, parents: function (e) { + return x.dir(e, "parentNode") + }, parentsUntil: function (e, t, n) { + return x.dir(e, "parentNode", n) + }, next: function (e) { + return Z(e, "nextSibling") + }, prev: function (e) { + return Z(e, "previousSibling") + }, nextAll: function (e) { + return x.dir(e, "nextSibling") + }, prevAll: function (e) { + return x.dir(e, "previousSibling") + }, nextUntil: function (e, t, n) { + return x.dir(e, "nextSibling", n) + }, prevUntil: function (e, t, n) { + return x.dir(e, "previousSibling", n) + }, siblings: function (e) { + return x.sibling((e.parentNode || {}).firstChild, e) + }, children: function (e) { + return x.sibling(e.firstChild) + }, contents: function (e) { + return e.contentDocument || x.merge([], e.childNodes) + } + }, function (e, t) { + x.fn[e] = function (n, r) { + var i = x.map(this, t, n); + return "Until" !== e.slice(-5) && (r = n), r && "string" == typeof r && (i = x.filter(r, i)), this.length > 1 && (K[e] || x.unique(i), J.test(e) && i.reverse()), this.pushStack(i) + } + }), x.extend({ + filter: function (e, t, n) { + var r = t[0]; + return n && (e = ":not(" + e + ")"), 1 === t.length && 1 === r.nodeType ? x.find.matchesSelector(r, e) ? [r] : [] : x.find.matches(e, x.grep(t, function (e) { + return 1 === e.nodeType + })) + }, dir: function (e, t, n) { + var r = [], i = n !== undefined; + while ((e = e[t]) && 9 !== e.nodeType)if (1 === e.nodeType) { + if (i && x(e).is(n))break; + r.push(e) + } + return r + }, sibling: function (e, t) { + var n = []; + for (; e; e = e.nextSibling)1 === e.nodeType && e !== t && n.push(e); + return n + } + }); + function et(e, t, n) { + if (x.isFunction(t))return x.grep(e, function (e, r) { + return !!t.call(e, r, e) !== n + }); + if (t.nodeType)return x.grep(e, function (e) { + return e === t !== n + }); + if ("string" == typeof t) { + if (G.test(t))return x.filter(t, e, n); + t = x.filter(t, e) + } + return x.grep(e, function (e) { + return g.call(t, e) >= 0 !== n + }) + } + + var tt = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi, nt = /<([\w:]+)/, rt = /<|&#?\w+;/, it = /<(?:script|style|link)/i, ot = /^(?:checkbox|radio)$/i, st = /checked\s*(?:[^=]|=\s*.checked.)/i, at = /^$|\/(?:java|ecma)script/i, ut = /^true\/(.*)/, lt = /^\s*\s*$/g, ct = { + option: [1, ""], + thead: [1, "", "
    "], + col: [2, "", "
    "], + tr: [2, "", "
    "], + td: [3, "", "
    "], + _default: [0, "", ""] + }; + ct.optgroup = ct.option, ct.tbody = ct.tfoot = ct.colgroup = ct.caption = ct.thead, ct.th = ct.td, x.fn.extend({ + text: function (e) { + return x.access(this, function (e) { + return e === undefined ? x.text(this) : this.empty().append((this[0] && this[0].ownerDocument || o).createTextNode(e)) + }, null, e, arguments.length) + }, append: function () { + return this.domManip(arguments, function (e) { + if (1 === this.nodeType || 11 === this.nodeType || 9 === this.nodeType) { + var t = pt(this, e); + t.appendChild(e) + } + }) + }, prepend: function () { + return this.domManip(arguments, function (e) { + if (1 === this.nodeType || 11 === this.nodeType || 9 === this.nodeType) { + var t = pt(this, e); + t.insertBefore(e, t.firstChild) + } + }) + }, before: function () { + return this.domManip(arguments, function (e) { + this.parentNode && this.parentNode.insertBefore(e, this) + }) + }, after: function () { + return this.domManip(arguments, function (e) { + this.parentNode && this.parentNode.insertBefore(e, this.nextSibling) + }) + }, remove: function (e, t) { + var n, r = e ? x.filter(e, this) : this, i = 0; + for (; null != (n = r[i]); i++)t || 1 !== n.nodeType || x.cleanData(mt(n)), n.parentNode && (t && x.contains(n.ownerDocument, n) && dt(mt(n, "script")), n.parentNode.removeChild(n)); + return this + }, empty: function () { + var e, t = 0; + for (; null != (e = this[t]); t++)1 === e.nodeType && (x.cleanData(mt(e, !1)), e.textContent = ""); + return this + }, clone: function (e, t) { + return e = null == e ? !1 : e, t = null == t ? e : t, this.map(function () { + return x.clone(this, e, t) + }) + }, html: function (e) { + return x.access(this, function (e) { + var t = this[0] || {}, n = 0, r = this.length; + if (e === undefined && 1 === t.nodeType)return t.innerHTML; + if ("string" == typeof e && !it.test(e) && !ct[(nt.exec(e) || ["", ""])[1].toLowerCase()]) { + e = e.replace(tt, "<$1>"); + try { + for (; r > n; n++)t = this[n] || {}, 1 === t.nodeType && (x.cleanData(mt(t, !1)), t.innerHTML = e); + t = 0 + } catch (i) { + } + } + t && this.empty().append(e) + }, null, e, arguments.length) + }, replaceWith: function () { + var e = x.map(this, function (e) { + return [e.nextSibling, e.parentNode] + }), t = 0; + return this.domManip(arguments, function (n) { + var r = e[t++], i = e[t++]; + i && (r && r.parentNode !== i && (r = this.nextSibling), x(this).remove(), i.insertBefore(n, r)) + }, !0), t ? this : this.remove() + }, detach: function (e) { + return this.remove(e, !0) + }, domManip: function (e, t, n) { + e = f.apply([], e); + var r, i, o, s, a, u, l = 0, c = this.length, p = this, h = c - 1, d = e[0], g = x.isFunction(d); + if (g || !(1 >= c || "string" != typeof d || x.support.checkClone) && st.test(d))return this.each(function (r) { + var i = p.eq(r); + g && (e[0] = d.call(this, r, i.html())), i.domManip(e, t, n) + }); + if (c && (r = x.buildFragment(e, this[0].ownerDocument, !1, !n && this), i = r.firstChild, 1 === r.childNodes.length && (r = i), i)) { + for (o = x.map(mt(r, "script"), ft), s = o.length; c > l; l++)a = r, l !== h && (a = x.clone(a, !0, !0), s && x.merge(o, mt(a, "script"))), t.call(this[l], a, l); + if (s)for (u = o[o.length - 1].ownerDocument, x.map(o, ht), l = 0; s > l; l++)a = o[l], at.test(a.type || "") && !q.access(a, "globalEval") && x.contains(u, a) && (a.src ? x._evalUrl(a.src) : x.globalEval(a.textContent.replace(lt, ""))) + } + return this + } + }), x.each({ + appendTo: "append", + prependTo: "prepend", + insertBefore: "before", + insertAfter: "after", + replaceAll: "replaceWith" + }, function (e, t) { + x.fn[e] = function (e) { + var n, r = [], i = x(e), o = i.length - 1, s = 0; + for (; o >= s; s++)n = s === o ? this : this.clone(!0), x(i[s])[t](n), h.apply(r, n.get()); + return this.pushStack(r) + } + }), x.extend({ + clone: function (e, t, n) { + var r, i, o, s, a = e.cloneNode(!0), u = x.contains(e.ownerDocument, e); + if (!(x.support.noCloneChecked || 1 !== e.nodeType && 11 !== e.nodeType || x.isXMLDoc(e)))for (s = mt(a), o = mt(e), r = 0, i = o.length; i > r; r++)yt(o[r], s[r]); + if (t)if (n)for (o = o || mt(e), s = s || mt(a), r = 0, i = o.length; i > r; r++)gt(o[r], s[r]); else gt(e, a); + return s = mt(a, "script"), s.length > 0 && dt(s, !u && mt(e, "script")), a + }, buildFragment: function (e, t, n, r) { + var i, o, s, a, u, l, c = 0, p = e.length, f = t.createDocumentFragment(), h = []; + for (; p > c; c++)if (i = e[c], i || 0 === i)if ("object" === x.type(i))x.merge(h, i.nodeType ? [i] : i); else if (rt.test(i)) { + o = o || f.appendChild(t.createElement("div")), s = (nt.exec(i) || ["", ""])[1].toLowerCase(), a = ct[s] || ct._default, o.innerHTML = a[1] + i.replace(tt, "<$1>") + a[2], l = a[0]; + while (l--)o = o.lastChild; + x.merge(h, o.childNodes), o = f.firstChild, o.textContent = "" + } else h.push(t.createTextNode(i)); + f.textContent = "", c = 0; + while (i = h[c++])if ((!r || -1 === x.inArray(i, r)) && (u = x.contains(i.ownerDocument, i), o = mt(f.appendChild(i), "script"), u && dt(o), n)) { + l = 0; + while (i = o[l++])at.test(i.type || "") && n.push(i) + } + return f + }, cleanData: function (e) { + var t, n, r, i, o, s, a = x.event.special, u = 0; + for (; (n = e[u]) !== undefined; u++) { + if (F.accepts(n) && (o = n[q.expando], o && (t = q.cache[o]))) { + if (r = Object.keys(t.events || {}), r.length)for (s = 0; (i = r[s]) !== undefined; s++)a[i] ? x.event.remove(n, i) : x.removeEvent(n, i, t.handle); + q.cache[o] && delete q.cache[o] + } + delete L.cache[n[L.expando]] + } + }, _evalUrl: function (e) { + return x.ajax({url: e, type: "GET", dataType: "script", async: !1, global: !1, "throws": !0}) + } + }); + function pt(e, t) { + return x.nodeName(e, "table") && x.nodeName(1 === t.nodeType ? t : t.firstChild, "tr") ? e.getElementsByTagName("tbody")[0] || e.appendChild(e.ownerDocument.createElement("tbody")) : e + } + + function ft(e) { + return e.type = (null !== e.getAttribute("type")) + "/" + e.type, e + } + + function ht(e) { + var t = ut.exec(e.type); + return t ? e.type = t[1] : e.removeAttribute("type"), e + } + + function dt(e, t) { + var n = e.length, r = 0; + for (; n > r; r++)q.set(e[r], "globalEval", !t || q.get(t[r], "globalEval")) + } + + function gt(e, t) { + var n, r, i, o, s, a, u, l; + if (1 === t.nodeType) { + if (q.hasData(e) && (o = q.access(e), s = q.set(t, o), l = o.events)) { + delete s.handle, s.events = {}; + for (i in l)for (n = 0, r = l[i].length; r > n; n++)x.event.add(t, i, l[i][n]) + } + L.hasData(e) && (a = L.access(e), u = x.extend({}, a), L.set(t, u)) + } + } + + function mt(e, t) { + var n = e.getElementsByTagName ? e.getElementsByTagName(t || "*") : e.querySelectorAll ? e.querySelectorAll(t || "*") : []; + return t === undefined || t && x.nodeName(e, t) ? x.merge([e], n) : n + } + + function yt(e, t) { + var n = t.nodeName.toLowerCase(); + "input" === n && ot.test(e.type) ? t.checked = e.checked : ("input" === n || "textarea" === n) && (t.defaultValue = e.defaultValue) + } + + x.fn.extend({ + wrapAll: function (e) { + var t; + return x.isFunction(e) ? this.each(function (t) { + x(this).wrapAll(e.call(this, t)) + }) : (this[0] && (t = x(e, this[0].ownerDocument).eq(0).clone(!0), this[0].parentNode && t.insertBefore(this[0]), t.map(function () { + var e = this; + while (e.firstElementChild)e = e.firstElementChild; + return e + }).append(this)), this) + }, wrapInner: function (e) { + return x.isFunction(e) ? this.each(function (t) { + x(this).wrapInner(e.call(this, t)) + }) : this.each(function () { + var t = x(this), n = t.contents(); + n.length ? n.wrapAll(e) : t.append(e) + }) + }, wrap: function (e) { + var t = x.isFunction(e); + return this.each(function (n) { + x(this).wrapAll(t ? e.call(this, n) : e) + }) + }, unwrap: function () { + return this.parent().each(function () { + x.nodeName(this, "body") || x(this).replaceWith(this.childNodes) + }).end() + } + }); + var vt, xt, bt = /^(none|table(?!-c[ea]).+)/, wt = /^margin/, Tt = RegExp("^(" + b + ")(.*)$", "i"), Ct = RegExp("^(" + b + ")(?!px)[a-z%]+$", "i"), kt = RegExp("^([+-])=(" + b + ")", "i"), Nt = {BODY: "block"}, Et = { + position: "absolute", + visibility: "hidden", + display: "block" + }, St = { + letterSpacing: 0, + fontWeight: 400 + }, jt = ["Top", "Right", "Bottom", "Left"], Dt = ["Webkit", "O", "Moz", "ms"]; + + function At(e, t) { + if (t in e)return t; + var n = t.charAt(0).toUpperCase() + t.slice(1), r = t, i = Dt.length; + while (i--)if (t = Dt[i] + n, t in e)return t; + return r + } + + function Lt(e, t) { + return e = t || e, "none" === x.css(e, "display") || !x.contains(e.ownerDocument, e) + } + + function qt(t) { + return e.getComputedStyle(t, null) + } + + function Ht(e, t) { + var n, r, i, o = [], s = 0, a = e.length; + for (; a > s; s++)r = e[s], r.style && (o[s] = q.get(r, "olddisplay"), n = r.style.display, t ? (o[s] || "none" !== n || (r.style.display = ""), "" === r.style.display && Lt(r) && (o[s] = q.access(r, "olddisplay", Rt(r.nodeName)))) : o[s] || (i = Lt(r), (n && "none" !== n || !i) && q.set(r, "olddisplay", i ? n : x.css(r, "display")))); + for (s = 0; a > s; s++)r = e[s], r.style && (t && "none" !== r.style.display && "" !== r.style.display || (r.style.display = t ? o[s] || "" : "none")); + return e + } + + x.fn.extend({ + css: function (e, t) { + return x.access(this, function (e, t, n) { + var r, i, o = {}, s = 0; + if (x.isArray(t)) { + for (r = qt(e), i = t.length; i > s; s++)o[t[s]] = x.css(e, t[s], !1, r); + return o + } + return n !== undefined ? x.style(e, t, n) : x.css(e, t) + }, e, t, arguments.length > 1) + }, show: function () { + return Ht(this, !0) + }, hide: function () { + return Ht(this) + }, toggle: function (e) { + return "boolean" == typeof e ? e ? this.show() : this.hide() : this.each(function () { + Lt(this) ? x(this).show() : x(this).hide() + }) + } + }), x.extend({ + cssHooks: { + opacity: { + get: function (e, t) { + if (t) { + var n = vt(e, "opacity"); + return "" === n ? "1" : n + } + } + } + }, + cssNumber: { + columnCount: !0, + fillOpacity: !0, + fontWeight: !0, + lineHeight: !0, + opacity: !0, + order: !0, + orphans: !0, + widows: !0, + zIndex: !0, + zoom: !0 + }, + cssProps: {"float": "cssFloat"}, + style: function (e, t, n, r) { + if (e && 3 !== e.nodeType && 8 !== e.nodeType && e.style) { + var i, o, s, a = x.camelCase(t), u = e.style; + return t = x.cssProps[a] || (x.cssProps[a] = At(u, a)), s = x.cssHooks[t] || x.cssHooks[a], n === undefined ? s && "get"in s && (i = s.get(e, !1, r)) !== undefined ? i : u[t] : (o = typeof n, "string" === o && (i = kt.exec(n)) && (n = (i[1] + 1) * i[2] + parseFloat(x.css(e, t)), o = "number"), null == n || "number" === o && isNaN(n) || ("number" !== o || x.cssNumber[a] || (n += "px"), x.support.clearCloneStyle || "" !== n || 0 !== t.indexOf("background") || (u[t] = "inherit"), s && "set"in s && (n = s.set(e, n, r)) === undefined || (u[t] = n)), undefined) + } + }, + css: function (e, t, n, r) { + var i, o, s, a = x.camelCase(t); + return t = x.cssProps[a] || (x.cssProps[a] = At(e.style, a)), s = x.cssHooks[t] || x.cssHooks[a], s && "get"in s && (i = s.get(e, !0, n)), i === undefined && (i = vt(e, t, r)), "normal" === i && t in St && (i = St[t]), "" === n || n ? (o = parseFloat(i), n === !0 || x.isNumeric(o) ? o || 0 : i) : i + } + }), vt = function (e, t, n) { + var r, i, o, s = n || qt(e), a = s ? s.getPropertyValue(t) || s[t] : undefined, u = e.style; + return s && ("" !== a || x.contains(e.ownerDocument, e) || (a = x.style(e, t)), Ct.test(a) && wt.test(t) && (r = u.width, i = u.minWidth, o = u.maxWidth, u.minWidth = u.maxWidth = u.width = a, a = s.width, u.width = r, u.minWidth = i, u.maxWidth = o)), a + }; + function Ot(e, t, n) { + var r = Tt.exec(t); + return r ? Math.max(0, r[1] - (n || 0)) + (r[2] || "px") : t + } + + function Ft(e, t, n, r, i) { + var o = n === (r ? "border" : "content") ? 4 : "width" === t ? 1 : 0, s = 0; + for (; 4 > o; o += 2)"margin" === n && (s += x.css(e, n + jt[o], !0, i)), r ? ("content" === n && (s -= x.css(e, "padding" + jt[o], !0, i)), "margin" !== n && (s -= x.css(e, "border" + jt[o] + "Width", !0, i))) : (s += x.css(e, "padding" + jt[o], !0, i), "padding" !== n && (s += x.css(e, "border" + jt[o] + "Width", !0, i))); + return s + } + + function Pt(e, t, n) { + var r = !0, i = "width" === t ? e.offsetWidth : e.offsetHeight, o = qt(e), s = x.support.boxSizing && "border-box" === x.css(e, "boxSizing", !1, o); + if (0 >= i || null == i) { + if (i = vt(e, t, o), (0 > i || null == i) && (i = e.style[t]), Ct.test(i))return i; + r = s && (x.support.boxSizingReliable || i === e.style[t]), i = parseFloat(i) || 0 + } + return i + Ft(e, t, n || (s ? "border" : "content"), r, o) + "px" + } + + function Rt(e) { + var t = o, n = Nt[e]; + return n || (n = Mt(e, t), "none" !== n && n || (xt = (xt || x(""; - break; - } - - // position 20070613 - var a = Fe.trim(op.position).toLowerCase().split(/\s/); - var body = Fe.body(); - Fe.show("FeDialog_" + this.hashCode); - if (Fe.isIE && _("FeDialogContent").offsetWidth < 136) - _("FeDialogContent").style.width = "130px"; - if (Fe.isIE && _("FeDialogContent").offsetHeight < 50) - _("FeDialogContent").style.height = "50px"; - var top = (Math.max( - parseInt((body.viewHeight - _("FeDialog").offsetHeight) / 2), 0) + body.scrollTop) - + "px"; - var left = (Math.max( - parseInt((body.viewWidth - _("FeDialog").offsetWidth) / 2), 0) + body.scrollLeft) - + "px"; - if (a.length == 1) { - if (a[0] == "" || a[0] == "center") { - } else if (a[0] == "top") - top = body.scrollTop + "px"; - else if (a[0] == "bottom") - top = (body.scrollTop + body.viewHeight - _("FeDialog").offsetHeight) - + "px"; - else if (a[0] == "left") - left = body.scrollLeft + "px"; - else if (a[0] == "right") - left = (body.scrollLeft + body.viewWidth - _("FeDialog").offsetWidth) - + "px"; - else if (/\d+%/.test(a[0])) - top = a[0]; - else if (/(\d+)(cm|mm|in|pt|pc|px|em|ex)?/.test(a[0])) - top = parseInt(RegExp.$1) + RegExp.$2 || "px"; - } else if (a.length > 1) { - if (/\d+%/.test(a[0])) - top = a[0]; - else if (/(\d+)(cm|mm|in|pt|pc|px|em|ex)?/.test(a[0])) - top = parseInt(RegExp.$1) + RegExp.$2 || "px"; - - if (/\d+%/.test(a[1])) - left = a[1]; - else if (/(\d+)(cm|mm|in|pt|pc|px|em|ex)?/.test(a[1])) - left = parseInt(RegExp.$1) + RegExp.$2 || "px"; - - if (a[0] == "top" || a[1] == "top") - top = body.scrollTop + "px"; - if (a[0] == "bottom" || a[1] == "bottom") - top = (body.scrollTop + body.viewHeight - _("FeDialog").offsetHeight) - + "px"; - if (a[0] == "left" || a[1] == "left") - left = body.scrollLeft + "px"; - if (a[0] == "right" || a[1] == "right") - left = (body.scrollLeft + body.viewWidth - _("FeDialog").offsetWidth) - + "px"; - } - _("FeDialog").style.top = top; - _("FeDialog").style.left = left; - - this.active = true; +Fe.DialogFactory.prototype.show = function (op) { + var me = this; + + function _(id) { + return Fe.G(id + "_" + me.hashCode) + } + + // set property + if (op.icon) { + _("FeDialogCaption").style.background = "url(" + op.icon + ") no-repeat left 3px"; + _("FeDialogCaptionText").style.paddingLeft = "18px"; + } + // * + _("FeDialog").style.font = op.font; + //_("FeDialog").style.fontSize = "12px"; + _("FeDialogCaptionText").innerHTML = op.title; + _("FeDialogCaption").style.display = op.titlebar ? "" : "none"; + _("FeDialogStatusBar").style.display = op.statusbar ? "" : "none"; + _("FeDialogControlBar").style.display = op.controlbar ? "" : "none"; + _("FeDialogButtonBar").style.display = op.buttonbar ? "" : "none"; + _("FeDialogButtonClose").style.display = op.buttonClose ? "" : "none"; + _("FeDialogButtonAccept").style.display = op.buttonAccept ? "" : "none"; + _("FeDialogButtonCancel").style.display = op.buttonCancel ? "" : "none"; + _("FeDialogButtonBar").style.textAlign = op.buttonbarAlign; + _("FeDialogButtonAccept").value = op.buttonAcceptValue; + _("FeDialogButtonCancel").value = op.buttonCancelValue; + with (_("FeDialogContent").style) { + width = op.width; + height = op.height; + overflow = op.overflow; + } + // */ + if (op.contentType.toLowerCase() == "htmlelement" && !Fe.G(op.content)) + op.contentType = "HTMLString"; + switch (op.contentType.toLowerCase()) { + case "htmlstring" : + _("FeDialogContent").innerHTML = op.content; + break; + case "htmlelement" : + var e = Fe.G(op.content); + this.opContentDisplay = e.style.display; + e.insertAdjacentHTML("beforeBegin", ""); + _("FeDialogContent").innerHTML = ""; + e.style.display = ""; + _("FeDialogContent").appendChild(e); + break; + default : + _("FeDialogContent").innerHTML = ""; + break; + } + + // position 20070613 + var a = Fe.trim(op.position).toLowerCase().split(/\s/); + var body = Fe.body(); + Fe.show("FeDialog_" + this.hashCode); + if (Fe.isIE && _("FeDialogContent").offsetWidth < 136) + _("FeDialogContent").style.width = "130px"; + if (Fe.isIE && _("FeDialogContent").offsetHeight < 50) + _("FeDialogContent").style.height = "50px"; + var top = (Math.max( + parseInt((body.viewHeight - _("FeDialog").offsetHeight) / 2), 0) + body.scrollTop) + + "px"; + var left = (Math.max( + parseInt((body.viewWidth - _("FeDialog").offsetWidth) / 2), 0) + body.scrollLeft) + + "px"; + if (a.length == 1) { + if (a[0] == "" || a[0] == "center") { + } else if (a[0] == "top") + top = body.scrollTop + "px"; + else if (a[0] == "bottom") + top = (body.scrollTop + body.viewHeight - _("FeDialog").offsetHeight) + + "px"; + else if (a[0] == "left") + left = body.scrollLeft + "px"; + else if (a[0] == "right") + left = (body.scrollLeft + body.viewWidth - _("FeDialog").offsetWidth) + + "px"; + else if (/\d+%/.test(a[0])) + top = a[0]; + else if (/(\d+)(cm|mm|in|pt|pc|px|em|ex)?/.test(a[0])) + top = parseInt(RegExp.$1) + RegExp.$2 || "px"; + } else if (a.length > 1) { + if (/\d+%/.test(a[0])) + top = a[0]; + else if (/(\d+)(cm|mm|in|pt|pc|px|em|ex)?/.test(a[0])) + top = parseInt(RegExp.$1) + RegExp.$2 || "px"; + + if (/\d+%/.test(a[1])) + left = a[1]; + else if (/(\d+)(cm|mm|in|pt|pc|px|em|ex)?/.test(a[1])) + left = parseInt(RegExp.$1) + RegExp.$2 || "px"; + + if (a[0] == "top" || a[1] == "top") + top = body.scrollTop + "px"; + if (a[0] == "bottom" || a[1] == "bottom") + top = (body.scrollTop + body.viewHeight - _("FeDialog").offsetHeight) + + "px"; + if (a[0] == "left" || a[1] == "left") + left = body.scrollLeft + "px"; + if (a[0] == "right" || a[1] == "right") + left = (body.scrollLeft + body.viewWidth - _("FeDialog").offsetWidth) + + "px"; + } + _("FeDialog").style.top = top; + _("FeDialog").style.left = left; + + this.active = true; }; /** * Fe.DialogFactory\u7684hide\u65b9\u6cd5\uff0c\u9690\u85cf\u4e00\u4e2a\u5bf9\u8bdd\u6846 */ -Fe.DialogFactory.prototype.hide = function(callback) { - Fe.hide("FeDialog_" + this.hashCode); - var me = this; - if (Fe.G("FeDialogFactoryInset_" + me.hashCode)) { - var e = Fe.G("FeDialogFactoryInset_" + me.hashCode); - var t = Fe.G("FeDialogContent_" + me.hashCode).childNodes[0]; - e.parentNode.insertBefore(t, e); - e.parentNode.removeChild(e); - t.style.display = me.opContentDisplay; - } - if ("function" == typeof(callback)) - callback(me); - setTimeout(function() { - me.active = false; - me.setContent(" "); - var e = Fe.G("FeDialogContent_" + me.hashCode); - if (e) { - e.style.width = e.style.height = e.style.overflow = ""; - } - }, 50); - clearTimeout(this.timer); +Fe.DialogFactory.prototype.hide = function (callback) { + Fe.hide("FeDialog_" + this.hashCode); + var me = this; + if (Fe.G("FeDialogFactoryInset_" + me.hashCode)) { + var e = Fe.G("FeDialogFactoryInset_" + me.hashCode); + var t = Fe.G("FeDialogContent_" + me.hashCode).childNodes[0]; + e.parentNode.insertBefore(t, e); + e.parentNode.removeChild(e); + t.style.display = me.opContentDisplay; + } + if ("function" == typeof(callback)) + callback(me); + setTimeout(function () { + me.active = false; + me.setContent(" "); + var e = Fe.G("FeDialogContent_" + me.hashCode); + if (e) { + e.style.width = e.style.height = e.style.overflow = ""; + } + }, 50); + clearTimeout(this.timer); }; /** * Fe.DialogFactory\u7684dispose\u65b9\u6cd5\u3002\u91ca\u653e\u5bf9\u8bdd\u6846\u6240\u7528\u7684\u8d44\u6e90\u3002 */ -Fe.DialogFactory.prototype.dispose = function() { - Fe.DialogFactory.dialogs = Fe.DialogFactory.dialogs.remove(this); - Fe.BaseClass.prototype.dispose.call(this); +Fe.DialogFactory.prototype.dispose = function () { + Fe.DialogFactory.dialogs = Fe.DialogFactory.dialogs.remove(this); + Fe.BaseClass.prototype.dispose.call(this); }; /** * Fe.DialogFactory\u7684setWidth\u65b9\u6cd5\u3002\u8bbe\u7f6e\u5bf9\u8bdd\u6846\u7684\u5bbd\u5ea6\u3002 * @param {Number} w \u9700\u8981\u8bbe\u7f6e\u7684\u5bbd\u5ea6\u503c */ -Fe.DialogFactory.prototype.setWidth = function(w) { - var e; - if (e = Fe.G("FeDialogContent_" + this.hashCode)) { - e.style.width = w; - } +Fe.DialogFactory.prototype.setWidth = function (w) { + var e; + if (e = Fe.G("FeDialogContent_" + this.hashCode)) { + e.style.width = w; + } }; /** * Fe.DialogFactory\u7684setHeight\u65b9\u6cd5\u3002\u8bbe\u7f6e\u5bf9\u8bdd\u6846\u7684\u9ad8\u5ea6\u3002 * @param {Number} h \u9700\u8981\u8bbe\u7f6e\u7684\u9ad8\u5ea6\u503c */ -Fe.DialogFactory.prototype.setHeight = function(h) { - var e; - if (e = Fe.G("FeDialogContent_" + this.hashCode)) { - e.style.height = h; - } +Fe.DialogFactory.prototype.setHeight = function (h) { + var e; + if (e = Fe.G("FeDialogContent_" + this.hashCode)) { + e.style.height = h; + } }; /** * Fe.DialogFactory\u7684setCaption\u65b9\u6cd5\u3002\u8bbe\u7f6e\u5bf9\u8bdd\u6846\u7684\u6807\u9898\u3002 * @param {String} s \u9700\u8981\u8bbe\u7f6e\u7684\u6807\u9898\u7684\u5185\u5bb9 */ -Fe.DialogFactory.prototype.setCaption = function(s) { - Fe.G("FeDialogCaptionText_" + this.hashCode).value = s; +Fe.DialogFactory.prototype.setCaption = function (s) { + Fe.G("FeDialogCaptionText_" + this.hashCode).value = s; } /** * Fe.DialogFactory\u7684setContent\u65b9\u6cd5\u3002\u8bbe\u7f6e\u5bf9\u8bdd\u6846\u7684\u5185\u5bb9\u3002 * @param {String} s \u9700\u8981\u8bbe\u7f6e\u7684\u5bf9\u8bdd\u6846\u7684\u5185\u5bb9 */ -Fe.DialogFactory.prototype.setContent = function(s) { - Fe.G("FeDialogContent_" + this.hashCode).innerHTML = s; +Fe.DialogFactory.prototype.setContent = function (s) { + Fe.G("FeDialogContent_" + this.hashCode).innerHTML = s; } /** * Fe.DialogFactory\u7684setStatus\u65b9\u6cd5\u3002\u8bbe\u7f6e\u5bf9\u8bdd\u6846\u7684\u72b6\u6001\u680f\u4fe1\u606f\u3002 * @param {String} s \u9700\u8981\u8bbe\u7f6e\u7684\u72b6\u6001\u680f\u4fe1\u606f\u7684\u5185\u5bb9 */ -Fe.DialogFactory.prototype.setStatus = function(s) { - Fe.G("FeDialogStatusText_" + this.hashCode).innerHTML = s; +Fe.DialogFactory.prototype.setStatus = function (s) { + Fe.G("FeDialogStatusText_" + this.hashCode).innerHTML = s; } /** * @ignore */ -Fe.DialogFactory.prototype.click = function(e) { - (window.event || e).cancelBubble = true; - this.setActive(); +Fe.DialogFactory.prototype.click = function (e) { + (window.event || e).cancelBubble = true; + this.setActive(); }; /** * Fe.DialogFactory\u7684resizeBy\u65b9\u6cd5\u3002\u8c03\u6574\u5bf9\u8bdd\u6846\u7684\u9ad8\u5ea6\u548c\u5bbd\u5ea6\u3002 */ -Fe.DialogFactory.prototype.resizeBy = function() { - var me = this, - layer = "FeDialogLayer_" + this.hashCode; - Fe.G("FeDialogBgLayer_" + this.hashCode).style.width = Fe.G(layer).offsetWidth + "px"; - Fe.G("FeDialogBgLayer_" + this.hashCode).style.height = Fe.G(layer).offsetHeight + "px"; - if (Fe.isIE && Fe.G("FeDialogBgLayer_" + this.hashCode)) { - if (Fe.isIE < 5.5) { - Fe.G("FeDialogLayer_" + this.hashCode).style.width = "130px"; - Fe.G("FeDialog_" + this.hashCode).style.width = Fe.G("FeDialogLayer_" + this.hashCode).offsetWidth + "px"; - } - var table = Fe.G("FeDialogBgLayer_" + this.hashCode); - if (table.rows[0].cells[0].currentStyle) { - var h1 = parseInt(table.rows[0].cells[0].currentStyle.height); - var h2 = parseInt(table.rows[2].cells[0].currentStyle.height); - if (!isNaN(h1) && !isNaN(h2)) { - table.rows[1].cells[1].style.height = (Math.max(Fe.G(layer).offsetHeight - h1 - h2, 12)) + "px"; - } - } - } - if (window.opera && Fe.G("FeDialogLayerTable_" + this.hashCode).offsetWidth < 130) - Fe.G("FeDialogLayerTable_" + this.hashCode).style.width = "130px"; - this.timer = setTimeout(function() { - me.resizeBy(); - }, 50); +Fe.DialogFactory.prototype.resizeBy = function () { + var me = this, + layer = "FeDialogLayer_" + this.hashCode; + Fe.G("FeDialogBgLayer_" + this.hashCode).style.width = Fe.G(layer).offsetWidth + "px"; + Fe.G("FeDialogBgLayer_" + this.hashCode).style.height = Fe.G(layer).offsetHeight + "px"; + if (Fe.isIE && Fe.G("FeDialogBgLayer_" + this.hashCode)) { + if (Fe.isIE < 5.5) { + Fe.G("FeDialogLayer_" + this.hashCode).style.width = "130px"; + Fe.G("FeDialog_" + this.hashCode).style.width = Fe.G("FeDialogLayer_" + this.hashCode).offsetWidth + "px"; + } + var table = Fe.G("FeDialogBgLayer_" + this.hashCode); + if (table.rows[0].cells[0].currentStyle) { + var h1 = parseInt(table.rows[0].cells[0].currentStyle.height); + var h2 = parseInt(table.rows[2].cells[0].currentStyle.height); + if (!isNaN(h1) && !isNaN(h2)) { + table.rows[1].cells[1].style.height = (Math.max(Fe.G(layer).offsetHeight - h1 - h2, 12)) + "px"; + } + } + } + if (window.opera && Fe.G("FeDialogLayerTable_" + this.hashCode).offsetWidth < 130) + Fe.G("FeDialogLayerTable_" + this.hashCode).style.width = "130px"; + this.timer = setTimeout(function () { + me.resizeBy(); + }, 50); }; /** * Fe.DialogFactory\u7684produce\u65b9\u6cd5\u3002\u521b\u5efa\u4e00\u4e2a\u65b0\u7684Fe.Dialog\u5b9e\u4f8b */ -Fe.DialogFactory.produce = function() { - for (var i = 0, n = Fe.DialogFactory.dialogs.length; i < n; i++) { - if (!Fe.DialogFactory.dialogs[i].active) { - if (i == (n - 1)) - setTimeout(function() { - new Fe.DialogFactory().create(); - }, 20); - return Fe.DialogFactory.dialogs[i]; - } - } - return null; +Fe.DialogFactory.produce = function () { + for (var i = 0, n = Fe.DialogFactory.dialogs.length; i < n; i++) { + if (!Fe.DialogFactory.dialogs[i].active) { + if (i == (n - 1)) + setTimeout(function () { + new Fe.DialogFactory().create(); + }, 20); + return Fe.DialogFactory.dialogs[i]; + } + } + return null; }; // 20071225 -Fe.on(document.body, "onkeydown", function(event) { - var el = event.target || event.srcElement; - if (!el) - return false; - if (el.tagName.toLowerCase() == 'textarea') - return false; - - var key = event.which || event.keyCode; - if (Fe.DialogFactory.currentDialog && Fe.DialogFactory.currentDialog.active) { - if (key == 27) - Fe.DialogFactory.currentDialog.oncancel(); - else if (key == 13) { - Fe.DialogFactory.currentDialog.onaccept(); - // FF2\u6ca1\u6709\u95ee\u9898\uff0cFF3\u51fa\u95ee\u9898\u4e86\uff1f - try { - event.keyCode = 0; - } catch (e) { - } - event.returnValue = false; - } - } +Fe.on(document.body, "onkeydown", function (event) { + var el = event.target || event.srcElement; + if (!el) + return false; + if (el.tagName.toLowerCase() == 'textarea') + return false; + + var key = event.which || event.keyCode; + if (Fe.DialogFactory.currentDialog && Fe.DialogFactory.currentDialog.active) { + if (key == 27) + Fe.DialogFactory.currentDialog.oncancel(); + else if (key == 13) { + Fe.DialogFactory.currentDialog.onaccept(); + // FF2\u6ca1\u6709\u95ee\u9898\uff0cFF3\u51fa\u95ee\u9898\u4e86\uff1f + try { + event.keyCode = 0; + } catch (e) { + } + event.returnValue = false; + } + } }); - - - /** * \u7ed9\u5143\u7d20el\u89e3\u9664\u4e8b\u4ef6(evt)\u7684\u5904\u7406\u51fd\u6570handler\u3002 * \u7528\u6cd5\uff1a @@ -1156,15 +1130,17 @@ Fe.on(document.body, "onkeydown", function(event) { * @param {Function} handler \u4e8b\u4ef6\u7684\u5904\u7406\u51fd\u6570 * @return {DOM} \u7ed1\u5b9a\u4e8b\u4ef6\u7684\u8282\u70b9 */ -Fe.un = function(el, type, handler){ - if(!(el = Fe.G(el))){ return el; } +Fe.un = function (el, type, handler) { + if (!(el = Fe.G(el))) { + return el; + } type = type.replace(/^on/, "").toLowerCase(); - if(el.attachEvent){ + if (el.attachEvent) { el.detachEvent('on' + type, el[type + handler]); el[type + handler] = null; - }else{ + } else { el.removeEventListener(type, handler, false); } @@ -1172,46 +1148,42 @@ Fe.un = function(el, type, handler){ }; - - - - /** @ignore */ function BdLockWindow() { - this.initialize(); + this.initialize(); } /** @ignore */ -BdLockWindow.prototype.initialize = function() { - var div = BdLockWindow.element = document.createElement("DIV"); - div.id = BdLockWindow.id; +BdLockWindow.prototype.initialize = function () { + var div = BdLockWindow.element = document.createElement("DIV"); + div.id = BdLockWindow.id; var style = div.style; - style.zIndex = 1; - style.top = "0px"; + style.zIndex = 1; + style.top = "0px"; style.left = "0px"; - style.width = "100%"; + style.width = "100%"; style.height = "100%"; - style.border = "none"; + style.border = "none"; style.display = "none"; - style.margin = 0; + style.margin = 0; style.padding = 0; - style.position = "absolute"; - style.backgroundColor = "#666699"; - style.backgroundImage = "url(" + Fe.path + "/img/blank.gif)"; + style.position = "absolute"; + style.backgroundColor = "#666699"; + style.backgroundImage = "url(" + Fe.path + "/img/blank.gif)"; document.body.insertBefore(div, document.body.firstChild); - BdLockWindow.onResize(); + BdLockWindow.onResize(); }; /** * \u91cd\u65b0\u8c03\u6574\u906e\u7f69\u5c42\u7684\u5927\u5c0f */ -BdLockWindow.onResize = function() { +BdLockWindow.onResize = function () { BdLockWindow.element.style.width = "100%"; BdLockWindow.element.style.height = "100%"; - setTimeout(function() { + setTimeout(function () { var body = Fe.body(); var W = body.documentWidth; var H = body.documentHeight; @@ -1221,7 +1193,7 @@ BdLockWindow.onResize = function() { }; /**@ignore */ -BdLockWindow._restore = function(TagName) { +BdLockWindow._restore = function (TagName) { var s = document.getElementsByTagName(TagName); for (var i = s.length - 1; i > -1; i--) { s[i].style.visibility = s[i].getAttribute("att_BdLockWindow_v") || ""; @@ -1230,7 +1202,7 @@ BdLockWindow._restore = function(TagName) { }; /**@ignore */ -BdLockWindow._safeguard = function(TagName) { +BdLockWindow._safeguard = function (TagName) { var s = document.getElementsByTagName(TagName); for (var i = s.length - 1; i > -1; i--) { s[i].setAttribute("att_BdLockWindow_v", s[i].style.visibility, 0); @@ -1247,9 +1219,9 @@ BdLockWindow.id = "BdLockWindow_" + new Date().getTime().toString(36); * @config {String} [opacity] \u900f\u660e\u5ea6\uff0c\u4f8b\u59820.5 * @config {String} [zIndex] \u9ad8\u5ea6\u503c */ -BdLockWindow.lock = function(options) { +BdLockWindow.lock = function (options) { var me = this; - if (!me.instance){ + if (!me.instance) { me.instance = new BdLockWindow(); } @@ -1258,17 +1230,17 @@ BdLockWindow.lock = function(options) { var style = me.element.style; me.onResize(); var op = Fe.extend({ - zIndex : 1, - opacity : 0.5 + zIndex: 1, + opacity: 0.5 }, options || {}); style.zIndex = op.zIndex; style.backgroundColor = op.backgroundColor || "#666699"; - if('opacity' in style){ + if ('opacity' in style) { style.opacity = op.opacity; - }else if('MozOpacity' in style){ // Firefox 0.9\u7684\u60c5\u51b5\uff0cFirefox 3.1\u5df2\u7ecf\u4e0d\u652f\u6301\u4e86 + } else if ('MozOpacity' in style) { // Firefox 0.9\u7684\u60c5\u51b5\uff0cFirefox 3.1\u5df2\u7ecf\u4e0d\u652f\u6301\u4e86 style.MozOpacity = op.opacity; - }else if('filter' in style){ + } else if ('filter' in style) { // \u53ea\u80fdQuirks Mode\u4e0b\u9762\u751f\u6548?? style.filter = (style.filter || '').replace(/alpha\([^\)]*\)/gi, "") + (op.opacity == 1 ? "" : "alpha(opacity=" + op.opacity * 100 + ")"); // IE filters only apply to elements with "layout." @@ -1276,11 +1248,11 @@ BdLockWindow.lock = function(options) { } /* - for(var tags = ["SELECT","OBJECT","EMBED"], i = 0, j = tags.length; i < j; i ++){ - this._safeguard(tags[i]) - } - */ - for(var tags = ["SELECT"], i = 0, j = tags.length; i < j; i ++){ + for(var tags = ["SELECT","OBJECT","EMBED"], i = 0, j = tags.length; i < j; i ++){ + this._safeguard(tags[i]) + } + */ + for (var tags = ["SELECT"], i = 0, j = tags.length; i < j; i++) { this._safeguard(tags[i]) } }; @@ -1288,20 +1260,19 @@ BdLockWindow.lock = function(options) { /** * \u5c4f\u5e55\u89e3\u9501 */ -BdLockWindow.unlock = function() { +BdLockWindow.unlock = function () { if (!this.instance) { this.instance = new BdLockWindow(); return; } Fe.hide(this.id); Fe.un(window, "onresize", this.onResize); - for(var tags = ["SELECT","OBJECT","EMBED"], i = 0, j = tags.length; i < j; i ++){ + for (var tags = ["SELECT", "OBJECT", "EMBED"], i = 0, j = tags.length; i < j; i++) { this._restore(tags[i]) } }; - /** * Fe.Dialog \u5bf9\u8bdd\u6846\u7684\u57fa\u7c7b * @constructor @@ -1328,97 +1299,97 @@ BdLockWindow.unlock = function() { * @config {String} [buttonCancelValue] \u53d6\u6d88\u6309\u94ae\u4e0a\u9762\u7684\u6587\u5b57 */ // {contentType title width height scroll resizable help} -Fe.Dialog = function(op) { - Fe.BaseClass.call(this); - // this.drag = true; - this.help = false; - this.font = "normal 12px sans-serif"; - - /** - * \u5bf9\u8bdd\u6846\u7684\u6807\u9898 - * @type String - */ - this.title = "Fe.Dialog"; - /** - * \u5bf9\u8bdd\u6846\u7684\u5bbd\u5ea6 - * @type Number - */ - this.width = ""; - /** - * \u5bf9\u8bdd\u6846\u7684\u9ad8\u5ea6 - * @type Number - */ - this.height = ""; - - this.autofit = false; - /** - * \u5bf9\u8bdd\u6846\u7684\u5185\u5bb9 - * @type String - */ - this.content = " "; - /** - * \u5bf9\u8bdd\u6846\u5185\u5bb9\u6ea2\u51fa\u7684\u65f6\u5019\uff0c\u5982\u4f55\u5904\u7406(visible/hidden) - * @type String - */ - this.overflow = "visible"; - /** - * \u5bf9\u8bdd\u6846\u663e\u793a\u7684\u4f4d\u7f6e(length|percentage|alignment) - * @type String - */ - this.position = "center"; // length|percentage|alignment - /** - * \u662f\u5426\u663e\u793a\u6807\u9898\u680f - * @type Boolean - */ - this.titlebar = true; - this.scrolling = "auto"; - /** - * \u662f\u5426\u663e\u793a\u6309\u94ae\u680f - * @type Boolean - */ - this.buttonbar = false; - /** - * \u662f\u5426\u663e\u793a\u72b6\u6001\u680f - * @type Boolean - */ - this.statusbar = false; - this.resizable = false; - this.controlbar = true; - /** - * \u662f\u5426\u663e\u793a"\u5173\u95ed"\u6309\u94ae - * @type Boolean - */ - this.buttonClose = true; - /** - * \u5bf9\u8bdd\u6846\u7684\u7c7b\u578b(htmlstring,htmlelement,iframe) - * @type String - */ - this.contentType = "HTMLString"; - /** - * \u662f\u5426\u663e\u793a"\u786e\u5b9a"\u6309\u94ae - * @type Boolean - */ - this.buttonAccept = false; - /** - * \u662f\u5426\u663e\u793a"\u53d6\u6d88"\u6309\u94ae - * @type Boolean - */ - this.buttonCancel = false; - /** - * \u5bf9\u8bdd\u6846\u5e95\u90e8\u6309\u94ae\u533a\u57df\u7684\u5bf9\u9f50\u65b9\u5f0f(left, right, center) - * @type String - */ - this.buttonbarAlign = "right"; - /** - * "\u786e\u5b9a"\u6309\u94ae\u4e0a\u9762\u7684\u6587\u5b57 - * @type String - */ - this.buttonAcceptValue = "\u786e \u5b9a"; - /** - * "\u53d6\u6d88"\u6309\u94ae\u4e0a\u9762\u7684\u6587\u5b57 - * @type String - */ - this.buttonCancelValue = "\u53d6 \u6d88"; +Fe.Dialog = function (op) { + Fe.BaseClass.call(this); + // this.drag = true; + this.help = false; + this.font = "normal 12px sans-serif"; + + /** + * \u5bf9\u8bdd\u6846\u7684\u6807\u9898 + * @type String + */ + this.title = "Fe.Dialog"; + /** + * \u5bf9\u8bdd\u6846\u7684\u5bbd\u5ea6 + * @type Number + */ + this.width = ""; + /** + * \u5bf9\u8bdd\u6846\u7684\u9ad8\u5ea6 + * @type Number + */ + this.height = ""; + + this.autofit = false; + /** + * \u5bf9\u8bdd\u6846\u7684\u5185\u5bb9 + * @type String + */ + this.content = " "; + /** + * \u5bf9\u8bdd\u6846\u5185\u5bb9\u6ea2\u51fa\u7684\u65f6\u5019\uff0c\u5982\u4f55\u5904\u7406(visible/hidden) + * @type String + */ + this.overflow = "visible"; + /** + * \u5bf9\u8bdd\u6846\u663e\u793a\u7684\u4f4d\u7f6e(length|percentage|alignment) + * @type String + */ + this.position = "center"; // length|percentage|alignment + /** + * \u662f\u5426\u663e\u793a\u6807\u9898\u680f + * @type Boolean + */ + this.titlebar = true; + this.scrolling = "auto"; + /** + * \u662f\u5426\u663e\u793a\u6309\u94ae\u680f + * @type Boolean + */ + this.buttonbar = false; + /** + * \u662f\u5426\u663e\u793a\u72b6\u6001\u680f + * @type Boolean + */ + this.statusbar = false; + this.resizable = false; + this.controlbar = true; + /** + * \u662f\u5426\u663e\u793a"\u5173\u95ed"\u6309\u94ae + * @type Boolean + */ + this.buttonClose = true; + /** + * \u5bf9\u8bdd\u6846\u7684\u7c7b\u578b(htmlstring,htmlelement,iframe) + * @type String + */ + this.contentType = "HTMLString"; + /** + * \u662f\u5426\u663e\u793a"\u786e\u5b9a"\u6309\u94ae + * @type Boolean + */ + this.buttonAccept = false; + /** + * \u662f\u5426\u663e\u793a"\u53d6\u6d88"\u6309\u94ae + * @type Boolean + */ + this.buttonCancel = false; + /** + * \u5bf9\u8bdd\u6846\u5e95\u90e8\u6309\u94ae\u533a\u57df\u7684\u5bf9\u9f50\u65b9\u5f0f(left, right, center) + * @type String + */ + this.buttonbarAlign = "right"; + /** + * "\u786e\u5b9a"\u6309\u94ae\u4e0a\u9762\u7684\u6587\u5b57 + * @type String + */ + this.buttonAcceptValue = "\u786e \u5b9a"; + /** + * "\u53d6\u6d88"\u6309\u94ae\u4e0a\u9762\u7684\u6587\u5b57 + * @type String + */ + this.buttonCancelValue = "\u53d6 \u6d88"; } Fe.inherit(Fe.Dialog, Fe.BaseClass, "Fe.Dialog"); @@ -1446,248 +1417,228 @@ Fe.inherit(Fe.Dialog, Fe.BaseClass, "Fe.Dialog"); * @config {String} [buttonAcceptValue] \u786e\u5b9a\u6309\u94ae\u4e0a\u9762\u7684\u6587\u5b57 * @config {String} [buttonCancelValue] \u53d6\u6d88\u6309\u94ae\u4e0a\u9762\u7684\u6587\u5b57 */ -Fe.Dialog.prototype.render = function(content, op) { - if ("undefined" != typeof(content)) - this.content = content; - if ("object" == typeof(op)) - Fe.extend(this, op); - // if(!isNaN(parseInt(this.width))) this.width = - // Math.max(parseInt(this.width), 150); - if ("number" == typeof(this.width)) - this.width += "px"; - if ("number" == typeof(this.height)) - this.height += "px"; - var me = this, - d = this.dialog = Fe.DialogFactory.produce(); - - /** @ignore */ - d.onaccept = function() { - me.accept() - }; - /** @ignore */ - d.oncancel = function() { - me.cancel() - }; - /** @ignore */ - d.onclose = function() { - me.close() - }; - /** @ignore */ - d.onhelp = function() { - me.help(); - }; - - d.show(this); - d.setActive(); - if (this.buttonbar && this.buttonAccept) - Fe.G("FeDialogButtonAccept_" + d.hashCode).focus(); - - if (this.locked) { - BdLockWindow.lock({ - opacity : 0.4, - backgroundColor : "#FFFFFF", - zIndex : (52000 - 10) - }); - this.addEventListener("onclose", function() { - BdLockWindow.unlock(); - }); - } - - setTimeout(function() { - me.dispatchEvent(new Fe.BaseEvent("onopen")); - }, 10); +Fe.Dialog.prototype.render = function (content, op) { + if ("undefined" != typeof(content)) + this.content = content; + if ("object" == typeof(op)) + Fe.extend(this, op); + // if(!isNaN(parseInt(this.width))) this.width = + // Math.max(parseInt(this.width), 150); + if ("number" == typeof(this.width)) + this.width += "px"; + if ("number" == typeof(this.height)) + this.height += "px"; + var me = this, + d = this.dialog = Fe.DialogFactory.produce(); + + /** @ignore */ + d.onaccept = function () { + me.accept() + }; + /** @ignore */ + d.oncancel = function () { + me.cancel() + }; + /** @ignore */ + d.onclose = function () { + me.close() + }; + /** @ignore */ + d.onhelp = function () { + me.help(); + }; + + d.show(this); + d.setActive(); + if (this.buttonbar && this.buttonAccept) + Fe.G("FeDialogButtonAccept_" + d.hashCode).focus(); + + if (this.locked) { + BdLockWindow.lock({ + opacity: 0.4, + backgroundColor: "#FFFFFF", + zIndex: (52000 - 10) + }); + this.addEventListener("onclose", function () { + BdLockWindow.unlock(); + }); + } + + setTimeout(function () { + me.dispatchEvent(new Fe.BaseEvent("onopen")); + }, 10); }; /** * Fe.Dialog\u7684setContent\u65b9\u6cd5\uff0c\u7528\u6765\u4fee\u6539\u5bf9\u8bdd\u6846\u7684\u5185\u5bb9 * @param {String} content \u5bf9\u8bdd\u6846\u7684\u5185\u5bb9 */ -Fe.Dialog.prototype.setContent = function(content) { - this.dialog.setContent(content) +Fe.Dialog.prototype.setContent = function (content) { + this.dialog.setContent(content) }; /** * Fe.Dialog\u7684setCaption\u65b9\u6cd5\uff0c\u7528\u6765\u4fee\u6539\u5bf9\u8bdd\u6846\u7684\u6807\u9898 * @param {String} caption \u5bf9\u8bdd\u6846\u7684\u6807\u9898 */ -Fe.Dialog.prototype.setCaption = function(caption) { - this.dialog.setCaption(caption) +Fe.Dialog.prototype.setCaption = function (caption) { + this.dialog.setCaption(caption) }; /** * Fe.Dialog\u7684setWidth\u65b9\u6cd5\uff0c\u7528\u6765\u4fee\u6539\u5bf9\u8bdd\u6846\u7684\u5bbd\u5ea6 * @param {Number} w \u5bf9\u8bdd\u6846\u7684\u5bbd\u5ea6 */ -Fe.Dialog.prototype.setWidth = function(w) { - this.dialog.setWidth(w) +Fe.Dialog.prototype.setWidth = function (w) { + this.dialog.setWidth(w) }; /** * Fe.Dialog\u7684setHeight\u65b9\u6cd5\uff0c\u7528\u6765\u4fee\u6539\u5bf9\u8bdd\u6846\u7684\u5bbd\u5ea6 * @param {Number} h \u5bf9\u8bdd\u6846\u7684\u9ad8\u5ea6 */ -Fe.Dialog.prototype.setHeight = function(h) { - this.dialog.setHeight(h) +Fe.Dialog.prototype.setHeight = function (h) { + this.dialog.setHeight(h) }; /** * Fe.Dialog\u7684getIframe\u65b9\u6cd5\uff0c\u7528\u6765\u83b7\u53d6\u5bf9\u8bdd\u6846\u5185\u90e8iframe\u7684\u5bf9\u8c61\u5f15\u7528 */ -Fe.Dialog.prototype.getIframe = function() { - return Fe.G("FeDialogIframe_" + this.dialog.hashCode); +Fe.Dialog.prototype.getIframe = function () { + return Fe.G("FeDialogIframe_" + this.dialog.hashCode); } /** * Fe.Dialog\u7684close\u65b9\u6cd5\uff0c\u7528\u6765\u5173\u95ed\u5bf9\u8bdd\u6846\uff0c\u5e76\u5206\u53d1onclose\u4e8b\u4ef6 */ -Fe.Dialog.prototype.close = function() { - var me = this, e = new Fe.BaseEvent("onclose"); - me.dispatchEvent(e); - if (!e.returnValue) - return; - this.dialog.hide(function() { - me.dispose(); - }); +Fe.Dialog.prototype.close = function () { + var me = this, e = new Fe.BaseEvent("onclose"); + me.dispatchEvent(e); + if (!e.returnValue) + return; + this.dialog.hide(function () { + me.dispose(); + }); } /** * Fe.Dialog\u7684accept\u65b9\u6cd5\uff0c\u70b9\u51fb\u786e\u5b9a\u6309\u94ae\u7684\u65f6\u5019\u8c03\u7528\u8fd9\u4e2a\u51fd\u6570\uff0c\u5e76\u5206\u53d1onaccept\u4e8b\u4ef6 */ -Fe.Dialog.prototype.accept = function() { - var e = new Fe.BaseEvent("onaccept"); - this.dispatchEvent(e); - if (!e.returnValue) - return; - this.close(); +Fe.Dialog.prototype.accept = function () { + var e = new Fe.BaseEvent("onaccept"); + this.dispatchEvent(e); + if (!e.returnValue) + return; + this.close(); }; /** * Fe.Dialog\u7684cancel\u65b9\u6cd5\uff0c\u70b9\u51fb\u53d6\u6d88\u6309\u94ae\u7684\u65f6\u5019\u8c03\u7528\u8fd9\u4e2a\u51fd\u6570\uff0c\u5e76\u5206\u53d1oncancel\u4e8b\u4ef6 */ -Fe.Dialog.prototype.cancel = function() { - var e = new Fe.BaseEvent("oncancel"); - this.dispatchEvent(e); - if (!e.returnValue) - return; - this.close(); +Fe.Dialog.prototype.cancel = function () { + var e = new Fe.BaseEvent("oncancel"); + this.dispatchEvent(e); + if (!e.returnValue) + return; + this.close(); }; /** * Fe.Dialog\u7684cancel\u65b9\u6cd5\uff0c\u70b9\u51fb\u6807\u9898\u680f\u4e0a\u9762\u7684\u5e2e\u52a9\u56fe\u6807\u7684\u65f6\u5019\u8c03\u7528\u8fd9\u4e2a\u51fd\u6570\uff0c\u5e76\u5206\u53d1onhelp\u4e8b\u4ef6\u3002 * (\u6682\u65f6\u6ca1\u6709\u652f\u6301) */ -Fe.Dialog.prototype.help = function() { - this.dispatchEvent(new Fe.BaseEvent("onhelp")); +Fe.Dialog.prototype.help = function () { + this.dispatchEvent(new Fe.BaseEvent("onhelp")); }; - -if(Fe.isIE && Fe.isIE < 7){ - try{ - document.execCommand("BackgroundImageCache", false, true); - }catch(e){} -}; - +if (Fe.isIE && Fe.isIE < 7) { + try { + document.execCommand("BackgroundImageCache", false, true); + } catch (e) { + } +} +; /** * \u5173\u95ed\u6240\u6709\u7684\u5bf9\u8bdd\u6846 */ -Fe.Dialog.close = function() { - for (var i = 0, n = Fe.DialogFactory.dialogs.length; i < n; i++) { - var dialog = Fe.DialogFactory.dialogs[i]; - if (dialog.active && typeof(dialog.onclose == "function")) { - dialog.onclose(); - } - } +Fe.Dialog.close = function () { + for (var i = 0, n = Fe.DialogFactory.dialogs.length; i < n; i++) { + var dialog = Fe.DialogFactory.dialogs[i]; + if (dialog.active && typeof(dialog.onclose == "function")) { + dialog.onclose(); + } + } }; - - - - /** * Fe.Dialog\u6269\u5c55\u7684\u9759\u6001\u65b9\u6cd5 * \u6253\u5f00\u4e00\u4e2a\u666e\u901a\u7684Dialog * @param {String} content \u5bf9\u8bdd\u6846\u7684\u5185\u5bb9 * @param {Object} op \u5bf9\u8bdd\u6846\u7684\u914d\u7f6e\u4fe1\u606f */ -Fe.Dialog.open = function(content, op) { - var dialog = new Fe.Dialog(); - dialog.render(content, op); - return dialog; +Fe.Dialog.open = function (content, op) { + var dialog = new Fe.Dialog(); + dialog.render(content, op); + return dialog; }; - - - /** * \u6253\u5f00\u4e00\u4e2a\u7c7b\u4f3calert\u5f62\u5f0f\u7684\u5bf9\u8bdd\u6846 * @param {String} content \u5bf9\u8bdd\u6846\u7684\u5185\u5bb9 * @param {Object} op \u5bf9\u8bdd\u6846\u7684\u914d\u7f6e\u4fe1\u606f */ -Fe.Dialog.alert = function(content, op) { - return this.open(content, Fe.extend({ - buttonbar : true, - buttonAccept : true - }, op || {})); +Fe.Dialog.alert = function (content, op) { + return this.open(content, Fe.extend({ + buttonbar: true, + buttonAccept: true + }, op || {})); }; - - - - /** * \u6253\u5f00\u4e00\u4e2a\u7c7b\u4f3cconfirm\u5f62\u5f0f\u7684\u5bf9\u8bdd\u6846 * @param {String} content \u5bf9\u8bdd\u6846\u7684\u5185\u5bb9 * @param {Object} op \u5bf9\u8bdd\u6846\u7684\u914d\u7f6e\u4fe1\u606f */ -Fe.Dialog.confirm = function(content, op) { - return this.open(content, Fe.extend({ - locked : true, - buttonbar : true, - buttonAccept : true, - buttonCancel : true - }, op || {})); +Fe.Dialog.confirm = function (content, op) { + return this.open(content, Fe.extend({ + locked: true, + buttonbar: true, + buttonAccept: true, + buttonCancel: true + }, op || {})); }; - - - - /** * \u6253\u5f00\u4e00\u4e2a\u7c7b\u4f3cshowModalDialog\u5f62\u5f0f\u7684\u5bf9\u8bdd\u6846 * @param {String} content \u5bf9\u8bdd\u6846\u7684\u5185\u5bb9 * @param {Object} op \u5bf9\u8bdd\u6846\u7684\u914d\u7f6e\u4fe1\u606f */ -Fe.Dialog.showModalDialog = function(content, op) { - return this.open(content, Fe.extend({ - locked : true, - position : "center" - }, op || {})); +Fe.Dialog.showModalDialog = function (content, op) { + return this.open(content, Fe.extend({ + locked: true, + position: "center" + }, op || {})); }; - - - - - /** * \u63d0\u4ea4form\u5230\u5bf9\u8bdd\u6846 * @param {Form} form \u5c06form\u63d0\u4ea4\u5230\u5bf9\u8bdd\u6846\u5185\u90e8 * @param {Object} op \u5bf9\u8bdd\u6846\u7684\u914d\u7f6e\u4fe1\u606f */ -Fe.Dialog.submit = function(form, op) { - var dialog = this.open("about:blank", Fe.extend({ - contentType : "page" - }, op || {})); - var target = form.target; - form.target = dialog.getIframe().name; - form.submit(); - form.target = target; - return dialog; +Fe.Dialog.submit = function (form, op) { + var dialog = this.open("about:blank", Fe.extend({ + contentType: "page" + }, op || {})); + var target = form.target; + form.target = dialog.getIframe().name; + form.submit(); + form.target = target; + return dialog; }; \ No newline at end of file diff --git a/src/main/webapp/stat/js/ui/editor/css/editor.css b/src/main/webapp/stat/js/ui/editor/css/editor.css new file mode 100644 index 000000000..9b4706879 --- /dev/null +++ b/src/main/webapp/stat/js/ui/editor/css/editor.css @@ -0,0 +1,388 @@ +.tangram_editor_container { + padding: 5px; + border: 1px solid #D3D3D3; + background: #fff +} + +/* 工具栏 */ +.editor-tools { + height: 30px; + background: #fff url(img/editor-icon.gif) repeat-x; + border: 1px solid #ddd; + border-bottom: 1px solid #7b8982; + position: relative +} + +.editor-tools div, .editor-tools td { + font-size: 12px +} + +.editor-toolbar { + height: 23px; + padding: 4px; + border-bottom: 1px solid #d5d5d5; + position: relative +} + +.editor-toolbar div, .editor-toolbar p, .editor-toolbar span { + position: relative; + display: inline-block; + cursor: default; + vertical-align: middle +} + +* html .editor-toolbar div, * html .editor-toolbar p, * html .editor-toolbar span { + display: inline +} + +*:first-child + html .editor-toolbar div, *:first-child + html .editor-toolbar p, *:first-child + html .editor-toolbar span { + display: inline +} + +.editor-toolbar .btn_hover { + padding: 0 +} + +.editor-toolbar .btn_hover div { + border-top: 1px solid #729bd1; + border-bottom: 1px solid #729bd1; + background: #fff; +} + +.editor-toolbar .btn_hover p { + border-left: 1px solid #729bd1; + border-right: 1px solid #729bd1; + padding: 1px 2px +} + +.editor-toolbar .btn_disabled { + padding: 0 +} + +.editor-toolbar .btn_disabled div { + color: #C8C8C8; + padding: 0 1px; + border-color: #ddd +} + +.editor-toolbar .btn_disabled p { + border-color: #ddd; + padding: 2px +} + +.editor-toolbar .btn_active { + padding: 0 +} + +.editor-toolbar .btn_active div { + border-top: 1px solid #ddd; + border-bottom: 1px solid #ddd; + background: #DDE1EB +} + +.editor-toolbar .btn_active p { + border-left: 1px solid #ddd; + border-right: 1px solid #ddd +} + +.editor-toolbar .btn_highlight { + padding: 0 +} + +.editor-toolbar .btn_highlight div { + border-top: 1px solid #729bd1; + border-bottom: 1px solid #729bd1; + background: #dde1eb +} + +.editor-toolbar .btn_highlight p { + border-left: 1px solid #729bd1; + border-right: 1px solid #729bd1; + padding: 1px 2px +} + +.editor-toolbar div { + margin: 0 3px; + *margin-right: 4px; + padding: 0 1px; +} + +.editor-toolbar div div { + margin: 0; + padding: 0 +} + +.editor-toolbar div div p { + margin: 0 -1px; + padding: 2px; + *padding: 3px 2px 3px; + vertical-align: top; + *left: -1px; +} + +.editor-toolbar div .btn_undo { + width: 17px; + height: 17px; + background: url(img/editor-icon.gif) no-repeat center -35px +} + +.editor-toolbar div .btn_redo { + width: 17px; + height: 17px; + background: url(img/editor-icon.gif) no-repeat center -56px +} + +.editor-toolbar div .btn_bold { + width: 17px; + height: 17px; + background: url(img/editor-icon.gif) no-repeat center -78px +} + +.editor-toolbar div .btn_italic { + width: 17px; + height: 17px; + background: url(img/editor-icon.gif) no-repeat center -100px +} + +.editor-toolbar div .btn_underline { + width: 17px; + height: 17px; + background: url(img/editor-icon.gif) no-repeat center -119px +} + +.editor-toolbar div .btn_justifyleft { + width: 17px; + height: 17px; + background: url(img/editor-icon.gif) no-repeat center -162px +} + +.editor-toolbar div .btn_justifycenter { + width: 17px; + height: 17px; + background: url(img/editor-icon.gif) no-repeat center -183px +} + +.editor-toolbar div .btn_justifyright { + width: 17px; + height: 17px; + background: url(img/editor-icon.gif) no-repeat center -204px +} + +.editor-toolbar div .btn_image { + width: 17px; + height: 17px; + background: url(img/editor-icon.gif) no-repeat center -224px +} + +.editor-toolbar div .btn_bar { + width: 1px; + height: 17px; + background: #D0D0D0 +} + +.editor-toolbar .btn_disabled .btn_undo { + background-position: center -245px +} + +.editor-toolbar .btn_disabled .btn_redo { + background-position: center -265px +} + +.editor-toolbar .btn_disabled .btn_bold { + background-position: center -288px +} + +.editor-toolbar .btn_disabled .btn_italic { + background-position: center -309px +} + +.editor-toolbar .btn_disabled .btn_underline { + background-position: center -330px +} + +.editor-toolbar .btn_disabled .btn_justifyleft { + background-position: center -372px +} + +.editor-toolbar .btn_disabled .btn_justifycenter { + background-position: center -394px +} + +.editor-toolbar .btn_disabled .btn_justifyright { + background-position: center -415px +} + +.editor-toolbar .btn_disabled .btn_image { + background-position: center -434px +} + +/* 选择框 */ +.editor-toolbar-list { + position: absolute; + border: 1px solid #333333; + border-top-color: #999999; + border-left-color: #999999 /*required*/ +} + +.editor-toolbar-list { + position: absolute; + border: 1px solid #333333; + _margin-left: -10px; + border-top-color: #999999; + border-left-color: #999999 +} + +/*ie6下需复设置*/ +.editor-toolbar-list-item { + padding: 2px 5px; + white-space: nowrap; + overflow: hidden; + cursor: default; + font-size: 12px; + vertical-align: middle; + background-color: #FFFFFF; /*required*/ +} + +.editor-toolbar-list-item { + padding: 2px 5px; +} + +/*ie6下需复设置*/ +.editor-toolbar-list-item-selected { + background-color: #DDDDDD; +} + +.editor-toolbar-list-item span { + display: inline-block; +} + +.editor-toolbar-list-item-hover { + background-color: #3366FF; + color: #FFFFFF; +} + +.editor-toolbar-fontname-list { +} + +.editor-toolbar-forecolor-list { +} + +.editor-toolbar-fontsize-list { +} + +.editor-toolbar-fontname-item { + width: 100px +} + +.editor-toolbar-forecolor-item { + width: 80px +} + +.editor-toolbar-fontsize-item { + width: 65px +} + +/* 字体按钮 */ +.editor-toolbar .editor-toolbar-select-fontfamily { + padding: 0; + text-align: center; +} + +.editor-toolbar .editor-toolbar-select-fontfamily div { + border-top: 1px solid #999; + border-bottom: 1px solid #999; + background: #fff; + padding: 0 +} + +.editor-toolbar .editor-toolbar-select-fontfamily p { + border-left: 1px solid #999; + border-right: 1px solid #999; + padding: 1px 2px +} + +.editor-toolbar .editor-toolbar-select-fontfamily div.editor-toolbar-select-caption { + width: 50px; + overflow: hidden; + vertical-align: middle; + white-space: nowrap; + border: none; + margin-right: 3px +} + +.editor-toolbar .editor-toolbar-select-fontfamily div.editor-toolbar-select-dropdown { + width: 7px; + vertical-align: middle; + background: transparent url(img/editor-icon.gif) no-repeat center -488px; + border: none +} + +/* 字号按钮 */ +.editor-toolbar .editor-toolbar-select-fontsize { + padding: 0; + text-align: center; +} + +.editor-toolbar .editor-toolbar-select-fontsize div { + border-top: 1px solid #999; + border-bottom: 1px solid #999; + background: #fff; + padding: 0 +} + +.editor-toolbar .editor-toolbar-select-fontsize p { + border-left: 1px solid #999; + border-right: 1px solid #999; + padding: 1px 2px +} + +.editor-toolbar .editor-toolbar-select-fontsize div.editor-toolbar-select-caption { + width: 50px; + overflow: hidden; + vertical-align: middle; + white-space: nowrap; + border: none; + margin-right: 3px +} + +.editor-toolbar .editor-toolbar-select-fontsize div.editor-toolbar-select-dropdown { + width: 7px; + vertical-align: middle; + background: transparent url(img/editor-icon.gif) no-repeat center -488px; + border: none +} + +/* 字体颜色按钮 */ +.editor-toolbar .editor-toolbar-select-forecolor { + padding: 0; + text-align: center; +} + +.editor-toolbar .editor-toolbar-select-forecolor div { + border-top: 1px solid #999; + border-bottom: 1px solid #999; + background: #fff; + padding: 0 +} + +.editor-toolbar .editor-toolbar-select-forecolor p { + border-left: 1px solid #999; + border-right: 1px solid #999; + padding: 1px 2px +} + +.editor-toolbar .editor-toolbar-select-forecolor div.editor-toolbar-select-caption { + width: 50px; + overflow: hidden; + vertical-align: middle; + white-space: nowrap; + border: none; + margin-right: 3px +} + +.editor-toolbar .editor-toolbar-select-forecolor div.editor-toolbar-select-dropdown { + width: 7px; + vertical-align: middle; + background: transparent url(img/editor-icon.gif) no-repeat center -488px; + border: none +} diff --git a/src/main/webapp/stat/js/ui/editor/css/editorarea.css b/src/main/webapp/stat/js/ui/editor/css/editorarea.css new file mode 100644 index 000000000..480c49dce --- /dev/null +++ b/src/main/webapp/stat/js/ui/editor/css/editorarea.css @@ -0,0 +1,18 @@ +body { + color: #000; + margin: 0; + padding: 1px; + font-size: 13px; + font-family: Arial +} + +form, h1, h2, h3, h4, ul, li, dl, dt, dd, p { + margin: 0; + padding: 0 +} + +img { + border: 0; + margin: 0; + padding: 0 +} \ No newline at end of file diff --git a/WebContent/stat/js/ui/editor/css/img/editor-icon.gif b/src/main/webapp/stat/js/ui/editor/css/img/editor-icon.gif similarity index 100% rename from WebContent/stat/js/ui/editor/css/img/editor-icon.gif rename to src/main/webapp/stat/js/ui/editor/css/img/editor-icon.gif diff --git a/src/main/webapp/stat/js/ui/editor/js/editor.js b/src/main/webapp/stat/js/ui/editor/js/editor.js new file mode 100644 index 000000000..163e20feb --- /dev/null +++ b/src/main/webapp/stat/js/ui/editor/js/editor.js @@ -0,0 +1,4199 @@ +baidu.on = function (H, F, E, G) { + if (typeof E != "function") { + return H + } + F = F.replace(/^on/i, "").toLowerCase(); + function B(I) { + return I || window.event + } + + var D = function (I) { + E.call(D.src, B(I)) + }; + D.src = H; + var C = baidu.on._listeners; + var A = [H, F, E, D]; + C[C.length] = A; + if (H.attachEvent) { + H.attachEvent("on" + F, D) + } else { + if (H.addEventListener) { + H.addEventListener(F, D, false) + } + } + return H +}; +baidu.on._listeners = []; +baidu.string = baidu.string || {}; +baidu.isString = function (A) { + return (typeof A == "object" && A && A.constructor == String) || typeof A == "string" +}; +baidu.G = function () { + for (var A = [], B = arguments.length - 1; B > -1; B--) { + var C = arguments[B]; + A[B] = null; + if (typeof C == "object" && C && C.dom) { + A[B] = C.dom + } else { + if ((typeof C == "object" && C && C.tagName) || C == window || C == document) { + A[B] = C + } else { + if (baidu.isString(C) && (C = document.getElementById(C))) { + A[B] = C + } + } + } + } + return A.length < 2 ? A[0] : A +}; +(function () { + var B = {}; + baidu.BaseClass = function (C) { + B[(this.guid = (C || baidu.BaseClass.guid()))] = this + }; + var A = 0; + baidu.BaseClass.guid = function () { + return "MZ__" + (A++).toString(36) + }; + baidu.BaseClass.create = function (D) { + var E = new baidu.BaseClass(); + delete B[this.guid]; + for (var C in D) { + E[C] = D[C] + } + return E + }; + window.Instance = baidu.instance = function (C) { + return B[C] + }; + baidu.BaseClass.prototype.dispose = function () { + if (this.guid) { + delete B[this.guid] + } + for (var C in this) { + if (typeof this[C] != "function") { + delete this[C] + } + } + }; + baidu.BaseClass.decontrol = function (C) { + if (C && C.guid) { + delete B[C.guid] + } + }; + baidu.BaseClass.prototype.toString = function () { + return "[object " + (this._className || "Object") + "]" + } +})(); +baidu.BaseEvent = function (A, B) { + this.type = A; + this.returnValue = true; + this.target = B || null; + this.currentTarget = this.srcElement = null +}; +baidu.BaseClass.prototype.addEventListener = function (D, C, B) { + if (typeof C != "function") { + throw ("addEventListener:" + C + " is not a function") + } + if (!this.__listeners) { + this.__listeners = {} + } + var A = this.__listeners, E; + if (typeof B == "string" && B) { + if (/[^\w\-]/.test(B)) { + throw ("nonstandard key:" + B) + } else { + C.hashCode = B; + E = B + } + } + if (D.indexOf("on") != 0) { + D = "on" + D + } + if (typeof A[D] != "object") { + A[D] = {} + } + E = E || baidu.BaseClass.guid(); + C.hashCode = E; + A[D][E] = C +}; +baidu.BaseClass.prototype.removeEventListener = function (C, B) { + if (typeof B == "function") { + B = B.hashCode + } else { + if (typeof B != "string") { + return + } + } + if (!this.__listeners) { + this.__listeners = {} + } + if (C.indexOf("on") != 0) { + C = "on" + C + } + var A = this.__listeners; + if (!A[C]) { + return + } + if (A[C][B]) { + delete A[C][B] + } +}; +baidu.BaseClass.prototype.dispatchEvent = function (C) { + if (!this.__listeners) { + this.__listeners = {} + } + var B, A = this.__listeners, D = C.type; + C.target = C.srcElement = C.target || C.srcElement || this; + C.currentTarget = this; + if (typeof this[D] == "function") { + this[D](C) + } + if (typeof A[D] == "object") { + for (B in A[D]) { + if (typeof A[D][B] == "function") { + A[D][B].call(this, C) + } + } + } + return C.returnValue +}; +baidu.extend = function (C, A) { + if (C && A && typeof (A) == "object") { + for (var B in A) { + C[B] = A[B] + } + } + return C +}; +baidu.trim = function (B, A) { + if (A == "left") { + return B.replace(/(^[\s\t\xa0\u3000]+)/g, "") + } + if (A == "right") { + return B.replace(/([\u3000\xa0\s\t]+$)/g, "") + } + return B.replace(/(^[\s\t\xa0\u3000]+)|([\u3000\xa0\s\t]+$)/g, "") +}; +baidu.addClass = function (A, B) { + if (!(A = baidu.G(A))) { + return + } + B = baidu.trim(B); + if (!new RegExp("(^| )" + B.replace(/(\W)/g, "\\\x241") + "( |\x24)").test(A.className)) { + A.className = baidu.trim(A.className.split(/\s+/).concat(B).join(" ")) + } +}; +baidu.ac = baidu.addClass; +baidu.removeClass = function (A, B) { + if (!(A = baidu.G(A))) { + return + } + B = baidu.trim(B); + var C = A.className.replace(new RegExp("(^| +)" + B.replace(/(\W)/g, "\\\x241") + "( +|\x24)", "g"), "\x242"); + if (A.className != C) { + A.className = baidu.trim(C) + } +}; +baidu.rc = baidu.removeClass; +baidu.ui = baidu.ui || {}; +baidu.editor = { + _register: [], register: function (A) { + this._register[this._register.length] = A + }, _commands: {}, registCommand: function (B, A) { + this._commands[B] = A + }, _queries: {}, registQuery: function (B, A) { + this._queries[B] = A + }, _parser: {}, registParser: function (A, B) { + this._parser[A] = B + } +}; +baidu.editor.EditorConfig = { + docType: "", + skinCSS: "../static/js/ui/editor/css/editorarea.css", + maxUndoCount: 100, + hotkey: {"ctrl+66": "Bold", "meta+66": "Bold", "ctrl+90": "Undo", "ctrl+89": "Redo", "9": "Bold"} +}; +baidu.ie = 0; +if (/MSIE (\d+(\.\d+)?)/.test(navigator.userAgent) && !window.opera) { + baidu.ie = parseFloat(RegExp.$1) +} +baidu.editor.register(function (C) { + var A = baidu.editor.EditorConfig.hotkey; + if (A) { + function B(H) { + var D = H; + H = H.srcElement; + var G = H.keyCode || H.which; + if (H.ctrlKey && G == 86 || H.ctrlKey && G == 88 || H.shiftKey && G == 45 || H.shiftKey && G == 46) { + C.dispatchEvent(new baidu.BaseEvent("onneedsavescene")); + setTimeout(function () { + C.dispatchEvent(new baidu.BaseEvent("onbeforeselectionchange")); + C.dispatchEvent(new baidu.BaseEvent("onselectionchange")); + C.dispatchEvent(new baidu.BaseEvent("onafterselectionchange")); + C.dispatchEvent(new baidu.BaseEvent("onneedsavescene")) + }, 0); + D.returnValue = false; + return false + } + if (baidu.ie && G == 8) { + var I = C.getSelection().getSelectedElement(); + if (I) { + C.dispatchEvent(new baidu.BaseEvent("onneedsavescene")); + baidu.dom.element.remove(I, C.document); + C.dispatchEvent(new baidu.BaseEvent("onneedsavescene")); + if (H.preventDefault) { + H.preventDefault() + } + } + } + for (var F in A) { + if (/^(ctrl|meta)\+(\d+)$/.test(F.toLowerCase()) || /^(\d+)$/.test(F)) { + if ((H[RegExp.$1 + "Key"] && G == RegExp.$2) || G == RegExp.$1) { + try { + C.execCommand(A[F]) + } catch (E) { + } + D.returnValue = H.returnValue = false; + if (H.preventDefault) { + H.preventDefault() + } + return false + } + } + } + return true + } + + C.addEventListener("onbeforekeydown", B) + } +}); +baidu.inherits = function (A, E, D) { + var B, F, H = A.prototype, G = function () { + }; + G.prototype = E.prototype; + F = A.prototype = new G(); + if (typeof D == "string") { + F._className = D + } + for (B in H) { + F[B] = H[B] + } + A.prototype.constructor = H.constructor; + A.superClass = E.prototype; + H = G = null; + return F +}; +(function () { + function A(C, B) { + baidu.BaseClass.call(this); + this.iframe = null; + this.document = null; + this.window = null; + B = B || {}; + this.width = B.width || ""; + this.height = B.height || ""; + this.readyState = 0; + this.ieBakRange = null; + this.temp = {scene: {}}; + this.isBlur = true + } + + baidu.inherits(A, baidu.BaseClass, "baidu.Editor"); + A.prototype.render = function () { + var D = typeof this.width == "number" ? this.width + "px" : this.width; + var B = typeof this.height == "number" ? this.height + "px" : this.height; + B = "height:" + B + ";"; + var C = ["
    "); + C.push("
    "); + this._setReadyState(1); + this.availableIframe(); + return C.join("") + }; + A.prototype.availableIframe = function () { + var B = document.getElementById("tangram_editor_iframe_" + this.guid); + if (B) { + this.iframe = B; + this._setReadyState(3) + } else { + var C = this; + setTimeout(function () { + C.availableIframe() + }, 20) + } + }; + A.prototype.makeEditable = function (F) { + var D = this; + var B = [baidu.editor.EditorConfig.docType]; + B.push(""); + if (baidu.editor.EditorConfig.skinCSS) { + var C = baidu.editor.EditorConfig.skinCSS + (baidu.ie ? "" : "?tmp=" + new Date().getTime()); + B.push("") + } + B.push(""); + B.push(F || ""); + B.push(""); + D.window = D.iframe.contentWindow; + var E = D.document = D.window.document; + E.open(); + E.write(B.join("")); + E.close(); + if (baidu.ie) { + E.body.disabled = true; + E.body.contentEditable = true; + E.body.removeAttribute("disabled"); + D._setReadyState(4) + } else { + setTimeout(function () { + try { + E.body.spellcheck = false; + E.designMode = "on"; + var J = false; + try { + E.execCommand("styleWithCSS", false, J) + } catch (H) { + E.execCommand("useCSS", false, !J) + } + var I = false; + var G = true; + E.execCommand("enableObjectResizing", false, !I); + E.execCommand("enableInlineTableEditing", false, !G) + } catch (H) { + } + D._setReadyState(4) + }, 1) + } + }; + A.prototype.execCommand = function (G, D, E) { + var C = false, F = true; + this.focus(); + if (this.__hasEnterdExecCommand) { + F = false + } else { + this.__hasEnterdExecCommand = true + } + this.dispatchEvent(new baidu.BaseEvent("onbeforeexeccommand", {command: G, topOpearation: F})); + if (typeof G == "string") { + var B = baidu.editor._commands; + if (typeof B[G] == "function") { + C = B[G].apply(null, [this].concat(Array.prototype.slice.call(arguments, 1))) + } else { + C = this.document.execCommand(G, D, E) + } + } else { + if (typeof G == "function") { + C = G.apply(null, [this].concat(Array.prototype.slice.call(arguments, 1))) + } + } + if (F) { + this.__hasEnterdExecCommand = false + } + this.dispatchEvent(new baidu.BaseEvent("onafterexeccommand", {command: G, topOpearation: F})); + this.selectionChangeHandler(null, true); + return C + }; + A.prototype.queryContextState = function (B) { + var C = baidu.editor._parser; + if (typeof C[B] == "function") { + return C[B](this) + } + }; + A.prototype.queryCommandState = function (D) { + var B = baidu.editor._queries; + if (typeof B[D] == "function") { + return B[D](this) + } else { + var C = navigator.userAgent; + if (/(\d+\.\d)\s+safari/i.test(C) && !/chrome/i.test(C) && D.toLowerCase() == "paste") { + return false + } + return this.document.queryCommandEnabled(D) && this.document.queryCommandState(D) + } + }; + A.prototype.getContent = function (B) { + if (!B) { + var C = this.document.body.innerHTML; + return C + } else { + var C = baidu.editor.EditorConfig.docType; + C += ""; + C += this.document.documentElement.innerHTML; + C += ""; + return C + } + }; + A.prototype.setContent = function (C) { + var B = this; + this.document.body.innerHTML = C; + setTimeout(function () { + B.dispatchEvent(new baidu.BaseEvent("onbeforeselectionchange")); + B.dispatchEvent(new baidu.BaseEvent("onselectionchange")); + B.dispatchEvent(new baidu.BaseEvent("onafterselectionchange")) + }, 0) + }; + A.prototype._bindEvent = function () { + var D = this; + + function E(F) { + D.selectionChangeHandler(F) + } + + function B(H) { + H = D.window.event || H; + var G = H.keyCode || H.which, F; + D.dispatchEvent(F = new baidu.BaseEvent("onbeforekeydown", H)); + if (F.returnValue == false) { + return + } + D.dispatchEvent(F = new baidu.BaseEvent("onkeydown", H)); + if (F.returnValue == false) { + return + } + if (G != 27 && G != 16 && G != 17 && G != 18) { + clearTimeout(B.timer); + B.timer = setTimeout(function () { + E() + }, 500) + } + D.dispatchEvent(new baidu.BaseEvent("onafterkeydown", H)) + } + + function C(F) { + clearTimeout(C.timer); + C.timer = setTimeout(function () { + E() + }, 20) + } + + baidu.on(D.document, "mouseup", E); + baidu.on(D.document, "keydown", B); + baidu.on(D.document, "mousemove", C); + baidu.on(D.window, "blur", function () { + D.dispatchEvent(new baidu.BaseEvent("onblur")); + D.isBlur = true + }); + baidu.on(D.window, "focus", function () { + D.dispatchEvent(new baidu.BaseEvent("onfocus")); + D.isBlur = false + }); + if (baidu.ie) { + setInterval(function () { + if (!D.isBlur) { + D.ieBakRange = D.document.selection.createRange(); + D.ieBakRangeType = D.document.selection.type + } + }, 20) + } + this.dispatchEvent(new baidu.BaseEvent("onwysiwygready")) + }; + A.prototype.selectionChangeHandler = function (H) { + var G = this.temp.scene; + var C = this.document.body.innerHTML; + if (this.temp.innerHTML != C) { + this.temp.innerHTML = C; + H = this.window.event || H; + if (H && H.type && H.type.indexOf("key") >= 0) { + var E = H.srcElement || H.target; + if (E) { + if (E.nodeType == 3) { + E = E.parentNode + } + var I = E.getElementsByTagName("*").length; + if (E.tagName != "HTML" && E == G.target && I == G.count) { + return + } + G.target = E; + G.count = I + } + } + } else { + if (window.getSelection) { + var B = this.window.getSelection().getRangeAt(0); + if (B.startContainer == G.startContainer && B.endContainer == G.endContainer) { + if (B.collapsed) { + return + } else { + if (B.startOffset == G.startOffset && B.endOffset == G.endOffset) { + return + } + } + } + G.endOffset = B.endOffset; + G.startOffset = B.startOffset; + G.endContainer = B.endContainer; + G.startContainer = B.startContainer + } else { + if (document.selection) { + var F = this.document.selection; + var B = F.createRange(); + var D = F.type.toLowerCase(); + if (G.type == D) { + if (D == "control" && B(0) == G.control) { + return + } else { + if (G.text == B.text && G.parentElement == B.parentElement()) { + return + } + } + } + G.type = D; + if (D == "control") { + G.control = B(0) + } else { + G.text = B.text; + G.parentElement = B.parentElement() + } + } + } + } + this.dispatchEvent(new baidu.BaseEvent("onbeforeselectionchange")); + this.dispatchEvent(new baidu.BaseEvent("onselectionchange")); + this.dispatchEvent(new baidu.BaseEvent("onafterselectionchange")) + }; + A.prototype._setReadyState = function (B) { + this.readyState = B; + this.dispatchEvent(new baidu.BaseEvent("onreadystatechange", B)) + }; + A.prototype.addToolbarItem = function (B) { + if (B && typeof B.initialize == "function") { + B.initialize() + } + }; + baidu.editor.Editor = A +})(); +baidu.editor.create = function (D, A) { + var E = new baidu.editor.Editor(D, A); + if (typeof D == "string") { + D = document.getElementById(D) + } + var C = ""; + if (D && D.tagName) { + if (D.tagName.toLowerCase() == "textarea") { + C = D.value + } else { + C = D.innerHTML + } + } + if (C == "" && A) { + C = A.content || "" + } + if (!baidu.ie && C == "") { + C = "
    " + } + var B = baidu.BaseClass.guid(); + E.addEventListener("onreadystatechange", function (H) { + var G = H.currentTarget; + switch (G.readyState) { + case 3: + G.makeEditable(C); + break; + case 4: + for (var F = baidu.editor._register.length - 1; F >= 0; F--) { + baidu.editor._register[F](this) + } + G.removeEventListener("onreadystatechange", B); + G._bindEvent(); + break + } + }, B); + return E +}; +baidu.editor.Editor.prototype.focus = function () { + this.window.focus(); + try { + if (baidu.ie && this.ieBakRange) { + this.ieBakRange.select() + } + } catch (A) { + } +}; +baidu.dom = baidu.dom || {}; +baidu.isElement = function (A) { + if (A === undefined || A === null) { + return false + } + return A && A.nodeName && A.nodeType == 1 +}; +baidu.isDocument = function (A) { + if (A === undefined || A === null) { + return false + } + return A && A.nodeType == 9 +}; +baidu.dom.getWindow = function (A) { + if (!baidu.isDocument(A)) { + throw new Error("[baidu.dom.getWindow] param must be Document") + } + return A.parentWindow ? A.parentWindow : (A.defaultView ? A.defaultView : null) +}; +baidu.array = baidu.array || {}; +baidu.array.each = function (F, D) { + var C, E, B, A = F.length; + if ("function" == typeof D) { + for (B = 0; B < A; B++) { + E = F[B]; + C = D.call(F, E, B); + if (C === false) { + break + } + } + } + return F +}; +baidu.each = baidu.array.each; +baidu.isElement = function (A) { + if (A === undefined || A === null) { + return false + } + return A && A.nodeName && A.nodeType == 1 +}; +baidu.isText = function (A) { + if (A === undefined || A === null) { + return false + } + return A && A.nodeType == 3 +}; +baidu.browser = baidu.browser || {}; +(function () { + var A = navigator.userAgent; + baidu.firefox = baidu.browser.firefox = /firefox\/(\d+\.\d)/i.test(A) ? parseFloat(RegExp.$1) : 0; + baidu.ie = baidu.browser.ie = /msie (\d+\.\d)/i.test(A) ? parseFloat(RegExp.$1) : 0; + baidu.opera = baidu.browser.opera = /opera\/(\d+\.\d)/i.test(A) ? parseFloat(RegExp.$1) : 0; + baidu.safari = baidu.browser.safari = (/(\d+\.\d)\s+safari/i.test(A) && !/chrome/i.test(A)) ? parseFloat(RegExp.$1) : 0; + try { + baidu.browser.maxthon = /(\d+\.\d)/.test(external.max_version) ? parseFloat(RegExp.$1) : 0 + } catch (B) { + baidu.browser.maxthon = 0 + } + baidu.maxthon = baidu.browser.maxthon; + baidu.isGecko = baidu.browser.isGecko = /gecko/i.test(A) && !/like gecko/i.test(A); + baidu.isStrict = baidu.browser.isStrict = document.compatMode == "CSS1Compat"; + baidu.isWebkit = baidu.browser.isWebkit = /webkit/i.test(A) +})(); +baidu.dom.getDocument = function (A) { + return A.nodeType == 9 ? A : A.ownerDocument || A.document +}; +baidu.dom.getParent = function (B) { + var A = B.parentNode; + return (A && baidu.isElement(A)) ? A : null +}; +baidu.dom.getParents = function (B) { + var A = []; + do { + A.unshift(B) + } while (B = baidu.dom.getParent(B)); + return A +}; +baidu.dom.getIndex = function (C) { + var B = C.parentNode && C.parentNode.firstChild; + var A = -1; + while (B) { + A++; + if (B == C) { + return A + } + B = B.nextSibling + } + return -1 +}; +baidu.dom.getCommonAncestor = function (B, A) { + B = baidu.isElement(B) ? B : baidu.dom.getParent(B); + A = baidu.isElement(A) ? A : baidu.dom.getParent(A); + if (A === B) { + return B + } + if (baidu.dom.element.contains(A, B)) { + return A + } + do { + if (baidu.dom.element.contains(B, A)) { + return B + } + } while ((B = baidu.dom.getParent(B))); + return null +}; +baidu.dom.insertAfter = function (B, A) { + A.parentNode.insertBefore(B, A.nextSibling); + return A +}; +baidu.dom.clone = function (C, A, D) { + var E = C.cloneNode(A); + if (!D) { + var B = function (G) { + if (!baidu.isElement(G)) { + return + } + G.removeAttribute("id", false); + var H = G.childNodes; + for (var F = 0; F < H.length; F++) { + B(H[F]) + } + }; + B(E) + } + return E +}; +baidu.dom.getNext = function (B, C) { + var A = B.nextSibling; + while (C && A && (baidu.isText(A)) && !baidu.trim(A.nodeValue)) { + A = A.nextSibling + } + return A +}; +baidu.dom.getPrevious = function (B, C) { + var A = B.previousSibling; + while (C && A && (baidu.isText(A)) && !baidu.trim(A.nodeValue)) { + A = A.previousSibling + } + return A ? A : null +}; +baidu.dom.getAddress = function (D, F, G) { + var C = [], E = F.documentElement; + while (D && D != E) { + var A = D.parentNode, B = -1, H = A.firstChild; + while (H) { + if (G && H.nodeType == 3 && H.previousSibling && H.previousSibling.nodeType == 3) { + H = H.nextSibling; + continue + } + B++; + if (H == D) { + break + } + H = H.nextSibling + } + C.unshift(B); + D = D.parentNode + } + return C +}; +baidu.dom.getByAddress = function (G, B, H) { + G = G.documentElement; + for (var D = 0; G && D < B.length; D++) { + var F = B[D]; + if (!H) { + G = G.childNodes[F]; + continue + } + var A = -1; + for (var C = 0; C < G.childNodes.length; C++) { + var E = G.childNodes[C]; + if (H === true && E.nodeType == 3 && E.previousSibling && E.previousSibling.nodeType == 3) { + continue + } + A++; + if (A == F) { + G = E; + break + } + } + } + return G ? G : null +}; +baidu.dom.text = baidu.dom.text || {}; +baidu.dom.text.getLength = function (A) { + return A.nodeValue.length +}; +baidu.dom.text.split = function (E, D, C) { + if (baidu.ie && D == baidu.dom.text.getLength(E)) { + var B = C.createTextNode(""); + baidu.dom.insertAfter(B, E); + return B + } + var A = E.splitText(D); + if (!!document.documentMode) { + baidu.dom.insertAfter(C.createTextNode(""), A) + } + return A +}; +baidu.dom.element = baidu.dom.element || {}; +baidu.dom.element.getChildCount = function (A) { + return A.childNodes.length +}; +baidu.dom.element.getChild = function (B, A) { + if (!A.slice) { + B = B.childNodes[A] + } else { + while (A.length > 0 && B) { + B = B.childNodes[A.shift()] + } + } + return B +}; +baidu.dom.element.getName = function (B) { + var C = B.nodeName.toLowerCase(); + if (baidu.ie) { + var A = B.scopeName; + if (A != "HTML") { + C = A.toLowerCase() + ":" + C + } + } + return C +}; +baidu.dom.element.is = function (C) { + var A = baidu.dom.element.getName(C); + for (var B = 0; B < arguments.length; B++) { + if (arguments[B] == A) { + return true + } + } + return false +}; +baidu.dom.element.append = function (C, B, A) { + if (A) { + C.insertBefore(B, C.firstChild) + } else { + C.appendChild(B) + } + return B +}; +baidu.dom.element.remove = function (A, B) { + if (A && A.parentNode && A.nodeName != "BODY") { + A.parentNode.removeChild(A) + } +}; +baidu.dom.element.contains = baidu.ie || baidu.isWebkit ? function (B, A) { + return !baidu.isElement(A) ? B.contains(baidu.dom.getParent(A)) : B != A && B.contains(A) +} : function (B, A) { + return !!(B.compareDocumentPosition(A) & 16) +}; +baidu.dom.element.setAttr = function (C, A, D) { + var B = { + cellpadding: "cellPadding", + cellspacing: "cellSpacing", + colspan: "colSpan", + rowspan: "rowSpan", + valign: "vAlign", + height: "height", + width: "width", + usemap: "useMap", + frameborder: "frameBorder" + }; + if (baidu.isString(A)) { + if (A == "style") { + C.style.cssText = D + } else { + if (A == "class") { + C.className = D + } else { + if (A == "for") { + C.htmlFor = D + } else { + if (A in B) { + C.setAttribute(B[A], D) + } else { + C[A] = D + } + } + } + } + } else { + for (var E in A) { + if (typeof A[E] != "function") { + baidu.setAttr(C, E, A[E]) + } + } + } +}; +baidu.dom.element.setStyle = function () { + var C = {}, B = /z-?index|font-?weight|opacity|zoom|line-?height/i, A = function (D, E) { + return E.charAt(1).toUpperCase() + }; + return function (G, D, H) { + if (typeof D == "string") { + var E; + if (!(E = C[D])) { + E = C[D] = D.replace(/(-[a-z])/gi, A) + } + var F = G.style; + if (E == "opacity") { + if ("opacity" in F) { + F.opacity = H + } else { + if ("MozOpacity" in F) { + F.MozOpacity = H + } else { + if ("filter" in F) { + F.filter = (F.filter || "").replace(/alpha\([^\)]*\)/gi, "") + (H == 1 ? "" : "alpha(opacity=" + H * 100 + ")"); + F.zoom = 1 + } + } + } + } else { + if (H && H.constructor == Number && !B.test(D)) { + H = H + "px" + } + F[E] = H + } + } else { + for (var I in D) { + if (typeof D[I] != "function") { + baidu.setStyle(G, I, D[I]) + } + } + } + return + } +}(); +baidu.dom.element.hasAttribute = function (C, B) { + var A = C.attributes.getNamedItem(B); + return !!(A && A.specified) +}; +baidu.editor.Range = function (A) { + var B = this; + B.startContainer = null; + B.startOffset = null; + B.endContainer = null; + B.endOffset = null; + B.document = A; + B.collapsed = true +}; +(function () { + POSITION_AFTER_START = 1; + POSITION_BEFORE_END = 2; + POSITION_BEFORE_START = 3; + POSITION_AFTER_END = 4; + var B = function (C) { + C.collapsed = (C.startContainer && C.endContainer && C.startContainer === C.endContainer && C.startOffset == C.endOffset) + }; + var A = function (M, R, C) { + M.optimizeBookmark(); + var Z = M.startContainer; + var O = M.endContainer; + var T = M.startOffset; + var I = M.endOffset; + var Q; + var J; + if (baidu.isText(O)) { + O = baidu.dom.text.split(O, I, this.document) + } else { + var V; + if ((V = baidu.dom.element.getChildCount(O)) > 0) { + if (I >= V) { + O = baidu.dom.element.append(O, M.document.createTextNode("")); + J = true + } else { + O = baidu.dom.element.getChild(O, I) + } + } + } + if (baidu.isText(Z)) { + baidu.dom.text.split(Z, T, this.document); + if (Z === O) { + O = baidu.dom.getNext(Z) + } + } else { + if (!T) { + Z = Z.insertBefore(M.document.createTextNode(""), Z.firstChild); + Q = true + } else { + if (T >= baidu.dom.element.getChildCount(Z)) { + Z = baidu.dom.element.append(Z, M.document.createTextNode("")); + Q = true + } else { + Z = baidu.dom.getPrevious(baidu.dom.element.getChild(Z, T)) + } + } + } + var W = baidu.dom.getParents(Z); + var E = baidu.dom.getParents(O); + var U, a, Y; + for (U = 0; U < W.length; U++) { + a = W[U]; + Y = E[U]; + if (!(a === Y)) { + break + } + } + var X = C, N, L, G, K; + for (var S = U; S < W.length; S++) { + N = W[S]; + if (X && !(N === Z)) { + L = baidu.dom.element.append(X, baidu.dom.clone(N)) + } + G = baidu.dom.getNext(N); + while (G) { + if (G === E[S] || G === O) { + break + } + K = baidu.dom.getNext(G); + if (R == 2) { + baidu.dom.element.append(X, baidu.dom.clone(G, true)) + } else { + if (R == 1) { + baidu.dom.element.append(X, baidu.dom.clone(G, true)) + } + baidu.dom.element.remove(G, C) + } + G = K + } + if (X) { + X = L + } + } + X = C; + for (var P = U; P < E.length; P++) { + N = E[P]; + if (R > 0 && !(N === O)) { + L = baidu.dom.element.append(X, baidu.dom.clone(N)) + } + if (!W[P] || N.parentNode != W[P].parentNode) { + G = baidu.dom.getPrevious(N); + while (G) { + if (G === W[P] || G === Z) { + break + } + K = baidu.dom.getPrevious(G); + if (R == 2) { + X.insertBefore(G.cloneNode(true), X.firstChild) + } else { + baidu.dom.element.remove(G, C); + if (R == 1) { + X.insertBefore(G, X.firstChild) + } + } + G = K + } + } + if (X) { + X = L + } + } + if (R == 2) { + var D = M.startContainer; + if (baidu.isText(D)) { + D.data += D.nextSibling.data; + D.parentNode.removeChild(D.nextSibling) + } + var H = M.endContainer; + if (baidu.isText(H) && H.nextSibling) { + H.data += H.nextSibling.data; + H.parentNode.removeChild(H.nextSibling) + } + } else { + if (a && Y && (Z.parentNode != a.parentNode || O.parentNode != Y.parentNode)) { + var F = baidu.dom.getIndex(Y); + if (Q && Y.parentNode == Z.parentNode) { + F-- + } + M.setStart(baidu.dom.getParent(Y), F) + } + M.collapse(true) + } + if (Q) { + baidu.dom.element.remove(Z, C) + } + if (J && O.parentNode) { + baidu.dom.element.remove(O, C) + } + }; + baidu.editor.Range.prototype = { + deleteContents: function () { + var C = this.document.createDocumentFragment(); + if (this.collapsed) { + return + } + A(this, 0, C) + }, cloneContents: function () { + var C = this.document.createDocumentFragment(); + if (!this.collapsed) { + A(this, 2, C) + } + return C + }, extractContents: function () { + var C = this.document.createDocumentFragment(); + if (!this.collapsed) { + A(this, 1, C) + } + return C + }, clone: function () { + var C = new baidu.editor.Range(this.document); + C.startContainer = this.startContainer; + C.startOffset = this.startOffset; + C.endContainer = this.endContainer; + C.endOffset = this.endOffset; + C.collapsed = this.collapsed; + return C + }, collapse: function (C) { + if (C) { + this.endContainer = this.startContainer; + this.endOffset = this.startOffset + } else { + this.startContainer = this.endContainer; + this.startOffset = this.endOffset + } + this.collapsed = true + }, select: baidu.ie ? function () { + var G = this.collapsed; + var C; + var H; + var K = this.createBookmark(); + var E = K.startNode; + var I; + if (!G) { + I = K.endNode + } + var D = this.document.body.createTextRange(); + D.moveToElementText(E); + D.moveStart("character", 1); + if (I) { + var J = this.document.body.createTextRange(); + J.moveToElementText(I); + D.setEndPoint("EndToEnd", J); + D.moveEnd("character", -1) + } else { + H = this.document.createElement("span"); + H.innerHTML = ""; + E.parentNode.insertBefore(H, E); + var F = this.document.createTextNode("\ufeff"); + E.parentNode.insertBefore(F, E) + } + this.setStartBefore(E); + baidu.dom.element.remove(E, this.document); + if (G) { + D.moveStart("character", -1); + D.select(); + this.document.selection.clear(); + baidu.dom.element.remove(H, this.document) + } else { + this.setEndBefore(I); + baidu.dom.element.remove(I, this.document); + D.select() + } + } : function () { + var D = this.startContainer; + if (this.collapsed && baidu.isElement(D) && !baidu.dom.element.getChildCount(D)) { + baidu.dom.element.append(D, this.document.createTextNode("")) + } + var E = this.document.createRange(); + E.setStart(D, this.startOffset); + try { + E.setEnd(this.endContainer, this.endOffset) + } catch (F) { + if (F.toString().indexOf("NS_ERROR_ILLEGAL_VALUE") >= 0) { + this.collapse(true); + E.setEnd(this.endContainer, this.endOffset) + } else { + throw (F) + } + } + var C = baidu.dom.getWindow(this.document).getSelection(); + C.removeAllRanges(); + C.addRange(E) + }, createBookmark: function (F) { + var E, C; + var D; + var G; + E = this.document.createElement("span"); + baidu.dom.element.setAttr(E, "_BaiduEditor_bm", 1); + baidu.dom.element.setStyle(E, "display", "none"); + E.innerHTML = " "; + if (F) { + D = "_BaiduEditor_bm" + Math.floor(Math.random() * 2147483648).toString(36); + baidu.dom.element.setAttr(E, "id", D + "S") + } + if (!this.collapsed) { + C = baidu.dom.clone(E); + C.innerHTML = " "; + if (F) { + baidu.dom.element.setAttr(C, "id", D + "E") + } + G = this.clone(); + G.collapse(); + G.insertNode(C) + } + G = this.clone(); + G.collapse(true); + G.insertNode(E); + if (C) { + this.setStartAfter(E); + this.setEndBefore(C) + } else { + this.moveToPosition(E, POSITION_AFTER_END) + } + return {startNode: F ? D + "S" : E, endNode: F ? D + "E" : C, serializable: F} + }, moveToPosition: function (D, C) { + this.setStartAt(D, C); + this.collapse(true) + }, createBookmark2: function (I) { + var G = this.startContainer, H = this.endContainer; + var C = this.startOffset, E = this.endOffset; + var J, F; + if (!G || !H) { + return {start: 0, end: 0} + } + if (I) { + if (baidu.isElement(G)) { + J = baidu.dom.element.getChild(G, C); + if (J && baidu.isText(J) && C > 0 && baidu.isText(baidu.dom.getPrevious(J))) { + G = J; + C = 0 + } + } + while (baidu.isText(G) && (F = baidu.dom.getPrevious(G)) && baidu.isText(F)) { + G = F; + C += baidu.dom.text.getLength(F) + } + if (!this.isCollapsed) { + if (baidu.isElement(H)) { + J = baidu.dom.element.getChild(H, E); + if (J && baidu.isText(J) && E > 0 && baidu.isText(baidu.dom.getPrevious(J))) { + H = J; + E = 0 + } + } + while (baidu.isText(H) && (F = baidu.dom.getPrevious(H)) && baidu.isText(F)) { + H = F; + E += baidu.dom.text.getLength(F) + } + } + } + var D = baidu.dom.getAddress(G, this.document, I); + return { + start: D, + end: this.isCollapsed ? D : baidu.dom.getAddress(H, this.document, I), + startOffset: C, + endOffset: E, + normalized: I, + is2: true + } + }, moveToBookmark: function (H) { + if (H.is2) { + var I = baidu.dom.getByAddress(this.document, H.start, H.normalized), D = H.startOffset; + var J = H.end && baidu.dom.getByAddress(this.document, H.end, H.normalized), F = H.endOffset; + this.setStart(I, D); + if (J) { + this.setEnd(J, F) + } else { + this.collapse(true) + } + } else { + var G = H.serializable, E = G ? this.document.getElementById(H.startNode) : H.startNode, C = G ? this.document.getElementById(H.endNode) : H.endNode; + this.setStartBefore(E); + baidu.dom.element.remove(E, this.document); + if (C) { + this.setEndBefore(C); + baidu.dom.element.remove(C, this.document) + } else { + this.collapse(true) + } + } + }, setStart: function (D, C) { + this.startContainer = D; + this.startOffset = C; + if (!this.endContainer) { + this.endContainer = D; + this.endOffset = C + } + B(this) + }, setEnd: function (C, D) { + this.endContainer = C; + this.endOffset = D; + if (!this.startContainer) { + this.startContainer = C; + this.startOffset = D + } + B(this) + }, setStartBefore: function (C) { + this.setStart(baidu.dom.getParent(C), baidu.dom.getIndex(C)) + }, setStartAfter: function (C) { + this.setStart(baidu.dom.getParent(C), baidu.dom.getIndex(C) + 1) + }, setEndAfter: function (C) { + this.setEnd(baidu.dom.getParent(C), baidu.dom.getIndex(C) + 1) + }, setEndBefore: function (C) { + this.setEnd(baidu.dom.getParent(C), baidu.dom.getIndex(C)) + }, setStartAt: function (D, C) { + switch (C) { + case POSITION_AFTER_START: + this.setStart(D, 0); + break; + case POSITION_BEFORE_END: + if (baidu.isText(D)) { + this.setStart(D, baidu.dom.text.getLength(D)) + } else { + this.setStart(D, baidu.dom.element.getChildCount(D)) + } + break; + case POSITION_BEFORE_START: + this.setStartBefore(D); + break; + case POSITION_AFTER_END: + this.setStartAfter(D) + } + B(this) + }, setEndAt: function (D, C) { + switch (C) { + case POSITION_AFTER_START: + this.setEnd(D, 0); + break; + case POSITION_BEFORE_END: + if (baidu.isText(D)) { + this.setEnd(D, baidu.dom.text.getLength(D)) + } else { + this.setEnd(D, baidu.dom.element.getChildCount(D)) + } + break; + case POSITION_BEFORE_START: + this.setEndBefore(D); + break; + case POSITION_AFTER_END: + this.setEndAfter(D) + } + B(this) + }, getCommonAncestor: function (D, F) { + var G = this.startContainer, C = this.endContainer, E; + if (G === C) { + if (D && baidu.isElement(G) && this.startOffset == this.endOffset - 1) { + E = baidu.dom.element.getChild(G, this.startOffset) + } else { + E = G + } + } else { + E = baidu.dom.getCommonAncestor(G, C) + } + return F && !baidu.isElement(E) ? baidu.dom.getParent(E) : E + }, optimizeBookmark: function () { + var D = this.startContainer, C = this.endContainer; + if (baidu.isElement(D) && baidu.dom.element.is(D, "span") && baidu.dom.element.hasAttribute(D, "_BaiduEditor_bm")) { + this.setStartAt(D, POSITION_BEFORE_START) + } + if (C && baidu.isElement(C) && baidu.dom.element.is(C, "span") && baidu.dom.element.hasAttribute(C, "_BaiduEditor_bm")) { + this.setEndAt(C, POSITION_AFTER_END) + } + }, trim: function (F, I) { + var G = this.startContainer, C = this.startOffset, J = this.collapsed; + if ((!F || J) && G && baidu.isText(G)) { + if (!C) { + C = baidu.dom.getIndex(G); + G = baidu.dom.getParent(G) + } else { + if (C >= baidu.dom.text.getLength(G)) { + C = baidu.dom.getIndex(G) + 1; + G = baidu.dom.getParent(G) + } else { + var E = baidu.dom.text.split(G, C, this.document); + C = baidu.dom.getIndex(G) + 1; + G = baidu.dom.getParent(G); + if (!J && this.startContainer === this.endContainer) { + this.setEnd(E, this.endOffset - this.startOffset) + } + } + } + this.setStart(G, C); + if (J) { + this.collapse(true) + } + } + var H = this.endContainer; + var D = this.endOffset; + if (!(I || J) && H && baidu.isText(H)) { + if (!D) { + D = baidu.dom.getIndex(H); + H = baidu.dom.getParent(H) + } else { + if (D >= baidu.dom.text.getLength(H)) { + D = baidu.dom.getIndex(H) + 1; + H = baidu.dom.getParent(H) + } else { + baidu.dom.text.split(H, D, this.document); + D = baidu.dom.getIndex(H) + 1; + H = baidu.dom.getParent(H) + } + } + this.setEnd(H, D) + } + }, insertNode: function (F) { + this.optimizeBookmark(); + this.trim(false, true); + var E = this.startContainer; + var D = this.startOffset; + var C = baidu.dom.element.getChild(E, D); + if (C) { + C.parentNode.insertBefore(F, C) + } else { + E.appendChild(F) + } + if (baidu.dom.getParent(F) === this.endContainer) { + this.endOffset++ + } + this.setStartBefore(F) + }, getTouchedStartNode: function () { + var C = this.startContainer; + if (this.collapsed || !baidu.isElement(C)) { + return C + } + return baidu.dom.element.getChild(C, this.startOffset) || C + }, getTouchedEndNode: function () { + var C = this.endContainer; + if (this.collapsed || !baidu.isElement(C)) { + return C + } + return baidu.dom.element.getChild(this.endOffset - 1) || C + }, optimize: function () { + var C = this.startContainer; + var D = this.startOffset; + if (!baidu.isElement(C)) { + if (!D) { + this.setStartBefore(C) + } else { + if (D >= baidu.dom.text.getLength(C)) { + this.setStartAfter(C) + } + } + } + C = this.endContainer; + D = this.endOffset; + if (!baidu.isElement(C)) { + if (!D) { + this.setEndBefore(C) + } else { + if (D >= baidu.dom.text.getLength(C)) { + this.setEndAfter(C) + } + } + } + }, walk: function (L) { + var E = this.startContainer, H = this.startOffset, M = this.endContainer, I = this.endOffset, K = [{ + n: baidu.firefox && this.startContainer.nodeName.toUpperCase() == "TR" ? baidu.dom.getParent(this.getCommonAncestor(0, 1)) : this.getCommonAncestor(0, 1), + i: 0 + }], G, J = false; + + function D(P, O, N) { + try { + if (J == -1 && !baidu.dom.element.contains(P, E)) { + J = true + } + if (!J && (baidu.dom.getParent(P) == E && O == H)) { + J = true + } + if (baidu.isText(P) && P == E) { + if (baidu.dom.text.getLength(P) == H) { + J = -1 + } else { + if (!J) { + J = true + } + } + } + if (!N) { + return + } + if (baidu.isText(P) && P == M && I == 0) { + J = false + } + if (J == true || (J == -2 && P == M)) { + L(P) + } + if (baidu.dom.getParent(P) == M && O + 1 == I) { + J = -2 + } + if (baidu.isText(P) && P == M) { + J = false + } + } catch (Q) { + } + } + + while (G = K.pop()) { + var C = G.n, F = cri = G.i; + D(C, cri, false); + while (C.childNodes[cri] != undefined) { + K.push({n: C, i: cri}); + C = C.childNodes[cri]; + D(C, cri, false); + F = cri; + cri = 0 + } + D(C, F, true); + if (K.length) { + K[K.length - 1].i++ + } + } + }, dispose: function () { + for (var C in this) { + if (typeof this[C] != "function") { + delete this[C] + } + } + } + } +})(); +var SELECTION_NONE = 0; +var SELECTION_TEXT = 2; +var SELECTION_CONTROL = 3; +var styleObjectElements = { + img: 1, + hr: 1, + li: 1, + table: 1, + tr: 1, + td: 1, + embed: 1, + object: 1, + ol: 1, + ul: 1, + a: 1, + input: 1, + form: 1, + select: 1, + textarea: 1, + button: 1, + fieldset: 1, + th: 1, + thead: 1, + tfoot: 1 +}; +baidu.editor.Editor.prototype.getSelection = function () { + var B = this; + if (!B.selection) { + var A = B.document; + B.selection = { + getNative: baidu.ie ? function () { + return A.selection + } : function () { + return baidu.dom.getWindow(A).getSelection() + }, getNativeRange: function () { + if (baidu.ie) { + var C = this.getNative(), D = C.createRange(); + if (C.type.toUpperCase() != "CONTROL" && baidu.dom.getDocument(D.parentElement()) != B.document) { + range = B.ieBakRange; + if (range) { + return range + } + } + return D + } else { + throw new Error("[baidu.editor.selection.getNativeRange] only support ie now!") + } + }, getType: baidu.ie ? function () { + var C = SELECTION_NONE; + try { + var E = this.getNative(), F = E.type; + if (E.createRange().parentElement) { + C = SELECTION_TEXT + } + if (F.toUpperCase() != "CONTROL" && baidu.dom.getDocument(E.createRange().parentElement()) != B.document) { + if (!B.ieBakRange) { + return SELECTION_NONE + } + F = B.ieBakRangeType + } + if (F == "Text") { + C = SELECTION_TEXT + } + if (F == "Control") { + C = SELECTION_CONTROL + } + } catch (D) { + } + return C + } : function () { + var D = SELECTION_TEXT; + var F = this.getNative(); + if (!F) { + D = SELECTION_NONE + } else { + if (F.rangeCount == 1) { + var C = F.getRangeAt(0), E = C.startContainer; + if (E == C.endContainer && E.nodeType == 1 && (C.endOffset - C.startOffset) == 1 && styleObjectElements[E.childNodes[C.startOffset].nodeName.toLowerCase()]) { + D = SELECTION_CONTROL + } + } + } + return D + }, getRanges: baidu.ie ? (function () { + var C = function (I, E) { + I = I.duplicate(); + I.collapse(E); + var K = I.parentElement(); + var F = K.firstChild; + var G, H = 0; + while (F) { + if (F.nodeType == 1) { + G = I.duplicate(); + G.moveToElementText(F); + G.collapse(); + var L = G.compareEndPoints("StartToStart", I); + if (L > 0) { + break + } else { + if (L === 0) { + return {container: K, offset: H} + } + } + G = null + } + F = F.nextSibling; + H++ + } + if (!G) { + G = I.duplicate(); + G.moveToElementText(K); + G.collapse(false) + } + G.setEndPoint("StartToStart", I); + var D = G.text.length; + var J = K.childNodes; + while (D > 0 && H--) { + F = J[H]; + D -= F.nodeValue ? F.nodeValue.length : 0 + } + if (D === 0) { + return {container: K, offset: H} + } else { + if (D > 0) { + return {container: K, offset: 0} + } else { + return {container: J[H], offset: -D} + } + } + }; + return function () { + var F = this.getNative(), K = F && F.createRange(), L = this.getType(), J; + if (!F) { + return [] + } + if (L != SELECTION_CONTROL && F.createRange().parentElement().ownerDocument != B.document) { + K = B.ieBakRange; + if (!K) { + return [] + } + L = B.ieBakRangeType.toUpperCase() == "CONTROL" ? SELECTION_CONTROL : (B.ieBakRangeType.toUpperCase() == "TEXT" ? SELECTION_TEXT : SELECTION_NONE) + } + if (L === SELECTION_TEXT) { + J = this.createRange(); + var D = C(K, true); + J.setStart(D.container, D.offset); + D = C(K); + J.setEnd(D.container, D.offset); + return [J] + } else { + if (L == SELECTION_CONTROL) { + var E = []; + for (var H = 0; H < K.length; H++) { + var I = K.item(H), M = I.parentNode, G = 0; + J = this.createRange(); + for (; G < M.childNodes.length && M.childNodes[G] != I; G++) { + } + J.setStart(M, G); + J.setEnd(M, G + 1); + E.push(J) + } + return E + } + } + return [] + } + })() : function () { + var C = []; + var G = this.getNative(); + if (!G) { + return [] + } + for (var E = 0; E < G.rangeCount; E++) { + var F = G.getRangeAt(E); + var D = this.createRange(); + D.setStart(F.startContainer, F.startOffset); + D.setEnd(F.endContainer, F.endOffset); + C.push(D) + } + return C + }, createRange: function () { + return new baidu.editor.Range(A) + }, selectRanges: function (C) { + if (baidu.ie) { + if (C[0]) { + C[0].select() + } + } else { + var G = this.getNative(); + G.removeAllRanges(); + for (var E = 0; E < C.length; E++) { + var D = C[E]; + var F = A.createRange(); + F.setStart(D.startContainer, D.startOffset); + F.setEnd(D.endContainer, D.endOffset); + G.addRange(F) + } + } + }, setCursor: function (E, C) { + var D = this.createRange(A); + D.setStartAt(E, C); + D.collapse(true); + this.selectRanges([D]) + }, selectElement: function (C) { + var D = this; + if (baidu.ie) { + D.getNative().empty(); + try { + range = A.body.createControlRange(); + range.addElement(C); + range.select() + } catch (F) { + range = A.body.createTextRange(); + range.moveToElementText(C); + range.select() + } + } else { + range = A.createRange(); + range.selectNode(C); + var E = D.getNative(); + E.removeAllRanges(); + E.addRange(range) + } + }, pasteElements: function (F, C) { + var E = this; + range = E.getRanges()[0]; + range.deleteContents(); + for (var D = F.length - 1; D >= 0; D--) { + range.insertNode(F[D]) + } + if (C) { + range.setStartBefore(F[F.length - 1]); + range.setEndAfter(F[0]); + range.select() + } else { + E.setCursor(F[F.length - 1], 4) + } + }, pasteElement: function (E, D) { + var F = this, C = F.getRanges()[0]; + C.deleteContents(); + C.insertNode(E); + if (D) { + B.selection.selectElement(E) + } else { + F.setCursor(E, 4) + } + }, getText: function (C) { + if (baidu.ie) { + var D = B.document.selection.createRange(), E = C ? D.text : baidu.trim(D.text); + return E.replace("\r\n", "") + } else { + var D = B.window.getSelection().getRangeAt(0), E = C ? D.toString() : baidu.trim(D.toString()); + return E.replace("\n", "") + } + }, getTextNodes: function () { + var E = this; + var C = E.getRanges(); + var F = []; + for (var D = 0; D < C.length; D++) { + C[D].walk(function (G) { + if (G.nodeType == 3) { + F.push(G) + } + }) + } + return F + }, getSelectedElement: function () { + var D; + if (this.getType() == SELECTION_CONTROL) { + var E = this.getNative(); + if (baidu.ie) { + try { + D = E.createRange().item(0) + } catch (F) { + } + } else { + var C = E.getRangeAt(0); + D = C.startContainer.childNodes[C.startOffset] + } + } + return D + } + } + } + return B.selection +}; +baidu.editor.Editor.prototype.undo = function () { + this.execCommand("Undo") +}; +baidu.editor.Editor.prototype.redo = function () { + this.execCommand("Redo") +}; +(function () { + function B(E) { + var D = this; + D.editor = E; + E.addEventListener("onneedsavescene", function (F) { + D.save(false) + }) + } + + B.prototype.undoList = []; + B.prototype.undoIndex = 0; + B.prototype.getScene = function () { + var F = {bookmarks: []}; + var D = this.editor.getSelection().getRanges(); + for (var E = D.length - 1; E >= 0; E--) { + if (D[E]) { + F.bookmarks.push(D[E].createBookmark2(true)) + } else { + F.bookmarks.push(false) + } + } + F.content = this.editor.getContent(); + return F + }; + B.prototype.applyScene = function (G) { + if (!G) { + return + } + this.editor.setContent(G.content); + var D = []; + for (var F = G.bookmarks.length - 1; F >= 0; F--) { + if (G.bookmarks[F]) { + var E = this.editor.getSelection().createRange(); + E.moveToBookmark(G.bookmarks[F]); + D.push(E) + } + } + this.editor.getSelection().selectRanges(D); + this.undoIndex = G.index; + this.currentScene = G; + this.fireChange() + }; + B.prototype.save = function (E, G, H) { + var F = this.currentScene; + if (!G) { + G = this.getScene() + } + if (E && F && F.content == G.content) { + return + } + this.undoList = this.undoList.slice(0, this.undoIndex + 1); + this.undoList.push(G); + var D = this.undoList.length; + if (D > baidu.editor.EditorConfig.maxUndoCount) { + this.undoList = this.undoList.slice(D - baidu.editor.EditorConfig.maxUndoCount, D) + } + this.undoIndex = this.undoList.length - 1; + this.currentScene = G; + if (H !== false) { + this.fireChange() + } + return true + }; + B.prototype.getNextScene = function (E) { + var D = this.undoList, G = this.currentScene, H, F; + if (G) { + if (E) { + for (F = this.undoIndex - 1; F >= 0; F--) { + H = D[F]; + if (G.content != H.content) { + H.index = F; + return H + } + } + } else { + for (F = this.undoIndex + 1; F < D.length; F++) { + H = D[F]; + if (G.content != H.content) { + H.index = F; + return H + } + } + } + } + return null + }; + B.prototype.fireChange = function () { + this.hasUndo = !!this.getNextScene(true); + this.hasRedo = !!this.getNextScene(false); + this.resetType() + }; + B.prototype.resetType = function () { + this.typing = false; + delete this.lastKeystroke; + this.typesCount = 0; + this.modifiersCount = 0 + }; + baidu.editor.register(function (F) { + var E = new B(F); + F.undoMan = E; + function D(I) { + var I = F.window.event || I; + var H = I.keyCode || I.which; + modifierCodes = { + 8: 1, + 46: 1 + }, isModifier = H in modifierCodes, wasModifier = E.lastKeyCode in modifierCodes, lastWasSameModifier = isModifier && H == E.lastKeyCode, resetTypingCodes = { + 37: 1, + 38: 1, + 39: 1, + 40: 1 + }, isReset = H in resetTypingCodes, wasReset = E.lastKeyCode in resetTypingCodes, isContent = (!isModifier && !isReset), modifierSnapshot = (isModifier && !lastWasSameModifier), startedTyping = !E.typing || (isContent && (wasModifier || wasReset)); + if (startedTyping || modifierSnapshot) { + var G = E.getScene(); + + function J() { + var K = F.getContent(); + if (G.content != K) { + if (!E.save(true, G, false)) { + E.undoList = E.undoList.slice(0, E.undoIndex + 1) + } + E.hasUndo = true; + E.hasRedo = false; + E.typesCount = 1; + E.modifiersCount = 1 + } + } + + setTimeout(function () { + J() + }, 0) + } + E.lastKeyCode = H; + if (isModifier) { + E.typesCount = 0; + E.modifiersCount++; + if (E.modifiersCount > 25) { + E.save(true); + E.modifiersCount = 1 + } + } else { + if (!isReset) { + E.modifiersCount = 0; + E.typesCount++; + if (E.typesCount > 25) { + E.save(true); + E.typesCount = 1 + } + } + } + E.typing = true + } + + F.addEventListener("onkeydown", D, false); + F.addEventListener("onbeforeexeccommand", function (G) { + if (!G.target.topOpearation || G.target.command == "Undo" || G.target.command == "Redo") { + return + } + E.save(false) + }); + F.addEventListener("onafterexeccommand", function (G) { + if (!G.target.topOpearation || G.target.command == "Undo" || G.target.command == "Redo") { + return + } + E.save(false) + }); + E.save(true) + }); + function C(D) { + if (!D.undoMan.hasUndo) { + return + } + if (D.undoMan.undoIndex == D.undoMan.undoList.length - 1) { + D.undoMan.save(false) + } + D.undoMan.applyScene(D.undoMan.getNextScene(true)) + } + + function A(D) { + if (!D.undoMan.hasRedo) { + return + } + if (D.undoMan.undoIndex == D.undoMan.undoList.length - 1) { + return + } + D.undoMan.applyScene(D.undoMan.getNextScene(false)) + } + + baidu.editor.registCommand("Undo", function (D) { + C(D) + }); + baidu.editor.registCommand("Redo", function (D) { + A(D) + }); + baidu.editor.registQuery("Undo", function (D) { + return D.undoMan.hasUndo + }); + baidu.editor.registQuery("Redo", function (D) { + return D.undoMan.hasRedo + }) +})(); +baidu.editor.Editor.prototype.bold = function () { + this.execCommand("Bold"); + this.dispatchEvent(new baidu.BaseEvent("onbold")) +}; +(function () { + var J = {}; + var H = 1, B = 2, G = 3, E = 4, F = 5, I = 6; + + function K(N, M, L) { + var O = this; + O.context = M, O.range = L; + O.nodeInRange = function (P) { + O.context.contains.push(P); + var Q = P.lastChild; + while (Q) { + O.context.contains.push(Q); + Q = Q.previousSibling + } + }; + O.nodePartlyInRange = function (P, Q) { + O.context.partlyContains.push(P); + if (Q) { + var R = P.lastChild; + while (R) { + if (O.process(R) == E) { + break + } + R = R.previousSibling + } + } else { + var R = P.firstChild; + while (R) { + if (O.process(R) == G) { + break + } + R = R.nextSibling + } + } + }; + O.rangeInNode = function (T, U, Q) { + if (O.context.parents[0] != T) { + O.context.parents.unshift(T) + } + var P = Math.floor((Q + U) / 2); + while (Q >= U) { + var S = T.childNodes[P], R = O.compareRangeWithNode(S, L); + if (R == G) { + Q = P - 1 + } else { + if (R == E) { + U = P + 1 + } else { + if (R == I) { + O.rangeInNode(S, 0, S.childNodes.length - 1); + break + } else { + if (R == F) { + O.nodeInRange(S); + if (U <= P - 1) { + O.rangeInNode(T, U, P - 1) + } + if (P + 1 <= Q) { + O.rangeInNode(T, P + 1, Q) + } + break + } else { + if (R == H) { + O.nodePartlyInRange(S, true); + U = P + 1 + } else { + if (R == B) { + O.nodePartlyInRange(S, false); + Q = P - 1 + } + } + } + } + } + } + P = Math.floor((Q + U) / 2) + } + }; + O.process = function (P) { + var Q = O.compareRangeWithNode(P, O.range); + if (Q == F) { + O.nodeInRange(P) + } else { + if (Q == H || Q == B) { + O.nodePartlyInRange(P, Q == H) + } else { + if (Q == I) { + O.rangeInNode(P, 0, P.childNodes.length - 1) + } + } + } + return Q + }; + O.compareRangeWithNode = function (U, Q) { + if (baidu.ie) { + var T = N.document.body.createTextRange(); + if (U.nodeType == 1) { + T.moveToElementText(U) + } else { + var R = N.document.createElement("a"); + U.parentNode.insertBefore(R, U); + var a = N.document.body.createTextRange(); + a.moveToElementText(R); + R.parentNode.removeChild(R); + T.setEndPoint("StartToStart", a); + R = N.document.createElement("a"); + U.parentNode.insertBefore(R, U.nextSibling); + var a = N.document.body.createTextRange(); + a.moveToElementText(R); + R.parentNode.removeChild(R); + T.setEndPoint("EndToStart", a) + } + var S = Q.compareEndPoints("StartToStart", T), Y = Q.compareEndPoints("EndToStart", T), P = Q.compareEndPoints("StartToEnd", T), V = Q.compareEndPoints("EndToEnd", T) + } else { + var Z = N.document.createRange(); + if (baidu.isText(U) && U.parentNode.childNodes.length == 1) { + U = U.parentNode + } + Z.selectNode(U); + var X = N.document.createRange(); + X.selectNodeContents(U); + var W; + var S = (W = Q.compareBoundaryPoints(Range.START_TO_START, Z)) == Q.compareBoundaryPoints(Range.START_TO_START, X) ? W : 0, P = (W = Q.compareBoundaryPoints(Range.END_TO_START, Z)) == Q.compareBoundaryPoints(Range.END_TO_START, X) ? W : 0, Y = (W = Q.compareBoundaryPoints(Range.START_TO_END, Z)) == Q.compareBoundaryPoints(Range.START_TO_END, X) ? W : 0, V = (W = Q.compareBoundaryPoints(Range.END_TO_END, Z)) == Q.compareBoundaryPoints(Range.END_TO_END, X) ? W : 0 + } + if (S <= 0 && V >= 0) { + return F + } + if (S >= 0 && V <= 0) { + return I + } + if (S * Y == -1) { + return B + } + if (P * V == -1) { + return H + } + if (S <= 0 && Y <= 0) { + return G + } + if (P >= 0 && V >= 0) { + return E + } + } + } + + J.w3cParser = function (Q) { + function R(T) { + if (T.startContainer.nodeType == 3 && T.startContainer.nodeValue.length == T.startOffset) { + T.setStartAfter(T.startContainer) + } + if (T.endContainer.nodeType == 3 && T.endOffset == 0) { + T.setEndBefore(T.endContainer) + } + return T + } + + var S = new Array(), P = Q.window.getSelection(); + for (var N = 0; N < P.rangeCount; N++) { + var L = R(P.getRangeAt(N)); + context = {parents: [], collapsed: false, contains: [], partlyContains: []}; + if (L.collapsed) { + context.collapsed = true; + var O = L.startContainer; + do { + context.parents.push(O); + O = O.parentNode + } while (O.parentNode && O.nodeName != "HTML") + } else { + var M = L.commonAncestorContainer, O = baidu.isText(M) ? baidu.dom.getParent(M) : M; + do { + context.parents.push(O); + O = O.parentNode + } while (O.parentNode && O.nodeName != "HTML"); + (new K(Q, context, L)).process(M) + } + S.push(context) + } + return S + }; + J.ieParser = function (P) { + var M = "CONTROL", O = P.document.selection, N = O.type, L, Q = [{ + collapsed: [], + parents: [], + contains: [], + partlyContains: [] + }]; + if (N.toUpperCase() != M && O.createRange().parentElement().ownerDocument != P.document) { + L = P.ieBakRange; + if (!L) { + return Q + } + N = P.ieBakRangeType + } else { + L = O.createRange() + } + if (N.toUpperCase() == M) { + return C(P, L) + } else { + return A(P, L) + } + }; + function C(P, M) { + var Q = M.commonParentElement(), O = P.document.selection, N = { + collapsed: false, + parents: [], + contains: [], + partlyContains: [] + }; + do { + N.parents.push(Q); + Q = Q.parentNode + } while (Q.nodeName.toUpperCase() != "HTML"); + var L = []; + L.push(M.item(0)); + while (L.length > 0) { + var Q = L.pop(), R = Q.lastChild; + while (R) { + L.push(R); + R = R.previousSibling + } + N.contains.push(Q) + } + return [N] + } + + function A(M, L) { + var O = new Array(); + context = {collapsed: false, parents: [], contains: [], partlyContains: []}; + if (D(L)) { + context.collapsed = true + } + O.push(context); + var N = L.parentElement(); + do { + context.parents.push(N); + N = N.parentNode + } while (N.nodeName.toUpperCase() != "HTML"); + (new K(M, context, L)).process(L.parentElement()); + return O + } + + function D(M) { + try { + var L = M.duplicate(), O = M.duplicate(); + L.collapse(true); + O.collapse(false); + return L.inRange(O) + } catch (N) { + return false + } + } + + baidu.editor.Editor.prototype.getContexts = function () { + var N = this; + if (!N.contextParserInit) { + function L() { + var O; + if (baidu.ie) { + O = J.ieParser(N) + } else { + O = J.w3cParser(N) + } + if (O) { + N.contextsInfo = O + } + } + + N.addEventListener("onbeforeselectionchange", function (O) { + L() + }); + L(); + N.contextParserInit = true + } + if (!N.contextsObj) { + N.contextsObj = { + containNode: function (U, V) { + function O(g, a, c) { + var Y = [], f = -1; + for (var Z = a.length - 1; Z >= 0; Z--) { + Y = Y.concat(a[Z]) + } + a = Y; + if (!a) { + return f + } + for (var Z = a.length - 1; Z >= 0; Z--) { + var b = a[Z]; + try { + if (b.ownerDocument != N.document) { + continue + } + } catch (d) { + continue + } + if (baidu.isText(b)) { + if (baidu.trim(b.nodeValue)) { + b = baidu.dom.getParent(b) + } + } + if (!b) { + continue + } + if (c.toLowerCase().indexOf("," + b.nodeName.toLowerCase() + ",") != -1) { + continue + } + if (g.toLowerCase().indexOf("," + b.nodeName.toLowerCase() + ",") == -1) { + if (f == 1) { + return 2 + } + f = 0 + } else { + if (f == 0) { + return 2 + } + f = 1 + } + } + return f + } + + U = "," + U + ","; + V = "," + V + ","; + var Q = this; + var S = false, T = false; + for (var R = Q.contains.length - 1; R >= 0; R--) { + if (Q.contains[R].length) { + S = true + } + if (Q.partlyContains[R].length) { + T = true + } + } + if (S || T) { + var X = O(U, Q.contains, V), W = O(U, Q.partlyContains, V); + if ((W == 2) && (X == -1 || X == 0)) { + return 2 + } + if ((W != -1 || X != -1) && (X == 1 || X == -1) && (W == 1 || W == -1)) { + return 1 + } + if (W > 0 || X > 0) { + return 2 + } + } + var P = O(U, Q.parents, V); + if (P == 2 || P == 1) { + return 3 + } + return 0 + }, walkTextNode: function (Q) { + var T = this, O = []; + + function P(W) { + for (var V = W.length - 1; V >= 0; V--) { + for (var U = W[V].length - 1; U >= 0; U--) { + if (baidu.isText(W[V][U]) && baidu.trim(W[V][U].nodeValue)) { + O.push(W[V][U]) + } + } + } + } + + P(T.contains); + P(T.partlyContains); + for (var R = T.parents.length - 1; R >= 0; R--) { + try { + if (T.parents[R][0].ownerDocument != N.document) { + continue + } + } catch (S) { + continue + } + if (baidu.isText(T.parents[R][0]) && baidu.trim(T.parents[R][0].nodeValue)) { + O.push(T.parents[R][0]) + } + } + for (var R = O.length - 1; R >= 0; R--) { + Q(O[R]) + } + } + } + } + N.contextsObj.collapsed = []; + N.contextsObj.parents = []; + N.contextsObj.contains = []; + N.contextsObj.partlyContains = []; + for (var M = N.contextsInfo.length - 1; M >= 0; M--) { + N.contextsObj.collapsed.push(N.contextsInfo[M].collapsed); + N.contextsObj.parents.push(N.contextsInfo[M].parents); + N.contextsObj.contains.push(N.contextsInfo[M].contains); + N.contextsObj.partlyContains.push(N.contextsInfo[M].partlyContains) + } + return N.contextsObj + } +})(); +baidu.getStyle = function (C, A) { + if (C = baidu.G(C)) { + var B = baidu.isString(A); + A = B ? [A] : A; + var G = []; + var H = function (M, N) { + return N.charAt(1).toUpperCase() + }; + var J = function (M) { + var Q = M.split(","); + var P = "#", O; + for (var N = 0; O = Q[N]; N++) { + O = O.replace(/[^\d]/gi, ""); + O = parseInt(O, 10); + O = O.toString(16); + if (O.length == 1) { + O = "0" + O + } + P += O + } + return P.toUpperCase() + }; + for (var F = 0, D; F < A.length; F = F + 1) { + var E = A[F].replace(/(-[a-z])/gi, H); + if ("float" == E) { + E = baidu.isIE ? "styleFloat" : "cssFloat" + } + if ("opacity" == E && baidu.isIE) { + var L = C.style.filter; + D = L && L.indexOf("opacity=") >= 0 ? (parseFloat(L.match(/opacity=([^)]*)/)[1]) / 100) + "" : "1" + } + if (D = C.style[E]) { + G[F] = D + } else { + if (C.currentStyle) { + D = C.currentStyle[E] + } else { + var I = C.nodeType == 9 ? C : C.ownerDocument || C.document; + if (I.defaultView && I.defaultView.getComputedStyle) { + var K = I.defaultView.getComputedStyle(C, ""); + if (K) { + D = K[E] + } + } + } + } + if (/color/i.test(E) && D.indexOf("rgb(") != -1) { + D = J(D) + } + G[F] = D + } + if (B) { + G = G[0] + } + return G + } +}; +baidu.editor.registParser("bold", function (A) { + var B = -1; + A.getContexts().walkTextNode(function (C) { + var D = baidu.getStyle(baidu.dom.getParent(C), "font-weight"); + if (((parseInt(D) > 400 || D == "bold") && (C.parentNode.tagName.indexOf("H") !== 0)) && (B == -1 || B == 1)) { + B = 1 + } else { + B = 0 + } + }); + if (B == -1) { + B = 0 + } + return B +}); +baidu.editor.Editor.prototype.italic = function () { + this.execCommand("Italic"); + this.dispatchEvent(new baidu.BaseEvent("onitalic")) +}; +baidu.editor.registParser("italic", function (A) { + var B = -1; + A.getContexts().walkTextNode(function (C) { + var D = baidu.getStyle(baidu.dom.getParent(C), "font-style"); + if (D == "italic" && (B == -1 || B == 1)) { + B = 1 + } else { + B = 0 + } + }); + if (B == -1) { + B = 0 + } + return B +}); +baidu.editor.Editor.prototype.underline = function () { + this.execCommand("Underline"); + this.dispatchEvent(new baidu.BaseEvent("onunderline")) +}; +baidu.editor.registParser("underline", function (A) { + return A.getContexts().containNode("u") +}); +baidu.editor.Editor.prototype.fontname = function (A) { + this.execCommand("FontName", false, A); + this.dispatchEvent(new baidu.BaseEvent("onfontname")) +}; +(function () { + baidu.editor.Editor.prototype.queryFontname = function () { + var I = this; + var B = I.getSelection().getRanges(); + var H = []; + if (B.length == 1 && B[0].collapsed) { + var G = B[0]; + var F = G.startContainer; + while (F.nodeType == 3 && F.parentNode) { + F = F.parentNode + } + var E = baidu.getStyle(F, "font-family"); + return A(E) + } + for (var C = 0; C < B.length; C++) { + var G = B[C]; + G.walk(function (J) { + if (J.nodeType == 3) { + H.push(J) + } + }) + } + var E = null; + for (var C = 0; C < H.length; C++) { + var F = H[C]; + var D = A(baidu.getStyle(F.parentNode, "font-family")); + if (D && E && D != E) { + return null + } else { + if (E == null && D) { + E = D + } + } + } + return E + }; + function A(B) { + return B && B.replace(/\'/gi, "") + } +})(); +baidu.editor.Editor.prototype.fontsize = function (A) { + this.window.focus(); + this.execCommand("FontSize", false, A); + this.dispatchEvent(new baidu.BaseEvent("onfontsize")) +}; +(function () { + baidu.editor.Editor.prototype.queryFontsize = function () { + var I = this; + var D = I.getSelection().getRanges(); + var H = []; + if (D.length == 1 && D[0].collapsed) { + var G = D[0]; + var F = G.startContainer; + while (F.nodeType == 3 && F.parentNode) { + F = F.parentNode + } + var C = baidu.getStyle(F, "font-size"); + return A(C) + } + for (var E = 0; E < D.length; E++) { + var G = D[E]; + G.walk(function (J) { + if (J.nodeType == 3) { + H.push(J) + } + }) + } + var C = null; + for (var E = 0; E < H.length; E++) { + var F = H[E]; + var B = A(baidu.getStyle(F.parentNode, "font-size")); + if (B && C && B != C) { + return null + } else { + if (C == null && B) { + C = B + } + } + } + return C + }; + function A(C) { + var D = {"10px": 1, "13px": 2, "16px": 3, "18px": 4, "24px": 5, "32px": 6, "48px": 7}; + var B = {"x-small": 1, small: 2, medium: 3, large: 4, "x-large": 5, "xx-large": 6, "-webkit-xxx-large": 7}; + if (!C) { + return null + } else { + C = C.toLowerCase(); + if (C.indexOf("px") >= 0) { + return D[C] + } else { + if (/^\d+/g.test(C)) { + return C + } else { + return B[C] + } + } + } + } +})(); +baidu.editor.Editor.prototype.foreColor = function (A) { + this.execCommand("ForeColor", false, A); + this.dispatchEvent(new baidu.BaseEvent("onforecolor")) +}; +(function () { + baidu.editor.Editor.prototype.queryForeColor = function () { + var H = this, C = H.getSelection(), E = false, F = false, B = C.getRanges(), J = A || function (L) { + return L + }; + + function K(M) { + var L; + while (M.parentNode && !(L = J(baidu.getStyle(M, "color")))) { + M = M.parentNode + } + return L + } + + if (B.length == 1 && B[0].collapsed) { + var D = B[0].startContainer; + if (baidu.isText(D)) { + D = baidu.dom.getParent(D) + } + E = K(D) + } else { + var I = C.getTextNodes(); + for (var G = 0; G < I.length; G++) { + var F = K(I[G]); + if (F && E && F != E) { + return false + } else { + if (!E && F) { + E = F + } + } + } + } + return E + }; + function A(C) { + var B = { + aqua: "00FFFF", + black: "000000", + blue: "0000FF", + fuchsia: "FF00FF", + gray: "808080", + green: "008000", + lime: "00FF00", + maroon: "800000", + navy: "000080", + olive: "808000", + purple: "800080", + red: "FF0000", + silver: "C0C0C0", + teal: "008080", + white: "FFFFFF", + yellow: "FFFF00", + transparent: "" + }; + if (B[C] == undefined) { + return C + } + return B[C] ? "#" + B[C] : "" + } +})(); +baidu.editor.Editor.prototype.justifyLeft = function () { + this.execCommand("JustifyLeft", false); + this.dispatchEvent(new baidu.BaseEvent("onjustifyleft")) +}; +baidu.editor.Editor.prototype.justifyCenter = function () { + this.execCommand("JustifyCenter", false); + this.dispatchEvent(new baidu.BaseEvent("onjustifycenter")) +}; +baidu.editor.Editor.prototype.justifyRight = function () { + this.execCommand("JustifyRight", false); + this.dispatchEvent(new baidu.BaseEvent("onjustifyright")) +}; +baidu.editor.Editor.prototype.insertImage = function (A) { + this.execCommand("insertImage", A); + this.dispatchEvent(new baidu.BaseEvent("oninsertimage")) +}; +(function () { + function B(E, C) { + var D = E.document.createElement("IMG"); + D.src = C.src; + if (C.width) { + D.width = C.width + } + if (C.height) { + D.height = C.height + } + E.getSelection().pasteElement(D, true) + } + + function A(E) { + var C = E.getSelection().getRanges()[0], D; + D = C.startContainer; + if (D.nodeName != "IMG") { + D = baidu.dom.element.getChild(C.startContainer, C.startOffset) + } + if (D && D.nodeName == "IMG") { + return {src: D.style.backgroundImage || D.src} + } + } + + baidu.editor.Editor.prototype.getImage = function () { + return A(this) + }; + baidu.editor.registCommand("insertImage", B) +})(); +baidu.editor.registParser("image", function (A) { + return A.getContexts().containNode("img", "p") +}); +baidu.editor.toolbar = {}; +baidu.editor.toolbar.createElement = function (A) { + var B = document.createElement(A); + B.style.MozUserSelect = "none"; + B.unselectable = "on"; + return B +}; +function ItemBase(A) { + baidu.BaseClass.call(this); + this.name = ""; + this.editor = A +} +baidu.inherits(ItemBase, baidu.BaseClass, "biadu.editor.toolbar.ItemBase"); +baidu.editor.toolbar.ItemBase = ItemBase; +baidu.editor.toolbar.Bold = function (B, A) { + baidu.editor.toolbar.ItemBase.call(this, B); + this.name = "Bold"; + this.button = A +}; +baidu.inherits(baidu.editor.toolbar.Bold, baidu.editor.toolbar.ItemBase, "baidu.editor.toolbar.Bold"); +baidu.editor.toolbar.Bold.prototype.initialize = function () { + var B = this; + var A = B.editor; + var C = false; + this.button.addEventListener("onconfirm", function () { + A.bold() + }); + A.addEventListener("onselectionchange", function (E) { + var D = A.queryContextState("bold"); + switch (D) { + case 0: + C = false; + break; + case 1: + C = true; + break; + case 2: + C = false; + break; + case 3: + C = true; + break + } + }); + A.addEventListener("onbeforeselectionchange", function (D) { + A.tools.bold.enable() + }); + A.addEventListener("onafterselectionchange", function (D) { + if (C) { + B.button.highlight() + } else { + B.button.removeHighlight() + } + }) +}; +baidu.editor.toolbar.Italic = function (B, A) { + baidu.editor.toolbar.ItemBase.call(this, B); + this.name = "Italic"; + this.button = A +}; +baidu.inherits(baidu.editor.toolbar.Italic, baidu.editor.toolbar.ItemBase, "baidu.editor.toolbar.Italic"); +baidu.editor.toolbar.Italic.prototype.initialize = function () { + var B = this; + var A = B.editor; + var C = false; + this.button.addEventListener("onconfirm", function () { + A.italic() + }); + A.addEventListener("onselectionchange", function (E) { + var D = A.queryContextState("italic"); + switch (D) { + case 0: + C = false; + break; + case 1: + C = true; + break; + case 2: + C = false; + break; + case 3: + C = true; + break + } + }); + A.addEventListener("onbeforeselectionchange", function (D) { + A.tools.italic.enable() + }); + A.addEventListener("onafterselectionchange", function (D) { + if (C) { + B.button.highlight() + } else { + B.button.removeHighlight() + } + }) +}; +baidu.editor.toolbar.Underline = function (B, A) { + baidu.editor.toolbar.ItemBase.call(this, B); + this.name = "Underline"; + this.button = A +}; +baidu.inherits(baidu.editor.toolbar.Underline, baidu.editor.toolbar.ItemBase, "baidu.editor.toolbar.Underline"); +baidu.editor.toolbar.Underline.prototype.initialize = function () { + var A = this; + this.button.addEventListener("onconfirm", function () { + A.editor.underline() + }); + A.editor.addEventListener("onselectionchange", function (B) { + var C = A.editor.queryContextState("underline"); + if (C == 1 || C == 3) { + isHightlight = true + } else { + isHightlight = false + } + }); + A.editor.addEventListener("onafterselectionchange", function (B) { + if (isHightlight) { + A.button.highlight() + } else { + A.button.removeHighlight() + } + }) +}; +baidu.editor.toolbar.Undo = function (B, A) { + baidu.editor.toolbar.ItemBase.call(this, B); + this.name = "Undo"; + this.button = A +}; +baidu.inherits(baidu.editor.toolbar.Undo, baidu.editor.toolbar.ItemBase, "baidu.editor.toolbar.Undo"); +baidu.editor.toolbar.Undo.prototype.initialize = function () { + var B = this; + var A = B.editor; + this.button.addEventListener("onconfirm", function () { + A.undo() + }); + A.addEventListener("onselectionchange", function (C) { + if (A.queryCommandState("Undo")) { + A.tools.undo.enable() + } else { + A.tools.undo.disable() + } + }) +}; +baidu.editor.toolbar.Redo = function (B, A) { + baidu.editor.toolbar.ItemBase.call(this, B); + this.name = "Redo"; + this.button = A +}; +baidu.inherits(baidu.editor.toolbar.Redo, baidu.editor.toolbar.ItemBase, "baidu.editor.toolbar.Redo"); +baidu.editor.toolbar.Redo.prototype.initialize = function () { + var B = this; + var A = B.editor; + this.button.addEventListener("onconfirm", function () { + A.redo() + }); + A.addEventListener("onselectionchange", function (C) { + if (A.queryCommandState("Redo")) { + A.tools.redo.enable() + } else { + A.tools.redo.disable() + } + }) +}; +baidu.editor.toolbar.JustifyLeft = function (B, A) { + baidu.editor.toolbar.ItemBase.call(this, B); + this.name = "JustifyLeft"; + this.button = A +}; +baidu.inherits(baidu.editor.toolbar.JustifyLeft, baidu.editor.toolbar.ItemBase, "baidu.editor.toolbar.JustifyLeft"); +baidu.editor.toolbar.JustifyLeft.prototype.initialize = function () { + var A = this; + this.button.addEventListener("onconfirm", function () { + A.editor.justifyLeft() + }); + A.editor.addEventListener("onselectionchange", function (B) { + A.editor.document.queryCommandState("JustifyLeft") ? A.button.highlight() : A.button.removeHighlight() + }) +}; +baidu.editor.toolbar.JustifyCenter = function (B, A) { + baidu.editor.toolbar.ItemBase.call(this, B); + this.name = "JustifyCenter"; + this.button = A +}; +baidu.inherits(baidu.editor.toolbar.JustifyCenter, baidu.editor.toolbar.ItemBase, "baidu.editor.toolbar.JustifyCenter"); +baidu.editor.toolbar.JustifyCenter.prototype.initialize = function () { + var A = this; + this.button.addEventListener("onconfirm", function () { + A.editor.justifyCenter() + }); + A.editor.addEventListener("onselectionchange", function (B) { + A.editor.queryCommandState("JustifyCenter") ? A.button.highlight() : A.button.removeHighlight() + }) +}; +baidu.editor.toolbar.JustifyRight = function (B, A) { + baidu.editor.toolbar.ItemBase.call(this, B); + this.name = "JustifyRight"; + this.button = A +}; +baidu.inherits(baidu.editor.toolbar.JustifyRight, baidu.editor.toolbar.ItemBase, "baidu.editor.toolbar.JustifyRight"); +baidu.editor.toolbar.JustifyRight.prototype.initialize = function () { + var A = this; + this.button.addEventListener("onconfirm", function () { + A.editor.justifyRight() + }); + A.editor.addEventListener("onselectionchange", function (B) { + A.editor.queryCommandState("JustifyRight") ? A.button.highlight() : A.button.removeHighlight() + }) +}; +baidu.editor.toolbar.FontName = function (A, B) { + baidu.editor.toolbar.ItemBase.call(this, A); + this.name = "FontName"; + this.combo = B +}; +baidu.inherits(baidu.editor.toolbar.FontName, baidu.editor.toolbar.ItemBase, "baidu.editor.toolbar.FontName"); +baidu.editor.toolbar.FontName.prototype.initialize = function () { + var A = this; + this.combo.addEventListener("onchange", function () { + var B = A.combo.getValue(); + A.editor.fontname(B) + }); + A.editor.addEventListener("onselectionchange", function (C) { + var B = A.editor.queryFontname(); + A.combo.setValue(B) + }) +}; +baidu.editor.toolbar.FontSize = function (A, B) { + baidu.editor.toolbar.ItemBase.call(this, A); + this.name = "FontSize"; + this.combo = B +}; +baidu.inherits(baidu.editor.toolbar.FontSize, baidu.editor.toolbar.ItemBase, "baidu.editor.toolbar.FontSize"); +baidu.editor.toolbar.FontSize.prototype.initialize = function () { + var A = this; + this.combo.addEventListener("onchange", function () { + var B = A.combo.getValue(); + A.editor.fontsize(B) + }); + A.editor.addEventListener("onselectionchange", function (B) { + var C = A.editor.queryFontsize(); + A.combo.setValue(C) + }) +}; +baidu.editor.toolbar.ForeColor = function (A, B) { + baidu.editor.toolbar.ItemBase.call(this, A); + this.name = "ForeColor"; + this.combo = B +}; +baidu.inherits(baidu.editor.toolbar.ForeColor, baidu.editor.toolbar.ItemBase, "baidu.editor.toolbar.ForeColor"); +baidu.editor.toolbar.ForeColor.prototype.initialize = function () { + var A = this; + A.combo.addEventListener("onchange", function () { + A.editor.foreColor(A.combo.getValue()) + }); + A.editor.addEventListener("onselectionchange", function (C) { + var B = A.editor.queryForeColor("color"); + A.combo.setValue(B ? B.toUpperCase() : "") + }) +}; +baidu.editor.toolbar.Image = function (B, A) { + baidu.editor.toolbar.ItemBase.call(this, B); + this.name = "Image"; + this.button = A +}; +baidu.inherits(baidu.editor.toolbar.Image, baidu.editor.toolbar.ItemBase, "baidu.editor.toolbar.Image"); +baidu.editor.toolbar.Image.prototype.initialize = function () { + var B = this; + var A = B.editor; + var C = false; + this.button.addEventListener("onconfirm", function () { + var G = this; + var E = null; + if (A.queryContextState("image")) { + E = A.getImage() + } + if (!E) { + var H = A.maxPicNum || 10; + var I = A.document.getElementsByTagName("img"); + if (I && I.length >= H) { + var D; + if (H == 10) { + D = Fe.Dialog.alert("对不起,图片总数限制为" + H + "张:( !", {title: "提示", locked: true}) + } else { + D = Fe.Dialog.alert("对不起,图片总数限制为" + H + "张:( !", {title: "提示", locked: true}) + } + D.onopen = function () { + document.body.focus() + }; + D.onclose = function () { + A.focus() + }; + return + } + } + var F; + if (E) { + F = E.src + } + G.dialog = Fe.Dialog.open("../common/uploadRichTextImage.action" + (E != null ? "#imgUrlValue=" + encodeURIComponent(F) : ""), { + title: "添加或修改图片", + width: "380px", + height: "125px", + buttonbar: true, + buttonAccept: true, + buttonCancel: true, + locked: true, + contentType: "HTMLUrl" + }); + G.dialog.afterUpload = function (J) { + A.insertImage(J); + G.dialog.close(); + B.uploadNum++ + }; + G.dialog.onaccept = function (K) { + var J = G.dialog.window, J = G.dialog.window = (!J) ? G.dialog.getIframe().contentWindow : J, L = J.document; + J.startUpload(G); + K.returnValue = false + }; + G.dialog.onclose = function () { + A.focus() + } + }); + A.addEventListener("onselectionchange", function (E) { + var D = A.queryContextState("image"); + switch (D) { + case 0: + C = false; + break; + case 1: + C = true; + break; + case 2: + C = false; + break; + case 3: + C = true; + break + } + }); + A.addEventListener("onbeforeselectionchange", function (D) { + A.tools.image.enable() + }); + A.addEventListener("onafterselectionchange", function (D) { + if (C) { + B.button.highlight() + } else { + B.button.removeHighlight() + } + }) +}; +(function () { + baidu.editor.Editor.prototype.getFilter = function () { + var C = this; + if (!C._filter) { + var B = C._filter = new (function () { + var E = {}, F; + this.add = function (H, G) { + G = G || "key_" + (new Date()).getTime(); + E[G] = H + }; + this.remove = function (G) { + delete E[G] + }; + var D = this.builder = new A(C); + this.filter = function (H) { + D._process(H); + for (var G in E) { + E[G](H) + } + }; + updateTagCount = function (G) { + F = C.document.getElementsByTagName("*").length + }; + C.addEventListener("onafterexeccommand", updateTagCount); + C.addEventListener("onwysiwygready", updateTagCount); + C.addEventListener("onselectionchange", function (K) { + var G = C.document.getElementsByTagName("*").length, J, I, H; + if (baidu.ie) { + J = C.document.selection.createRange() + } else { + J = C.window.getSelection().getRangeAt(0) + } + if (G == F) { + return + } else { + if (G <= F * 0.8 || G >= F * 1.2) { + F = G; + I = C.document.body + } else { + F = G; + if (!baidu.ie) { + I = baidu.dom.getCommonAncestor(J.startContainer, J.endContainer) + } else { + H = C.document.selection; + if (H.type.toUpperCase() != "CONTROL") { + I = J.parentElement(); + if (baidu.dom.getDocument(I) != C.document) { + I = C.document.body + } + } else { + I = C.document.body + } + } + } + } + B.filter(I) + }) + })() + } + return C._filter + }; + var A = function (E) { + var D = {}; + var B = {}; + var C = []; + var G = function () { + this.attribute = {}; + this.allow = {}; + this.except = {}; + this.text = false; + this.html = false; + this.delegates = [] + }; + var F = false; + this.element = function (J) { + F = true; + C = []; + var I = J.split(","); + for (var H = 0; H < I.length; H++) { + I[H] = I[H].replace(/(^\s+|\s+$)/ig, "").toLowerCase(); + C.push(I[H]); + if (!D[I[H]]) { + D[I[H]] = new G() + } + } + return this + }; + this.allow = function (K) { + var J = K.split(","); + for (var I = 0; I < J.length; I++) { + J[I] = J[I].replace(/(^\s+|\s+$)/ig, "").toLowerCase(); + for (var H = 0; H < C.length; H++) { + D[C[H]].allow[J[I]] = true + } + } + return this + }; + this.except = function (K) { + var J = K.split(","); + for (var I = 0; I < J.length; I++) { + J[I] = J[I].replace(/(^\s+|\s+$)/ig, "").toLowerCase(); + for (var H = 0; H < C.length; H++) { + D[C[H]].except[J[I]] = true + } + } + return this + }; + this.attribute = function (K) { + var H = K.split(","); + for (var J = 0; J < H.length; J++) { + H[J] = H[J].replace(/(^\s+|\s+$)/ig, "").toLowerCase(); + for (var I = 0; I < C.length; I++) { + D[C[I]].attribute[H[J]] = true + } + } + return this + }; + this.text = function () { + for (var H = 0; H < C.length; H++) { + D[C[H]].text = true + } + return this + }; + this.html = function () { + for (var H = 0; H < C.length; H++) { + D[C[H]].html = true + } + return this + }; + this.delegate = function (I) { + for (var H = 0; H < C.length; H++) { + D[C[H]].delegates.push(I) + } + return this + }; + this.eliminate = function (J) { + F = true; + C = []; + var I = J.split(","); + for (var H = 0; H < I.length; H++) { + I[H] = I[H].replace(/(^\s+|\s+$)/ig, "").toLowerCase(); + if (!B[I[H]]) { + B[I[H]] = true + } + } + return this + }; + this._process = function (M) { + if (!F) { + return + } + var L = M.tagName ? D[M.tagName.toLowerCase()] : null; + while (!L && M.parentNode && M != E.document.body) { + M = M.parentNode; + L = M.tagName ? D[M.tagName.toLowerCase()] : null + } + L = M.tagName ? D[M.tagName.toLowerCase()] : null; + if (!L) { + return + } + var P = L.delegates.length; + for (var N = 0; N < P; N++) { + L.delegates[N](M) + } + var K = M.attributes; + for (var N = K.length - 1; N >= 0; N--) { + var J = K[N]; + if (!L.attribute[J.name.toLowerCase()]) { + M.removeAttribute(J.name) + } + } + if (M.className && !L.attribute["class"]) { + M.className = "" + } + var I = M.lastChild; + while (I) { + var Q = I.previousSibling; + switch (I.nodeType) { + case 1: + var H = I.tagName.toLowerCase(); + if (((L.html && D[H]) || L.allow[H]) && !L.except[H] && !B[H]) { + arguments.callee(I) + } else { + if (L.text && !B[H]) { + var O = I.innerHTML; + for (key in B) { + O = O.replace(new RegExp("<" + key + "[\\s\\S]*?>[\\s\\S]*?", "ig"), "") + } + O = O.replace(/<[\s\S]*?>/ig, "").replace(/ /g, " ").replace(/"/g, '"').replace(/</g, "<").replace(/>/g, ">").replace(/&/g, "&"); + M.insertBefore(E.document.createTextNode(O), I); + M.removeChild(I) + } else { + M.removeChild(I) + } + } + break; + case 3: + if (!L.text) { + M.removeChild(I) + } + break + } + I = Q + } + } + } +})(); +baidu.editor.register(function (A) { + A.getFilter().builder.element("body").attribute("contentEditable,style").html().text().element("span").attribute("style").html().text().element("pre").attribute("style").html().text().element("center").attribute("style").html().text().element("ul").attribute("style").html().text().element("ol").attribute("style").html().text().element("li").attribute("style").html().text().element("a").attribute("style, href, target").html().text().element("br").element("div").attribute("style, align").html().text().element("h1, h2, h3, h4, h5, h6").attribute("style, align").html().text().element("table").html("tbody, thead, tfoot, tr").attribute("style, cellpadding, cellspacing, border, align").element("tbody").html("thead, tfoot, tr").attribute("style").element("thead, tfoot").html("tr").attribute("style").element("tr").html("th", "td").attribute("style").element("th, td").attribute("style, colspan, rowspan, align").html().text().element("b,strong").attribute("style").html().text().element("i,em").attribute("style").html().text().element("u").attribute("style").html().text().element("font").attribute("face, size, color, style").html().text().element("p").attribute("style,align").html().text().element("img").attribute("src, style, width, height").eliminate("script, style, object, embed, applet, select, input, textarea") +}); +function ce(A) { + var B = document.createElement(A); + B.style.MozUserSelect = "none"; + B.unselectable = "on"; + return B +} +function stopEvent(A) { + if (A) { + A.cancelBubble = true; + if (A.stopPropagation) { + A.stopPropagation() + } + } +} +function preventDefault(A) { + A.returnValue = false; + if (A.preventDefault) { + A.preventDefault() + } +} +function Toolbar(B) { + var A = this; + A.id = B; + A.dom = baidu.G(B); + A.create() +} +baidu.extend(Toolbar.prototype, { + create: function () { + this.dom.style.MozUserSelect = "none"; + this.dom.unselectable = "on" + }, addButton: function (A) { + if (A && A.getDomObj) { + this.dom.appendChild(A.getDomObj()) + } + }, addBar: function () { + var B = ce("div"); + var A = ce("span"); + baidu.addClass(A, "btn_bar"); + B.appendChild(A); + A.style.MozUserSelect = "none"; + A.unselectable = "on"; + B.style.MozUserSelect = "none"; + B.unselectable = "on"; + this.dom.appendChild(B) + } +}); +Button.config = { + hover: "btn_hover", + active: "btn_active", + disabled: "btn_disabled", + highlight: "btn_highlight", + defaultClassName: "", + textButton: "btn_text btn_default", + idPrefix: "toolbar-button-" +}; +var buttonCounter = 0; +function Button(A) { + var B = this; + buttonCounter++; + baidu.BaseClass.call(B); + A = A || {}; + B.id = A.id || Button.config.idPrefix + buttonCounter; + B.className = A.className || Button.config.defaultClassName; + B._onclick = A.onclick; + B.label = A.label; + B.title = A.title; + B.button = null; + B.inner = null; + B.isDisabled = false; + B.isHighlight = false; + B._createWraper() +} +baidu.inherits(Button, baidu.BaseClass, "Button"); +baidu.extend(Button.prototype, { + _createWraper: function () { + var D = this; + var C = D.button = ce("div"); + C.id = D.id; + if (D.label) { + baidu.addClass(C, Button.config.textButton) + } + var B = ce("div"); + var A = D.inner = ce("p"); + C.appendChild(B); + B.appendChild(A); + B.title = D.title; + C.style.MozUserSelect = "none"; + B.style.MozUserSelect = "none"; + A.style.MozUserSelect = "none"; + C.unselectable = "on"; + B.unselectable = "on"; + A.unselectable = "on"; + D.createInner(); + D.registerHandlers(); + return D + }, createInner: function () { + var B = this; + var A = ce("span"); + baidu.addClass(A, B.className); + A.style.MozUserSelect = "none"; + A.unselectable = "on"; + B.addContent(A); + if (B.label) { + A.innerHTML = B.label + } + }, addContent: function (A) { + this.inner.appendChild(A) + }, registerHandlers: function () { + var B = this; + var A = B.button; + baidu.on(A, "mouseover", function (C) { + if (B.isDisabled) { + return + } + baidu.addClass(A, Button.config.hover) + }); + baidu.on(A, "mouseout", function (C) { + if (B.isDisabled) { + return + } + baidu.removeClass(A, Button.config.hover); + baidu.removeClass(A, Button.config.active) + }); + baidu.on(A, "mousedown", function (C) { + if (B.isDisabled) { + return + } + baidu.addClass(A, Button.config.active) + }); + baidu.on(A, "mouseup", function (C) { + if (B.isDisabled) { + return + } + baidu.removeClass(A, Button.config.active) + }); + baidu.on(A, "click", function (C) { + if (B.isDisabled) { + return + } + if (B._onclick && typeof B._onclick == "function") { + B._onclick() + } else { + B.confirm() + } + }) + }, getDomObj: function () { + return this.button + }, highlight: function () { + this.isHighlight = true; + baidu.addClass(this.button, Button.config.highlight) + }, disable: function () { + this.isDisabled = true; + baidu.removeClass(this.button, Button.config.highlight); + baidu.removeClass(this.button, Button.config.hover); + baidu.addClass(this.button, Button.config.disabled) + }, removeHighlight: function () { + this.isHighlight = false; + baidu.removeClass(this.button, Button.config.highlight) + }, enable: function () { + this.isDisabled = false; + baidu.removeClass(this.button, Button.config.disabled) + }, confirm: function () { + this.dispatchEvent(new baidu.BaseEvent("onconfirm")) + } +}); +Select.config = { + select: "editor-toolbar-select", + caption: "editor-toolbar-select-caption", + dropdown: "editor-toolbar-select-dropdown", + inline: "editor-toolbar-select-inline" +}; +var selectListCounter = 0; +baidu.extend(Select.config, Button.config); +function Select(A) { + var B = this; + A = A || {}; + B.caption = A.caption || "SELECT"; + B.options = A; + if (A.list) { + B.list = A.list + } else { + if (A.items) { + B.list = new List({ + id: (B.id ? "editor-select-list" + B.id : "editor-select-list" + selectListCounter++), + items: A.items, + listClassName: A.listClassName, + itemClassName: A.itemClassName + }) + } else { + return false + } + } + B.className = A.className; + B._onchange = A.onchange; + Button.call(B, A) +} +baidu.inherits(Select, Button, "Select"); +baidu.extend(Select.prototype, { + createInner: function () { + var B = this; + baidu.addClass(B.button, Select.config.select); + if (B.className) { + baidu.addClass(B.button, B.className) + } + var A = B.oCaption = ce("div"); + baidu.addClass(A, Select.config.inline); + baidu.addClass(A, Select.config.caption); + A.innerHTML = B.caption; + var C = ce("div"); + baidu.addClass(C, Select.config.inline); + baidu.addClass(C, Select.config.dropdown); + C.innerHTML = " "; + A.unselectable = "on"; + C.unselectable = "on"; + A.MozUserSelect = "none"; + C.MozUserSelect = "none"; + B.addContent(A); + B.addContent(C); + B._registerHanlders() + }, _registerHanlders: function () { + var A = this; + baidu.on(A.button, "mousedown", function (B) { + if (A.isDisabled) { + return + } + var C = baidu.getPosition(A.button); + A.list.setPosition({left: C.left, top: (C.top + A.button.offsetHeight)}); + A.list.toggle(); + stopEvent(B) + }); + baidu.on(A.button, "mouseup", function (B) { + if (A.isDisabled) { + return + } + stopEvent(B) + }); + A.list._onclick = function () { + A.list.hide(); + var B = A.list.getValue(); + A._setCaption(B) + }; + A.list.addEventListener("onchange", function () { + A.dispatchEvent(new baidu.BaseEvent("onchange")) + }) + }, _setCaption: function (B) { + var A = this; + if (!B) { + return false + } + if (A.options._setCaption) { + A.options._setCaption(A.oCaption, B); + return false + } + if (baidu.ie) { + this.oCaption.innerText = B ? B : this.caption + } else { + this.oCaption.innerHTML = B ? B : this.caption + } + }, setValue: function (B, C) { + var A = this; + A.list.setValue(B, C); + A._setCaption(B) + }, getValue: function () { + return this.list.getValue() + } +}); +List.config = { + wraper: "editor-toolbar-list", + outer: "editor-toolbar-list-item", + hover: "editor-toolbar-list-item-hover", + selected: "editor-toolbar-list-item-selected", + idPrefix: "editor-toolbar-list-" +}; +List.lists = []; +List.hideAll = function () { + for (var B = 0; B < List.lists.length; B++) { + var A = List.lists[B]; + if (A.isShow) { + A.hide() + } + } +}; +var listCounter = 0; +function List(A) { + var B = this; + baidu.BaseClass.call(B); + listCounter++; + A = A || {}; + B.items = A.items || []; + B.listClassName = A.listClassName; + B.itemClassName = A.itemClassName; + B.id = A.id || List.config.idPrefix + listCounter; + B._onclick = A.onclick; + B.list = null; + B._items = []; + B.isShow = false; + B.selectedIndex; + B._createDom(); + List.lists.push(this) +} +baidu.inherits(List, baidu.BaseClass, "List"); +baidu.extend(List.prototype, { + _createDom: function () { + var D = this; + var E = D.list = ce("div"); + baidu.addClass(E, List.config.wraper); + baidu.setStyle(E, "position", "absolute"); + baidu.setStyle(E, "background", "#FFF"); + E.id = D.id; + if (D.listClassName && typeof D.listClassName == "string") { + baidu.addClass(E, D.listClassName) + } + for (var C = 0, A = D.items.length; C < A; C++) { + var B = ce("div"); + baidu.addClass(B, List.config.outer); + if (D.itemClassName && typeof D.itemClassName == "string") { + baidu.addClass(B, D.itemClassName) + } + B.innerHTML = D.items[C].content; + B.value = D.items[C].value; + D._items.push({value: D.items[C].value, dom: B}); + B.style.MozUserSelect = "none"; + B.unselectable = "on"; + E.appendChild(B); + D._registerItemHandlers(C) + } + D._registerHandlers(); + D.hide(); + setTimeout(function () { + document.body.appendChild(E) + }, 1) + }, _registerItemHandlers: function (A) { + var C = this; + var B = C._items[A]; + baidu.on(B.dom, "mouseover", function (D) { + baidu.addClass(B.dom, List.config.hover) + }); + baidu.on(B.dom, "mouseout", function (D) { + baidu.removeClass(B.dom, List.config.hover) + }); + baidu.on(B.dom, "click", function (D) { + C._setItemSelected(A, true); + if (C._onclick && typeof C._onclick == "function") { + C._onclick() + } else { + C.confirm() + } + stopEvent(D) + }) + }, _registerHandlers: function () { + var A = this; + baidu.on(document, "mousedown", function (B) { + A.hide() + }); + baidu.on(document, "mouseup", function (B) { + A.hide() + }); + baidu.on(A.list, "mousedown", function (B) { + stopEvent(B) + }); + baidu.on(A.list, "mouseup", function (B) { + stopEvent(B) + }) + }, show: function () { + List.hideAll(); + this.list.style.display = ""; + this.isShow = true + }, hide: function () { + this.list.style.display = "none"; + this.isShow = false + }, toggle: function () { + if (this.isShow) { + this.hide() + } else { + this.show() + } + }, setPosition: function (A) { + this.list.style.left = typeof A.left == "number" ? A.left + "px" : A.left; + this.list.style.top = typeof A.top == "number" ? A.top + "px" : A.top + }, _setItemSelected: function (B, D) { + var C = this; + var A = B != C.selectedIndex; + if (C.selectedIndex != undefined) { + baidu.removeClass(C._items[C.selectedIndex].dom, List.config.selected) + } + if (B != undefined && B >= 0 && B < C._items.length) { + baidu.addClass(C._items[B].dom, List.config.selected); + C.selectedIndex = B + } else { + C.selectedIndex = undefined + } + if (A && D) { + C.dispatchEvent(new baidu.BaseEvent("onchange")) + } + }, setValue: function (F, G) { + var E = this; + var B = E._items; + var C; + for (var D = 0, A = B.length; D < A; D++) { + if (F == B[D].value) { + C = D; + break + } + } + E._setItemSelected(C, G) + }, getValue: function () { + var A = this; + if (A.selectedIndex != undefined) { + return A._items[A.selectedIndex].value + } else { + return null + } + }, confirm: function () { + this.dispatchEvent(new baidu.BaseEvent("onconfirm")) + } +}); +Menu.config = {menu: "toolbar-menu", idPrefix: "menu-"}; +var menuCounter = 0; +Menu.menus = []; +function Menu(A) { + var B = this; + baidu.BaseClass.call(B); + menuCounter++; + A = A || {}; + B.id = A.id || Menu.config.idPrefix + menuCounter; + B.menu = null; + B._menuitems = []; + B.isShow = false; + B._createDom(); + Menu.menus.push(this) +} +baidu.inherits(Menu, baidu.BaseClass, "Menu"); +baidu.extend(Menu.prototype, { + _createDom: function () { + var A = this; + var B = A.menu = ce("div"); + baidu.addClass(B, Menu.config.menu); + B.id = A.id; + A.hide(); + document.body.appendChild(B); + A._registerHandlers() + }, _registerHandlers: function () { + var A = this; + baidu.on(document, "mousedown", function (B) { + A.hide() + }); + baidu.on(document, "mouseup", function (B) { + A.hide() + }); + baidu.on(A.menu, "mousedown", function (B) { + stopEvent(B) + }); + baidu.on(A.menu, "mouseup", function (B) { + stopEvent(B) + }) + }, show: function () { + this.menu.style.display = ""; + this.isShow = true + }, hide: function () { + this.menu.style.display = "none"; + this.isShow = false + }, toggle: function () { + if (this.menu.style.display == "") { + this.hide() + } else { + this.show() + } + }, setPosition: function (A) { + this.menu.style.left = typeof A.left == "number" ? A.left + "px" : A.left; + this.menu.style.top = typeof A.top == "number" ? A.top + "px" : A.top + }, addMenuitem: function (B) { + if (!B || !B.getDom || !B.getDom()) { + return + } + var A = this; + A.menu.appendChild(B.getDom()); + B.addEventListener("onclick", function () { + A.hide() + }) + } +}); +MenuItem.config = { + menuitem: "menuitem", + hover: "menuitem-hover", + disabled: "menuitem-disabled", + idPrefix: "toolbar-menuitem-" +}; +var menuitemCounter = 0; +function MenuItem(A) { + var B = this; + menuitemCounter++; + A = A || {}; + B.label = A.label || "Menu Item "; + B.className = A.className; + B._onclick = A.onclick; + B.id = A.id || MenuItem.config.idPrefix + menuitemCounter; + B.button = null; + B.isDisabled = false; + baidu.BaseClass.call(B); + B._createDom() +} +baidu.inherits(MenuItem, baidu.BaseClass, "MenuItem"); +baidu.extend(MenuItem.prototype, { + _createDom: function () { + var B = this; + var A = B.button = ce("div"); + baidu.addClass(A, MenuItem.config.menuitem); + A.id = B.id; + if (B.className) { + baidu.addClass(A, B.className) + } + var C = document.createTextNode(B.label); + A.appendChild(C); + B._registerHandlers() + }, _registerHandlers: function () { + var B = this; + var A = B.button; + baidu.on(A, "mouseover", function (D) { + if (B.isDisabled) { + return + } + if (B.id == "insertTable") { + var D = D || window.event; + var G = D.target || D.srcElement; + baidu.addClass(A, "menuitem-arrow"); + setTablePanel.showTablePanel(); + var F = parseInt(G.parentNode.style.left); + var E = parseInt(G.parentNode.style.top); + var C = baidu.G("bdMenuInsertTable"); + C.style.left = F + G.offsetWidth + "px"; + C.style.top = E + "px" + } else { + baidu.addClass(A, MenuItem.config.hover) + } + }); + baidu.on(A, "mouseout", function () { + if (B.id == "insertTable") { + baidu.removeClass(A, "menuitem-arrow"); + setTablePanel.hiddenTablePanel() + } + baidu.removeClass(A, MenuItem.config.hover) + }); + baidu.on(A, "click", function () { + if (B.isDisabled) { + return + } + B.clicked(); + if (B._onclick && typeof B._onclick == "function") { + B._onclick() + } else { + B.confirm() + } + }) + }, getDom: function () { + return this.button + }, disable: function () { + var B = this; + var A = B.button; + this.isDisabled = true; + if (B.id == "insertTable") { + baidu.removeClass(A, "menuitem-arrow") + } + baidu.addClass(this.button, MenuItem.config.disabled) + }, enable: function () { + this.isDisabled = false; + baidu.removeClass(this.button, MenuItem.config.disabled) + }, confirm: function () { + this.dispatchEvent(new baidu.BaseEvent("onconfirm")) + }, clicked: function () { + this.dispatchEvent(new baidu.BaseEvent("onclick")) + } +}); +baidu.isElement = function (A) { + return A && A.nodeType == 1 +}; +baidu.isFirefox = /Firefox(\s|\/)(\d+(\.\d+)?)/.test(navigator.userAgent) ? RegExp.$2 : 0; +baidu.isIE = /MSIE (\d+(\.\d+)?)/.test(navigator.userAgent) ? RegExp.$1 : 0; +baidu.isWebkit = (navigator.userAgent.indexOf("KHTML") > -1 && /AppleWebKit\/([^\s]*)/.test(navigator.userAgent)) ? RegExp.$1 : 0; +baidu.isOpera = (window.opera && /Opera(\s|\/)(\d+(\.\d+)?)/.test(navigator.userAgent)) ? RegExp.$2 : 0; +baidu.isSafari = (navigator.userAgent.indexOf("Safari") > -1 && /Version\/(\d+(\.\d+)?)/.test(navigator.userAgent)) ? RegExp.$1 : 0; +baidu.isGecko = (navigator.userAgent.indexOf("Gecko") > -1 && navigator.userAgent.indexOf("KHTML") == -1 && /rv\:(\d+(\.\d+)?)/.test(navigator.userAgent)) ? RegExp.$1 : 0; +baidu.isStrict = (document.compatMode == "CSS1Compat"); +baidu.css = function (C, G) { + if (!C || !G) { + return null + } + C = typeof C == "string" ? document.getElementById(C) : C; + var B = !window.opera && navigator.userAgent.indexOf("MSIE") != -1; + if (G == "float") { + G = B ? "styleFloat" : "cssFloat" + } + G = G.replace(/(-[a-z])/gi, function (H, I) { + return I.charAt(1).toUpperCase() + }); + if ("opacity" == G && B) { + var A = C.style.filter; + return A && A.indexOf("opacity=") >= 0 ? (parseFloat(A.match(/opacity=([^)]*)/)[1]) / 100) + "" : "1" + } + var F = null; + if (F = C.style[G]) { + return F + } + if (C.currentStyle) { + return C.currentStyle[G] + } else { + var E = C.nodeType == 9 ? C : C.ownerDocument || C.document; + if (E.defaultView && E.defaultView.getComputedStyle) { + var D = E.defaultView.getComputedStyle(C, ""); + if (D) { + return D[G] + } + } + } + return null +}; +baidu.dom.getStyle = function (B, A) { + return baidu.css(B, A) +}; +baidu.dom.getPosition = function (D) { + D = baidu.G(D); + if (!baidu.isElement(D)) { + throw new Error("[baidu.dom.getPosition] param must be Element") + } + var G = baidu.dom.getDocument(D); + var F = baidu.isGecko > 0 && G.getBoxObjectFor && baidu.dom.getStyle(D, "position") == "absolute" && (D.style.top === "" || D.style.left === ""); + var H = {left: 0, top: 0}; + var B = (baidu.isIE && !baidu.isStrict) ? G.body : G.documentElement; + if (D == B) { + return H + } + var C = null; + var E; + if (D.getBoundingClientRect) { + E = D.getBoundingClientRect(); + H.left = E.left + Math.max(G.documentElement.scrollLeft, G.body.scrollLeft); + H.top = E.top + Math.max(G.documentElement.scrollTop, G.body.scrollTop); + H.left -= G.documentElement.clientLeft; + H.top -= G.documentElement.clientTop; + if (baidu.isIE && !baidu.isStrict) { + H.left -= 2; + H.top -= 2 + } + } else { + if (G.getBoxObjectFor && !F) { + E = G.getBoxObjectFor(D); + var A = G.getBoxObjectFor(B); + H.left = E.screenX - A.screenX; + H.top = E.screenY - A.screenY + } else { + C = D; + do { + H.left += C.offsetLeft; + H.top += C.offsetTop; + if (baidu.isWebkit > 0 && baidu.dom.getStyle(C, "position") == "fixed") { + H.left += G.body.scrollLeft; + H.top += G.body.scrollTop; + break + } + C = C.offsetParent + } while (C && C != D); + if (baidu.isOpera > 0 || (baidu.isWebkit > 0 && baidu.dom.getStyle(D, "position") == "absolute")) { + H.top -= G.body.offsetTop + } + C = D.offsetParent; + while (C && C != G.body) { + H.left -= C.scrollLeft; + if (!baidu.isOpera || C.tagName != "TR") { + H.top -= C.scrollTop + } + C = C.offsetParent + } + } + } + return H +}; +MenuButton.config = { + label: "toolbar-menu-button-label", + dropdown: "toolbar-menu-button-dropdown", + menubutton: "toolbar-menu-button" +}; +baidu.extend(MenuButton.config, Button.config); +function MenuButton(A) { + var B = this; + A = A || {}; + B.label = A.label || "MenuButton"; + B.items = []; + B.menu = new Menu(); + Button.call(B, A) +} +baidu.inherits(MenuButton, Button, "MenuButton"); +baidu.extend(MenuButton.prototype, { + createInner: function () { + var B = this; + baidu.addClass(B.button, MenuButton.config.textButton); + var A = ce("span"); + baidu.addClass(A, B.className); + A.innerHTML = B.label; + A.unselectable = "on"; + A.MozUserSelect = "none"; + B.addContent(A); + B._registerHandlers() + }, _registerHandlers: function () { + var A = this; + baidu.on(A.button, "mousedown", function (B) { + if (A.isDisabled) { + return + } + var C = baidu.dom.getPosition(A.button); + A.menu.setPosition({left: C.left, top: (C.top + A.button.offsetHeight)}); + A.menu.toggle(); + window.focus(); + stopEvent(B) + }); + baidu.on(A.button, "mouseup", function (B) { + if (A.isDisabled) { + return + } + stopEvent(B) + }) + }, addMenuitem: function (A) { + this.menu.addMenuitem(A) + } +}); +var EditorTools = function (F) { + this.undo; + this.redo; + this.bold; + this.italic; + this.image; + var E = new Toolbar(F); + this.undo = new Button({className: "btn_undo", title: "撤销"}); + E.addButton(this.undo); + this.redo = new Button({className: "btn_redo", title: "重做"}); + E.addButton(this.redo); + E.addBar(); + this.bold = new Button({className: "btn_bold", title: "加粗"}); + E.addButton(this.bold); + this.italic = new Button({className: "btn_italic", title: "斜体"}); + E.addButton(this.italic); + this.underline = new Button({className: "btn_underline", title: "下划线"}); + E.addButton(this.underline); + var L = [["黑色", "black", "000000"], ["红色", "red", "FF0000"], ["蓝色", "blue", "0000FF"], ["绿色", "green", "008000"], ["紫色", "purple", "800080"], ["黄色", "yellow", "FFFF00"], ["灰色", "gray", "808080"], ["浅绿色", "aqua", "00FFFF"], ["紫红色", "fuchsia", "FF00FF"], ["褐紫色", "maroon", "800000"], ["藏青色", "navy", "000080"], ["黄褐色", "olive", "808000"], ["银白色", "silver", "C0C0C0"]]; + var B = { + "000000": "黑色", + FF0000: "红色", + "0000FF": "蓝色", + "008000": "绿色", + "800080": "紫色", + FFFF00: "黄色", + "808080": "灰色", + "00FFFF": "浅绿色", + FF00FF: "紫红色", + "800000": "褐紫色", + "000080": "藏青色", + "808000": "黄褐色", + C0C0C0: "银白色" + }; + var A = []; + for (var J in B) { + var K = {}; + K.value = J; + K.content = '' + B[J] + ""; + A.push(K) + } + this.forecolor = new Select({ + caption: "字体颜色", + title: "字体颜色", + className: "editor-toolbar-select-forecolor", + items: A, + listClassName: "editor-toolbar-forecolor-list", + itemClassName: "editor-toolbar-forecolor-item", + _setCaption: function (M, O) { + if (!O) { + return false + } + var O = O.replace("#", ""); + O = O == "000" ? "000000" : O; + var N = B[O]; + N = N || "字体颜色"; + baidu.ie ? M.innerText = N : M.innerHTML = N + } + }); + E.addButton(this.forecolor); + E.addBar(); + this.justifyleft = new Button({className: "btn_justifyleft", title: "居左"}); + E.addButton(this.justifyleft); + this.justifycenter = new Button({className: "btn_justifycenter", title: "居中"}); + E.addButton(this.justifycenter); + this.justifyright = new Button({className: "btn_justifyright", title: "居右"}); + E.addButton(this.justifyright); + var H = ["sans-serif", "宋体", "黑体", "幼圆", "楷体_GB2312", "仿宋_GB2312", "Arial", "Comic Sans MS", "Courier New", "Tahoma", "Times New Roman", "Verdana"]; + var I = []; + for (var C = 0; C < H.length; C++) { + var K = {}; + K.value = H[C]; + K.content = '' + H[C] + ""; + I.push(K) + } + this.fontname = new Select({ + caption: "选择字体", + title: "字体", + className: "editor-toolbar-select-fontfamily", + listClassName: "editor-toolbar-fontname-list", + itemClassName: "editor-toolbar-fontname-item", + items: I + }); + E.addButton(this.fontname); + var D = {"1": "10", "2": "13", "3": "16", "4": "18", "5": "24", "6": "32", "7": "48"}; + var G = []; + for (var J in D) { + var K = {}; + K.value = J; + K.content = '' + D[J] + ""; + G.push(K) + } + this.fontsize = new Select({ + caption: "选择字号", + title: "字号", + className: "editor-toolbar-select-fontsize", + items: G, + listClassName: "editor-toolbar-fontsize-list", + itemClassName: "editor-toolbar-fontsize-item", + _setCaption: function (M, N) { + if (!N) { + return false + } + var O = D[N]; + O = O || "选择字号"; + baidu.ie ? M.innerText = O : M.innerHTML = O + } + }); + E.addButton(this.fontsize); + E.addBar(); + this.image = new Button({className: "btn_image", title: "插入/编辑图片"}); + E.addButton(this.image); + this.buttonDisable() +}; +EditorTools.prototype.buttonEnable = function () { + this.bold.enable(); + this.italic.enable(); + this.image.enable(); + this.underline.enable(); + this.justifyleft.enable(); + this.justifycenter.enable(); + this.justifyright.enable(); + this.fontname.enable(); + this.fontsize.enable(); + this.forecolor.enable() +}; +EditorTools.prototype.buttonDisable = function () { + this.undo.disable(); + this.redo.disable(); + this.bold.disable(); + this.italic.disable(); + this.image.disable(); + this.underline.disable(); + this.justifyleft.disable(); + this.justifycenter.disable(); + this.justifyright.disable(); + this.fontname.disable(); + this.fontsize.disable(); + this.forecolor.disable() +}; +function editorInit(A) { + var B = A.tools; + A.addToolbarItem(new baidu.editor.toolbar.Undo(A, B.undo)); + A.addToolbarItem(new baidu.editor.toolbar.Redo(A, B.redo)); + A.addToolbarItem(new baidu.editor.toolbar.Bold(A, B.bold)); + A.addToolbarItem(new baidu.editor.toolbar.Italic(A, B.italic)); + A.addToolbarItem(new baidu.editor.toolbar.Underline(A, B.underline)); + A.addToolbarItem(new baidu.editor.toolbar.JustifyLeft(A, B.justifyleft)); + A.addToolbarItem(new baidu.editor.toolbar.JustifyCenter(A, B.justifycenter)); + A.addToolbarItem(new baidu.editor.toolbar.JustifyRight(A, B.justifyright)); + A.addToolbarItem(new baidu.editor.toolbar.Image(A, B.image)); + A.addToolbarItem(new baidu.editor.toolbar.FontName(A, B.fontname)); + A.addToolbarItem(new baidu.editor.toolbar.FontSize(A, B.fontsize)); + A.addToolbarItem(new baidu.editor.toolbar.ForeColor(A, B.forecolor)) +} +(function () { + baidu.getPosition = function (C) { + return {left: A(C), top: B(C)} + }; + function A(D) { + var C = 0; + while (D != null) { + C += D.offsetLeft; + D = D.offsetParent + } + return C + } + + function B(D) { + var C = 0; + while (D != null) { + C += D.offsetTop; + D = D.offsetParent + } + return C + } +})(); +(function () { + baidu.getPointer = function (C) { + var B = document.documentElement, A = document.body || {scrollLeft: 0, scrollTop: 0}; + return { + x: C.pageX || (C.clientX + (B.scrollLeft || A.scrollLeft) - (B.clientLeft || 0)), + y: C.pageY || (C.clientY + (B.scrollTop || A.scrollTop) - (B.clientTop || 0)) + } + } +})(); \ No newline at end of file diff --git a/WebContent/stat/js/ui/editor/js/editorPlugin.js b/src/main/webapp/stat/js/ui/editor/js/editorPlugin.js similarity index 61% rename from WebContent/stat/js/ui/editor/js/editorPlugin.js rename to src/main/webapp/stat/js/ui/editor/js/editorPlugin.js index 644afd034..d50cb2d32 100644 --- a/WebContent/stat/js/ui/editor/js/editorPlugin.js +++ b/src/main/webapp/stat/js/ui/editor/js/editorPlugin.js @@ -5,27 +5,27 @@ var esEditor = window.esEditor || {}; * @return {String} 去除html标签等后的字符串 */ esEditor.getEditorText = function (html) { - html = html.replace(/]*>(.*?)<\/embed>/ig,""); - html = html.replace(/]*>(.*?)<\/object>/ig,""); - html = html.replace(/]*>(.*?)<\/applet>/ig,""); - html = html.replace(/]*>(.*?)<\/script>/ig,""); - html = html.replace(/]*>(.*?)<\/style>/ig,""); - html = html.replace(//ig,""); - html = html.replace(//ig,""); - html = html.replace(/\r/g,""); - html = html.replace(/\n/g,""); - html = html.replace(//ig,""); - html = html.replace(/<\/p>/ig,"
    "); - html = html.replace(/
    /ig,""); - html = html.replace(/
    /ig,""); + html = html.replace(/]*>(.*?)<\/embed>/ig, ""); + html = html.replace(/]*>(.*?)<\/object>/ig, ""); + html = html.replace(/]*>(.*?)<\/applet>/ig, ""); + html = html.replace(/]*>(.*?)<\/script>/ig, ""); + html = html.replace(/]*>(.*?)<\/style>/ig, ""); + html = html.replace(//ig, ""); + html = html.replace(//ig, ""); + html = html.replace(/\r/g, ""); + html = html.replace(/\n/g, ""); + html = html.replace(//ig, ""); + html = html.replace(/<\/p>/ig, "
    "); + html = html.replace(/
    /ig, ""); + html = html.replace(/
    /ig, ""); html = html.replace(/<[^<>]*>/gi, ""); - html = html.replace(/>/g,">"); - html = html.replace(/</g,"<"); - html = html.replace(/ /ig," "); - html = html.replace(/&/g,"&"); - html = html.replace(/'/g,"\'"); - html = html.replace(/"/g,"\""); - html = html.replace(/\r\n  /g,""); + html = html.replace(/>/g, ">"); + html = html.replace(/</g, "<"); + html = html.replace(/ /ig, " "); + html = html.replace(/&/g, "&"); + html = html.replace(/'/g, "\'"); + html = html.replace(/"/g, "\""); + html = html.replace(/\r\n  /g, ""); html = baidu.trim(html); return html; }; @@ -55,13 +55,13 @@ esEditor.disableEditor = function (editorSuffix) { baidu.show(shadeDivEl); baidu.setStyles(shadeDivEl, { - "position" : "absolute", - "height" : height, - "width" : width, - "left" : 0, - "top" : 0, - "background" : "#000", - "opacity" : 0.3 + "position": "absolute", + "height": height, + "width": width, + "left": 0, + "top": 0, + "background": "#000", + "opacity": 0.3 }); }; @@ -80,7 +80,7 @@ esEditor.enableEditor = function (editorSuffix) { */ esEditor.getImgNum = function (editor) { var imgNum = 0; - if(!editor) { + if (!editor) { return imgNum; } var imgEls = editor.document.getElementsByTagName("img"); diff --git a/WebContent/stat/js/ui/floater/.svn/all-wcprops b/src/main/webapp/stat/js/ui/floater/.svn/all-wcprops similarity index 100% rename from WebContent/stat/js/ui/floater/.svn/all-wcprops rename to src/main/webapp/stat/js/ui/floater/.svn/all-wcprops diff --git a/WebContent/stat/js/ui/floater/.svn/entries b/src/main/webapp/stat/js/ui/floater/.svn/entries similarity index 100% rename from WebContent/stat/js/ui/floater/.svn/entries rename to src/main/webapp/stat/js/ui/floater/.svn/entries diff --git a/WebContent/stat/js/ui/floater/css/.svn/all-wcprops b/src/main/webapp/stat/js/ui/floater/css/.svn/all-wcprops similarity index 100% rename from WebContent/stat/js/ui/floater/css/.svn/all-wcprops rename to src/main/webapp/stat/js/ui/floater/css/.svn/all-wcprops diff --git a/WebContent/stat/js/ui/floater/css/.svn/entries b/src/main/webapp/stat/js/ui/floater/css/.svn/entries similarity index 100% rename from WebContent/stat/js/ui/floater/css/.svn/entries rename to src/main/webapp/stat/js/ui/floater/css/.svn/entries diff --git a/WebContent/stat/js/ui/floater/css/.svn/text-base/floater.css.svn-base b/src/main/webapp/stat/js/ui/floater/css/.svn/text-base/floater.css.svn-base similarity index 100% rename from WebContent/stat/js/ui/floater/css/.svn/text-base/floater.css.svn-base rename to src/main/webapp/stat/js/ui/floater/css/.svn/text-base/floater.css.svn-base diff --git a/src/main/webapp/stat/js/ui/floater/css/floater.css b/src/main/webapp/stat/js/ui/floater/css/floater.css new file mode 100644 index 000000000..74ce671c7 --- /dev/null +++ b/src/main/webapp/stat/js/ui/floater/css/floater.css @@ -0,0 +1,93 @@ +.floaterd { + padding-top: 3px; +} + +.floaterd-top { + background: #3B5C55 +} + +.floaterd-bottom { + display: none +} + +.floater { + position: absolute !important; + border-radius: 6px; + -webkit-box-shadow: 0 5px 15px rgba(0, 0, 0, .5); + box-shadow: 0 5px 15px rgba(0, 0, 0, .5); + background-color: #fff; + background-clip: padding-box; + border: 1px solid rgba(0, 0, 0, .2); + outline: none; + border: none; +} + +.ec-form.floater { + padding-top: 52px; +} + +.floater-title { + cursor: move; + border-radius: 6px 6px 0 0; + position: absolute; + left: 0; + top: 0; + height: 52px; + padding: 4px 10px 0 18px; + font-size: 18px; + color: #333; + min-height: 16.42857143px; + padding: 15px; + border-bottom: 1px solid #e5e5e5; + font-weight: bold; + position: absolute +} + +.floater-close { + position: absolute; + right: 18px; + top: 14px; + font-size: 1px; + font-size: 22px; + font-weight: bold; + line-height: 1; + color: #000; + text-shadow: 0 1px 0 #fff; + opacity: .2; + cursor: pointer; +} + +.floater-close:after { + content: '×'; +} + +.floater-close:hover { + opacity: .4; +} + +.floater-content { + -webkit-box-shadow: 0 5px 15px rgba(0, 0, 0, .5); + box-shadow: 0 5px 15px rgba(0, 0, 0, .5); + background-color: #fff; + background-clip: padding-box; + border-radius: 0 0 6px 6px; + outline: none; +} + +.floater-inner { + overflow-y: auto; + overflow-x: hidden +} + +.floater-corner { + background: #fff +} + +.div-floater-control { + padding: 15px 20px 2px; + margin-top: 20px; + text-align: right; + border-top: 1px solid #e5e5e5; + margin-left: -19px; + margin-right: -19px; +} \ No newline at end of file diff --git a/WebContent/stat/js/ui/floater/css/img/.svn/all-wcprops b/src/main/webapp/stat/js/ui/floater/css/img/.svn/all-wcprops similarity index 100% rename from WebContent/stat/js/ui/floater/css/img/.svn/all-wcprops rename to src/main/webapp/stat/js/ui/floater/css/img/.svn/all-wcprops diff --git a/WebContent/stat/js/ui/floater/css/img/.svn/entries b/src/main/webapp/stat/js/ui/floater/css/img/.svn/entries similarity index 100% rename from WebContent/stat/js/ui/floater/css/img/.svn/entries rename to src/main/webapp/stat/js/ui/floater/css/img/.svn/entries diff --git a/WebContent/stat/js/ui/floater/css/img/.svn/prop-base/btn.gif.svn-base b/src/main/webapp/stat/js/ui/floater/css/img/.svn/prop-base/btn.gif.svn-base similarity index 100% rename from WebContent/stat/js/ui/floater/css/img/.svn/prop-base/btn.gif.svn-base rename to src/main/webapp/stat/js/ui/floater/css/img/.svn/prop-base/btn.gif.svn-base diff --git a/WebContent/stat/js/ui/floater/css/img/.svn/prop-base/close.gif.svn-base b/src/main/webapp/stat/js/ui/floater/css/img/.svn/prop-base/close.gif.svn-base similarity index 100% rename from WebContent/stat/js/ui/floater/css/img/.svn/prop-base/close.gif.svn-base rename to src/main/webapp/stat/js/ui/floater/css/img/.svn/prop-base/close.gif.svn-base diff --git a/WebContent/stat/js/ui/floater/css/img/.svn/prop-base/global_bg.png.svn-base b/src/main/webapp/stat/js/ui/floater/css/img/.svn/prop-base/global_bg.png.svn-base similarity index 100% rename from WebContent/stat/js/ui/floater/css/img/.svn/prop-base/global_bg.png.svn-base rename to src/main/webapp/stat/js/ui/floater/css/img/.svn/prop-base/global_bg.png.svn-base diff --git a/WebContent/stat/js/ui/floater/css/img/.svn/text-base/btn.gif.svn-base b/src/main/webapp/stat/js/ui/floater/css/img/.svn/text-base/btn.gif.svn-base similarity index 100% rename from WebContent/stat/js/ui/floater/css/img/.svn/text-base/btn.gif.svn-base rename to src/main/webapp/stat/js/ui/floater/css/img/.svn/text-base/btn.gif.svn-base diff --git a/WebContent/stat/js/ui/floater/css/img/.svn/text-base/close.gif.svn-base b/src/main/webapp/stat/js/ui/floater/css/img/.svn/text-base/close.gif.svn-base similarity index 100% rename from WebContent/stat/js/ui/floater/css/img/.svn/text-base/close.gif.svn-base rename to src/main/webapp/stat/js/ui/floater/css/img/.svn/text-base/close.gif.svn-base diff --git a/WebContent/stat/js/ui/floater/css/img/.svn/text-base/global_bg.png.svn-base b/src/main/webapp/stat/js/ui/floater/css/img/.svn/text-base/global_bg.png.svn-base similarity index 100% rename from WebContent/stat/js/ui/floater/css/img/.svn/text-base/global_bg.png.svn-base rename to src/main/webapp/stat/js/ui/floater/css/img/.svn/text-base/global_bg.png.svn-base diff --git a/WebContent/stat/js/ui/floater/css/img/btn.gif b/src/main/webapp/stat/js/ui/floater/css/img/btn.gif similarity index 100% rename from WebContent/stat/js/ui/floater/css/img/btn.gif rename to src/main/webapp/stat/js/ui/floater/css/img/btn.gif diff --git a/WebContent/stat/js/ui/floater/css/img/close.gif b/src/main/webapp/stat/js/ui/floater/css/img/close.gif similarity index 100% rename from WebContent/stat/js/ui/floater/css/img/close.gif rename to src/main/webapp/stat/js/ui/floater/css/img/close.gif diff --git a/WebContent/stat/js/ui/floater/css/img/global_bg.png b/src/main/webapp/stat/js/ui/floater/css/img/global_bg.png similarity index 100% rename from WebContent/stat/js/ui/floater/css/img/global_bg.png rename to src/main/webapp/stat/js/ui/floater/css/img/global_bg.png diff --git a/WebContent/stat/js/ui/floater/js/.svn/all-wcprops b/src/main/webapp/stat/js/ui/floater/js/.svn/all-wcprops similarity index 100% rename from WebContent/stat/js/ui/floater/js/.svn/all-wcprops rename to src/main/webapp/stat/js/ui/floater/js/.svn/all-wcprops diff --git a/WebContent/stat/js/ui/floater/js/.svn/entries b/src/main/webapp/stat/js/ui/floater/js/.svn/entries similarity index 100% rename from WebContent/stat/js/ui/floater/js/.svn/entries rename to src/main/webapp/stat/js/ui/floater/js/.svn/entries diff --git a/WebContent/stat/js/ui/floater/js/.svn/text-base/floater.js.svn-base b/src/main/webapp/stat/js/ui/floater/js/.svn/text-base/floater.js.svn-base similarity index 100% rename from WebContent/stat/js/ui/floater/js/.svn/text-base/floater.js.svn-base rename to src/main/webapp/stat/js/ui/floater/js/.svn/text-base/floater.js.svn-base diff --git a/WebContent/stat/js/ui/floater/js/floater.js b/src/main/webapp/stat/js/ui/floater/js/floater.js similarity index 93% rename from WebContent/stat/js/ui/floater/js/floater.js rename to src/main/webapp/stat/js/ui/floater/js/floater.js index bc468a469..499ca506c 100644 --- a/WebContent/stat/js/ui/floater/js/floater.js +++ b/src/main/webapp/stat/js/ui/floater/js/floater.js @@ -18,11 +18,11 @@ ecui.ui.Form.prototype.showModal = function (opacity) { } var ecFloater = { - /** - * 显示指定的浮动层 + /** + * 显示指定的浮动层 * @param {String} ecId 获取ec控件需要的id - */ - show : function(ecId) { + */ + show: function (ecId) { var floater = ecui.get(ecId); floater.showModal(); @@ -39,5 +39,5 @@ var ecFloater = { var y = parseInt((viewHeight - elHeight) / 2 + scrollHeight, 10); floater.setPosition(x, y); - } + } }; diff --git a/WebContent/stat/js/ui/foldable/.svn/all-wcprops b/src/main/webapp/stat/js/ui/foldable/.svn/all-wcprops similarity index 100% rename from WebContent/stat/js/ui/foldable/.svn/all-wcprops rename to src/main/webapp/stat/js/ui/foldable/.svn/all-wcprops diff --git a/WebContent/stat/js/ui/foldable/.svn/entries b/src/main/webapp/stat/js/ui/foldable/.svn/entries similarity index 100% rename from WebContent/stat/js/ui/foldable/.svn/entries rename to src/main/webapp/stat/js/ui/foldable/.svn/entries diff --git a/WebContent/stat/js/ui/foldable/css/.svn/all-wcprops b/src/main/webapp/stat/js/ui/foldable/css/.svn/all-wcprops similarity index 100% rename from WebContent/stat/js/ui/foldable/css/.svn/all-wcprops rename to src/main/webapp/stat/js/ui/foldable/css/.svn/all-wcprops diff --git a/WebContent/stat/js/ui/foldable/css/.svn/entries b/src/main/webapp/stat/js/ui/foldable/css/.svn/entries similarity index 100% rename from WebContent/stat/js/ui/foldable/css/.svn/entries rename to src/main/webapp/stat/js/ui/foldable/css/.svn/entries diff --git a/WebContent/stat/js/ui/foldable/css/.svn/text-base/foldable.css.svn-base b/src/main/webapp/stat/js/ui/foldable/css/.svn/text-base/foldable.css.svn-base similarity index 100% rename from WebContent/stat/js/ui/foldable/css/.svn/text-base/foldable.css.svn-base rename to src/main/webapp/stat/js/ui/foldable/css/.svn/text-base/foldable.css.svn-base diff --git a/src/main/webapp/stat/js/ui/foldable/css/foldable.css b/src/main/webapp/stat/js/ui/foldable/css/foldable.css new file mode 100644 index 000000000..c93766385 --- /dev/null +++ b/src/main/webapp/stat/js/ui/foldable/css/foldable.css @@ -0,0 +1,52 @@ +/*.ec-foldable {border:solid 1px #000}*/ +.ec-foldable-title { + padding: 2px 0 4px 20px; + cursor: pointer; + border-bottom: 1px solid #DFF4CD; + color: #356502; + font-size: 14px; +} + +/*.ec-foldable-title-over {background-color:#EEE}*/ +/*.ec-foldable-title-press {background-color:#CCC}*/ +.ec-foldable-handler { + float: right; + margin: 3px 3px 0 0 +} + +.ec-foldable-title-fold .ec-foldable-handler, .ec-foldable-title-unfold .ec-foldable-handler { + width: 16px; + height: 16px +} + +.ec-foldable-title-fold .ec-foldable-handler { + background: url("img/remove.gif") no-repeat scroll 0 0 transparent; +} + +.ec-foldable-title-unfold .ec-foldable-handler { + background: url("img/add.gif") no-repeat scroll 0 0 transparent; +} + +.icon-a .ec-foldable-title, .icon-b .ec-foldable-title, .icon-c .ec-foldable-title, .icon-d .ec-foldable-title, .icon-e .ec-foldable-title { + background: url("img/icon.gif") no-repeat scroll 0 -145px transparent; +} + +.icon-b .ec-foldable-title { + background-position: 0 -170px; +} + +.icon-c .ec-foldable-title { + background-position: 0 -195px; +} + +.icon-d .ec-foldable-title { + background-position: 0 -248px; +} + +.icon-e .ec-foldable-title { + background-position: 0 -273px; +} + +.ec-foldable-content { + margin: 5px +} diff --git a/WebContent/stat/js/ui/foldable/css/img/.svn/all-wcprops b/src/main/webapp/stat/js/ui/foldable/css/img/.svn/all-wcprops similarity index 100% rename from WebContent/stat/js/ui/foldable/css/img/.svn/all-wcprops rename to src/main/webapp/stat/js/ui/foldable/css/img/.svn/all-wcprops diff --git a/WebContent/stat/js/ui/foldable/css/img/.svn/entries b/src/main/webapp/stat/js/ui/foldable/css/img/.svn/entries similarity index 100% rename from WebContent/stat/js/ui/foldable/css/img/.svn/entries rename to src/main/webapp/stat/js/ui/foldable/css/img/.svn/entries diff --git a/WebContent/stat/js/ui/foldable/css/img/.svn/prop-base/add.gif.svn-base b/src/main/webapp/stat/js/ui/foldable/css/img/.svn/prop-base/add.gif.svn-base similarity index 100% rename from WebContent/stat/js/ui/foldable/css/img/.svn/prop-base/add.gif.svn-base rename to src/main/webapp/stat/js/ui/foldable/css/img/.svn/prop-base/add.gif.svn-base diff --git a/WebContent/stat/js/ui/foldable/css/img/.svn/prop-base/icon.gif.svn-base b/src/main/webapp/stat/js/ui/foldable/css/img/.svn/prop-base/icon.gif.svn-base similarity index 100% rename from WebContent/stat/js/ui/foldable/css/img/.svn/prop-base/icon.gif.svn-base rename to src/main/webapp/stat/js/ui/foldable/css/img/.svn/prop-base/icon.gif.svn-base diff --git a/WebContent/stat/js/ui/foldable/css/img/.svn/prop-base/remove.gif.svn-base b/src/main/webapp/stat/js/ui/foldable/css/img/.svn/prop-base/remove.gif.svn-base similarity index 100% rename from WebContent/stat/js/ui/foldable/css/img/.svn/prop-base/remove.gif.svn-base rename to src/main/webapp/stat/js/ui/foldable/css/img/.svn/prop-base/remove.gif.svn-base diff --git a/WebContent/stat/js/ui/foldable/css/img/.svn/text-base/add.gif.svn-base b/src/main/webapp/stat/js/ui/foldable/css/img/.svn/text-base/add.gif.svn-base similarity index 100% rename from WebContent/stat/js/ui/foldable/css/img/.svn/text-base/add.gif.svn-base rename to src/main/webapp/stat/js/ui/foldable/css/img/.svn/text-base/add.gif.svn-base diff --git a/WebContent/stat/js/ui/foldable/css/img/.svn/text-base/icon.gif.svn-base b/src/main/webapp/stat/js/ui/foldable/css/img/.svn/text-base/icon.gif.svn-base similarity index 100% rename from WebContent/stat/js/ui/foldable/css/img/.svn/text-base/icon.gif.svn-base rename to src/main/webapp/stat/js/ui/foldable/css/img/.svn/text-base/icon.gif.svn-base diff --git a/WebContent/stat/js/ui/foldable/css/img/.svn/text-base/remove.gif.svn-base b/src/main/webapp/stat/js/ui/foldable/css/img/.svn/text-base/remove.gif.svn-base similarity index 100% rename from WebContent/stat/js/ui/foldable/css/img/.svn/text-base/remove.gif.svn-base rename to src/main/webapp/stat/js/ui/foldable/css/img/.svn/text-base/remove.gif.svn-base diff --git a/WebContent/stat/js/ui/foldable/css/img/add.gif b/src/main/webapp/stat/js/ui/foldable/css/img/add.gif similarity index 100% rename from WebContent/stat/js/ui/foldable/css/img/add.gif rename to src/main/webapp/stat/js/ui/foldable/css/img/add.gif diff --git a/WebContent/stat/js/ui/foldable/css/img/icon.gif b/src/main/webapp/stat/js/ui/foldable/css/img/icon.gif similarity index 100% rename from WebContent/stat/js/ui/foldable/css/img/icon.gif rename to src/main/webapp/stat/js/ui/foldable/css/img/icon.gif diff --git a/WebContent/stat/js/ui/foldable/css/img/remove.gif b/src/main/webapp/stat/js/ui/foldable/css/img/remove.gif similarity index 100% rename from WebContent/stat/js/ui/foldable/css/img/remove.gif rename to src/main/webapp/stat/js/ui/foldable/css/img/remove.gif diff --git a/WebContent/stat/js/ui/foldable/js/.svn/all-wcprops b/src/main/webapp/stat/js/ui/foldable/js/.svn/all-wcprops similarity index 100% rename from WebContent/stat/js/ui/foldable/js/.svn/all-wcprops rename to src/main/webapp/stat/js/ui/foldable/js/.svn/all-wcprops diff --git a/WebContent/stat/js/ui/foldable/js/.svn/entries b/src/main/webapp/stat/js/ui/foldable/js/.svn/entries similarity index 100% rename from WebContent/stat/js/ui/foldable/js/.svn/entries rename to src/main/webapp/stat/js/ui/foldable/js/.svn/entries diff --git a/WebContent/stat/js/ui/foldable/js/.svn/text-base/ecomui.foldable.js.svn-base b/src/main/webapp/stat/js/ui/foldable/js/.svn/text-base/ecomui.foldable.js.svn-base similarity index 100% rename from WebContent/stat/js/ui/foldable/js/.svn/text-base/ecomui.foldable.js.svn-base rename to src/main/webapp/stat/js/ui/foldable/js/.svn/text-base/ecomui.foldable.js.svn-base diff --git a/src/main/webapp/stat/js/ui/foldable/js/ecomui.foldable.js b/src/main/webapp/stat/js/ui/foldable/js/ecomui.foldable.js new file mode 100644 index 000000000..fc7d57e2d --- /dev/null +++ b/src/main/webapp/stat/js/ui/foldable/js/ecomui.foldable.js @@ -0,0 +1,66 @@ +var ecomui = ecomui || {}; + +(function () { + var lib = baidu, + core = ecui, + dom = core.dom, + ui = core.ui, + util = core.util, + inherits = util.inherits, + copy = util.copy, + + children = dom.children, + createDom = dom.create, + $fastCreate = core.$fastCreate, + setText = dom.setText, + + DOCUMENT = document, + UI_CONTROL = ui.Control, + ECOM_FOLDABLE_CLASS; + + ecomui.Foldable = ui.Foldable = function (el, params) { + var typeClass = params.type, + contentEl = children(el)[0]; + titleEl = createDom(typeClass + "-title"), + handlerEl = createDom(typeClass + "-handler"); + + el.insertBefore(titleEl, contentEl); + setText(titleEl, params.title || ""); + titleEl.insertBefore(handlerEl, titleEl.firstChild); + + params.capture = false; + + UI_CONTROL.call(this, el, params); + + this._uTitle = $fastCreate(UI_CONTROL, titleEl, this); + this._uContent = $fastCreate(UI_CONTROL, contentEl, this, {capture: false}); + this._uHandler = $fastCreate(UI_CONTROL, handlerEl, this._uTitle, {capture: false}); + + this._uTitle["on" + (params.trigger || "click")] = ECOM_FOLDABLE_TITLECLICK; + + ECOM_FOLDABLE_TOGGLECONTENT.call(this._uTitle, params.initFold || false); + }; + + function ECOM_FOLDABLE_TITLECLICK() { + ECOM_FOLDABLE_TOGGLECONTENT.call(this); + } + + function ECOM_FOLDABLE_TOGGLECONTENT(fold) { + var control = this.getParent(), + content = control._uContent, + handler = control._uHandler, + handlerEl = handler.getBase(), + isShow = fold !== undefined ? fold : content.isShow(); + + isShow ? content.hide() : content.show(); + handlerEl.setAttribute("title", isShow ? "点击展开" : "点击折叠"); + + this.$alterClass(isShow ? "unfold" : "fold"); + this.$alterClass(isShow ? "fold" : "unfold", true); + + control.$resize(); + } + + ECOM_FOLDABLE_CLASS = inherits(ui.Foldable, UI_CONTROL); + +})(); diff --git a/WebContent/stat/js/ui/popup/css/img/popup_bg.jpg b/src/main/webapp/stat/js/ui/popup/css/img/popup_bg.jpg similarity index 100% rename from WebContent/stat/js/ui/popup/css/img/popup_bg.jpg rename to src/main/webapp/stat/js/ui/popup/css/img/popup_bg.jpg diff --git a/WebContent/stat/js/ui/popup/css/img/popup_more.jpg b/src/main/webapp/stat/js/ui/popup/css/img/popup_more.jpg similarity index 100% rename from WebContent/stat/js/ui/popup/css/img/popup_more.jpg rename to src/main/webapp/stat/js/ui/popup/css/img/popup_more.jpg diff --git a/WebContent/stat/js/ui/popup/css/img/popup_more_over.jpg b/src/main/webapp/stat/js/ui/popup/css/img/popup_more_over.jpg similarity index 100% rename from WebContent/stat/js/ui/popup/css/img/popup_more_over.jpg rename to src/main/webapp/stat/js/ui/popup/css/img/popup_more_over.jpg diff --git a/WebContent/stat/js/ui/popup/css/img/popup_more_over_oh.jpg b/src/main/webapp/stat/js/ui/popup/css/img/popup_more_over_oh.jpg similarity index 100% rename from WebContent/stat/js/ui/popup/css/img/popup_more_over_oh.jpg rename to src/main/webapp/stat/js/ui/popup/css/img/popup_more_over_oh.jpg diff --git a/WebContent/stat/js/ui/popup/css/img/popup_over.jpg b/src/main/webapp/stat/js/ui/popup/css/img/popup_over.jpg similarity index 100% rename from WebContent/stat/js/ui/popup/css/img/popup_over.jpg rename to src/main/webapp/stat/js/ui/popup/css/img/popup_over.jpg diff --git a/WebContent/stat/js/ui/popup/css/img/popup_over_oh.jpg b/src/main/webapp/stat/js/ui/popup/css/img/popup_over_oh.jpg similarity index 100% rename from WebContent/stat/js/ui/popup/css/img/popup_over_oh.jpg rename to src/main/webapp/stat/js/ui/popup/css/img/popup_over_oh.jpg diff --git a/WebContent/stat/js/ui/popup/css/img/popup_tb.jpg b/src/main/webapp/stat/js/ui/popup/css/img/popup_tb.jpg similarity index 100% rename from WebContent/stat/js/ui/popup/css/img/popup_tb.jpg rename to src/main/webapp/stat/js/ui/popup/css/img/popup_tb.jpg diff --git a/WebContent/stat/js/ui/popup/css/img/select.jpg b/src/main/webapp/stat/js/ui/popup/css/img/select.jpg similarity index 100% rename from WebContent/stat/js/ui/popup/css/img/select.jpg rename to src/main/webapp/stat/js/ui/popup/css/img/select.jpg diff --git a/src/main/webapp/stat/js/ui/popup/css/popup.css b/src/main/webapp/stat/js/ui/popup/css/popup.css new file mode 100644 index 000000000..771399928 --- /dev/null +++ b/src/main/webapp/stat/js/ui/popup/css/popup.css @@ -0,0 +1,150 @@ +.popupdtr { + padding-top: 9px; + padding-bottom: 9px +} + +.popupdtr-top { + background: url(img/popup_tb.jpg) top left no-repeat; + overflow: hidden; + font-size: 0px +} + +.popupdtr-bottom { + background: url(img/popup_tb.jpg) 0px -9px no-repeat; + font-size: 0px +} + +.ec-popup { + padding-right: 13px; + border-width: auto; + border: none; + background: url(img/popup_bg.jpg) top left repeat-y; + width: 267px; + overflow-y: auto; + overflow-x: hidden +} + +.ec-popup .ec-item { + padding: auto; + height: 22px; + margin-left: 3px; + margin-right: 3px; + padding-left: 32px; + line-height: 22px; + cursor: default; + border-width: auto; + border: none +} + +.ec-popup-item { + padding: auto; + height: 22px; + margin-left: 3px; + margin-right: 3px; + padding-left: 32px; + line-height: 22px; + cursor: default; + background: none; + border-bottom: none +} + +.ec-popup-item-over { + background: url(img/popup_over.jpg) top left no-repeat +} + +.ec-popup-item-complex { + background: url(img/popup_more.jpg) 245px 7px no-repeat +} + +.ec-popup-item-complex-over { + background: url(img/popup_more_over.jpg) left top no-repeat +} + +.ec-scpopup { + padding-right: 13px; + border-width: auto; + border: none; + background: url(img/popup_bg.jpg) top left repeat-y; + width: 267px +} + +.ec-scpopup-layout { + width: 260px; + height: 100%; + overflow-y: auto; + overflow-x: hidden +} + +.ec-scpopup .ec-item { + padding: auto; + height: 22px; + margin-left: 3px; + margin-right: 3px; + padding-left: 10px; + line-height: 22px; + cursor: default; + border-width: auto; + border: none +} + +.ec-scpopup-item { + padding: auto; + height: 22px; + margin-left: 3px; + margin-right: 3px; + padding-left: 10px; + line-height: 22px; + cursor: default; + background: none; + border-bottom: none +} + +.ec-scpopup-item-over { + background: url(img/popup_over.jpg) top left no-repeat +} + +.ec-scpopup-item-complex { + background: url(img/popup_more.jpg) 244px 7px no-repeat +} + +.ec-scpopup-item-complex-over { + background: url(img/popup_more_over.jpg) left top no-repeat +} + +.ec-scpopup-layout-overheight .ec-scpopup-item-complex { + background: url(img/popup_more.jpg) 227px 7px no-repeat +} + +.ec-scpopup-layout-overheight .ec-scpopup-item-complex-over { + background: url(img/popup_more_over_oh.jpg) left top no-repeat +} + +.ec-scpopup-layout-overheight .ec-scpopup-item-over { + background: url(img/popup_over_oh.jpg) top left no-repeat +} + +.ec-ecombox { + top: 5px; + width: 120px; + height: 17px; + border: 1px solid #CCC; + background: #FFF +} + +.ec-ecombox-button { + top: 0px; + right: 0px; + width: 17px; + height: 17px; + background: url(img/select.jpg) 0px 0px no-repeat +} + +.ec-ecombox-over .ec-ecombox-button { + background: url(img/select.jpg) -17px 0px no-repeat +} + +.ec-ecombox-press .ec-ecombox-button { + background: url(img/select.jpg) -34px 0px no-repeat +} + + diff --git a/src/main/webapp/stat/js/ui/popup/js/ecpopup.js b/src/main/webapp/stat/js/ui/popup/js/ecpopup.js new file mode 100644 index 000000000..2a4ebe656 --- /dev/null +++ b/src/main/webapp/stat/js/ui/popup/js/ecpopup.js @@ -0,0 +1,246 @@ +(function () { + var core = ecui, + dom = core.dom, + ui = core.ui, + util = core.util, + ext = core.ext, + + createControl = core.create, + inherits = util.inherits, + getView = util.getView, + getPosition = dom.getPosition, + first = dom.first, + copy = util.copy, + blank = core.blank, + restore = core.restore, + trim = core.string.trim, + setStyles = dom.setStyles, + insertFloor = dom.insertFloor, + mask = core.mask, + removeDom = dom.remove, + getChild = dom.children, + setText = dom.setText, + getText = dom.getText, + createDom = dom.create, + moveElements = dom.moveElements, + + DOCUMENT = document, + + + UI_EDIT = ui.Edit, + UI_ITEM = ui.Item, + UI_CONTROL = ui.Control, + UI_CONTROL_CLASS = UI_CONTROL.prototype, + UI_EDIT_CLASS = UI_EDIT.prototype, + UI_POPUP = ui.Popup, + UI_POPUP_CLASS = UI_POPUP.prototype; + + var UI_ECOMBOX = ui.Ecombox = function (el, params) { + var me = this, + typeClass = params.type, + items; + + me._uPopup = createControl( + 'Scpopup', + { + 'element': first(el) + } + ); + me._uPopup.$setParent(me); + items = me._uPopup.getItems(); + + for (var i = 0, item; item = items[i]; i++) { + UI_ECOMBOX_ATTACHHANDLER(item); + } + + + UI_EDIT.call(me, el, params); + + (params.maxlength) && (this.getInput().maxLength = params.maxlength); + this.getInput().style.position = 'absolute'; + + (me._uButton = createControl( + 'Control', + { + 'base': typeClass + '-button', + 'parent': me, + 'capture': false + } + )).getOuter().style.position = 'absolute'; + + el.style.position = 'relative'; + }, + + UI_ECOMBOX_CLASS = inherits(UI_ECOMBOX, UI_EDIT); + + UI_ECOMBOX_CLASS.$click = function (event) { + var target = event.target; + UI_EDIT_CLASS.$click.call(this, event); + if (target.getControl && target.getControl() == this._uButton) { + this.showPopup(); + } + }; + + UI_ECOMBOX_CLASS.setValue = function (text) { + if (this.getInput().value != text) { + UI_EDIT_CLASS.setValue.call(this, text); + return true; + } + else { + return false; + } + }; + + UI_ECOMBOX_CLASS.showPopup = function () { + var pos = getPosition(this.getOuter()), + o = this._uPopup, + popupTop = pos.top + this.getHeight(), + items; + + o.setPosition( + pos.left, + popupTop + o.getHeight() <= getView().bottom ? popupTop : pos.top - o.getHeight() + ); + + items = o.getItems(); + for (var i = 0, item; item = items[i]; i++) { + (item._cPopup) && (item._cPopup.paint()); + } + + mask(0.05); + o.show(); + o.onhide = UI_ECOMBOX_HIDEMASK; + }; + + UI_ECOMBOX_CLASS.$setSize = function (width, height) { + UI_EDIT_CLASS.$setSize.call(this, width, height); + + width = this.getBodyWidth() - height; + this.getInput().style.width = width + 'px' + setStyles(this.getInput(), {'width': width + 'px', 'height': height + 'px'}); + }; + + function UI_ECOMBOX_HIDEMASK() { + mask(); + } + + function UI_ECOMBOX_SETVALUE() { + var el = this.getBody(), + value = el.getAttribute('value'), + text = trim(el.getAttribute('title') ? el.getAttribute('title') : el.innerHTML), + con = this; + + while ((con = con.getParent()) && !(con instanceof UI_ECOMBOX)) { + } + + if ((con) && (con.setValue(text)) && (con.onpostdata)) { + con.onpostdata(value); + } + + } + + function UI_ECOMBOX_ATTACHHANDLER(item) { + var childs = item.getChildItems(); + if (childs.length == 0) { + return; + } + for (var i = 0, child; child = childs[i]; i++) { + child.onclick = UI_ECOMBOX_SETVALUE; + UI_ECOMBOX_ATTACHHANDLER(child); + } + } + + var UI_SCPOPUP = ui.Scpopup = function (el, params) { + var i = 0, + o; + + UI_CONTROL.call(this, el, params); + + o = createDom(); + moveElements(o, el); + el.appendChild(o); + this._eBody = o; + this._eBody.className = params.type + '-layout'; + + this._nMaxHeight = params.maxheight || 300; + this._nMaxTextLen = params.maxTextLen || 20; + + /* 初始化菜单项 */ + //this.setParent(DOCUMENT.body); + DOCUMENT.body.appendChild(el); + this.$initItems(); + this.$alterItems(); + + el = this.getOuter().style; + el.display = 'none'; + el.position = 'absolute'; + + /* 弹出菜单初始化完成后就不允许改变父对象 */ + this.setParent = blank; + + /* 初始化子弹出菜单 */ + for (el = this.getItems(); o = el[i++];) { + o._cPopup && o.setClass(params.base + '-item-complex'); + } + + /* 修正文字长度不能超过限制 */ + for (i = 0, el = getChild(this._eBody); o = el[i++];) { + if (first(o) && first(o).tagName.toLowerCase() == 'label') { + o = first(o); + } + if ((getText(o).length) > this._nMaxTextLen) { + o.setAttribute('title', getText(o)); + setText(o, getText(o).substring(0, this._nMaxTextLen - 3) + '...'); + } + } + }, + + UI_SCPOPUP_CLASS = inherits(UI_SCPOPUP, UI_POPUP); + + UI_SCPOPUP_CLASS.$createChild = function (item, el) { + var popup; + if (trim(el.innerHTML) == '') { + removeDom(el); + return false; + } + popup = item._cPopup = createControl( + 'Scpopup', + { + base: item.getParent().getClass(), + element: el + } + ); + + popup.$setParent(item); + return popup; + }; + + UI_SCPOPUP_CLASS.$create = function () { + new ext.TBDecorator(this, 'popupdtr'); + UI_CONTROL_CLASS.$create.call(this); + }; + + UI_SCPOPUP_CLASS.$setSize = function (width, height) { + var el = this._eBody; + if (height > this._nMaxHeight) { + height = this._nMaxHeight; + if (el.className.indexOf('overheight') < 0) { + el.className = el.className + ' ' + this.getBaseClass() + '-layout-overheight'; + } + } + UI_CONTROL_CLASS.$setSize.call(this, width, height); + }; + + UI_SCPOPUP_CLASS.$forcibly = function (event) { + var con = event.getTarget(), find = false; + while (con) { + if (con == this) { + find = true; + break; + } + con = con.getParent(); + } + (!find) && (UI_POPUP_CLASS.$forcibly.call(this)); + return false; + } +})() diff --git a/WebContent/stat/js/ui/scroll/css/img/hscroll.jpg b/src/main/webapp/stat/js/ui/scroll/css/img/hscroll.jpg similarity index 100% rename from WebContent/stat/js/ui/scroll/css/img/hscroll.jpg rename to src/main/webapp/stat/js/ui/scroll/css/img/hscroll.jpg diff --git a/WebContent/stat/js/ui/scroll/css/img/scroll.jpg b/src/main/webapp/stat/js/ui/scroll/css/img/scroll.jpg similarity index 100% rename from WebContent/stat/js/ui/scroll/css/img/scroll.jpg rename to src/main/webapp/stat/js/ui/scroll/css/img/scroll.jpg diff --git a/src/main/webapp/stat/js/ui/scroll/css/scroll.css b/src/main/webapp/stat/js/ui/scroll/css/scroll.css new file mode 100644 index 000000000..4264d1e00 --- /dev/null +++ b/src/main/webapp/stat/js/ui/scroll/css/scroll.css @@ -0,0 +1,141 @@ +.ec-vscroll { + background: #F0F0F0; + width: auto; + padding: 15px 0px 15px 0px; + font-size: 0px +} + +.ec-hscroll { + background: #F0F0F0; + height: auto; + padding: 0px 15px 0px 15px; + font-size: 0px +} + +.ec-hscroll-block { + background: url(img/hscroll.jpg) -2px -30px repeat-x +} + +.ec-vscroll-block { + background: url(img/scroll.jpg) 0px 0px repeat-y +} + +.ec-hscroll-block-over { + background: url(img/hscroll.jpg) -0px -45px repeat-x +} + +.ec-hscroll-block-press { + background: url(img/hscroll.jpg) -0px -60px repeat-x +} + +.ec-vscroll-block-over { + background: url(img/scroll.jpg) -15px 0px repeat-y +} + +.ec-vscroll-block-press { + background: url(img/scroll.jpg) -30px 0px repeat-y +} + +.ec-vscroll-prev { + background: url(img/scroll.jpg) -45px -40px no-repeat; +} + +.ec-vscroll-prev-over { + background: url(img/scroll.jpg) -75px -40px no-repeat; +} + +.ec-vscroll-prev-press { + background: url(img/scroll.jpg) -60px -40px no-repeat; +} + +.ec-vscroll-next { + background: url(img/scroll.jpg) -45px -55px no-repeat; +} + +.ec-vscroll-next-over { + background: url(img/scroll.jpg) -75px -55px no-repeat; +} + +.ec-vscroll-next-press { + background: url(img/scroll.jpg) -60px -55px no-repeat; +} + +.ec-hscroll-prev { + background: url(img/scroll.jpg) -45px -85px no-repeat; +} + +.ec-hscroll-prev-over { + background: url(img/scroll.jpg) -75px -85px no-repeat; +} + +.ec-hscroll-prev-press { + background: url(img/scroll.jpg) -60px -85px no-repeat; +} + +.ec-hscroll-next { + background: url(img/scroll.jpg) -45px -70px no-repeat; +} + +.ec-hscroll-next-over { + background: url(img/scroll.jpg) -75px -70px no-repeat; +} + +.ec-hscroll-next-press { + background: url(img/scroll.jpg) -60px -70px no-repeat; +} + +.vsblockdtr { + padding: 2px 0px +} + +.vsblockdtr-top { + background: url(img/scroll.jpg) -45px 0px no-repeat +} + +.vsblockdtr-bottom { + background: url(img/scroll.jpg) -45px -18px no-repeat +} + +.vsblockdtr-over .vsblockdtr-top { + background: url(img/scroll.jpg) -45px -20px no-repeat +} + +.vsblockdtr-over .vsblockdtr-bottom { + background: url(img/scroll.jpg) -45px -38px no-repeat +} + +.vsblockdtr-press .vsblockdtr-top { + background: url(img/scroll.jpg) -60px 0px no-repeat +} + +.vsblockdtr-press .vsblockdtr-bottom { + background: url(img/scroll.jpg) -60px -38px no-repeat +} + +.hsblockdtr { + padding: 0px 2px +} + +.hsblockdtr-left { + background: url(img/hscroll.jpg) -60px 0px no-repeat +} + +.hsblockdtr-right { + background: url(img/hscroll.jpg) -18px 0px no-repeat +} + +.hsblockdtr-over .hsblockdtr-left { + background: url(img/hscroll.jpg) -40px -0px no-repeat +} + +.hsblockdtr-over .hsblockdtr-right { + background: url(img/hscroll.jpg) -38px -0px no-repeat +} + +.hsblockdtr-press .hsblockdtr-left { + background: url(img/hscroll.jpg) -40px -15px no-repeat +} + +.hsblockdtr-press .hsblockdtr-right { + background: url(img/hscroll.jpg) -38px -15px no-repeat +} diff --git a/WebContent/stat/js/ui/selectbox/.svn/all-wcprops b/src/main/webapp/stat/js/ui/selectbox/.svn/all-wcprops similarity index 100% rename from WebContent/stat/js/ui/selectbox/.svn/all-wcprops rename to src/main/webapp/stat/js/ui/selectbox/.svn/all-wcprops diff --git a/WebContent/stat/js/ui/selectbox/.svn/entries b/src/main/webapp/stat/js/ui/selectbox/.svn/entries similarity index 100% rename from WebContent/stat/js/ui/selectbox/.svn/entries rename to src/main/webapp/stat/js/ui/selectbox/.svn/entries diff --git a/WebContent/stat/js/ui/selectbox/css/.svn/all-wcprops b/src/main/webapp/stat/js/ui/selectbox/css/.svn/all-wcprops similarity index 100% rename from WebContent/stat/js/ui/selectbox/css/.svn/all-wcprops rename to src/main/webapp/stat/js/ui/selectbox/css/.svn/all-wcprops diff --git a/WebContent/stat/js/ui/selectbox/css/.svn/entries b/src/main/webapp/stat/js/ui/selectbox/css/.svn/entries similarity index 100% rename from WebContent/stat/js/ui/selectbox/css/.svn/entries rename to src/main/webapp/stat/js/ui/selectbox/css/.svn/entries diff --git a/WebContent/stat/js/ui/selectbox/css/.svn/text-base/selectbox.css.svn-base b/src/main/webapp/stat/js/ui/selectbox/css/.svn/text-base/selectbox.css.svn-base similarity index 100% rename from WebContent/stat/js/ui/selectbox/css/.svn/text-base/selectbox.css.svn-base rename to src/main/webapp/stat/js/ui/selectbox/css/.svn/text-base/selectbox.css.svn-base diff --git a/WebContent/stat/js/ui/selectbox/css/img/.svn/all-wcprops b/src/main/webapp/stat/js/ui/selectbox/css/img/.svn/all-wcprops similarity index 100% rename from WebContent/stat/js/ui/selectbox/css/img/.svn/all-wcprops rename to src/main/webapp/stat/js/ui/selectbox/css/img/.svn/all-wcprops diff --git a/WebContent/stat/js/ui/selectbox/css/img/.svn/entries b/src/main/webapp/stat/js/ui/selectbox/css/img/.svn/entries similarity index 100% rename from WebContent/stat/js/ui/selectbox/css/img/.svn/entries rename to src/main/webapp/stat/js/ui/selectbox/css/img/.svn/entries diff --git a/WebContent/stat/js/ui/selectbox/css/img/.svn/prop-base/scroll_bg.gif.svn-base b/src/main/webapp/stat/js/ui/selectbox/css/img/.svn/prop-base/scroll_bg.gif.svn-base similarity index 100% rename from WebContent/stat/js/ui/selectbox/css/img/.svn/prop-base/scroll_bg.gif.svn-base rename to src/main/webapp/stat/js/ui/selectbox/css/img/.svn/prop-base/scroll_bg.gif.svn-base diff --git a/WebContent/stat/js/ui/selectbox/css/img/.svn/text-base/scroll_bg.gif.svn-base b/src/main/webapp/stat/js/ui/selectbox/css/img/.svn/text-base/scroll_bg.gif.svn-base similarity index 100% rename from WebContent/stat/js/ui/selectbox/css/img/.svn/text-base/scroll_bg.gif.svn-base rename to src/main/webapp/stat/js/ui/selectbox/css/img/.svn/text-base/scroll_bg.gif.svn-base diff --git a/WebContent/stat/js/ui/selectbox/css/img/scroll_bg.gif b/src/main/webapp/stat/js/ui/selectbox/css/img/scroll_bg.gif similarity index 100% rename from WebContent/stat/js/ui/selectbox/css/img/scroll_bg.gif rename to src/main/webapp/stat/js/ui/selectbox/css/img/scroll_bg.gif diff --git a/src/main/webapp/stat/js/ui/selectbox/css/selectbox.css b/src/main/webapp/stat/js/ui/selectbox/css/selectbox.css new file mode 100644 index 000000000..0270394c6 --- /dev/null +++ b/src/main/webapp/stat/js/ui/selectbox/css/selectbox.css @@ -0,0 +1,79 @@ +.ec-panel { + z-index: 9000; + height: 100px; + width: 137px; + background: #fff +} + +.ec-panel-corner { + background: #F0F0F0; + font-size: 1px; +} + +.ec-panel-layout { + border: 1px solid #CCC; + line-height: 20px; + padding: 3px; +} + +.select-box .ec-panel-layout { + text-align: left; + margin-top: 1px; + background: #fff; +} + +.select-box .ec-vscroll { + border-right: 1px #ccc solid; + cursor: pointer; + cursor: hand; +} + +.select-box button { + margin: 5px 0; +} + +.select-box .ec-edit { + padding-right: 15px; + height: 15px; + background: #fff url("img/scroll_bg.gif") no-repeat right -15px; + border: 1px #ccc solid; + cursor: pointer; + cursor: hand; +} + +.ec-panel-corner { + background: #F0F0F0; + font-size: 1px; +} + +.ec-panel-layout { + background: #fff; + border: 1px solid #CCC; + line-height: 20px; + padding: 3px; +} + +.select-box .ec-panel-layout { + text-align: left; + margin-top: 1px; + background: #fff; +} + +.select-box .ec-vscroll { + border-right: 1px #ccc solid; + cursor: pointer; + cursor: hand; +} + +.select-box button { + margin: 5px 0; +} + +.sel-edit { + z-index: 9000; + padding-right: 13px; + background: #fff url("img/scroll_bg.gif") no-repeat right -14px; + border: 1px #ccc solid; + cursor: pointer; + cursor: hand; +} diff --git a/WebContent/stat/js/ui/selectbox/js/.svn/all-wcprops b/src/main/webapp/stat/js/ui/selectbox/js/.svn/all-wcprops similarity index 100% rename from WebContent/stat/js/ui/selectbox/js/.svn/all-wcprops rename to src/main/webapp/stat/js/ui/selectbox/js/.svn/all-wcprops diff --git a/WebContent/stat/js/ui/selectbox/js/.svn/entries b/src/main/webapp/stat/js/ui/selectbox/js/.svn/entries similarity index 100% rename from WebContent/stat/js/ui/selectbox/js/.svn/entries rename to src/main/webapp/stat/js/ui/selectbox/js/.svn/entries diff --git a/WebContent/stat/js/ui/selectbox/js/.svn/text-base/selectbox.js.svn-base b/src/main/webapp/stat/js/ui/selectbox/js/.svn/text-base/selectbox.js.svn-base similarity index 100% rename from WebContent/stat/js/ui/selectbox/js/.svn/text-base/selectbox.js.svn-base rename to src/main/webapp/stat/js/ui/selectbox/js/.svn/text-base/selectbox.js.svn-base diff --git a/src/main/webapp/stat/js/ui/selectbox/js/selectbox.js b/src/main/webapp/stat/js/ui/selectbox/js/selectbox.js new file mode 100644 index 000000000..2dc4e4c1c --- /dev/null +++ b/src/main/webapp/stat/js/ui/selectbox/js/selectbox.js @@ -0,0 +1,142 @@ +//按钮的点击事件 +function wrapHide(tg) { + var wrap = baidu.dom.getAncestorByClass(tg, "ec-panel"); + wrap = wrap.getControl(); + var selectBox = wrap.getParent(); + var edit = selectBox._uEdit.getInput(); + var allBox = selectBox._uPanel.getOuter().getElementsByTagName("input") + var str = ""; + for (var i = 0, j = 0; i < allBox.length && j < 4; i++) { + if (allBox[i].checked) { + j++; + show = baidu.dom.next(allBox[i]).innerHTML; + if (j == 1) { + str += show + } + else if (j < 4) { + str += "," + show + } + else { + str += "," + show + "..." + } + } + } + edit.value = str; + wrap.hide(); +} + +//以下为多选下拉用到的js +var ecomui = ecomui || {}; +(function () { + var core = ecui, + ui = core.ui, + util = core.util; + inherits = util.inherits, + UI_CONTROL = ui.Control; + + /** + * --------------------- + * 多选下拉构造函数 + * --------------------- + */ + ecomui.SelectBox = ui.SelectBox = function (el, params) { + UI_CONTROL.call(this, el, params); + var id = this.getUID(), body = this.getBody(); + var panelHTML = '
    '; + panelHTML += '
    '; + body.innerHTML = panelHTML; + core.init(body); + this.setClass("select-box"); + + this._uHeight = params.pHeight || 30 + this._uCol = params.col || 1; + this._uName = params.name; + this._uEdit = core.get("edit-" + id); + this._uPanel = core.get("panel-" + id); + + //最开始隐藏下拉层 + this._uPanel.hide(); + this.init(); + //绑定事件 + this._uEdit.onclick = SELECT_BOX_CLASS.oneditclick; + } + + //原型继承至基础控件 + SELECT_BOX_CLASS = inherits(ui.SelectBox, UI_CONTROL); + + + //点击输入框弹出下拉层 + SELECT_BOX_CLASS.oneditclick = function () { + var wrap = this.getParent() + var panelDom = wrap._uPanel.getBase(); + baidu.dom.toggle(panelDom); + + } + + //屏蔽点击事件,返回给控件 + SELECT_BOX_CLASS.$pressend = function () { + ecui.forcibly(this); + mask(0, 65534); + } + + //重写$forcibly方法 + SELECT_BOX_CLASS.$forcibly = function () { + var wrap = this.getParent() + var panelDom = wrap._uPanel.getBase(); + baidu.dom.toggle(panelDom); + } + + + //设置下拉面板的可见高度 + SELECT_BOX_CLASS.setPHeight = function () { + var pHeight = this._uHeight; + var pStyle = this._uPanel.getOuter().style; + pStyle.height = pHeight; + + } + + //控件初始化 + SELECT_BOX_CLASS.init = function () { + this.setPst(); + this.setPHeight(); + } + + //根据edit定位下拉层 + SELECT_BOX_CLASS.setPst = function () { + var edit = this._uEdit.getBase(); + var editX = baidu.dom.getPosition(edit).left; + var editY = baidu.dom.getPosition(edit).top; + var pStyle = this._uPanel.getBase(); + pStyle.style.position = "absolute"; + this._uPanel.setPosition(editX, editY + 15); + } + + SELECT_BOX_CLASS.updata = function () { + var allBox = this._uPanel; + alert(allBox) + + + } + + //滚动条不因后面的内容增加而出现 TODO + //设置下拉框中的内容,根据数据构造多个checkbox + SELECT_BOX_CLASS.setData = function (data) { + var sData = data; + var Fname = this._uName; + var Fcol = this._uCol; + var optionHTML = ""; + var checkboxIndex = 1; + var panelContent = this._uPanel.getBody(); + baidu.array.each(sData, function (item, i) { + Schecked = item.isChecked ? 'checked="checked"' : ""; + optionHTML += ''; + optionHTML += ''; + if (checkboxIndex % Fcol == 0) optionHTML += '
    '; + checkboxIndex++; + }); + optionHTML += '
    ' + panelContent.innerHTML = optionHTML; + } + + +})() \ No newline at end of file diff --git a/WebContent/stat/js/ui/table/.svn/all-wcprops b/src/main/webapp/stat/js/ui/table/.svn/all-wcprops similarity index 100% rename from WebContent/stat/js/ui/table/.svn/all-wcprops rename to src/main/webapp/stat/js/ui/table/.svn/all-wcprops diff --git a/WebContent/stat/js/ui/table/.svn/entries b/src/main/webapp/stat/js/ui/table/.svn/entries similarity index 100% rename from WebContent/stat/js/ui/table/.svn/entries rename to src/main/webapp/stat/js/ui/table/.svn/entries diff --git a/WebContent/stat/js/ui/table/css/.svn/all-wcprops b/src/main/webapp/stat/js/ui/table/css/.svn/all-wcprops similarity index 100% rename from WebContent/stat/js/ui/table/css/.svn/all-wcprops rename to src/main/webapp/stat/js/ui/table/css/.svn/all-wcprops diff --git a/WebContent/stat/js/ui/table/css/.svn/entries b/src/main/webapp/stat/js/ui/table/css/.svn/entries similarity index 100% rename from WebContent/stat/js/ui/table/css/.svn/entries rename to src/main/webapp/stat/js/ui/table/css/.svn/entries diff --git a/WebContent/stat/js/ui/table/css/.svn/text-base/table.css.svn-base b/src/main/webapp/stat/js/ui/table/css/.svn/text-base/table.css.svn-base similarity index 100% rename from WebContent/stat/js/ui/table/css/.svn/text-base/table.css.svn-base rename to src/main/webapp/stat/js/ui/table/css/.svn/text-base/table.css.svn-base diff --git a/WebContent/stat/js/ui/table/css/img/.svn/all-wcprops b/src/main/webapp/stat/js/ui/table/css/img/.svn/all-wcprops similarity index 100% rename from WebContent/stat/js/ui/table/css/img/.svn/all-wcprops rename to src/main/webapp/stat/js/ui/table/css/img/.svn/all-wcprops diff --git a/WebContent/stat/js/ui/table/css/img/.svn/entries b/src/main/webapp/stat/js/ui/table/css/img/.svn/entries similarity index 100% rename from WebContent/stat/js/ui/table/css/img/.svn/entries rename to src/main/webapp/stat/js/ui/table/css/img/.svn/entries diff --git a/WebContent/stat/js/ui/table/css/img/.svn/prop-base/cr.gif.svn-base b/src/main/webapp/stat/js/ui/table/css/img/.svn/prop-base/cr.gif.svn-base similarity index 100% rename from WebContent/stat/js/ui/table/css/img/.svn/prop-base/cr.gif.svn-base rename to src/main/webapp/stat/js/ui/table/css/img/.svn/prop-base/cr.gif.svn-base diff --git a/WebContent/stat/js/ui/table/css/img/.svn/prop-base/hscroll.gif.svn-base b/src/main/webapp/stat/js/ui/table/css/img/.svn/prop-base/hscroll.gif.svn-base similarity index 100% rename from WebContent/stat/js/ui/table/css/img/.svn/prop-base/hscroll.gif.svn-base rename to src/main/webapp/stat/js/ui/table/css/img/.svn/prop-base/hscroll.gif.svn-base diff --git a/WebContent/stat/js/ui/table/css/img/.svn/prop-base/hscroll_blue.gif.svn-base b/src/main/webapp/stat/js/ui/table/css/img/.svn/prop-base/hscroll_blue.gif.svn-base similarity index 100% rename from WebContent/stat/js/ui/table/css/img/.svn/prop-base/hscroll_blue.gif.svn-base rename to src/main/webapp/stat/js/ui/table/css/img/.svn/prop-base/hscroll_blue.gif.svn-base diff --git a/WebContent/stat/js/ui/table/css/img/.svn/prop-base/hscroll_bluegray.gif.svn-base b/src/main/webapp/stat/js/ui/table/css/img/.svn/prop-base/hscroll_bluegray.gif.svn-base similarity index 100% rename from WebContent/stat/js/ui/table/css/img/.svn/prop-base/hscroll_bluegray.gif.svn-base rename to src/main/webapp/stat/js/ui/table/css/img/.svn/prop-base/hscroll_bluegray.gif.svn-base diff --git a/WebContent/stat/js/ui/table/css/img/.svn/prop-base/loading.gif.svn-base b/src/main/webapp/stat/js/ui/table/css/img/.svn/prop-base/loading.gif.svn-base similarity index 100% rename from WebContent/stat/js/ui/table/css/img/.svn/prop-base/loading.gif.svn-base rename to src/main/webapp/stat/js/ui/table/css/img/.svn/prop-base/loading.gif.svn-base diff --git a/WebContent/stat/js/ui/table/css/img/.svn/prop-base/scroll.gif.svn-base b/src/main/webapp/stat/js/ui/table/css/img/.svn/prop-base/scroll.gif.svn-base similarity index 100% rename from WebContent/stat/js/ui/table/css/img/.svn/prop-base/scroll.gif.svn-base rename to src/main/webapp/stat/js/ui/table/css/img/.svn/prop-base/scroll.gif.svn-base diff --git a/WebContent/stat/js/ui/table/css/img/.svn/prop-base/scroll_blue.gif.svn-base b/src/main/webapp/stat/js/ui/table/css/img/.svn/prop-base/scroll_blue.gif.svn-base similarity index 100% rename from WebContent/stat/js/ui/table/css/img/.svn/prop-base/scroll_blue.gif.svn-base rename to src/main/webapp/stat/js/ui/table/css/img/.svn/prop-base/scroll_blue.gif.svn-base diff --git a/WebContent/stat/js/ui/table/css/img/.svn/prop-base/scroll_bluegray.gif.svn-base b/src/main/webapp/stat/js/ui/table/css/img/.svn/prop-base/scroll_bluegray.gif.svn-base similarity index 100% rename from WebContent/stat/js/ui/table/css/img/.svn/prop-base/scroll_bluegray.gif.svn-base rename to src/main/webapp/stat/js/ui/table/css/img/.svn/prop-base/scroll_bluegray.gif.svn-base diff --git a/WebContent/stat/js/ui/table/css/img/.svn/prop-base/table.gif.svn-base b/src/main/webapp/stat/js/ui/table/css/img/.svn/prop-base/table.gif.svn-base similarity index 100% rename from WebContent/stat/js/ui/table/css/img/.svn/prop-base/table.gif.svn-base rename to src/main/webapp/stat/js/ui/table/css/img/.svn/prop-base/table.gif.svn-base diff --git a/WebContent/stat/js/ui/table/css/img/.svn/prop-base/table_blue.gif.svn-base b/src/main/webapp/stat/js/ui/table/css/img/.svn/prop-base/table_blue.gif.svn-base similarity index 100% rename from WebContent/stat/js/ui/table/css/img/.svn/prop-base/table_blue.gif.svn-base rename to src/main/webapp/stat/js/ui/table/css/img/.svn/prop-base/table_blue.gif.svn-base diff --git a/WebContent/stat/js/ui/table/css/img/.svn/prop-base/table_bluegray.gif.svn-base b/src/main/webapp/stat/js/ui/table/css/img/.svn/prop-base/table_bluegray.gif.svn-base similarity index 100% rename from WebContent/stat/js/ui/table/css/img/.svn/prop-base/table_bluegray.gif.svn-base rename to src/main/webapp/stat/js/ui/table/css/img/.svn/prop-base/table_bluegray.gif.svn-base diff --git a/WebContent/stat/js/ui/table/css/img/.svn/text-base/cr.gif.svn-base b/src/main/webapp/stat/js/ui/table/css/img/.svn/text-base/cr.gif.svn-base similarity index 100% rename from WebContent/stat/js/ui/table/css/img/.svn/text-base/cr.gif.svn-base rename to src/main/webapp/stat/js/ui/table/css/img/.svn/text-base/cr.gif.svn-base diff --git a/WebContent/stat/js/ui/table/css/img/.svn/text-base/hscroll.gif.svn-base b/src/main/webapp/stat/js/ui/table/css/img/.svn/text-base/hscroll.gif.svn-base similarity index 100% rename from WebContent/stat/js/ui/table/css/img/.svn/text-base/hscroll.gif.svn-base rename to src/main/webapp/stat/js/ui/table/css/img/.svn/text-base/hscroll.gif.svn-base diff --git a/WebContent/stat/js/ui/table/css/img/.svn/text-base/hscroll_blue.gif.svn-base b/src/main/webapp/stat/js/ui/table/css/img/.svn/text-base/hscroll_blue.gif.svn-base similarity index 100% rename from WebContent/stat/js/ui/table/css/img/.svn/text-base/hscroll_blue.gif.svn-base rename to src/main/webapp/stat/js/ui/table/css/img/.svn/text-base/hscroll_blue.gif.svn-base diff --git a/WebContent/stat/js/ui/table/css/img/.svn/text-base/hscroll_bluegray.gif.svn-base b/src/main/webapp/stat/js/ui/table/css/img/.svn/text-base/hscroll_bluegray.gif.svn-base similarity index 100% rename from WebContent/stat/js/ui/table/css/img/.svn/text-base/hscroll_bluegray.gif.svn-base rename to src/main/webapp/stat/js/ui/table/css/img/.svn/text-base/hscroll_bluegray.gif.svn-base diff --git a/WebContent/stat/js/ui/table/css/img/.svn/text-base/loading.gif.svn-base b/src/main/webapp/stat/js/ui/table/css/img/.svn/text-base/loading.gif.svn-base similarity index 100% rename from WebContent/stat/js/ui/table/css/img/.svn/text-base/loading.gif.svn-base rename to src/main/webapp/stat/js/ui/table/css/img/.svn/text-base/loading.gif.svn-base diff --git a/WebContent/stat/js/ui/table/css/img/.svn/text-base/scroll.gif.svn-base b/src/main/webapp/stat/js/ui/table/css/img/.svn/text-base/scroll.gif.svn-base similarity index 100% rename from WebContent/stat/js/ui/table/css/img/.svn/text-base/scroll.gif.svn-base rename to src/main/webapp/stat/js/ui/table/css/img/.svn/text-base/scroll.gif.svn-base diff --git a/WebContent/stat/js/ui/table/css/img/.svn/text-base/scroll_blue.gif.svn-base b/src/main/webapp/stat/js/ui/table/css/img/.svn/text-base/scroll_blue.gif.svn-base similarity index 100% rename from WebContent/stat/js/ui/table/css/img/.svn/text-base/scroll_blue.gif.svn-base rename to src/main/webapp/stat/js/ui/table/css/img/.svn/text-base/scroll_blue.gif.svn-base diff --git a/WebContent/stat/js/ui/table/css/img/.svn/text-base/scroll_bluegray.gif.svn-base b/src/main/webapp/stat/js/ui/table/css/img/.svn/text-base/scroll_bluegray.gif.svn-base similarity index 100% rename from WebContent/stat/js/ui/table/css/img/.svn/text-base/scroll_bluegray.gif.svn-base rename to src/main/webapp/stat/js/ui/table/css/img/.svn/text-base/scroll_bluegray.gif.svn-base diff --git a/WebContent/stat/js/ui/table/css/img/.svn/text-base/table.gif.svn-base b/src/main/webapp/stat/js/ui/table/css/img/.svn/text-base/table.gif.svn-base similarity index 100% rename from WebContent/stat/js/ui/table/css/img/.svn/text-base/table.gif.svn-base rename to src/main/webapp/stat/js/ui/table/css/img/.svn/text-base/table.gif.svn-base diff --git a/WebContent/stat/js/ui/table/css/img/.svn/text-base/table_blue.gif.svn-base b/src/main/webapp/stat/js/ui/table/css/img/.svn/text-base/table_blue.gif.svn-base similarity index 100% rename from WebContent/stat/js/ui/table/css/img/.svn/text-base/table_blue.gif.svn-base rename to src/main/webapp/stat/js/ui/table/css/img/.svn/text-base/table_blue.gif.svn-base diff --git a/WebContent/stat/js/ui/table/css/img/.svn/text-base/table_bluegray.gif.svn-base b/src/main/webapp/stat/js/ui/table/css/img/.svn/text-base/table_bluegray.gif.svn-base similarity index 100% rename from WebContent/stat/js/ui/table/css/img/.svn/text-base/table_bluegray.gif.svn-base rename to src/main/webapp/stat/js/ui/table/css/img/.svn/text-base/table_bluegray.gif.svn-base diff --git a/WebContent/stat/js/ui/table/css/img/cr.gif b/src/main/webapp/stat/js/ui/table/css/img/cr.gif similarity index 100% rename from WebContent/stat/js/ui/table/css/img/cr.gif rename to src/main/webapp/stat/js/ui/table/css/img/cr.gif diff --git a/WebContent/stat/js/ui/table/css/img/hscroll.gif b/src/main/webapp/stat/js/ui/table/css/img/hscroll.gif similarity index 100% rename from WebContent/stat/js/ui/table/css/img/hscroll.gif rename to src/main/webapp/stat/js/ui/table/css/img/hscroll.gif diff --git a/WebContent/stat/js/ui/table/css/img/hscroll_blue.gif b/src/main/webapp/stat/js/ui/table/css/img/hscroll_blue.gif similarity index 100% rename from WebContent/stat/js/ui/table/css/img/hscroll_blue.gif rename to src/main/webapp/stat/js/ui/table/css/img/hscroll_blue.gif diff --git a/WebContent/stat/js/ui/table/css/img/hscroll_bluegray.gif b/src/main/webapp/stat/js/ui/table/css/img/hscroll_bluegray.gif similarity index 100% rename from WebContent/stat/js/ui/table/css/img/hscroll_bluegray.gif rename to src/main/webapp/stat/js/ui/table/css/img/hscroll_bluegray.gif diff --git a/WebContent/stat/js/ui/table/css/img/loading.gif b/src/main/webapp/stat/js/ui/table/css/img/loading.gif similarity index 100% rename from WebContent/stat/js/ui/table/css/img/loading.gif rename to src/main/webapp/stat/js/ui/table/css/img/loading.gif diff --git a/WebContent/stat/js/ui/table/css/img/scroll.gif b/src/main/webapp/stat/js/ui/table/css/img/scroll.gif similarity index 100% rename from WebContent/stat/js/ui/table/css/img/scroll.gif rename to src/main/webapp/stat/js/ui/table/css/img/scroll.gif diff --git a/WebContent/stat/js/ui/table/css/img/scroll_blue.gif b/src/main/webapp/stat/js/ui/table/css/img/scroll_blue.gif similarity index 100% rename from WebContent/stat/js/ui/table/css/img/scroll_blue.gif rename to src/main/webapp/stat/js/ui/table/css/img/scroll_blue.gif diff --git a/WebContent/stat/js/ui/table/css/img/scroll_bluegray.gif b/src/main/webapp/stat/js/ui/table/css/img/scroll_bluegray.gif similarity index 100% rename from WebContent/stat/js/ui/table/css/img/scroll_bluegray.gif rename to src/main/webapp/stat/js/ui/table/css/img/scroll_bluegray.gif diff --git a/WebContent/stat/js/ui/table/css/img/table.gif b/src/main/webapp/stat/js/ui/table/css/img/table.gif similarity index 100% rename from WebContent/stat/js/ui/table/css/img/table.gif rename to src/main/webapp/stat/js/ui/table/css/img/table.gif diff --git a/WebContent/stat/js/ui/table/css/img/table_blue.gif b/src/main/webapp/stat/js/ui/table/css/img/table_blue.gif similarity index 100% rename from WebContent/stat/js/ui/table/css/img/table_blue.gif rename to src/main/webapp/stat/js/ui/table/css/img/table_blue.gif diff --git a/WebContent/stat/js/ui/table/css/img/table_bluegray.gif b/src/main/webapp/stat/js/ui/table/css/img/table_bluegray.gif similarity index 100% rename from WebContent/stat/js/ui/table/css/img/table_bluegray.gif rename to src/main/webapp/stat/js/ui/table/css/img/table_bluegray.gif diff --git a/src/main/webapp/stat/js/ui/table/css/table.css b/src/main/webapp/stat/js/ui/table/css/table.css new file mode 100644 index 000000000..6e22dff4c --- /dev/null +++ b/src/main/webapp/stat/js/ui/table/css/table.css @@ -0,0 +1,600 @@ +/* FOR OPERA */ +div { + border: 0; +} + +.ec-ecom-table .ec-vscroll { + background: #F2F8EE; + width: 15px; + padding: 15px 0px 15px 0px; + font-size: 1px +} + +.ec-ecom-table .ec-hscroll { + background: #F2F8EE; + height: 15px; + padding: 0px 15px 0px 15px; + font-size: 1px +} + +.ec-ecom-table .ec-hscroll-block { + background: url("img/hscroll.gif") -2px -30px repeat-x; + border: 1px solid #76A258; + border-width: 0 1px +} + +.ec-ecom-table .ec-vscroll-block { + background: url("img/scroll.gif") 0px 0px repeat-y; + border: 1px solid #76A258; + border-width: 1px 0 +} + +.ec-ecom-table .ec-hscroll-block-over { + background: url("img/hscroll.gif") -0px -45px repeat-x +} + +.ec-ecom-table .ec-hscroll-block-press { + background: url("img/hscroll.gif") -0px -60px repeat-x +} + +.ec-ecom-table .ec-vscroll-block-over { + background: url("img/scroll.gif") -15px 0px repeat-y +} + +.ec-ecom-table .ec-vscroll-block-press { + background: url("img/scroll.gif") -30px 0px repeat-y +} + +.ec-ecom-table .ec-vscroll-prev { + background: url("img/scroll.gif") -45px -40px no-repeat; +} + +.ec-ecom-table .ec-vscroll-prev-over { + background: url("img/scroll.gif") -75px -40px no-repeat; +} + +.ec-ecom-table .ec-vscroll-prev-press { + background: url("img/scroll.gif") -60px -40px no-repeat; +} + +.ec-ecom-table .ec-vscroll-next { + background: url("img/scroll.gif") -45px -55px no-repeat; +} + +.ec-ecom-table .ec-vscroll-next-over { + background: url("img/scroll.gif") -75px -55px no-repeat; +} + +.ec-ecom-table .ec-vscroll-next-press { + background: url("img/scroll.gif") -60px -55px no-repeat; +} + +.ec-ecom-table .ec-hscroll-prev { + background: url("img/scroll.gif") -45px -85px no-repeat; +} + +.ec-ecom-table .ec-hscroll-prev-over { + background: url("img/scroll.gif") -75px -85px no-repeat; +} + +.ec-ecom-table .ec-hscroll-prev-press { + background: url("img/scroll.gif") -60px -85px no-repeat; +} + +.ec-ecom-table .ec-hscroll-next { + background: url("img/scroll.gif") -45px -70px no-repeat; +} + +.ec-ecom-table .ec-hscroll-next-over { + background: url("img/scroll.gif") -75px -70px no-repeat; +} + +.ec-ecom-table .ec-hscroll-next-press { + background: url("img/scroll.gif") -60px -70px no-repeat; +} + +.ec-ecom-table .vsblockdtr { + padding: 2px 0px +} + +.ec-ecom-table .vsblockdtr-top { + background: url("img/scroll.gif") -45px 0px no-repeat +} + +.ec-ecom-table .vsblockdtr-bottom { + background: url("img/scroll.gif") -45px -18px no-repeat +} + +.ec-ecom-table .vsblockdtr-over .vsblockdtr-top { + background: url("img/scroll.gif") -45px -20px no-repeat +} + +.ec-ecom-table .vsblockdtr-over .vsblockdtr-bottom { + background: url("img/scroll.gif") -45px -38px no-repeat +} + +.ec-ecom-table .vsblockdtr-press .vsblockdtr-top { + background: url("img/scroll.gif") -60px 0px no-repeat +} + +.ec-ecom-table .vsblockdtr-press .vsblockdtr-bottom { + background: url("img/scroll.gif") -60px -38px no-repeat +} + +.ec-ecom-table .ec-panel-disabled .vsblockdtr div { + display: none +} + +.ec-ecom-table .hsblockdtr { + padding: 0px 2px +} + +.ec-ecom-table .hsblockdtr-left { + background: url("img/hscroll.gif") -60px 0px no-repeat +} + +.ec-ecom-table .hsblockdtr-right { + background: url("img/hscroll.gif") -18px 0px no-repeat +} + +.ec-ecom-table .hsblockdtr-over .hsblockdtr-left { + background: url("img/hscroll.gif") -40px -0px no-repeat +} + +.ec-ecom-table .hsblockdtr-over .hsblockdtr-right { + background: url("img/hscroll.gif") -38px -0px no-repeat +} + +.ec-ecom-table .hsblockdtr-press .hsblockdtr-left { + background: url("img/hscroll.gif") -40px -15px no-repeat +} + +.ec-ecom-table .hsblockdtr-press .hsblockdtr-right { + background: url("img/hscroll.gif") -38px -15px no-repeat +} + +.ec-ecom-table .ec-panel-disabled .hsblockdtr div { + display: none +} + +.ec-ecom-table { + border: 1px solid #9CD167; + padding-top: 23px; + background-color: #DCEFD1 +} + +.ec-ecom-table .checkbox { + padding-left: 0px; + padding-right: 0px; +} + +.ec-ecom-table .checkbox-item { + padding-left: 0px; + padding-right: 0px; +} + +.ec-ecom-table .checkbox-disabled { + background: url(img/cr.gif) -68px 0px no-repeat; + width: 17px; + height: 17px;; + margin-right: 5px +} + +.ec-ecom-table table { + border-collapse: collapse; + border-spacing: 0px +} + +.ec-ecom-table-layout { + background: #FFF; + color: #333 +} + +.ec-ecom-table-head, .ec-print-table th { + font-weight: normal; + color: #326700; + padding: 6px 5px; + padding-right: 12px; + line-height: 15px; + border: 0; + border-left: 1px solid #CCE9B9; + border-bottom: 1px solid #9CD167; + overflow: hidden; + white-space: nowrap; + word-wrap: normal; + word-break: keep-all +} + +.ec-ecom-table-item, .ec-print-table td { + line-height: 15px; + border: 0; + padding: 5px 5px; + padding-right: 12px; + border-left: 1px solid #CCE9B9; + word-break: break-all; + white-space: normal; + word-wrap: break-word; + overflow: hidden +} + +.ec-ecom-table .od td { + background-color: #FFF; +} + +.ec-ecom-table .ev td { + background-color: #F2F8EE; +} + +.ec-ecom-table .od td.dk { + background-color: #EAF1E2; +} + +.ec-ecom-table .ev td.dk { + background-color: #DDE9D0; +} + +.ec-ecom-table-row-focus td.ec-ecom-table-item, +.ec-ecom-table-row-over td.ec-ecom-table-item, +.ec-ecom-table .ec-ecom-table-row-focus td.dk, +.ec-ecom-table .ec-ecom-table-row-over td.dk { + background-color: #FFFCE2 +} + +/* +.ec-ecom-table-row-over .ev .ec-ecom-table-item, +.ec-ecom-table-row-over .ev td.dk, +.ec-ecom-table-row-over .od .ec-ecom-table-item, +.ec-ecom-table-row-over .od td.dk, +.ec-ecom-table-row-focus .ev .ec-ecom-table-item, +.ec-ecom-table-row-focus .ev td.dk, +.ec-ecom-table-row-focus .od .ec-ecom-table-item, +.ec-ecom-table-row-focus .od td.dk, +.ec-ecom-table-row-focus .ec-ecom-table-item, +.ec-ecom-table-row-over .ec-ecom-table-item {background-color:#FFFCE2} +*/ +/*排序*/ +.ec-ecom-table-area .sort, .ec-ecom-table-area .sort-over, .ec-ecom-table-area .sort-focus { + text-align: left; + cursor: pointer; + background: url("img/table.gif") no-repeat 93% -33px; +} + +.ec-ecom-table-area .sort-over { + background-color: #F6FFB8; +} + +.ec-ecom-table-area .sort-up, .ec-ecom-table-area .sort-down { + cursor: pointer; /*text-align:right;*/ + background: #F6FFB8 url("img/table.gif") no-repeat 93% -33px; +} + +.ec-ecom-table-area .sort-up { + background-position: 93% -63px; +} + +.ec-ecom-table-area .sort-down { + background-position: 93% -93px; +} + +.ec-ecom-table-row .op { + text-align: center; + border: 0 none; + border-left: 1px solid #9CD167 +} + +/*复选框*/ +.ec-checkbox { + background: url("img/cr.gif") 0px 0px no-repeat; + width: 17px; + height: 15px +} + +.ec-checkbox-display { + background: url("img/cr.gif") -34px 0px no-repeat; +} + +.ec-checkbox-over { + background: url("img/cr.gif") -17px 0px no-repeat; +} + +.ec-checkbox-checked { + background: url("img/cr.gif") -34px 0px no-repeat +} + +.ec-checkbox-checked-over { + background: url("img/cr.gif") -51px 0px no-repeat +} + +.ec-checkbox-part { + background: url("img/cr.gif") -102px 0px no-repeat +} + +/*展开按钮(上)*/ +.ec-col-toggler, .ec-col-toggler-o { + width: 17px; + height: 20px; + position: absolute; + top: 2px; + right: 0; + background: #DCEFD1 url("img/table.gif") no-repeat 0px 0px; + cursor: pointer; +} + +.ec-col-toggler-o { + background-position: -22px 0px +} + +/*展开按钮(下)*/ +.ec-v-toggler { + width: 15px; + background: #DDE9D0; + position: absolute; + right: 0; + bottom: 0; + _right: -1px; + cursor: pointer; + border-left: 1px solid #9CD167; /*border-right:1px solid #9CD167;*/ +} + +.ec-v-toggler div { + width: 9px; + height: 10px; + overflow: hidden; + background: url("img/table.gif") no-repeat -8px -22px; + position: absolute; + right: 3px; + bottom: 50%; + _padding-top: 50%; + cursor: pointer; +} + +.ec-v-toggler-over { + background-color: #EAF1E2 +} + +/*验证*/ +.valid-error td.ec-ecom-table-item { + background-color: pink !important; +} + +/* *分页 *囧, 有同名的list宏,需转义 */ +.ec-page a, .ec-page b { + margin: 0; + text-indent: 0; + display: inline-block; + *display: inline; + zoom: 1; + height: 20px; + line-height: 20px; + background: url("img/table.gif") repeat-x 0 -150px; + border: 1px solid #9CD167; + padding: 0 3px; + text-decoration: none; + color: #326700; +} + +.ec-page a:hover { + background-position: 0 -176px; +} + +.ec-page .page-n { + /*width:20px;*/ + text-align: center; /*padding:0;*/ + padding: 0 5px; +} + +.ec-page b { + background-image: none; + color: #666; + background-color: #EEE; + font-weight: normal; +} + +.ec-page b.page-n { + background-image: none; + background-color: #FFF; + color: #000; + font-weight: bold; +} + +.ec-page { + color: #326700; + margin-top: 10px +} + +.ec-page em { + font-style: normal; + color: #000; + padding: 0 3px; +} + +.target-page { + width: 25px; +} + +/* 弹出菜单 */ +.ec-popup { + background-color: #DCEFD1; + border: 1px solid #9CD167; + border-width: 1px 1px 0 1px; + width: 70px; +} + +.ec-popup-item { + background-color: #DCEFD1; /* width:70px; */ + height: 25px; + line-height: 25px; + border-bottom: 1px solid #9CD167; + padding-left: 24px; + cursor: pointer; + vertical-align: bottom; + position: relative; +} + +.ec-popup-item-over { + background-color: #FFFCE2; +} + +.ec-popup-item .ec-checkbox { + /*float:left;*/ + /*margin:4px 4px 0 4px;*/ + position: absolute; + top: 4px; + left: 4px; + border: 0 none; /*text-indent: 14px;*/ +} + +.cb-ctnr { + background: #DCEFD1 url("img/table.gif") 0 -200px; + height: 14px; + margin: 0; + border: 0 none; + width: 15px; + position: absolute; + top: 7px; + cursor: pointer; +} + +/* 提示信息显示 */ +.tb-msg { + visibility: hidden; + margin: 0 0 4px 0; +} + +.tb-msg .tb-msg-txt { + background: #FFFCE2; + color: #D2691E; + font-weight: bold; + padding: 0 4px; + display: inline-block; + *display: inline; + zoom: 1; + height: 20px; + line-height: 20px; +} + +.tb-msg .clo-btn { + font-weight: normal; + margin: 0 0 0 14px; + cursor: pointer; +} + +/* 二次屏蔽的提示框 */ +.ectable-modal-tip { + background: #FFF; + position: absolute; + width: 200px; + height: 50px; + border: 2px solid #CCC +} + +.ectable-modal-tip-title { + position: absolute; + height: 20px; + line-height: 20px; + text-indent: 5px; + margin: 0; + display: block; + top: 0; + left: 0; + background: #CCC; + width: 100% +} + +.ectable-modal-tip-cont { + padding: 25px 5px 5px 25px; + background: transparent url(img/loading.gif) no-repeat scroll 5px 25px +} + +/* 打印 */ +@media screen { + .ec-print-table { + border: 1px solid #9CD167; + border-width: 1px; + border-collapse: collapse; + background-color: #DCEFD1 + } + + .ec-print-table th, .ec-print-table td { + border: 1px solid #9CD167; + border-width: 0 0 1px 1px; + } + + .ec-print-table td { + background-color: #FFF; + } +} + +@media print { + body { + font-family: "微软雅黑", "黑体"; + font-size: 10px; + } + + .strik-info { + color: #000; + } + + .noprint, .nav { + display: none; + } + + .area-v, .area-w { + display: none; + } + + .area { + border: 1px solid #ddd; + margin-top: 6px; + background: #fff; + } + + .mess-query .area-inner { + background: none; + border: 0; + } + + .mess-query .area { + border: 0; + } + + .area h5 { + border: 0; + } + + .area h5 b { + background: none; + border: 0; + color: #000; + } + + .old td { + background: #ddd; + } + + .ec-print-table { + border: 1px solid #666; + border-width: 1px 0 1px 1px; + border-collapse: collapse + } + + .ec-print-table th { + padding: 2px; + text-align: center; + border-right: 1px solid #666; + border-color: #666 + } + + .ec-print-table td { + padding: 2px 6px; + border: 1px solid #666; + border-width: 1px 1px 0 0; + border-color: #666 + } + + * { + word-wrap: break-word; + word-break: break-all; + } +} + diff --git a/WebContent/stat/js/ui/table/js/.svn/all-wcprops b/src/main/webapp/stat/js/ui/table/js/.svn/all-wcprops similarity index 100% rename from WebContent/stat/js/ui/table/js/.svn/all-wcprops rename to src/main/webapp/stat/js/ui/table/js/.svn/all-wcprops diff --git a/WebContent/stat/js/ui/table/js/.svn/entries b/src/main/webapp/stat/js/ui/table/js/.svn/entries similarity index 100% rename from WebContent/stat/js/ui/table/js/.svn/entries rename to src/main/webapp/stat/js/ui/table/js/.svn/entries diff --git a/WebContent/stat/js/ui/table/js/.svn/text-base/ecomui.table.js.svn-base b/src/main/webapp/stat/js/ui/table/js/.svn/text-base/ecomui.table.js.svn-base similarity index 100% rename from WebContent/stat/js/ui/table/js/.svn/text-base/ecomui.table.js.svn-base rename to src/main/webapp/stat/js/ui/table/js/.svn/text-base/ecomui.table.js.svn-base diff --git a/src/main/webapp/stat/js/ui/table/js/ecomui.table.js b/src/main/webapp/stat/js/ui/table/js/ecomui.table.js new file mode 100644 index 000000000..1ac6cc02a --- /dev/null +++ b/src/main/webapp/stat/js/ui/table/js/ecomui.table.js @@ -0,0 +1,571 @@ +var ecomui = ecomui || {}; + +// IE 6 背景图片缓存 +try { + document.execCommand("BackgroundImageCache", false, true); +} catch (e) { +} + +(function () { + var lib = baidu, + core = ecui, + dom = core.dom, + ui = core.ui, + util = core.util, + inherits = util.inherits, + copy = util.copy, + toNumber = util.toNumber, + get = core.get, + query = core.query, + setStyles = lib.dom.setStyles, + getPosition = dom.getPosition, + calcHeightRevise = core.calcHeightRevise, + + DOCUMENT = document, + UI_TABLE = ui.LockedTable, + UI_TABLE_CLASS = UI_TABLE.prototype, + UI_CONTROL = ui.Control, + ECOM_TABLE_CLASS; + + ecomui.Table = ui.EcomTable = function (el, params) { + /* + * 计算表格宽度 + */ + var tbEl = el.getElementsByTagName("table")[0]; + if (!tbEl.style.width) { + var colEls = tbEl.rows[0].cells; + var tbOldWidth = tbEl.offsetWidth; + var tbWidth = 0; + + for (var i = 0, len = colEls.length; i < len; i++) { + var o = colEls[i].style.width; + tbWidth += (o !== undefined) ? + (/px$/.test(o) ? parseInt(o, 10) : tbOldWidth * (parseFloat(o) / 100)) : + 130; + } + tbEl.style.width = Math.max(el.offsetWidth * 0.99, tbWidth) + "px"; + } + + //隐藏待渲染的表格, 在vm里定义visibility=hidden + //渲染表格 + UI_TABLE.call(this, el, params); + + //显示渲染好的表格 + this.getOuter().style.visibility = "visible"; + + //记录表格索引 + this._nTbId = params.tbid; + + //是否有选择整列表按钮 + this._bCustom = params.custom; + + var colToggler, verticalBar, showOpColumn, colCount; + + showOpColumn = params.rightLock; + + //如果有操作列 + if (showOpColumn) { + //初始操作列是展开的 + this._bOpColumnUnfolded = true; + + var base = this.getBase(); + + //记住操作列和前一列 + //TODO 倒数第二列不能作为部件, 因为不是表格不可缺少的 + //在使用时取一下 + //colCount = this._aCol.length - 1; + //this._uOpColumn = this.getCol(colCount); + + //收缩按钮 + var el = DOCUMENT.createElement("div"); + el.className = "ec-col-toggler"; + base.appendChild(el); + colToggler = this._uColToggler + = core.$fastCreate( + UI_CONTROL, + el, + this, + {} + ); + + //竖条 + var el = DOCUMENT.createElement("div"); + el.innerHTML = "
    "; + el.className = "ec-v-toggler"; + base.appendChild(el); + verticalBar = this._uVerticalBar + = core.$fastCreate( + UI_CONTROL, + el, + this, + {} + ); + verticalBar.hide(); + + //如果有纵向滚动条, 调整收缩按钮的位置 + //FIXME 此时VScroll总是有的 + var vScroll = this.$getSection("VScroll"); + colToggler.getOuter().style.right = 2 + + ((vScroll && vScroll.isShow()) ? vScroll.getWidth() : 0) + "px"; + //绑定事件 + colToggler.onclick = colTogglerClick; + verticalBar.onclick = vBarClick; + verticalBar.show = vBarShow; + + } + + //浮动表头 + if (params.floatthead) { + var self = this; + self._bFloatThead = true; + lib.event.on(window, "scroll", function () { + floatThead(self); + }); + } + + + }; + + ECOM_TABLE_CLASS = inherits(ui.EcomTable, UI_TABLE); + + /* + * 此处获得操作列 + */ + ECOM_TABLE_CLASS.$init = function () { + UI_TABLE_CLASS.$init.call(this); + if (this._nRightLock) { + this._uOpColumn = this.getCol(this._aCol.length - 1); + } + + //整列表选择按钮 + if (this._bCustom) { + var customBtn = core.get("cbCtnr_" + this._nTbId); + customBtn && initCustomBtn(customBtn, this); + } + }; + + /** + * 展开/收起按钮点击 + * @private + */ + function colTogglerClick() { + //this为按钮 + var table = this.getParent(), + vBar = table.$getSection("VerticalBar"); + + if (table._bOpColumnUnfolded) { + //收起操作列 + foldOpColumn(table); + vBar.show(); + this.alterClass("o"); + } else { + //展开操作列 + unfoldOpColumn(table); + vBar.hide(); + this.alterClass("o", true); + } + } + + /** + * 竖条点击 + * @private + */ + function vBarClick() { + //this 为竖条 + var table = this.getParent(); + + //展开操作列 + unfoldOpColumn(table); + + this.hide(); + } + + /** + * 收起操作列 + * @private + */ + function foldOpColumn(table) { + var tableWidth = table.getWidth(), + tableBodyWidth = table.getBody().offsetWidth; + + table._uOpColumn.hide(); + + //设置倒数第二列的宽度 + var col = table.getCol(table.getCols().length - 2); + col.setSize(col.getWidth() + table._uOpColumn.getWidth()); + + table._bOpColumnUnfolded = false; + }; + + /** + * 展开操作列 + * @private + */ + function unfoldOpColumn(table) { + var prevCol = getSndLastCol(table); + + //恢复倒数第二列恢复原来的宽度 + var col = table.getCol(table.getCols().length - 2); + col.setSize(col.getWidth() - table._uOpColumn.getWidth()); + + table._uOpColumn.show(); + + + table._bOpColumnUnfolded = true; + }; + + /** + * 获得倒数第二列 + * @private + */ + function getSndLastCol(table) { + var colCount = table._aCol.length - 1, + ret; + while (colCount--) { + ret = table.getCol(colCount); + if (ret.isShow()) { + break; + } + } + return ret; + } + + /** + * 展开/收缩操作列时设置表格宽度 + * @private + */ + function setTableWidth(table, tableWidth, tableBodyWidth) { + var oldWidth = table._nOldWidth = table.getWidth(); + if (tableWidth > tableBodyWidth) { + table.setSize(oldWidth + table) + } + } + + /** + * 显示竖条 + * @private + */ + function vBarShow() { + UI_CONTROL.prototype.show.call(this); + setVBarPosition(this); + setVBarHeight(this); + } + + /** + * 设置竖条定位 + * @private + */ + function setVBarPosition(vBar) { + var table = vBar.getParent(), + vBarWidth = vBar.getWidth(), + vs = table.$getSection("VScroll"), + style = table.getBase().style, + contentWidth = table.getWidth() + - (toNumber(style.borderLeftWidth) + toNumber(style.borderRightWidth)); + + vBar.getOuter().style.left = contentWidth - vBarWidth + - ((vs && vs.isShow()) ? vs.getWidth() : 0) + + "px"; + } + + + /** + * 在竖条显示时设置其高度 + * @private + */ + function setVBarHeight(vBar) { + var table = vBar.getParent(), + hs = table.$getSection("HScroll"), + th = table.$getSection("Head"), + hscrValue; + + if (hs && hs.isShow()) {//存在水平滚动条 + hs.setValue(hs.getTotal()); + hscrValue = hs.isShow() ? hs.getHeight() : 0; + } + else { + hscrValue = 0; + } + + //TODO -2 用 sumStyle算边框值 + vBar.setSize(0, table.getHeight() - th.getHeight() - 2 - hscrValue); + var style = vBar.getOuter().style; + style.bottom = hscrValue + "px"; + } + + /** + * 表头随浏览器滚动条锁定 + * @private + */ + function floatThead(t) { + var headEl = t._uHead.getOuter(), + lockedHeadEl = t._uLockedHead.getOuter(), + lockedMainEl = t._uLockedMain.getOuter(); + + if (t._uColToggler) { + var colTogglerEl = t._uColToggler.getOuter(); + } + + var outer = t.getOuter(); + + var scrollTop = DOCUMENT.body.scrollTop || DOCUMENT.documentElement.scrollTop, + pos = getPosition(outer), + top = pos.top + 1, + left = pos.left; + + var headHeight = headEl.offsetHeight + calcHeightRevise(headEl), + tbHeightDelta = t.getHeight() - headHeight, + relativeTop = scrollTop - top; + + var floatStyles = { + position: "absolute", + top: relativeTop + "px", + zIndex: 999 + }; + + if (scrollTop + && relativeTop > 0 + && relativeTop < tbHeightDelta) { + setStyles(headEl, floatStyles); + setStyles(lockedHeadEl, floatStyles); + setStyles(lockedMainEl, {top: headHeight + "px"}); + + //TODO 此处性能优化 + //ecui 1.1.0 fix + setStyles(lockedHeadEl, {width: lockedHeadEl.getElementsByTagName("table")[0].style.width}); + + if (colTogglerEl) { + setStyles(colTogglerEl, {top: 2 + relativeTop + "px", zIndex: 999}); + } + } + + else { + setStyles(headEl, {top: 0, zIndex: 0}); + setStyles(lockedHeadEl, {position: "static", zIndex: 0}); + setStyles(lockedMainEl, {top: ""}); + + if (colTogglerEl) { + setStyles(colTogglerEl, {top: "", zIndex: 0}); + } + } + }; + + /** + * 初始化整列表选择按钮 + */ + function initCustomBtn(customBtn, table) { + var tbId = table._nTbId; + + var popup = core.get("cbPop_" + tbId), + popupItems = core.query({"parent": popup}), + popupItemsLen = popupItems.length; + + var cbCurList = core.get("cball_" + tbId), + cbWholeList = core.get("cbsall_" + tbId), + cbCurInferiors = cbCurList.getInferiors(); + + DOCUMENT.body.appendChild(popup.getOuter()); + + customBtn.onclick = function () { + var containerOuter = this.getOuter(); + containerPos = getPosition(containerOuter); + + popup.setPosition( + containerPos.left + this.getBodyWidth(), + containerPos.top + ); + + popup.show(); + }; + + cbWholeList.onclick = (function () { + var checked = false; + return function () { + var i = cbCurInferiors.length, + msg = [ + "已选择整列表, 子项目不能取消选择", + "已取消选择整列表" + ]; + + var msgBox = table.setMsg((!checked) ? msg[0] : msg[1]); + + msgBox.parentNode.parentNode.style.visibility = "visible"; + + var hcbsall = lib.dom.g("hcbsall_" + tbId); + while (i--) { + cbCurInferiors[i].setChecked(!checked); + cbCurList.setEnabled(checked); + cbCurInferiors[i].setEnabled(checked); + hcbsall.value = checked ? 0 : 1; + } + + checked = !checked; + } + })(); + + while (popupItemsLen--) { + popupItems[popupItemsLen].onclick = function () { + var cb = core.query({"parent": this})[0]; + cb.click(); + }; + } + } + + /** + * 改写$resize方法 + */ + ECOM_TABLE_CLASS.$resize = function () { + UI_TABLE_CLASS.$resize.call(this); + + //如果存在竖条并且竖条显示, 重设其高度 + var vBar = this._uVerticalBar; + if (vBar && vBar.isShow()) { + setVBarHeight(vBar); + setVBarPosition(vBar); + } + + //修正浮动表头的位置 + if (this._bFloatThead) { + floatThead(this); + } + }; + + /** + * 找出table中被选中行 + * @public + * + * @return {Array} 被选中行 + */ + ECOM_TABLE_CLASS.getChecked = function () { + var ret = []; + try { + var col = this.getCol(0), + cbs = core.get("cball_" + this._nTbId), + cbs = (cbs instanceof core.ui.Checkbox) ? cbs : core.query({"parent": cbs})[0], + cbs = cbs.getInferiors(), + i = cbs.length; + + while (i--) { + if (cbs[i].isChecked()) { + ret.push(cbs[i].getParent()); + } + } + } catch (e) { + } + return ret; + }; + + /** + * 找出table中被选中行个数 + * @public + * + * @return {Number} 被选中行的个数 + */ + ECOM_TABLE_CLASS.getCheckedCount = function () { + return this.getChecked().length; + }; + + /** + * 设置消息 + * @public + * + * @return {HTMLElement} 消息div元素 + */ + ECOM_TABLE_CLASS.setMsg = function (msg) { + var msgBox = lib.dom.g("tbMsg_" + this._nTbId); + dom.setText(msgBox, msg); + return msgBox; + }; +})(); + +/* + * 排序 + */ +var defaultSort = (function () { + // 屏蔽二次点击标志 + var dbClickFlag = false; + + return function () { + if (!dbClickFlag) { + window.sortClick(this.getBase().getAttribute('sort')); + dbClickFlag = true; + } + else { + ecTable.showModal("正在排序, 请稍候..."); + } + } +})(); + +/** + * 为兼容以前版本加的补丁 + */ +var ecTable = { + getChecked: function (table) { + return ecomui.Table.prototype.getChecked.call(table, table); + }, + getCheckedCount: function (table) { + return ecomui.Table.prototype.getCheckedCount.call(table, table); + } +}; + +ecui.getChildren = function (control) { + return ecui.query({parent: control}); +}; + +/** + * 整体遮罩, 用于屏蔽二次点击 + */ +var ecTable = ecTable || {}; + +ecTable.showModalTip = function (text) { + var modalCtrl = baidu.dom.g("ecTableModalTip"); + modalCtrl = modalCtrl && modalCtrl.getControl(); + + // 创建提示信息窗体 + if (!modalCtrl) { + modalCtrl = document.createElement("div"); + modalCtrl.id = "ecTableModalTip" + modalCtrl.className = "ectable-modal-tip"; + modalCtrl.style.visibility = "hidden"; + modalCtrl.innerHTML = [ + '', + '
    ' + ].join(""); + document.body.appendChild(modalCtrl); + + modalCtrl = ecui.$fastCreate( + ecui.ui.Form, + modalCtrl, + null, + {hide: true} + ); + } + + // 给窗体设置文字并显示 + var contEl = modalCtrl.getBody().getElementsByTagName("div")[0]; + ecui.dom.setText(contEl, text); + modalCtrl.getOuter().style.zIndex = 32768; + + + // 窗体居中 + var viewWidth = baidu.page.getViewWidth(), + viewHeight = baidu.page.getViewHeight(), + width = modalCtrl.getWidth(), + height = modalCtrl.getHeight(); + + baidu.setStyles(modalCtrl.getOuter(), { + position: "absolute", + left: Math.max(viewWidth - width, 0) / 2, + top: Math.max(viewHeight - height, 0) / 2 + }); + + modalCtrl.getOuter().style.visibility = ""; + ecui.mask(0.03); + + // 五秒没反应显示刷新链接 + setTimeout(function () { + contEl.innerHTML = '好像没响应? 请刷新'; + }, 5000); + +}; + diff --git a/src/main/webapp/stat/js/ui/table/js/table.js b/src/main/webapp/stat/js/ui/table/js/table.js new file mode 100644 index 000000000..fe35a7fac --- /dev/null +++ b/src/main/webapp/stat/js/ui/table/js/table.js @@ -0,0 +1,323 @@ +/** + *@file support_table.js + *@description 支持模块使用ecui实现的列表 + * + * 修改记录 + * 2010.01.07 加入当前页或者整列表的选择(样式) + */ + +/* + * IE 6 背景图片缓存 + */ +try { + document.execCommand("BackgroundImageCache", false, true); +} catch (e) { +} + +/* + *滚动条装饰器 + */ +ecui.ui.VScroll.prototype.$create = function () { + var me = this, + block = this.$getSection('Block'); + new ecui.ext.TBDecorator(block, 'vsblockdtr'); + ecui.ui.Control.prototype.$create.call(this); +}; + +ecui.ui.HScroll.prototype.$create = function () { + var block = this.$getSection('Block'); + new ecui.ext.LRDecorator(block, 'hsblockdtr'); + ecui.ui.Control.prototype.$create.call(this); +}; + + +function initEcuiTable(table) { + var t = table || ecui.get(table), + vs = t.$getSection('VScroll'), + hs = t.$getSection('HScroll'), + th = t.$getSection('Head'), + cCount = t._aCol.length - 1, + col = t.getCol(cCount), + prevCol = t.getCol(cCount - 1); + + //此时重绘,防止火狐下高度异常 + //t.paint(); + + /* + * 展开/收起按钮 + */ + //TODO 判断是否含有操作列 + if (col.getBase().parentNode != prevCol.getBase().parentNode) { + //收缩按钮 + var ct = ecui.create('Control', { + type: 'ec-col-toggler', + parent: t.getBase() + }), + + //竖条 + h = ecui.create('Control', { + type: 'ec-v-toggler', + parent: t.getBase() + }), + + cw = col.getWidth(), + pw = prevCol.getWidth(), + hscrValue; + + h.getBody().innerHTML = '
    ' + h.hide(); + h.onclick = function () { + ct.click(); + }; + + ct.onclick = function () { + toggleStatus(this); + vs && vs.paint(); + //col.paint(); + }; + ct.onpaint = function () { + setHbarHeight(h); + //alert("paint col toggler") + } + + //根据是否有滚动条设置按钮位置 + if (vs && vs.isShow()) { + ct.getBase().style.right = vs.getWidth() + "px"; + } + /* + * 设置竖条高度 + */ + var setHbarHeight = function (hbar) { + if (hs) {//存在水平滚动条 + hs.setValue(hs.getTotal()); + hscrValue = hs.isShow() ? hs.getHeight() : 0; + } + else { + hscrValue = 0; + } + hbar.setSize(undefined, t.getHeight() - th.getHeight() - 2 - hscrValue); + var style = hbar.getOuter().style; + if (vs && vs.isShow()) style.right = vs.getWidth() + "px"; + style.bottom = hscrValue + "px"; + } + + /* + * 点击'收起按钮'的回调函数 + */ + var toggleStatus = function (ct) { + + //hack:避免第一次隐藏列后对不齐 + prevCol.setSize(pw); + + if (col.isShow()) { + _autoSize(t, prevCol, pw); + ct.alterClass('o'); + col.hide(); + setHbarHeight(h); + h.show(); + } else { + prevCol.setSize(pw); + ct.alterClass('o', true); + //console.log(hscrValue); + col.show(); + h.hide(); + hs && hs.setValue(hs.getTotal()); + } + + col.paint(); + }; + + /* + * 表格列自适应宽度 + */ + var _autoSize = function (t, c, ow) { + var tw = t.getWidth(), + tcw = t.getBody().offsetWidth; + if (tw > tcw) { + c.setSize(tw - tcw + ow); + } + }; + } + + /* + * 垂直滚动条高度 + + if (vs) { + _setVSHeight = function(vs) { + vs.setSize(undefined, vs.getHeight() - th.getHeight()); + vs.getBase().style.top = ""; + vs.getBase().style.bottom = vs.getWidth() + "px"; + } + vs.onpaint = function() { + this.$paint(); + _setVSHeight(this); + document.body.className = document.body.className; + return false; + } + _setVSHeight(vs); + } + */ + + /* + * 排序-记录水平位置 + + var ectable_xpos = baidu.cookie.getRaw('ectable_xpos'); + if (ectable_xpos) { + hs.setValue(ectable_xpos); + baidu.cookie.remove('ectable_xpos'); + } + */ + + /* + * 排序 + */ + var defaultSort = function () { + window.sortClick(this.getBase().getAttribute('sort')); + baidu.cookie.setRaw('ectable_xpos', hs.getValue()); + }; + + for (var i = 0, cCount = t._aCol.length; i < cCount; i++) { + var col = t.getCol(i); + if (col.getBase().className.match(/\s*sort\s*/)) { + col.onclick = defaultSort; + } + } + + //hack for ie 8 + //document.body.className = document.body.className; + + + /* + * custom checkbox处理 + */ + + var popupContainer = ecui.query({"parent": t.getCol(0)})[0]; + + if (popupContainer) { + var ctrlIdx = popupContainer.getBase().id + .replace(/^s+|s+$/, '') + .match(/cbCtnr_([0-9a-zA-Z_]+)/)[1], + //弹出菜单容器和弹出菜单 + popup = document.getElementById('cbPop_' + ctrlIdx).getControl(), + popupItems = ecui.query({"parent": popup}), + popupItemsLen = popupItems.length, + + //checkbox 控件 + cbCurList = document.getElementById("cbCurList").getControl(), + cbWholeList = document.getElementById("cbWholeList").getControl(), + cbCurInferiors = cbCurList.getInferiors(); + //msgBox = document.getElementById('tbMsg_' + ctrlIdx); + + + popupContainer.onclick = function () { + var containerOuter = this.getOuter(); + containerPos = ecui.dom.getPosition(containerOuter); + + popup.setPosition(containerPos.left + this.getBodyWidth(), containerPos.top); + + popup.show(); + }; + + cbWholeList.onclick = (function () { + var checked = false; + return function () { + //console.log("xx"); + var i = cbCurInferiors.length, + msg = [ + "已选择整列表, 子项目不能取消选择", + "已取消选择整列表" + ]; + + var msgBox = ecTable.setMsg(t, (!checked) ? msg[0] : msg[1]); + msgBox.style.visibility = "visible"; + + while (i--) { + cbCurInferiors[i].setChecked(!checked); + cbCurList.setEnabled(checked); + cbCurInferiors[i].setEnabled(checked); + } + + checked = !checked; + } + })(); + + while (popupItemsLen--) { + popupItems[popupItemsLen].onclick = function () { + var cb = ecui.query({"parent": this})[0]; + cb.click(); + }; + } + + } +} +var ecTable = { + /** + * 给表格的消息框设置 + * @param {ecTable} table + * @param {String} msg + * @return {String} 消息框 + */ + setMsg: function (table, msg) { + var msgBox = table.getBase(), + first = ecui.dom.first; + + do { + msgBox = msgBox.previousSibling; + } while (msgBox.nodeType != 1) + + first(first(msgBox)).innerHTML = msg; + return msgBox; + }, + + /** + *找出table中被选中条目 + *@param {ecTable} table + *@return {Array} 被选中行 + */ + getChecked: function (table) { + var col = table.getCol(0), + cbs = ecui.query({"parent": col})[0], + cbs = (cbs instanceof ecui.ui.Checkbox) ? cbs : ecui.query({"parent": cbs})[0], + cbs = cbs.getInferiors(), + i = cbs.length, + ret = []; + + while (i--) { + if (cbs[i].isChecked()) { + ret.push(cbs[i].getParent()); + } + } + + return ret; + }, + /** + *获得table中有选中条目个数 + *@param {EcTable} table + *@return {Number} 选中条目个数 + */ + getCheckedCount: function (table) { + return ecTable.getChecked(table).length; + }, + + /** + * 获得当前页面所有table + * @return 包含所有table的数组 + */ + getTables: function () { + return ecui.query({"type": ecui.ui.Table}); + }, + + /** + *初始化当前页所有列表 + */ + init: function () { + var tables = ecTable.getTables(), + len = tables.length; + + while (len--) { + initEcuiTable(tables[len]); + } + } +}; + +ecui.dom.ready(ecTable.init); diff --git a/WebContent/stat/js/ui/wick/css/wick.css b/src/main/webapp/stat/js/ui/wick/css/wick.css similarity index 80% rename from WebContent/stat/js/ui/wick/css/wick.css rename to src/main/webapp/stat/js/ui/wick/css/wick.css index 97315c382..ca456051a 100644 --- a/WebContent/stat/js/ui/wick/css/wick.css +++ b/src/main/webapp/stat/js/ui/wick/css/wick.css @@ -14,35 +14,40 @@ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND */ .wickFloater { -position:absolute; -z-index:2; -display:none; -padding:0; + position: absolute; + z-index: 2; + display: none; + padding: 0; } .wickFloater td { -background-color:white; -border:1px inset #979797; -color:black; + background-color: white; + border: 1px inset #979797; + color: black; } .matchedSmartInputItem { -font-size:12px; -padding: 5px 10px 1px 5px; -margin:0; -cursor:pointer; + font-size: 12px; + padding: 5px 10px 1px 5px; + margin: 0; + cursor: pointer; } .selectedSmartInputItem { -color:white; -background-color:#3875D7; + color: white; + background-color: #3875D7; } #smartInputResults { -padding:0;margin:0; + padding: 0; + margin: 0; } .siwCredit { -margin:0;padding:0;margin-top:10px;font-size:12px;color:black; + margin: 0; + padding: 0; + margin-top: 10px; + font-size: 12px; + color: black; } diff --git a/src/main/webapp/stat/js/ui/wick/js/wick.js b/src/main/webapp/stat/js/ui/wick/js/wick.js new file mode 100644 index 000000000..d164cf5ae --- /dev/null +++ b/src/main/webapp/stat/js/ui/wick/js/wick.js @@ -0,0 +1,482 @@ +function freezeEvent(e) { + if (e.preventDefault) e.preventDefault(); + e.returnValue = false; + e.cancelBubble = true; + if (e.stopPropagation) e.stopPropagation(); + return false; +}//freezeEvent + +function isWithinNode(e, i, c, t, obj) { + answer = false; + te = e; + while (te && !answer) { + if ((te.id && (te.id == i)) || (te.className && (te.className == i + "Class")) + || (!t && c && te.className && (te.className == c)) + || (!t && c && te.className && (te.className.indexOf(c) != -1)) + || (t && te.tagName && (te.tagName.toLowerCase() == t)) + || (obj && (te == obj)) + ) { + answer = te; + } else { + te = te.parentNode; + } + } + return te; +}//isWithinNode + +function getEvent(event) { + return (event ? event : window.event); +}//getEvent() + +function getEventElement(e) { + return (e.srcElement ? e.srcElement : (e.target ? e.target : e.currentTarget)); +}//getEventElement() + +function findElementPosX(obj) { + curleft = 0; + if (obj.offsetParent) { + while (obj.offsetParent) { + curleft += obj.offsetLeft; + obj = obj.offsetParent; + } + }//if offsetParent exists + else if (obj.x) + curleft += obj.x + return curleft; +}//findElementPosX + +function findElementPosY(obj) { + curtop = 0; + if (obj.offsetParent) { + while (obj.offsetParent) { + curtop += obj.offsetTop; + obj = obj.offsetParent; + } + }//if offsetParent exists + else if (obj.y) + curtop += obj.y + return curtop; +}//findElementPosY + +/* end dhtml building blocks */ + +function handleKeyPress(event) { + e = getEvent(event); + eL = getEventElement(e); + + upEl = isWithinNode(eL, null, "wickEnabled", null, null); + + kc = e["keyCode"]; + + if (siw && ((kc == 13) || (kc == 9))) { + siw.selectingSomething = true; + if (siw.isSafari) siw.inputBox.blur(); //hack to "wake up" safari + siw.inputBox.focus(); + siw.inputBox.value = siw.inputBox.value.replace(/[ \r\n\t\f\s]+$/gi, ' '); + hideSmartInputFloater(); + } else if (upEl && (kc != 38) && (kc != 40) && (kc != 37) && (kc != 39) && (kc != 13) && (kc != 27)) { + if (!siw || (siw && !siw.selectingSomething)) { + processSmartInput(upEl); + } + } else if (siw && siw.inputBox) { + siw.inputBox.focus(); //kinda part of the hack. + } + +}//handleKeyPress() + + +function handleKeyDown(event) { + e = getEvent(event); + eL = getEventElement(e); + + if (siw && (kc = e["keyCode"])) { + if (kc == 40) { + siw.selectingSomething = true; + freezeEvent(e); + if (siw.isGecko) siw.inputBox.blur(); + /* Gecko hack */ + selectNextSmartInputMatchItem(); + } else if (kc == 38) { + siw.selectingSomething = true; + freezeEvent(e); + if (siw.isGecko) siw.inputBox.blur(); + selectPreviousSmartInputMatchItem(); + } else if ((kc == 13) || (kc == 9)) { + siw.selectingSomething = true; + activateCurrentSmartInputMatch(); + freezeEvent(e); + } else if (kc == 27) { + hideSmartInputFloater(); + freezeEvent(e); + } else { + siw.selectingSomething = false; + } + } + +}//handleKeyDown() + +function handleFocus(event) { + e = getEvent(event); + eL = getEventElement(e); + if (focEl = isWithinNode(eL, null, "wickEnabled", null, null)) { + if (!siw || (siw && !siw.selectingSomething)) processSmartInput(focEl); + } +}//handleFocus() + +function handleBlur(event) { + e = getEvent(event); + eL = getEventElement(e); + if (blurEl = isWithinNode(eL, null, "wickEnabled", null, null)) { + if (siw && !siw.selectingSomething) hideSmartInputFloater(); + } +}//handleBlur() + +function handleClick(event) { + e2 = getEvent(event); + eL2 = getEventElement(e2); + if (siw && siw.selectingSomething) { + selectFromMouseClick(); + } +}//handleClick() + +function handleMouseOver(event) { + e = getEvent(event); + eL = getEventElement(e); + if (siw && (mEl = isWithinNode(eL, null, "matchedSmartInputItem", null, null))) { + siw.selectingSomething = true; + selectFromMouseOver(mEl); + } else if (isWithinNode(eL, null, "siwCredit", null, null)) { + siw.selectingSomething = true; + } else if (siw) { + siw.selectingSomething = false; + } +}//handleMouseOver + +function showSmartInputFloater() { + if (!siw.floater.style.display || (siw.floater.style.display == "none")) { + if (!siw.customFloater) { + x = findElementPosX(siw.inputBox); + y = findElementPosY(siw.inputBox) + siw.inputBox.offsetHeight; + //hack: browser-specific adjustments. + if (!siw.isGecko && !siw.isWinIE) x += 8; + if (!siw.isGecko && !siw.isWinIE) y += 10; + siw.floater.style.left = x; + siw.floater.style.top = y; + } else { + //you may + //do additional things for your custom floater + //beyond setting display and visibility + } + siw.floater.style.display = "block"; + siw.floater.style.visibility = "visible"; + } +}//showSmartInputFloater() + +function hideSmartInputFloater() { + if (siw) { + siw.floater.style.display = "none"; + siw.floater.style.visibility = "hidden"; + siw = null; + }//siw exists +}//hideSmartInputFloater + +function processSmartInput(inputBox) { + if (!siw) siw = new smartInputWindow(); + siw.inputBox = inputBox; + + classData = inputBox.className.split(" "); + siwDirectives = null; + for (i = 0; (!siwDirectives && classData[i]); i++) { + if (classData[i].indexOf("wickEnabled") != -1) + siwDirectives = classData[i]; + } + + if (siwDirectives && (siwDirectives.indexOf(":") != -1)) { + siw.customFloater = true; + newFloaterId = siwDirectives.split(":")[1]; + siw.floater = document.getElementById(newFloaterId); + siw.floaterContent = siw.floater.getElementsByTagName("div")[0]; + } + + + setSmartInputData(); + if (siw.matchCollection && (siw.matchCollection.length > 0)) selectSmartInputMatchItem(0); + var content = content || null; + content = getSmartInputBoxContent(); + if (content) { + modifySmartInputBoxContent(content); + showSmartInputFloater(); + } else { + hideSmartInputFloater(); + } +}//processSmartInput() + +function smartInputMatch(cleanValue, value) { + this.cleanValue = cleanValue; + this.value = value; + this.isSelected = false; +}//smartInputMatch + +function simplify(s) { + return s.toLowerCase().replace(/^[ \s\f\t\n\r]+/, '').replace(/[ \s\f\t\n\r]+$/, ''); +//.replace(/[?,?,?,?,\u00E9,\u00E8,\u00EA,\u00EB]/gi,"e").replace(/[?,?,\u00E0,\u00E2]/gi,"a"). +}//simplify + +function getUserInputToMatch(s) { + a = s; + fields = s.split(","); + if (fields.length > 0) a = fields[fields.length - 1]; + return a; +}//getUserInputToMatch + +function getUserInputBase() { + s = siw.inputBox.value; + a = s; + if ((lastComma = s.lastIndexOf(",")) != -1) { + a = a.replace(/^(.*\,[ \r\n\t\f\s]*).*$/i, '$1'); + } + else { + a = ""; + } + return a; +}//getUserInputBase() + +function runMatchingLogic(userInput, standalone) { + userInput = simplify(userInput); + uifc = userInput.charAt(0).toLowerCase(); + if (uifc == '"') uifc = (n = userInput.charAt(1)) ? n.toLowerCase() : "z"; + if (standalone) userInput = uifc; + if (siw) siw.matchCollection = new Array(); + pointerToCollectionToUse = collection; + if (siw && siw.revisedCollection && (siw.revisedCollection.length > 0) && siw.lastUserInput && (userInput.indexOf(siw.lastUserInput) == 0)) { + pointerToCollectionToUse = siw.revisedCollection; + } else if (collectionIndex[userInput] && (collectionIndex[userInput].length > 0)) { + pointerToCollectionToUse = collectionIndex[userInput]; + } else if (collectionIndex[uifc] && (collectionIndex[uifc].length > 0)) { + pointerToCollectionToUse = collectionIndex[uifc]; + } else if (siw && (userInput.length == 1) && (!collectionIndex[uifc])) { + siw.buildIndex = true; + } else if (siw) { + siw.buildIndex = false; + } + + tempCollection = new Array(); + + re1m = new RegExp("^([ \"\>\<\-]*)(" + userInput + ")", "i"); + re2m = new RegExp("([ \"\>\<\-]+)(" + userInput + ")", "i"); + re1 = new RegExp("^([ \"\}\{\-]*)(" + userInput + ")", "gi"); + re2 = new RegExp("([ \"\}\{\-]+)(" + userInput + ")", "gi"); + + for (i = 0, j = 0; (i < pointerToCollectionToUse.length); i++) { + displayMatches = ((!standalone) && (j < siw.MAX_MATCHES)); + entry = pointerToCollectionToUse[i]; + mEntry = simplify(entry); + if (!standalone && (mEntry.indexOf(userInput) == 0)) { + userInput = userInput.replace(/\>/gi, '\\}').replace(/\< ?/gi, '\\{'); + re = new RegExp("(" + userInput + ")", "i"); + if (displayMatches) { + siw.matchCollection[j] = new smartInputMatch(entry, mEntry.replace(/\>/gi, '}').replace(/\< ?/gi, '{').replace(re, "$1")); + } + tempCollection[j] = entry; + j++; + } else if (mEntry.match(re1m) || mEntry.match(re2m)) { + if (!standalone && displayMatches) { + siw.matchCollection[j] = new smartInputMatch(entry, mEntry.replace(/\>/gi, '}').replace(/\$2").replace(re2, "$1$2")); + } + tempCollection[j] = entry; + j++; + } + }//loop thru collection + if (siw) { + siw.lastUserInput = userInput; + siw.revisedCollection = tempCollection.join(",").split(","); + collectionIndex[userInput] = tempCollection.join(",").split(","); + } + if (standalone || siw.buildIndex) { + collectionIndex[uifc] = tempCollection.join(",").split(","); + if (siw) siw.buildIndex = false; + } +}//runMatchingLogic + +function setSmartInputData() { + if (siw) { + orgUserInput = siw.inputBox.value; + orgUserInput = getUserInputToMatch(orgUserInput); + userInput = orgUserInput.toLowerCase().replace(/[\r\n\t\f\s]+/gi, ' ').replace(/^ +/gi, '').replace(/ +$/gi, '').replace(/ +/gi, ' ').replace(/\\/gi, '').replace(/\[/gi, '').replace(/\(/gi, '').replace(/\./gi, '\.').replace(/\?/gi, ''); + if (userInput && (userInput != "") && (userInput != '"')) { + runMatchingLogic(userInput); + }//if userinput not blank and is meaningful + else { + siw.matchCollection = null; + } + }//siw exists ... uhmkaaayyyyy +}//setSmartInputData + +function getSmartInputBoxContent() { + a = null; + if (siw && siw.matchCollection && (siw.matchCollection.length > 0)) { + a = ''; + for (i = 0; i < siw.matchCollection.length; i++) { + selectedString = siw.matchCollection[i].isSelected ? ' selectedSmartInputItem' : ''; + a += '

    ' + siw.matchCollection[i].value.replace(/\{ */gi, "<").replace(/\} */gi, ">") + '

    '; + }// + }//siw exists + return a; +}//getSmartInputBoxContent + +function modifySmartInputBoxContent(content) { + //todo: remove credits 'cuz no one gives a shit ;] - done + siw.floaterContent.innerHTML = '
    ' + content + (siw.showCredit ? ('

    Powered By: Chris Holland

    ') : '') + '
    '; + siw.matchListDisplay = document.getElementById("smartInputResults"); +}//modifySmartInputBoxContent() + +function selectFromMouseOver(o) { + currentIndex = getCurrentlySelectedSmartInputItem(); + if (currentIndex != null) deSelectSmartInputMatchItem(currentIndex); + newIndex = getIndexFromElement(o); + selectSmartInputMatchItem(newIndex); + modifySmartInputBoxContent(getSmartInputBoxContent()); +}//selectFromMouseOver + +function selectFromMouseClick() { + activateCurrentSmartInputMatch(); + siw.inputBox.focus(); + hideSmartInputFloater(); +}//selectFromMouseClick + +function getIndexFromElement(o) { + index = 0; + while (o = o.previousSibling) { + index++; + }// + return index; +}//getIndexFromElement + +function getCurrentlySelectedSmartInputItem() { + answer = null; + for (i = 0; ((i < siw.matchCollection.length) && !answer); i++) { + if (siw.matchCollection[i].isSelected) + answer = i; + }// + return answer; +}//getCurrentlySelectedSmartInputItem + +function selectSmartInputMatchItem(index) { + siw.matchCollection[index].isSelected = true; +}//selectSmartInputMatchItem() + +function deSelectSmartInputMatchItem(index) { + siw.matchCollection[index].isSelected = false; +}//deSelectSmartInputMatchItem() + +function selectNextSmartInputMatchItem() { + currentIndex = getCurrentlySelectedSmartInputItem(); + if (currentIndex != null) { + deSelectSmartInputMatchItem(currentIndex); + if ((currentIndex + 1) < siw.matchCollection.length) + selectSmartInputMatchItem(currentIndex + 1); + else + selectSmartInputMatchItem(0); + } else { + selectSmartInputMatchItem(0); + } + modifySmartInputBoxContent(getSmartInputBoxContent()); +}//selectNextSmartInputMatchItem + +function selectPreviousSmartInputMatchItem() { + currentIndex = getCurrentlySelectedSmartInputItem(); + if (currentIndex != null) { + deSelectSmartInputMatchItem(currentIndex); + if ((currentIndex - 1) >= 0) + selectSmartInputMatchItem(currentIndex - 1); + else + selectSmartInputMatchItem(siw.matchCollection.length - 1); + } else { + selectSmartInputMatchItem(siw.matchCollection.length - 1); + } + modifySmartInputBoxContent(getSmartInputBoxContent()); +}//selectPreviousSmartInputMatchItem + +function activateCurrentSmartInputMatch() { + baseValue = getUserInputBase(); + if ((selIndex = getCurrentlySelectedSmartInputItem()) != null) { + addedValue = siw.matchCollection[selIndex].cleanValue; + theString = (baseValue ? baseValue : "") + addedValue + ", "; + siw.inputBox.value = theString; + runMatchingLogic(addedValue, true); + } +}//activateCurrentSmartInputMatch + +function smartInputWindow() { + this.customFloater = false; + this.floater = document.getElementById("smartInputFloater"); + this.floaterContent = document.getElementById("smartInputFloaterContent"); + this.selectedSmartInputItem = null; + this.MAX_MATCHES = 15; + this.isGecko = (navigator.userAgent.indexOf("Gecko/200") != -1); + this.isSafari = (navigator.userAgent.indexOf("Safari") != -1); + this.isWinIE = ((navigator.userAgent.indexOf("Win") != -1 ) && (navigator.userAgent.indexOf("MSIE") != -1 )); + this.showCredit = false; +}//smartInputWindow Object + +function registerSmartInputListeners() { + inputs = document.getElementsByTagName("input"); + texts = document.getElementsByTagName("textarea"); + allinputs = new Array(); + z = 0; + y = 0; + while (inputs[z]) { + allinputs[z] = inputs[z]; + z++; + }// + while (texts[y]) { + allinputs[z] = texts[y]; + z++; + y++; + }// + + for (i = 0; i < allinputs.length; i++) { + if ((c = allinputs[i].className) && (c == "wickEnabled")) { + allinputs[i].setAttribute("autocomplete", "OFF"); + allinputs[i].onfocus = handleFocus; + allinputs[i].onblur = handleBlur; + allinputs[i].onkeydown = handleKeyDown; + allinputs[i].onkeyup = handleKeyPress; + } + }//loop thru inputs +}//registerSmartInputListeners + +siw = null; + +if (document.addEventListener) { + document.addEventListener("keydown", handleKeyDown, false); + document.addEventListener("keyup", handleKeyPress, false); + document.addEventListener("mouseup", handleClick, false); + document.addEventListener("mouseover", handleMouseOver, false); +} else { + document.onkeydown = handleKeyDown; + document.onkeyup = handleKeyPress; + document.onmouseup = handleClick; + document.onmouseover = handleMouseOver; +} + +registerSmartInputListeners(); + +document.write( + ']", "i"), bv = /^(?:checkbox|radio)$/, bw = /checked\s*(?:[^=]|=\s*.checked.)/i, bx = /\/(java|ecma)script/i, by = /^\s*\s*$/g, bz = { + option: [1, ""], + legend: [1, "
    ", "
    "], + thead: [1, "
    ' + + '<\/td><\/tr><\/table>' +); + +//note: instruct users to the fact that no commas should be present in entries. +//it would make things insanely messy. +//this is why i'm filtering commas here: +for (x = 0; x < collection.length; x++) { + collection[x] = collection[x].replace(/\,/gi, ''); +}// + +collectionIndex = new Array(); + +ds = ""; +function debug(s) { + ds += ( s + "\n"); +} diff --git a/WebContent/stat/js/util/console-compability.js b/src/main/webapp/stat/js/util/console-compability.js similarity index 88% rename from WebContent/stat/js/util/console-compability.js rename to src/main/webapp/stat/js/util/console-compability.js index 645349990..beaa9ba6c 100644 --- a/WebContent/stat/js/util/console-compability.js +++ b/src/main/webapp/stat/js/util/console-compability.js @@ -1,5 +1,4 @@ -!function() { - // console handler +!function () { if (typeof window.console === 'undefined') { window.console = {}; } @@ -15,7 +14,7 @@ } function genereateConsoleMethod(key) { - return function(msg) { + return function (msg) { if (window.showConsoleMsg) document.body.innerHTML += '
    [' + key + ']:' + msg; }; diff --git a/src/main/webapp/stat/js/util/dateFormat.min.js b/src/main/webapp/stat/js/util/dateFormat.min.js new file mode 100644 index 000000000..a8734e330 --- /dev/null +++ b/src/main/webapp/stat/js/util/dateFormat.min.js @@ -0,0 +1,194 @@ +/*! jquery-dateFormat 10-05-2014 */ +var DateFormat = {}; +!function (a) { + var b = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"], c = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"], d = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"], e = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"], f = { + Jan: "01", + Feb: "02", + Mar: "03", + Apr: "04", + May: "05", + Jun: "06", + Jul: "07", + Aug: "08", + Sep: "09", + Oct: "10", + Nov: "11", + Dec: "12" + }, g = /\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.?\d{0,3}[Z\-+]?(\d{2}:?\d{2})?/; + a.format = function () { + function a(a) { + return b[parseInt(a, 10)] || a + } + + function h(a) { + return c[parseInt(a, 10)] || a + } + + function i(a) { + var b = parseInt(a, 10) - 1; + return d[b] || a + } + + function j(a) { + var b = parseInt(a, 10) - 1; + return e[b] || a + } + + function k(a) { + return f[a] || a + } + + function l(a) { + var b, c, d, e, f, g = a, h = ""; + return -1 !== g.indexOf(".") && (e = g.split("."), g = e[0], h = e[1]), f = g.split(":"), 3 === f.length ? (b = f[0], c = f[1], d = f[2].replace(/\s.+/, "").replace(/[a-z]/gi, ""), g = g.replace(/\s.+/, "").replace(/[a-z]/gi, ""), { + time: g, + hour: b, + minute: c, + second: d, + millis: h + }) : {time: "", hour: "", minute: "", second: "", millis: ""} + } + + function m(a, b) { + for (var c = b - String(a).length, d = 0; c > d; d++)a = "0" + a; + return a + } + + return { + parseDate: function (a) { + var b = {date: null, year: null, month: null, dayOfMonth: null, dayOfWeek: null, time: null}; + if ("number" == typeof a)return this.parseDate(new Date(a)); + if ("function" == typeof a.getFullYear)b.year = String(a.getFullYear()), b.month = String(a.getMonth() + 1), b.dayOfMonth = String(a.getDate()), b.time = l(a.toTimeString()); else if (-1 != a.search(g))values = a.split(/[T\+-]/), b.year = values[0], b.month = values[1], b.dayOfMonth = values[2], b.time = l(values[3].split(".")[0]); else switch (values = a.split(" "), 6 === values.length && isNaN(values[5]) && (values[values.length] = "()"), values.length) { + case 6: + b.year = values[5], b.month = k(values[1]), b.dayOfMonth = values[2], b.time = l(values[3]); + break; + case 2: + subValues = values[0].split("-"), b.year = subValues[0], b.month = subValues[1], b.dayOfMonth = subValues[2], b.time = l(values[1]); + break; + case 7: + case 9: + case 10: + b.year = values[3], b.month = k(values[1]), b.dayOfMonth = values[2], b.time = l(values[4]); + break; + case 1: + subValues = values[0].split(""), b.year = subValues[0] + subValues[1] + subValues[2] + subValues[3], b.month = subValues[5] + subValues[6], b.dayOfMonth = subValues[8] + subValues[9], b.time = l(subValues[13] + subValues[14] + subValues[15] + subValues[16] + subValues[17] + subValues[18] + subValues[19] + subValues[20]); + break; + default: + return null + } + return b.date = new Date(b.year, b.month - 1, b.dayOfMonth), b.dayOfWeek = String(b.date.getDay()), b + }, date: function (b, c) { + try { + var d = this.parseDate(b); + if (null === d)return b; + for (var e = (d.date, d.year), f = d.month, g = d.dayOfMonth, k = d.dayOfWeek, l = d.time, n = "", o = "", p = "", q = !1, r = 0; r < c.length; r++) { + var s = c.charAt(r), t = c.charAt(r + 1); + if (q)"'" == s ? (o += "" === n ? "'" : n, n = "", q = !1) : n += s; else switch (n += s, p = "", n) { + case"ddd": + o += a(k), n = ""; + break; + case"dd": + if ("d" === t)break; + o += m(g, 2), n = ""; + break; + case"d": + if ("d" === t)break; + o += parseInt(g, 10), n = ""; + break; + case"D": + g = 1 == g || 21 == g || 31 == g ? parseInt(g, 10) + "st" : 2 == g || 22 == g ? parseInt(g, 10) + "nd" : 3 == g || 23 == g ? parseInt(g, 10) + "rd" : parseInt(g, 10) + "th", o += g, n = ""; + break; + case"MMMM": + o += j(f), n = ""; + break; + case"MMM": + if ("M" === t)break; + o += i(f), n = ""; + break; + case"MM": + if ("M" === t)break; + o += m(f, 2), n = ""; + break; + case"M": + if ("M" === t)break; + o += parseInt(f, 10), n = ""; + break; + case"y": + case"yyy": + if ("y" === t)break; + o += n, n = ""; + break; + case"yy": + if ("y" === t)break; + o += String(e).slice(-2), n = ""; + break; + case"yyyy": + o += e, n = ""; + break; + case"HH": + o += m(l.hour, 2), n = ""; + break; + case"H": + if ("H" === t)break; + o += parseInt(l.hour, 10), n = ""; + break; + case"hh": + hour = 0 === parseInt(l.hour, 10) ? 12 : l.hour < 13 ? l.hour : l.hour - 12, o += m(hour, 2), n = ""; + break; + case"h": + if ("h" === t)break; + hour = 0 === parseInt(l.hour, 10) ? 12 : l.hour < 13 ? l.hour : l.hour - 12, o += parseInt(hour, 10), n = ""; + break; + case"mm": + o += m(l.minute, 2), n = ""; + break; + case"m": + if ("m" === t)break; + o += l.minute, n = ""; + break; + case"ss": + o += m(l.second.substring(0, 2), 2), n = ""; + break; + case"s": + if ("s" === t)break; + o += l.second, n = ""; + break; + case"S": + case"SS": + if ("S" === t)break; + o += n, n = ""; + break; + case"SSS": + o += l.millis.substring(0, 3), n = ""; + break; + case"a": + o += l.hour >= 12 ? "PM" : "AM", n = ""; + break; + case"p": + o += l.hour >= 12 ? "p.m." : "a.m.", n = ""; + break; + case"E": + o += h(k), n = ""; + break; + case"'": + n = "", q = !0; + break; + default: + o += s, n = "" + } + } + return o += p + } catch (u) { + return console && console.log && console.log(u), b + } + }, prettyDate: function (a) { + var b, c, d; + return ("string" == typeof a || "number" == typeof a) && (b = new Date(a)), "object" == typeof a && (b = new Date(a.toString())), c = ((new Date).getTime() - b.getTime()) / 1e3, d = Math.floor(c / 86400), isNaN(d) || 0 > d ? void 0 : 60 > c ? "just now" : 120 > c ? "1 minute ago" : 3600 > c ? Math.floor(c / 60) + " minutes ago" : 7200 > c ? "1 hour ago" : 86400 > c ? Math.floor(c / 3600) + " hours ago" : 1 === d ? "Yesterday" : 7 > d ? d + " days ago" : 31 > d ? Math.ceil(d / 7) + " weeks ago" : d >= 31 ? "more than 5 weeks ago" : void 0 + }, toBrowserTimeZone: function (a, b) { + return this.date(new Date(a), b || "MM/dd/yyyy HH:mm:ss") + } + } + }() +}(DateFormat), function (a) { + a.format = DateFormat.format +}(jQuery); \ No newline at end of file diff --git a/src/main/webapp/stat/js/util/dist/mock-min.map b/src/main/webapp/stat/js/util/dist/mock-min.map new file mode 100644 index 000000000..7a692a400 --- /dev/null +++ b/src/main/webapp/stat/js/util/dist/mock-min.map @@ -0,0 +1 @@ +{"version":3,"file":"dist/mock-min.js","sources":["dist/mock.js"],"names":["undefined","Mock","version","_mocked","Util","extend","options","name","src","copy","clone","target","arguments","i","length","this","isArray","isObject","each","obj","iterator","context","key","type","call","String","Object","prototype","toString","match","toLowerCase","split","value","isObjectOrArray","isNumeric","isNaN","parseFloat","isFinite","heredoc","fn","replace","noop","Random","boolean","min","max","cur","parseInt","Math","random","bool","natural","round","integer","int","float","dmin","dmax","ret","dcount","character","pool","pools","lower","upper","number","symbol","alpha","charAt","char","string","text","str","range","start","stop","step","len","ceil","idx","Array","patternLetters","yyyy","yy","date","getFullYear","slice","y","MM","m","getMonth","M","dd","d","getDate","HH","h","getHours","H","hh","mm","getMinutes","ss","s","getSeconds","SS","ms","getMilliseconds","S","A","a","rformat","RegExp","re","push","join","format","$0","flag","callee","randomDate","Date","getTime","time","datetime","ad_size","screen_size","video_size","image","size","background","foreground","pick","indexOf","img","apply","brandColors","4ormat","500px","About.me (blue)","About.me (yellow)","Addvocate","Adobe","Aim","Amazon","Android","Angie's List","AOL","Atlassian","Behance","Big Cartel","bitly","Blogger","Boeing","Booking.com","Carbonmade","Cheddar","Code School","Delicious","Dell","Designmoo","Deviantart","Designer News","Devour","DEWALT","Disqus (blue)","Disqus (orange)","Dribbble","Dropbox","Drupal","Dunked","eBay","Ember","Engadget","Envato","Etsy","Evernote","Fab.com","Facebook","Firefox","Flickr (blue)","Flickr (pink)","Forrst","Foursquare","Garmin","GetGlue","Gimmebar","GitHub","Google Blue","Google Green","Google Red","Google Yellow","Google+","Grooveshark","Groupon","Hacker News","HelloWallet","Heroku (light)","Heroku (dark)","HootSuite","Houzz","HTML5","IKEA","IMDb","Instagram","Intel","Intuit","Kickstarter","kippt","Kodery","LastFM","LinkedIn","Livestream","Lumo","Mixpanel","Meetup","Nokia","NVIDIA","Opera","Path","PayPal (dark)","PayPal (light)","Pinboard","Pinterest","PlayStation","Pocket","Prezi","Pusha","Quora","QUOTE.fm","Rdio","Readability","Red Hat","Resource","Rockpack","Roon","RSS","Salesforce","Samsung","Shopify","Skype","Snagajob","Softonic","SoundCloud","Space Box","Spotify","Sprint","Squarespace","StackOverflow","Staples","Status Chart","Stripe","StudyBlue","StumbleUpon","T-Mobile","Technorati","The Next Web","Treehouse","Trulia","Tumblr","Twitch.tv","Twitter","TYPO3","Ubuntu","Ustream","Verizon","Vimeo","Vine","Virb","Virgin Media","Wooga","WordPress (blue)","WordPress (orange)","WordPress (grey)","Wunderlist","XBOX","XING","Yahoo!","Yandex","Yelp","YouTube","Zalongo","Zendesk","Zerply","Zootool","brands","b","dataImageHolder","dataImage","canvas","document","createElement","ctx","getContext","width","height","text_height","font","textAlign","textBaseline","fillStyle","fillRect","fillText","toDataURL","color","colour","floor","capitalize","word","toUpperCase","substr","arr","shuffle","old","result","index","splice","paragraph","sentence","title","first","names","concat","last","middle","url","domain","tld","email","ip","tlds","areas","area","regions","region","address","city","phone","areacode","street","street_suffixes","street_suffix","states","state","zip","todo","d4","d6","d8","d12","d20","d100","guid","id","sum","rank","autoIncrementInteger","increment","inc","rkey","rrange","rplaceholder","mock","rurl","rtype","template","Handle","gen","parameters","count","decimal","point","array","j","object","parts","placeholders","ph","phed","test","placeholder","_all","exec","lkey","okey","params","handle","mockjax","jQuery","mockxhr","open","send","getAllResponseHeaders","readyState","status","convert","isFunction","prefilter","surl","dataFilter","converters","xhr","ajaxPrefilter","KISSY","add","_original_ajax","io","responseText","responseXML","statusText","timeoutTimer","console","log","data","success","complete","module","exports","define","amd","cmd","requires","Mock4Tpl","tpl","input","helpers","partials","parse","Handlebars","debug","node","isString","ast","parseOptions","__path","group","JSON","stringify","preLength","groupEnd","ma","option","rComment","comments","lastIndex","Function","val","def","Error","mocked","program","statements","mustache","currentContext","contextLength","unshift","isHelper","hash","block","inverse","Helpers","custom","pop","shift","pair","pairs","ID","prev","valType","preOptions","depth","partial","partialName","content","PARTIAL_NAME","DATA","STRING","INTEGER","BOOLEAN","comment","unless","XTemplate","Mock4XTpl","use","T","xtpl","xparse","compiler","RunTime","commands","subTpls","other","hold","parseVal","expr","queryArray","prop","query","queryObject","set","if","with","path","_","__","___","include","tplExpression","expression","unaryExpression","multiplicativeExpression","additiveExpression","op1","op2","pow","relationalExpression","equalityExpression","conditionalAndExpression","conditionalOrExpression","fix"],"mappings":"CAEA,SAAUA,GACN,GAAIC,IACAC,QAAS,QACTC,YAGAC,EAAO,WACP,GAAIA,KA4DJ,OA3DAA,GAAKC,OAAS,WACV,GAAmEC,GAASC,EAAMC,EAAKC,EAAMC,EAAzFC,EAASC,UAAU,OAAUC,EAAI,EAAGC,EAASF,UAAUE,MAK3D,KAJe,IAAXA,IACAH,EAASI,KACTF,EAAI,GAEEC,EAAJD,EAAYA,IAEd,GADAP,EAAUM,UAAUC,GAEpB,IAAKN,IAAQD,GACTE,EAAMG,EAAOJ,GACbE,EAAOH,EAAQC,GACXI,IAAWF,GACXA,IAAST,IACTI,EAAKY,QAAQP,IAASL,EAAKa,SAASR,IAChCL,EAAKY,QAAQP,KAAOC,EAAQF,GAAOJ,EAAKY,QAAQR,GAAOA,MACvDJ,EAAKa,SAASR,KAAOC,EAAQF,GAAOJ,EAAKa,SAAST,GAAOA,MAC7DG,EAAOJ,GAAQH,EAAKC,OAAOK,EAAOD,IAElCE,EAAOJ,GAAQE,EAI3B,OAAOE,IAEXP,EAAKc,KAAO,SAAcC,EAAKC,EAAUC,GACrC,GAAIR,GAAGS,CACP,IAAuB,WAAnBP,KAAKQ,KAAKJ,GACV,IAAKN,EAAI,EAAOM,EAAJN,EAASA,IACjBO,EAASP,EAAGA,OAEb,IAAIM,EAAIL,UAAYK,EAAIL,OAC3B,IAAKD,EAAI,EAAGA,EAAIM,EAAIL,QACZM,EAASI,KAAKH,EAASF,EAAIN,GAAIA,EAAGM,MAAS,EADvBN,SAI5B,KAAKS,IAAOH,GACR,GAAIC,EAASI,KAAKH,EAASF,EAAIG,GAAMA,EAAKH,MAAS,EAAO,OAItEf,EAAKmB,KAAO,SAAcJ,GACtB,MAAe,QAARA,GAAgBA,IAAQnB,EAAYyB,OAAON,GAAOO,OAAOC,UAAUC,SAASJ,KAAKL,GAAKU,MAAM,oBAAoB,GAAGC,eAE9H1B,EAAKc,KAAK,sCAAsCa,MAAM,KAAM,SAASC,GACjE5B,EAAK,KAAO4B,GAAS,SAASb,GAC1B,MAAOf,GAAKmB,KAAKJ,KAASa,EAAMF,iBAGxC1B,EAAK6B,gBAAkB,SAASD,GAC5B,MAAO5B,GAAKa,SAASe,IAAU5B,EAAKY,QAAQgB,IAEhD5B,EAAK8B,UAAY,SAASF,GACtB,OAAQG,MAAMC,WAAWJ,KAAWK,SAASL,IAEjD5B,EAAKkC,QAAU,SAAiBC,GAC5B,MAAOA,GAAGX,WAAWY,QAAQ,gBAAiB,IAAIA,QAAQ,cAAe,IAAIA,QAAQ,aAAc,IAAIA,QAAQ,aAAc,KAEjIpC,EAAKqC,KAAO,aACLrC,KAGPsC,EAAS,WACT,GAAIA,IACArC,OAAQD,EAAKC,OAkkBjB,OAhkBAqC,GAAOrC,QACHsC,UAAW,SAASC,EAAKC,EAAKC,GAC1B,MAAIA,KAAQ9C,GACR4C,EAAqB,mBAARA,IAAwBT,MAAMS,GAA2B,EAApBG,SAASH,EAAK,IAChEC,EAAqB,mBAARA,IAAwBV,MAAMU,GAA2B,EAApBE,SAASF,EAAK,IACzDG,KAAKC,SAAW,GAAKL,EAAMC,GAAOD,GAAOE,EAAMA,GAEnDE,KAAKC,UAAY,IAE5BC,KAAM,SAASN,EAAKC,EAAKC,GACrB,MAAO/B,MAAK4B,QAAQC,EAAKC,EAAKC,IAElCK,QAAS,SAASP,EAAKC,GAGnB,MAFAD,GAAqB,mBAARA,GAAsBG,SAASH,EAAK,IAAM,EACvDC,EAAqB,mBAARA,GAAsBE,SAASF,EAAK,IAAM,iBAChDG,KAAKI,MAAMJ,KAAKC,UAAYJ,EAAMD,IAAQA,GAErDS,QAAS,SAAST,EAAKC,GAGnB,MAFAD,GAAqB,mBAARA,GAAsBG,SAASH,EAAK,IAAM,kBACvDC,EAAqB,mBAARA,GAAsBE,SAASF,EAAK,IAAM,iBAChDG,KAAKI,MAAMJ,KAAKC,UAAYJ,EAAMD,IAAQA,GAErDU,MAAO,SAASV,EAAKC,GACjB,MAAO9B,MAAKsC,QAAQT,EAAKC,IAE7BU,QAAS,SAASX,EAAKC,EAAKW,EAAMC,GAC9BD,EAAOA,IAASxD,EAAY,EAAIwD,EAChCA,EAAOR,KAAKH,IAAIG,KAAKJ,IAAIY,EAAM,IAAK,GACpCC,EAAOA,IAASzD,EAAY,GAAKyD,EACjCA,EAAOT,KAAKH,IAAIG,KAAKJ,IAAIa,EAAM,IAAK,EAEpC,KAAK,GADDC,GAAM3C,KAAKsC,QAAQT,EAAKC,GAAO,IAC1BhC,EAAI,EAAG8C,EAAS5C,KAAKoC,QAAQK,EAAMC,GAAWE,EAAJ9C,EAAYA,IAC3D6C,GAAO3C,KAAK6C,UAAU,SAE1B,OAAOxB,YAAWsB,EAAK,KAE3BE,UAAW,SAASC,GAChB,GAAIC,IACAC,MAAO,6BACPC,MAAO,6BACPC,OAAQ,aACRC,OAAQ,eAKZ,OAHAJ,GAAMK,MAAQL,EAAMC,MAAQD,EAAME,MAClCF,EAAiB,UAAIA,EAAMC,MAAQD,EAAME,MAAQF,EAAMG,OAASH,EAAMI,OACtEL,EAAOC,GAAO,GAAKD,GAAM/B,gBAAkB+B,EACpCA,EAAKO,OAAO1B,EAAOS,QAAQ,EAAGU,EAAK/C,OAAS,KAEvDuD,OAAQ,SAASR,GACb,MAAO9C,MAAK6C,UAAUC,IAE1BS,OAAQ,SAAST,EAAMjB,EAAKC,GACxB,GAAI/B,EACqB,KAArBF,UAAUE,SACVA,EAAS4B,EAAOS,QAAQP,EAAKC,IAER,IAArBjC,UAAUE,SACkB,gBAAjBF,WAAU,GACjBE,EAAS8B,GAET9B,EAAS4B,EAAOS,QAAQU,EAAMjB,GAC9BiB,EAAO7D,IAGU,IAArBY,UAAUE,SACVA,EAAS+C,EACTA,EAAO7D,GAEc,IAArBY,UAAUE,SACVA,EAAS4B,EAAOS,QAAQ,EAAG,GAG/B,KAAK,GADDoB,GAAO,GACF1D,EAAI,EAAOC,EAAJD,EAAYA,IACxB0D,GAAQ7B,EAAOkB,UAAUC,EAE7B,OAAOU,IAEXC,IAAK,SAASX,EAAMjB,EAAKC,GACrB,MAAO9B,MAAKuD,OAAOT,EAAMjB,EAAKC,IAElC4B,MAAO,SAASC,EAAOC,EAAMC,GACrBhE,UAAUE,QAAU,IACpB6D,EAAOD,GAAS,EAChBA,EAAQ,GAEZE,EAAOhE,UAAU,IAAM,CAIvB,KAHA,GAAIiE,GAAM7B,KAAKH,IAAIG,KAAK8B,MAAMH,EAAOD,GAASE,GAAO,GACjDG,EAAM,EACNN,EAAQ,GAAIO,OAAMH,GACTA,EAANE,GACHN,EAAMM,KAASL,EACfA,GAASE,CAEb,OAAOH,MAGf/B,EAAOrC,QACH4E,gBACIC,KAAM,cACNC,GAAI,SAASC,GACT,OAAQ,GAAKA,EAAKC,eAAeC,MAAM,IAE3CC,EAAG,KACHC,GAAI,SAASJ,GACT,GAAIK,GAAIL,EAAKM,WAAa,CAC1B,OAAW,IAAJD,EAAS,IAAMA,EAAIA,GAE9BE,EAAG,SAASP,GACR,MAAOA,GAAKM,WAAa,GAE7BE,GAAI,SAASR,GACT,GAAIS,GAAIT,EAAKU,SACb,OAAW,IAAJD,EAAS,IAAMA,EAAIA,GAE9BA,EAAG,UACHE,GAAI,SAASX,GACT,GAAIY,GAAIZ,EAAKa,UACb,OAAW,IAAJD,EAAS,IAAMA,EAAIA,GAE9BE,EAAG,WACHC,GAAI,SAASf,GACT,GAAIY,GAAIZ,EAAKa,WAAa,EAC1B,OAAW,IAAJD,EAAS,IAAMA,EAAIA,GAE9BA,EAAG,SAASZ,GACR,MAAOA,GAAKa,WAAa,IAE7BG,GAAI,SAAShB,GACT,GAAIK,GAAIL,EAAKiB,YACb,OAAW,IAAJZ,EAAS,IAAMA,EAAIA,GAE9BA,EAAG,aACHa,GAAI,SAASlB,GACT,GAAImB,GAAInB,EAAKoB,YACb,OAAW,IAAJD,EAAS,IAAMA,EAAIA,GAE9BA,EAAG,aACHE,GAAI,SAASrB,GACT,GAAIsB,GAAKtB,EAAKuB,iBACd,OAAY,IAALD,GAAW,KAAOA,GAAW,IAALA,GAAY,IAAMA,GAAMA,GAE3DE,EAAG,kBACHC,EAAG,SAASzB,GACR,MAAOA,GAAKa,WAAa,GAAK,KAAO,MAEzCa,EAAG,SAAS1B,GACR,MAAOA,GAAKa,WAAa,GAAK,KAAO,SAIjDvD,EAAOrC,QACH0G,QAAS,GAAIC,QAAO,WAChB,GAAIC,KACJ,KAAK,GAAIpG,KAAK6B,GAAOuC,eAAgBgC,EAAGC,KAAKrG,EAC7C,OAAO,IAAMoG,EAAGE,KAAK,KAAO,OAC3B,KACLC,OAAQ,SAAShC,EAAMgC,GACnB,GAAInC,GAAiBvC,EAAOuC,eAAgB8B,EAAUrE,EAAOqE,OAC7D,OAAOK,GAAO5E,QAAQuE,EAAS,SAASM,EAAIC,GACxC,MAAuC,kBAAzBrC,GAAeqC,GAAuBrC,EAAeqC,GAAMlC,GAAQH,EAAeqC,IAASrC,GAAiBrE,UAAU2G,OAAOF,EAAIpC,EAAeqC,IAASlC,EAAKH,EAAeqC,SAGnME,WAAY,SAAS5E,EAAKC,GAGtB,MAFAD,GAAMA,IAAQ5C,EAAY,GAAIyH,MAAK,GAAK7E,EACxCC,EAAMA,IAAQ7C,EAAY,GAAIyH,MAAS5E,EAChC,GAAI4E,MAAKzE,KAAKC,UAAYJ,EAAI6E,UAAY9E,EAAI8E,aAEzDtC,KAAM,SAASgC,GAEX,MADAA,GAASA,GAAU,aACZrG,KAAKqG,OAAOrG,KAAKyG,aAAcJ,IAE1CO,KAAM,SAASP,GAEX,MADAA,GAASA,GAAU,WACZrG,KAAKqG,OAAOrG,KAAKyG,aAAcJ,IAE1CQ,SAAU,SAASR,GAEf,MADAA,GAASA,GAAU,sBACZrG,KAAKqG,OAAOrG,KAAKyG,aAAcJ,MAG9C1E,EAAOrC,QACHwH,SAAW,UAAW,UAAW,UAAW,UAAW,UAAW,UAAW,SAAU,SAAU,QAAS,SAAU,SAAU,UAAW,UAAW,SAAU,UAAW,UAAW,WACpLC,aAAe,UAAW,UAAW,UAAW,UAAW,UAAW,WAAY,WAAY,WAAY,WAAY,YAAa,aACnIC,YAAc,UAAW,UAAW,WAAY,aAChDC,MAAO,SAASC,EAAMC,EAAYC,EAAYf,EAAQ7C,GAYlD,MAXyB,KAArB3D,UAAUE,SACVyD,EAAO6C,EACPA,EAASpH,GAEY,IAArBY,UAAUE,SACVyD,EAAO4D,EACPA,EAAanI,GAEZiI,IAAMA,EAAOlH,KAAKqH,KAAKrH,KAAK8G,UAC7BK,IAAeA,EAAWG,QAAQ,OAAMH,EAAaA,EAAW5C,MAAM,IACtE6C,IAAeA,EAAWE,QAAQ,OAAMF,EAAaA,EAAW7C,MAAM,IACnE,yBAA2B2C,GAAQC,EAAa,IAAMA,EAAa,KAAOC,EAAa,IAAMA,EAAa,KAAOf,EAAS,IAAMA,EAAS,KAAO7C,EAAO,SAAWA,EAAO,KAEpL+D,IAAK,WACD,MAAOvH,MAAKiH,MAAMO,MAAMxH,KAAMH,cAGtC8B,EAAOrC,QACHmI,aACIC,SAAU,UACVC,QAAS,UACTC,kBAAmB,UACnBC,oBAAqB,UACrBC,UAAW,UACXC,MAAO,UACPC,IAAK,UACLC,OAAQ,UACRC,QAAS,UACTC,eAAgB,UAChBC,IAAK,UACLC,UAAW,UACXC,QAAS,UACTC,aAAc,UACdC,MAAO,UACPC,QAAS,UACTC,OAAQ,UACRC,cAAe,UACfC,WAAY,UACZC,QAAS,UACTC,cAAe,UACfC,UAAW,UACXC,KAAM,UACNC,UAAW,UACXC,WAAY,UACZC,gBAAiB,UACjBC,OAAQ,UACRC,OAAQ,UACRC,gBAAiB,UACjBC,kBAAmB,UACnBC,SAAU,UACVC,QAAS,UACTC,OAAQ,UACRC,OAAQ,UACRC,KAAM,UACNC,MAAO,UACPC,SAAU,UACVC,OAAQ,UACRC,KAAM,UACNC,SAAU,UACVC,UAAW,UACXC,SAAU,UACVC,QAAS,UACTC,gBAAiB,UACjBC,gBAAiB,UACjBC,OAAQ,UACRC,WAAY,UACZC,OAAQ,UACRC,QAAS,UACTC,SAAU,UACVC,OAAQ,UACRC,cAAe,UACfC,eAAgB,UAChBC,aAAc,UACdC,gBAAiB,UACjBC,UAAW,UACXC,YAAa,UACbC,QAAS,UACTC,cAAe,UACfC,YAAa,UACbC,iBAAkB,UAClBC,gBAAiB,UACjBC,UAAW,UACXC,MAAO,UACPC,MAAO,UACPC,KAAM,UACNC,KAAM,UACNC,UAAW,UACXC,MAAO,UACPC,OAAQ,UACRC,YAAa,UACbC,MAAO,UACPC,OAAQ,UACRC,OAAQ,UACRC,SAAU,UACVC,WAAY,UACZC,KAAM,UACNC,SAAU,UACVC,OAAQ,UACRC,MAAO,UACPC,OAAQ,UACRC,MAAO,UACPC,KAAM,UACNC,gBAAiB,UACjBC,iBAAkB,UAClBC,SAAU,UACVC,UAAW,UACXC,YAAa,UACbC,OAAQ,UACRC,MAAO,UACPC,MAAO,UACPC,MAAO,UACPC,WAAY,UACZC,KAAM,UACNC,YAAa,UACbC,UAAW,UACXC,SAAU,UACVC,SAAU,UACVC,KAAM,UACNC,IAAK,UACLC,WAAY,UACZC,QAAS,UACTC,QAAS,UACTC,MAAO,UACPC,SAAU,UACVC,SAAU,UACVC,WAAY,UACZC,YAAa,UACbC,QAAS,UACTC,OAAQ,UACRC,YAAa,UACbC,cAAe,UACfC,QAAS,UACTC,eAAgB,UAChBC,OAAQ,UACRC,UAAW,UACXC,YAAa,UACbC,WAAY,UACZC,WAAY,UACZC,eAAgB,UAChBC,UAAW,UACXC,OAAQ,UACRC,OAAQ,UACRC,YAAa,UACbC,QAAS,UACTC,MAAO,UACPC,OAAQ,UACRC,QAAS,UACTC,QAAS,UACTC,MAAO,UACPC,KAAM,UACNC,KAAM,UACNC,eAAgB,UAChBC,MAAO,UACPC,mBAAoB,UACpBC,qBAAsB,UACtBC,mBAAoB,UACpBC,WAAY,UACZC,KAAM,UACNC,KAAM,UACNC,SAAU,UACVC,OAAQ,UACRC,KAAM,UACNC,QAAS,UACTC,QAAS,UACTC,QAAS,UACTC,OAAQ,UACRC,QAAS,WAEbC,OAAQ,WACJ,GAAIA,KACJ,KAAK,GAAIC,KAAK/Q,MAAKyH,YACfqJ,EAAO3K,KAAK4K,EAEhB,OAAOD,IAEXE,gBAAiB,SAAS9J,GACtB,MAAO,aAAeA,GAE1B+J,UAAW,SAAS/J,EAAM1D,GACtB,GAAI0N,GAA6B,mBAAbC,WAA4BA,SAASC,cAAc,UAAWC,EAAMH,GAAUA,EAAOI,YAAcJ,EAAOI,WAAW,KACzI,KAAKJ,IAAWG,EAAK,MAAO,EACvBnK,KAAMA,EAAOlH,KAAKqH,KAAKrH,KAAK8G,UACjCtD,EAAOA,IAASvE,EAAYuE,EAAO0D,EACnCA,EAAOA,EAAKlG,MAAM,IAClB,IAAIuQ,GAAQvP,SAASkF,EAAK,GAAI,IAAKsK,EAASxP,SAASkF,EAAK,GAAI,IAAKC,EAAanH,KAAKyH,YAAYzH,KAAKqH,KAAKrH,KAAK8Q,WAAY1J,EAAa,OAAQqK,EAAc,GAAIC,EAAO,YAU1K,OATAR,GAAOK,MAAQA,EACfL,EAAOM,OAASA,EAChBH,EAAIM,UAAY,SAChBN,EAAIO,aAAe,SACnBP,EAAIQ,UAAY1K,EAChBkK,EAAIS,SAAS,EAAG,EAAGP,EAAOC,GAC1BH,EAAIQ,UAAYzK,EAChBiK,EAAIK,KAAO,QAAUD,EAAc,MAAQC,EAC3CL,EAAIU,SAASvO,EAAM+N,EAAQ,EAAGC,EAAS,EAAGD,GACnCL,EAAOc,UAAU,gBAGhCrQ,EAAOrC,QACH2S,MAAO,WACH,GAAIC,GAASjQ,KAAKkQ,MAAsB,SAAhBlQ,KAAKC,UAA8CrB,SAAS,GAEpF,OADAqR,GAAS,KAAO,SAAWA,GAAQ3N,MAAM,OAIjD5C,EAAOrC,QACH8S,WAAY,SAASC,GACjB,MAAOA,GAAKhP,OAAO,GAAGiP,cAAgBD,EAAKE,OAAO,IAEtDtP,MAAO,SAASQ,GACZ,MAAOA,GAAI6O,eAEftP,MAAO,SAASS,GACZ,MAAOA,GAAI1C,eAEfsG,KAAM,SAASmL,GACX,MAAOA,GAAIxS,KAAKoC,QAAQ,EAAGoQ,EAAIzS,OAAS,KAE5C0S,QAAS,SAASD,GAEd,IAAK,GADDE,GAAMF,EAAIjO,MAAM,GAAIoO,KAAaC,EAAQ,EAAG7S,EAAS2S,EAAI3S,OACpDD,EAAI,EAAOC,EAAJD,EAAYA,IACxB8S,EAAQ5S,KAAKoC,QAAQ,EAAGsQ,EAAI3S,OAAS,GACrC4S,EAAOxM,KAAKuM,EAAIE,IAChBF,EAAIG,OAAOD,EAAO,EAEtB,OAAOD,MAGfhR,EAAOrC,QACHwT,UAAW,SAASjR,EAAKC,GACrB,GAAIgC,EACqB,KAArBjE,UAAUE,SAAc+D,EAAMnC,EAAOS,QAAQ,EAAG,IAC3B,IAArBvC,UAAUE,SAAc+D,EAAMhC,EAAMD,GACf,IAArBhC,UAAUE,SACV8B,EAAMG,SAASH,EAAK,IACpBC,EAAME,SAASF,EAAK,IACpBgC,EAAMnC,EAAOS,QAAQP,EAAKC,GAG9B,KAAK,GADD0Q,MACK1S,EAAI,EAAOgE,EAAJhE,EAASA,IACrB0S,EAAIrM,KAAKxE,EAAOoR,WAEpB,OAAOP,GAAIpM,KAAK,MAEpB2M,SAAU,SAASlR,EAAKC,GACpB,GAAIgC,EACqB,KAArBjE,UAAUE,SAAc+D,EAAMnC,EAAOS,QAAQ,GAAI,KAC5B,IAArBvC,UAAUE,SAAc+D,EAAMhC,EAAMD,GACf,IAArBhC,UAAUE,SACV8B,EAAMG,SAASH,EAAK,IACpBC,EAAME,SAASF,EAAK,IACpBgC,EAAMnC,EAAOS,QAAQP,EAAKC,GAG9B,KAAK,GADD0Q,MACK1S,EAAI,EAAOgE,EAAJhE,EAASA,IACrB0S,EAAIrM,KAAKxE,EAAO0Q,OAEpB,OAAO1Q,GAAOyQ,WAAWI,EAAIpM,KAAK,MAAQ,KAE9CiM,KAAM,SAASxQ,EAAKC,GAChB,GAAIgC,EACqB,KAArBjE,UAAUE,SAAc+D,EAAMnC,EAAOS,QAAQ,EAAG,KAC3B,IAArBvC,UAAUE,SAAc+D,EAAMhC,EAAMD,GACf,IAArBhC,UAAUE,SACV8B,EAAMG,SAASH,EAAK,IACpBC,EAAME,SAASF,EAAK,IACpBgC,EAAMnC,EAAOS,QAAQP,EAAKC,GAG9B,KAAK,GADD6Q,GAAS,GACJ7S,EAAI,EAAOgE,EAAJhE,EAASA,IACrB6S,GAAUhR,EAAOkB,UAAU,QAE/B,OAAO8P,IAEXK,MAAO,SAASnR,EAAKC,GACjB,GAAIgC,GAAK6O,IACgB,KAArB9S,UAAUE,SAAc+D,EAAMnC,EAAOS,QAAQ,EAAG,IAC3B,IAArBvC,UAAUE,SAAc+D,EAAMhC,EAAMD,GACf,IAArBhC,UAAUE,SACV8B,EAAMG,SAASH,EAAK,IACpBC,EAAME,SAASF,EAAK,IACpBgC,EAAMnC,EAAOS,QAAQP,EAAKC,GAE9B,KAAK,GAAIhC,GAAI,EAAOgE,EAAJhE,EAASA,IACrB6S,EAAOxM,KAAKnG,KAAKoS,WAAWpS,KAAKqS,QAErC,OAAOM,GAAOvM,KAAK,QAG3BzE,EAAOrC,QACH2T,MAAO,WACH,GAAIC,IAAU,QAAS,OAAQ,SAAU,UAAW,UAAW,QAAS,UAAW,UAAW,SAAU,SAAU,cAAe,SAAU,OAAQ,OAAQ,SAAU,SAAU,UAAW,SAAU,SAAU,QAAS,SAAU,UAAW,QAAS,QAAS,UAAW,OAAQ,UAAW,OAAQ,QAAS,UAAW,QAAS,QAAS,QAASC,QAAS,OAAQ,WAAY,QAAS,UAAW,YAAa,WAAY,QAAS,QAAS,WAAY,UAAW,OAAQ,QAAS,QAAS,QAAS,QAAS,SAAU,QAAS,QAAS,OAAQ,SAAU,WAAY,QAAS,QAAS,WAAY,UAAW,UAAW,UAAW,UAAW,SAAU,UAAW,SAAU,MAAO,QAC5pB,OAAOnT,MAAKqH,KAAK6L,IAGrBE,KAAM,WACF,GAAIF,IAAU,QAAS,UAAW,WAAY,QAAS,QAAS,SAAU,QAAS,SAAU,YAAa,SAAU,WAAY,WAAY,SAAU,SAAU,YAAa,QAAS,SAAU,UAAW,WAAY,QAAS,QAAS,MAAO,WAAY,SAAU,QAAS,QAAS,WAAY,SAAU,QAAS,OAAQ,QAAS,QACxU,OAAOlT,MAAKqH,KAAK6L,IAGrB1T,KAAM,SAAS6T,GACX,MAAOrT,MAAKiT,QAAU,KAAOI,EAASrT,KAAKiT,QAAU,IAAM,IAAMjT,KAAKoT,UAG9EzR,EAAOrC,QACHgU,IAAK,WACD,MAAO,UAAYtT,KAAKuT,SAAW,IAAMvT,KAAKqS,QAElDkB,OAAQ,SAASC,GACb,MAAOxT,MAAKqS,OAAS,KAAOmB,GAAOxT,KAAKwT,QAE5CC,MAAO,SAASF,GACZ,MAAOvT,MAAK6C,UAAU,SAAW,IAAM7C,KAAKoT,OAAOrS,cAAgB,IAAMf,KAAKoT,OAAOrS,cAAgB,IAAMf,KAAKwT,OAGpHE,GAAI,WACA,MAAO1T,MAAKoC,QAAQ,EAAG,KAAO,IAAMpC,KAAKoC,QAAQ,EAAG,KAAO,IAAMpC,KAAKoC,QAAQ,EAAG,KAAO,IAAMpC,KAAKoC,QAAQ,EAAG,MAElHuR,MAAQ,MAAO,MAAO,MAAO,MAAO,QAAS,MAAO,MACpDH,IAAK,WACD,MAAOxT,MAAKqH,KAAKrH,KAAK2T,SAG9BhS,EAAOrC,QACHsU,OAAS,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,MAC7CC,KAAM,WACF,MAAO7T,MAAKqH,KAAKrH,KAAK4T,QAE1BE,SAAW,aAAc,aAAc,aAAc,aAAc,gBAAiB,aAAc,aAAc,cAAe,aAAc,aAAc,aAAc,aAAc,aAAc,aAAc,aAAc,aAAc,aAAc,aAAc,aAAc,iBAAkB,aAAc,aAAc,aAAc,aAAc,aAAc,eAAgB,aAAc,aAAc,aAAc,iBAAkB,kBAAmB,kBAAmB,aAAc,iBAAkB,kBACngBC,OAAQ,WACJ,MAAO/T,MAAKqH,KAAKrH,KAAK8T,SAAS9S,MAAM,KAAK,IAE9CgT,QAAS,aACTC,KAAM,aACNC,MAAO,aACPC,SAAU,aACVC,OAAQ,aACRC,gBAAiB,aACjBC,cAAe,aACfC,OAAQ,aACRC,MAAO,aACPC,IAAK,SAAS3Q,GAEV,IAAK,GADD2Q,GAAM,GACD3U,EAAI,GAAQgE,GAAO,GAAZhE,EAAgBA,IAAK2U,GAAOzU,KAAKoC,QAAQ,EAAG,EAC5D,OAAOqS,MAGf9S,EAAOrC,QACHoV,KAAM,WACF,MAAO,UAGf/S,EAAOrC,QACHqV,GAAI,WACA,MAAO3U,MAAKoC,QAAQ,EAAG,IAE3BwS,GAAI,WACA,MAAO5U,MAAKoC,QAAQ,EAAG,IAE3ByS,GAAI,WACA,MAAO7U,MAAKoC,QAAQ,EAAG,IAE3B0S,IAAK,WACD,MAAO9U,MAAKoC,QAAQ,EAAG,KAE3B2S,IAAK,WACD,MAAO/U,MAAKoC,QAAQ,EAAG,KAE3B4S,KAAM,WACF,MAAOhV,MAAKoC,QAAQ,EAAG,MAE3B6S,KAAM,WACF,GAAInS,GAAO,mBAAoBmS,EAAOjV,KAAKuD,OAAOT,EAAM,GAAK,IAAM9C,KAAKuD,OAAOT,EAAM,GAAK,IAAM9C,KAAKuD,OAAOT,EAAM,GAAK,IAAM9C,KAAKuD,OAAOT,EAAM,GAAK,IAAM9C,KAAKuD,OAAOT,EAAM,GAC5K,OAAOmS,IAEXC,GAAI,WACA,GAAIA,GAAIC,EAAM,EAAGC,GAAS,IAAK,IAAK,KAAM,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,KAAM,IAAK,IAAK,IAAK,KAAOhC,GAAS,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAC9K8B,GAAKlV,KAAKqH,KAAKrH,KAAK8T,SAAS9S,MAAM,KAAK,GAAKhB,KAAKqE,KAAK,YAAcrE,KAAKuD,OAAO,SAAU,EAC3F,KAAK,GAAIzD,GAAI,EAAGA,EAAIoV,EAAGnV,OAAQD,IAC3BqV,GAAOD,EAAGpV,GAAKsV,EAAKtV,EAGxB,OADAoV,IAAM9B,EAAK+B,EAAM,KAGrBE,qBAAsB,EACtBC,UAAW,SAASzR,GAChB,MAAO7D,MAAKqV,uBAAyBxR,GAAQ,GAEjD0R,IAAK,SAAS1R,GACV,MAAO7D,MAAKsV,UAAUzR,MAGvBlC,KAGP6T,EAAO,iDAAkDC,EAAS,gBAAiBC,EAAe,yCACtGxW,GAAKI,OAASD,EAAKC,OACnBJ,EAAKyW,KAAO,SAASC,EAAMC,EAAOC,GAC9B,MAAyB,KAArBjW,UAAUE,OAAqBgW,EAAOC,IAAIJ,IACrB,IAArB/V,UAAUE,SACV+V,EAAWD,EACXA,EAAQ5W,GAEZC,EAAKE,QAAQwW,GAAQC,GAAS,MAC1BD,KAAMA,EACNC,MAAOA,EACPC,SAAUA,GAEP5W,GAEX,IAAI6W,IACAzW,OAAQD,EAAKC,OAEjByW,GAAOC,IAAM,SAASF,EAAUtW,EAAMY,GAClC,GAAslBuS,GAAllBsD,GAAczW,EAAOA,GAAQ,IAAIsB,MAAM0U,GAAO9R,EAAQuS,GAAcA,EAAW,IAAMA,EAAW,GAAGnV,MAAM2U,GAAS5T,EAAM6B,GAAS1B,SAAS0B,EAAM,GAAI,IAAK5B,EAAM4B,GAAS1B,SAAS0B,EAAM,GAAI,IAAKwS,EAAQxS,GAASA,EAAM,IAAM1B,SAAS0B,EAAM,GAAI,KAAO/B,EAAOW,QAAQT,EAAKC,GAAO,EAAGqU,EAAUF,GAAcA,EAAW,IAAMA,EAAW,GAAGnV,MAAM2U,GAAShT,EAAO0T,GAAWnU,SAASmU,EAAQ,GAAI,IAAKzT,EAAOyT,GAAWnU,SAASmU,EAAQ,GAAI,IAAKvT,EAASuT,GAAWA,EAAQ,IAAMnU,SAASmU,EAAQ,GAAI,KAAOxU,EAAOW,QAAQG,EAAMC,GAAQ,EAAG0T,EAAQH,GAAcA,EAAW,GAAIzV,EAAOnB,EAAKmB,KAAKsV,EAC3kB,OAAIC,GAAOvV,GACPmS,EAASoD,EAAOvV,IACZA,KAAMA,EACNsV,SAAUA,EACVtW,KAAMA,EACNY,IAAKA,EACL6V,WAAYA,EACZvS,MAAOA,EACP7B,IAAKA,EACLC,IAAKA,EACLoU,MAAOA,EACPC,QAASA,EACT1T,KAAMA,EACNC,KAAMA,EACNE,OAAQA,EACRwT,MAAOA,IAIRN,GAEXC,EAAOzW,QACH+W,MAAO,SAAS9W,GACZ,GAAiBO,GAAGwW,EAAhB3D,IACJ,IAAKpT,EAAQ0W,WAKT,GAAsB,IAAlB1W,EAAQ2W,OAAe3W,EAAQuW,SAAS/V,OAAS,EACjD4S,EAAShR,EAAO0F,KAAK0O,EAAOC,IAAIzW,EAAQuW,eAExC,KAAKhW,EAAI,EAAGA,EAAIP,EAAQ2W,MAAOpW,IAAK,CAChCwW,EAAI,CACJ,GACI3D,GAAOxM,KAAK4P,EAAOC,IAAIzW,EAAQuW,SAASQ,aACnCA,EAAI/W,EAAQuW,SAAS/V,YAXtC,KAAKD,EAAI,EAAGA,EAAIP,EAAQuW,SAAS/V,OAAQD,IACrC6S,EAAOxM,KAAK4P,EAAOC,IAAIzW,EAAQuW,SAAShW,IAchD,OAAO6S,IAEX4D,OAAQ,SAAShX,GACb,GAAiBgB,GAAKgV,EAAlB5C,IACJ,KAAKpS,IAAOhB,GAAQuW,SAChBnD,EAAOpS,EAAIkB,QAAQ+T,EAAM,OAASO,EAAOC,IAAIzW,EAAQuW,SAASvV,GAAMA,EAAKoS,GACzE4C,EAAMhV,EAAIO,MAAM0U,GACZD,GAAOA,EAAI,IAA2C,WAArClW,EAAKmB,KAAKjB,EAAQuW,SAASvV,MAC5ChB,EAAQuW,SAASvV,IAAQyB,SAASuT,EAAI,GAAI,IAGlD,OAAO5C,IAEXzP,OAAQ,SAAS3D,GACb,GAAIoT,GAAQ6D,EAAO1W,CACnB,IAAIP,EAAQ6W,MAAO,CAKf,IAJA7W,EAAQuW,UAAY,GACpBU,EAAQjX,EAAQuW,SAAS9U,MAAM,KAC/BwV,EAAM,GAAKjX,EAAQmE,MAAQnE,EAAQ2W,MAAQM,EAAM,GACjDA,EAAM,IAAMA,EAAM,IAAM,IAAIjS,MAAM,EAAGhF,EAAQqD,QACxC9C,EAAI,EAAG0W,EAAM,GAAGzW,OAASR,EAAQqD,OAAQ9C,IAC1C0W,EAAM,IAAM7U,EAAOkB,UAAU,SAEjC8P,GAAStR,WAAWmV,EAAMpQ,KAAK,KAAM,QAErCuM,GAASpT,EAAQmE,QAAUnE,EAAQ0W,WAAW,GAAK1W,EAAQ2W,MAAQ3W,EAAQuW,QAE/E,OAAOnD,IAEX/Q,UAAW,SAASrC,GAChB,GAAIoT,EAEJ,OADAA,GAASpT,EAAQ0W,WAAatU,EAAOQ,KAAK5C,EAAQsC,IAAKtC,EAAQuC,IAAKvC,EAAQuW,UAAYvW,EAAQuW,UAGpGvS,OAAQ,SAAShE,GACb,GAAiBO,GAAG2W,EAAcC,EAAIC,EAAlChE,EAAS,EACb,IAAIpT,EAAQuW,SAAS/V,OAAQ,CACzB,IAAKD,EAAI,EAAGA,EAAIP,EAAQ2W,MAAOpW,IAC3B6S,GAAUpT,EAAQuW,QAGtB,KADAW,EAAe9D,EAAO7R,MAAM4U,OACvB5V,EAAI,EAAGA,EAAI2W,EAAa1W,OAAQD,IAEjC,GADA4W,EAAKD,EAAa3W,GACd,MAAM8W,KAAKF,GACXD,EAAa5D,OAAO/S,IAAK,OAD7B,CAKA,GADA6W,EAAOZ,EAAOc,YAAYH,EAAInX,EAAQa,KACV,IAAxBqW,EAAa1W,QAAgB2W,IAAO/D,EAAQ,CAC5C,GAAItT,EAAK8B,UAAUwV,GAAO,CACtBhE,EAAStR,WAAWsV,EAAM,GAC1B,OAEJ,GAAI,iBAAiBC,KAAKD,GAAO,CAC7BhE,EAAkB,SAATgE,GAAkB,EAAgB,UAATA,GAAmB,EAAQA,CAC7D,QAGRhE,EAASA,EAAOlR,QAAQiV,EAAIC,QAGhChE,GAASpT,EAAQmE,MAAQ/B,EAAO4B,OAAOhE,EAAQ2W,OAAS3W,EAAQuW,QAEpE,OAAOnD,MAGfoD,EAAOzW,QACHwX,KAAM,WACF,GAAI5Q,KACJ,KAAK,GAAI3F,KAAOoB,GAAQuE,EAAG3F,EAAIQ,eAAiBR,CAChD,OAAO2F,IAEX2Q,YAAa,SAASA,EAAazW,GAC/BsV,EAAaqB,KAAK,GAClB,IAAIP,GAAQd,EAAaqB,KAAKF,GAActW,EAAMiW,GAASA,EAAM,GAAIQ,EAAOzW,GAAOA,EAAIQ,cAAekW,EAAOjX,KAAK8W,OAAOE,GAAOE,EAASV,GAASA,EAAM,GAAKA,EAAM,GAAGxV,MAAM,UAC5K,IAAIZ,GAAOG,IAAOH,GAAK,MAAOA,GAAIG,EAClC,MAAMA,IAAOoB,IAAaqV,IAAQrV,IAAasV,IAAQtV,IAAS,MAAOkV,EACvE,KAAK,GAAI/W,GAAI,EAAGA,EAAIoX,EAAOnX,OAAQD,IAC/B4V,EAAaqB,KAAK,IACdrB,EAAakB,KAAKM,EAAOpX,MACzBoX,EAAOpX,GAAKiW,EAAOc,YAAYK,EAAOpX,GAAIM,GAGlD,IAAI+W,GAASxV,EAAOpB,IAAQoB,EAAOqV,IAASrV,EAAOsV,EACnD,QAAQ5X,EAAKmB,KAAK2W,IAChB,IAAK,QACH,MAAOxV,GAAO0F,KAAK8P,EAErB,KAAK,WACH,GAAIjR,GAAKiR,EAAO3P,MAAM7F,EAAQuV,EAE9B,OADIhR,KAAOjH,IAAWiH,EAAK,IACpBA,MAKnBhH,EAAKkY,QAAU,SAAiBC,GAC5B,QAASC,KACL,OACIC,KAAMF,EAAO3V,KACb8V,KAAMH,EAAO3V,KACb+V,sBAAuBJ,EAAO3V,KAC9BgW,WAAY,EACZC,OAAQ,KAGhB,QAASC,GAAQjC,GACb,MAAO,YACH,MAAOzW,GAAKyW,KAAK0B,EAAOQ,WAAWlC,EAAKG,UAAYH,EAAKG,WAAaH,EAAKG,WAGnF,QAASgC,GAAUvY,GACf,IAAK,GAAIwY,KAAQ7Y,GAAKE,QAAS,CAC3B,GAAIuW,GAAOzW,EAAKE,QAAQ2Y,EACxB,KAA+B,WAA3BV,EAAO7W,KAAKmV,EAAKC,OACbD,EAAKC,OAASrW,EAAQ+T,OAEC,WAA3B+D,EAAO7W,KAAKmV,EAAKC,OACZD,EAAKC,KAAKgB,KAAKrX,EAAQ+T,MADhC,CAGA/T,EAAQyY,WAAaJ,EAAQjC,GAC7BpW,EAAQ0Y,WAAW,aAAeL,EAAQjC,GAC1CpW,EAAQ2Y,IAAMZ,CACd,SAMR,MAHAD,GAAOc,cAAc,IAAKL,GAC1BT,EAAOc,cAAc,OAAQL,GAC7BT,EAAOc,cAAc,QAASL,GACvB5Y,GAEU,mBAAVmY,SAAuBnY,EAAKkY,QAAQC,QAC3B,mBAATe,QAAwBA,MAAMC,MACrCnZ,EAAKkY,QAAU,SAAiBgB,GAC5B,GAAIE,GAAiBF,EAAMG,GACvBL,GACAR,WAAY,EACZc,aAAc,GACdC,YAAa,KACbjE,MAAO,EACPmD,OAAQ,IACRe,WAAY,UACZC,aAAc,KAElBP,GAAMG,GAAK,SAAShZ,GAChB,IAAK,GAAIwY,KAAQ7Y,GAAKE,QAAS,CAC3B,GAAIuW,GAAOzW,EAAKE,QAAQ2Y,EACxB,KAA8B,WAA1BK,EAAM5X,KAAKmV,EAAKC,OACZD,EAAKC,OAASrW,EAAQ+T,OAEA,WAA1B8E,EAAM5X,KAAKmV,EAAKC,OACXD,EAAKC,KAAKgB,KAAKrX,EAAQ+T,MADhC,CAGAsF,QAAQC,IAAI,SAAUtZ,EAAQ+T,IAAK,IAAKqC,EAAKC,KAC7C,IAAIkD,GAAO5Z,EAAKyW,KAAKA,EAAKG,SAI1B,OAHA8C,SAAQC,IAAI,SAAUC,GAClBvZ,EAAQwZ,SAASxZ,EAAQwZ,QAAQD,EAAM,UAAWZ,GAClD3Y,EAAQyZ,UAAUzZ,EAAQyZ,SAASF,EAAM,UAAWZ,GACjDE,GAEX,MAAOE,GAAe9Q,MAAMxH,KAAMH,cAK9CX,EAAKG,KAAOA,EACZH,EAAKyC,OAASA,EACdzC,EAAKqC,QAAUlC,EAAKkC,QACE,gBAAX0X,SAAuBA,OAAOC,QACrCD,OAAOC,QAAUha,EACQ,kBAAXia,SAAyBA,OAAOC,IAC9CD,OAAO,WACH,MAAOja,KAEc,kBAAXia,SAAyBA,OAAOE,KAC9CF,OAAO,WACH,MAAOja,KAGfc,KAAKd,KAAOA,EACZc,KAAK2B,OAASA,EACM,mBAATyW,QACP/Y,EAAKc,MAAO,OAAQ,wBAAyB,iBAAkB,2BAA4B,4BAA8B,SAAkBX,GACvI4Y,MAAMC,IAAI7Y,EAAM,SAASqG,GAErB,MADA3G,GAAKkY,QAAQvR,GACN3G,IAEPoa,UAAY,YAKxB,SAAUra,GACN,GAAIsa,IACApa,QAAS,QAERa,MAAKd,OAAM+Z,OAAOC,QAAUK,GACjCra,EAAKsa,IAAM,SAASC,EAAOla,EAASma,EAASC,GACzC,MAAOJ,GAAS5D,KAAK8D,EAAOla,EAASma,EAASC,IAElDza,EAAK0a,MAAQ,SAASH,GAClB,MAAOI,YAAWD,MAAMH,IAE5BF,EAAS5D,KAAO,SAAS8D,EAAOla,EAASma,EAASC,GAG9C,MAFAD,GAAUA,EAAUra,EAAKC,UAAWoa,EAASG,WAAWH,SAAWG,WAAWH,QAC9EC,EAAWA,EAAWta,EAAKC,UAAWqa,EAAUE,WAAWF,UAAYE,WAAWF,SAC3E5D,EAAOC,IAAIyD,EAAO,KAAMla,EAASma,EAASC,GAErD,IAAI5D,IACA+D,MAAOP,EAASO,QAAS,EACzBxa,OAAQD,EAAKC,OAEjByW,GAAOC,IAAM,SAAS+D,EAAMzZ,EAASf,EAASma,EAASC,GACnD,GAAIta,EAAK2a,SAASD,GAAO,CACrB,GAAIE,GAAMJ,WAAWD,MAAMG,EAC3Bxa,GAAUwW,EAAOmE,aAAaH,EAAMxa,EACpC,IAAIuZ,GAAO/C,EAAOC,IAAIiE,EAAK3Z,EAASf,EAASma,EAASC,EACtD,OAAOb,GAIX,GAFAxY,EAAUA,QACVf,EAAUA,MACNS,KAAK+Z,EAAKvZ,QAAUnB,EAAKqC,KAA7B,CACAnC,EAAQ4a,OAAS5a,EAAQ4a,YACrBZ,EAASO,OAAS/D,EAAO+D,SACzBlB,QAAQC,MACRD,QAAQwB,MAAM,IAAML,EAAKvZ,KAAO,IAAK6Z,KAAKC,UAAUP,IACpDnB,QAAQC,IAAI,YAAatZ,EAAQ4a,OAAOpa,OAAQsa,KAAKC,UAAU/a,IAEnE,IAAIgb,GAAYhb,EAAQ4a,OAAOpa,MAM/B,OALAC,MAAK+Z,EAAKvZ,MAAMuZ,EAAMzZ,EAASf,EAASma,EAASC,GACjDpa,EAAQ4a,OAAOtH,OAAO0H,IAClBhB,EAASO,OAAS/D,EAAO+D,QACzBlB,QAAQ4B,WAELla,EAAQA,EAAQP,OAAS,KAEpCgW,EAAOmE,aAAe,SAAST,EAAOla,GAClC,GACgDO,GAAG2a,EAAIC,EADnDC,EAAW,2CACXC,EAAWnB,EAAM3Y,MAAM6Z,GAAWhY,IACtC,KAAK7C,EAAI,EAAG8a,GAAY9a,EAAI8a,EAAS7a,OAAQD,IACzC6a,EAASE,UAAY,EACrBJ,EAAKE,EAAS5D,KAAK6D,EAAS9a,IACxB2a,IACAC,EAAS,GAAII,UAAS,UAAYL,EAAG,IACrCC,EAASA,IACTrb,EAAKC,OAAOqD,EAAK+X,GAGzB,OAAOrb,GAAKC,OAAOqD,EAAKpD,IAE5BwW,EAAOgF,IAAM,SAASvb,EAAMD,EAASe,EAAS0a,GAC1C,GAAIxb,IAASD,EAAQ4a,OAAO5a,EAAQ4a,OAAOpa,OAAS,GAAI,KAAM,IAAIkb,OAAMzb,EAAO,MAAQD,EAAQ4a,OAG/F,KAFIZ,EAASO,OAAS/D,EAAO+D,QAAOlB,QAAQC,IAAI,YAAarZ,EAAMD,EAAQ4a,QACvEa,IAAQ/b,IAAW+b,EAAM9b,EAAKyW,KAAKqF,IACnCzb,EAAS,CACT,GAAI2b,GAAShc,EAAKyW,KAAKpW,EACvB,IAAIF,EAAK2a,SAASkB,GAAS,MAAOA,EAClC,IAAI1b,IAAQ0b,GACR,MAAOA,GAAO1b,GAGtB,MAAIH,GAAKY,QAAQK,EAAQ,OAClB0a,IAAQ/b,EAAY+b,EAAMxb,GAAQmC,EAAO0Q,QAEpD0D,EAAOoF,QAAU,SAASpB,EAAMzZ,EAASf,EAASma,EAASC,GACvD,IAAK,GAAI7Z,GAAI,EAAGA,EAAIia,EAAKqB,WAAWrb,OAAQD,IACxCE,KAAKgW,IAAI+D,EAAKqB,WAAWtb,GAAIQ,EAASf,EAASma,EAASC,IAGhE5D,EAAOsF,SAAW,SAAStB,EAAMzZ,EAASf,EAASma,EAASC,GACxD,GAAI7Z,GAAGwb,EAAiBhb,EAAQ,GAAIib,EAAgBjb,EAAQP,MAM5D,IALkC,UAA9BV,EAAKmB,KAAK8a,KACVA,EAAenV,SACfmV,EAAiBA,EAAeA,EAAevb,OAAS,GACxDO,EAAQkb,QAAQF,IAEhBvB,EAAK0B,UAAY/B,GAAWA,EAAQK,EAAK7E,GAAG3R,QAAS,CACrD,GAA2B,IAAvBwW,EAAK7C,OAAOnX,YACZ,KAAKD,EAAI,EAAGA,EAAIia,EAAK7C,OAAOnX,OAAQD,IAChCE,KAAKgW,IAAI+D,EAAK7C,OAAOpX,GAAIQ,EAASf,EAASma,EAASC,EAGxDI,GAAK2B,MAAM1b,KAAKgW,IAAI+D,EAAK2B,KAAMpb,EAASf,EAASma,EAASC,OAE9D3Z,MAAKgW,IAAI+D,EAAK7E,GAAI5U,EAASf,EAASma,EAASC,EAE7CrZ,GAAQP,OAASwb,GAAejb,EAAQuS,OAAO,EAAGvS,EAAQP,OAASwb,IAE3ExF,EAAO4F,MAAQ,SAAS5B,EAAMzZ,EAASf,EAASma,EAASC,GACrD,GAAoC7Z,GAAGgE,EAAK/B,EAAKgZ,EAAKva,EAAlDgW,EAAQuD,EAAKsB,SAASnG,GAAGsB,MAA+B8E,EAAiBhb,EAAQ,GAAIib,EAAgBjb,EAAQP,MAEjH,IADIga,EAAK6B,QACL7B,EAAKsB,SAASI,UAAY/B,GAAWA,EAAQK,EAAKsB,SAASnG,GAAG3R,QAC9D/C,EAAOgW,EAAM,GACbuE,GAAOc,EAAQrb,IAASqb,EAAQC,QAAQtU,MAAMxH,KAAMH,WACpDyb,EAAiBhb,EAAQ,OAEzB,KAAKR,EAAI,EAAGA,EAAI0W,EAAMzW,OAAQD,IAC1BP,EAAQ4a,OAAOhU,KAAKqQ,EAAM1W,IAC1BiC,EAAMyU,EAAM1W,GACZib,EAAM/a,KAAK+a,IAAIhZ,EAAKxC,EAASe,MAC7Bgb,EAAevZ,GAAO1C,EAAKY,QAAQ8a,QAAcA,EACjDva,EAAOnB,EAAKmB,KAAK8a,EAAevZ,KACnB,WAATvB,GAA8B,UAATA,KACrB8a,EAAiBA,EAAevZ,GAChCzB,EAAQkb,QAAQF,GAI5B,IAAIvB,EAAKoB,QACL,GAAkC,UAA9B9b,EAAKmB,KAAK8a,GAEV,IADAxX,EAAMiX,EAAIhb,QAAU4B,EAAOW,QAAQ,EAAG,GACjCxC,EAAI,EAAOgE,EAAJhE,EAASA,IACjBwb,EAAenV,KAAuB,mBAAX4U,GAAIjb,GAAqBib,EAAIjb,OACxDP,EAAQ4a,OAAOhU,KAAK,MACpB7F,EAAQkb,QAAQF,EAAeA,EAAevb,OAAS,IACvDC,KAAKgW,IAAI+D,EAAKoB,QAAS7a,EAASf,EAASma,EAASC,GAClDpa,EAAQ4a,OAAO4B,MACfzb,EAAQ0b,YAEThc,MAAKgW,IAAI+D,EAAKoB,QAAS7a,EAASf,EAASma,EAASC,EAEzDrZ,GAAQP,OAASwb,GAAejb,EAAQuS,OAAO,EAAGvS,EAAQP,OAASwb,IAE3ExF,EAAO2F,KAAO,SAAS3B,EAAMzZ,EAASf,EAASma,EAASC,GACpD,GAAwBsC,GAAMnc,EAAGwW,EAA7B4F,EAAQnC,EAAKmC,KACjB,KAAKpc,EAAI,EAAGA,EAAIoc,EAAMnc,OAAQD,IAE1B,IADAmc,EAAOC,EAAMpc,GACRwW,EAAI,EAAGA,EAAI2F,EAAKlc,OAAQuW,IACzBtW,KAAKgW,IAAIiG,EAAK3F,GAAIhW,EAASf,EAASma,EAASC,IAIzD5D,EAAOoG,GAAK,SAASpC,EAAMzZ,EAASf,GAChC,GAAwBO,GAAGgE,EAAK/B,EAAKqa,EAAMpB,EAAKD,EAAKva,EAAM6b,EAASC,EAAhE9F,EAAQuD,EAAKvD,MAA+D8E,EAAiBhb,EAAQyZ,EAAKwC,OAAQhB,EAAgBjb,EAAQP,MAE9I,IADIV,EAAKY,QAAQqb,KAAiBA,EAAiBhb,EAAQyZ,EAAKwC,MAAQ,IACnE/F,EAAMzW,OACP,IAAKD,EAAI,EAAGgE,EAAM0S,EAAMzW,OAAY+D,EAAJhE,EAASA,IACrCP,EAAQ4a,OAAOhU,KAAKqQ,EAAM1W,IAC1BiC,EAAMyU,EAAM1W,GACZsc,EAAO5F,EAAM1W,EAAI,GACjBwc,EAAa/c,EAAQ6c,GACrBpB,EAAMlb,IAAMgE,EAAM,EAAIwX,EAAevZ,MACrCgZ,EAAM/a,KAAK+a,IAAIhZ,EAAKxC,EAASe,EAAS0a,GACtCxa,EAAOnB,EAAKmB,KAAK8a,EAAevZ,IAChCsa,EAAUhd,EAAKmB,KAAKua,GACP,cAATva,EAEI8a,EAAevZ,GADX+B,EAAM,EAAVhE,GAA2B,WAAZuc,GAAoC,UAAZA,KAGjBhd,EAAKY,QAAQ8a,QAAcA,EAG7CjX,EAAM,EAAVhE,GAAwB,WAATU,GAA8B,UAATA,IACpC8a,EAAevZ,GAAO1C,EAAKY,QAAQ8a,YAG3Cva,EAAOnB,EAAKmB,KAAK8a,EAAevZ,KACnB,WAATvB,GAA8B,UAATA,KACrB8a,EAAiBA,EAAevZ,GAChCzB,EAAQkb,QAAQF,SAIxBhb,EAAQP,OAASwb,GAAejb,EAAQuS,OAAO,EAAGvS,EAAQP,OAASwb,IAE3ExF,EAAOyG,QAAU,SAASzC,EAAMzZ,EAASf,EAASma,EAASC,GACvD,GAAIna,GAAOua,EAAK0C,YAAYjd,KAAMgd,EAAU7C,GAAYA,EAASna,GAAO+b,EAAgBjb,EAAQP,MAC5Fyc,IAASzG,EAAOC,IAAIwG,EAASlc,EAASf,EAASma,EAASC,GACxDrZ,EAAQP,OAASwb,GAAejb,EAAQuS,OAAO,EAAGvS,EAAQP,OAASwb,IAE3ExF,EAAO2G,QAAUrd,EAAKqC,KACtBqU,EAAO4G,aAAetd,EAAKqC,KAC3BqU,EAAO6G,KAAOvd,EAAKqC,KACnBqU,EAAO8G,OAASxd,EAAKqC,KACrBqU,EAAO+G,QAAUzd,EAAKqC,KACtBqU,EAAOgH,QAAU1d,EAAKqC,KACtBqU,EAAOiH,QAAU3d,EAAKqC,IACtB,IAAIma,KACJA,GAAQ1b,KAAO,SAAS4Z,EAAMzZ,EAASf,GACnC,GAAIO,GAAGgE,EAAK/B,EAAKgZ,EAAKvE,EAAOwE,EAAKxa,EAAM8a,EAAiBhb,EAAQ,EAEjE,KADAkW,EAAQuD,EAAKsB,SAASnE,OAAO,GAAGV,MAC3B1W,EAAI,EAAGgE,EAAM0S,EAAMzW,OAAY+D,EAAJhE,EAASA,IACrCP,EAAQ4a,OAAOhU,KAAKqQ,EAAM1W,IAC1BiC,EAAMyU,EAAM1W,GACZkb,EAAMlb,IAAMgE,EAAM,QAClBiX,EAAM/a,KAAK+a,IAAIhZ,EAAKxC,EAASe,EAAS0a,GACtCM,EAAevZ,GAAO1C,EAAKY,QAAQ8a,QAAcA,EACjDva,EAAOnB,EAAKmB,KAAK8a,EAAevZ,KACnB,WAATvB,GAA8B,UAATA,KACrB8a,EAAiBA,EAAevZ,GAChCzB,EAAQkb,QAAQF,GAGxB,OAAOP,IAEXc,EAAQ,MAAQA,EAAQoB,OAAS,SAASlD,EAAMzZ,EAASf,GACrD,GAAmCO,GAAGwW,EAAGvU,EAAKgZ,EAAKvE,EAAOwE,EAAKxa,EAA3D0W,EAAS6C,EAAKsB,SAASnE,OAA0CoE,EAAiBhb,EAAQ,EAC9F,KAAKR,EAAI,EAAGA,EAAIoX,EAAOnX,OAAQD,IAE3B,IADA0W,EAAQU,EAAOpX,GAAG0W,MACbF,EAAI,EAAGA,EAAIE,EAAMzW,OAAQuW,IAChB,IAANxW,GAASP,EAAQ4a,OAAOhU,KAAKqQ,EAAMF,IACvCvU,EAAMyU,EAAMF,GACZ0E,EAAM1E,IAAME,EAAMzW,OAAS,EAAI,qBAC/Bgb,EAAM/a,KAAK+a,IAAIhZ,EAAKxC,EAASe,EAAS0a,GAClC1E,IAAME,EAAMzW,OAAS,IACrBgb,EAAc,SAARA,GAAiB,EAAe,UAARA,GAAkB,EAAQA,GAE5DO,EAAevZ,GAAO1C,EAAKY,QAAQ8a,MAAYA,EAC/Cva,EAAOnB,EAAKmB,KAAK8a,EAAevZ,KACnB,WAATvB,GAA8B,UAATA,KACrB8a,EAAiBA,EAAevZ,GAChCzB,EAAQkb,QAAQF,GAI5B,OAAOP,IAEXc,EAAQ,QAAU,SAAS9B,EAAMzZ,EAASf,GACtC,GAAIO,GAAGiC,EAAKgZ,EAAKvE,EAAOwE,EAAKM,EAAiBhb,EAAQ,EAEtD,KADAkW,EAAQuD,EAAKsB,SAASnE,OAAO,GAAGV,MAC3B1W,EAAI,EAAGA,EAAI0W,EAAMzW,OAAQD,IAC1BP,EAAQ4a,OAAOhU,KAAKqQ,EAAM1W,IAC1BiC,EAAMyU,EAAM1W,GACZkb,KACAD,EAAM/a,KAAK+a,IAAIhZ,EAAKxC,EAASe,EAAS0a,GACtCM,EAAiBA,EAAevZ,GAAOgZ,EACvCza,EAAQkb,QAAQF,EAEpB,OAAOP,IAEXc,EAAQhD,IAAM,aACdgD,EAAQC,OAAS,SAAS/B,EAAMzZ,EAASf,GACrC,GAAIO,GAAGgE,EAAK/B,EAAKgZ,EAAKvE,EAAOwE,EAAKxa,EAAM8a,EAAiBhb,EAAQ,EACjE,IAAoC,IAAhCyZ,EAAKsB,SAASnE,OAAOnX,OAAzB,CAcI,IADAyW,EAAQuD,EAAKsB,SAASnE,OAAO,GAAGV,MAC3B1W,EAAI,EAAGgE,EAAM0S,EAAMzW,OAAY+D,EAAJhE,EAASA,IACrCP,EAAQ4a,OAAOhU,KAAKqQ,EAAM1W,IAC1BiC,EAAMyU,EAAM1W,GACZkb,EAAMlb,IAAMgE,EAAM,QAClBiX,EAAM/a,KAAK+a,IAAIhZ,EAAKxC,EAASe,EAAS0a,GACtCM,EAAevZ,GAAO1C,EAAKY,QAAQ8a,QAAcA,EACjDva,EAAOnB,EAAKmB,KAAK8a,EAAevZ,KACnB,WAATvB,GAA8B,UAATA,KACrB8a,EAAiBA,EAAevZ,GAChCzB,EAAQkb,QAAQF,GAI5B,OAAOP,MAEZta,KAAKT,MAER,SAAUf,GACN,GAAqB,mBAAVmZ,OAAX,CACA,GAGI8E,GAHAC,GACArD,OAAO,EAGX1B,OAAMgF,IAAI,YAAa,SAASvX,EAAGwX,GAC/BH,EAAYG,IAEXrd,KAAKd,OAAM+Z,OAAOC,QAAUiE,GACjCje,EAAKoe,KAAO,SAAS7D,EAAOla,EAASma,EAASC,GAC1C,MAAOwD,GAAUxH,KAAK8D,EAAOla,EAASma,EAASC,IAEnDza,EAAKqe,OAAS,SAAS9D,GACnB,MAAOyD,GAAUM,SAAS5D,MAAMH,IAEpC0D,EAAUxH,KAAO,SAAS8D,EAAOla,EAASma,EAASC,GAG/C,MAFAD,GAAUA,EAAUra,EAAKC,UAAWoa,EAASwD,EAAUO,QAAQC,UAAYR,EAAUO,QAAQC,SAC7F/D,EAAWA,EAAWta,EAAKC,UAAWqa,EAAUuD,EAAUO,QAAQE,SAAWT,EAAUO,QAAQE,QACxF3d,KAAKgW,IAAIyD,EAAO,KAAMla,EAASma,EAASC,OAEnDwD,EAAUvD,MAAQ,SAASH,GACvB,MAAOyD,GAAUM,SAAS5D,MAAMH,IAEpC0D,EAAUnH,IAAM,SAAS+D,EAAMzZ,EAASf,EAASma,EAASC,EAAUiE,GAChE,GAAoB,gBAAT7D,GAAmB,CACtBoD,EAAUrD,OACVlB,QAAQC,IAAI,cAAekB,EAE/B,IAAIE,GAAMja,KAAK4Z,MAAMG,EACrBxa,GAAUS,KAAKka,aAAaH,EAAMxa,EAClC,IAAIuZ,GAAO9Y,KAAKgW,IAAIiE,EAAK3Z,EAASf,EAASma,EAASC,EAAUiE,EAC9D,OAAO9E,GAKX,GAHAxY,EAAUA,QACVf,EAAUA,MACVwa,EAAKvZ,KAAOuZ,EAAKvZ,KACbR,KAAK+Z,EAAKvZ,QAAUnB,EAAKqC,KAA7B,CACAnC,EAAQ4a,OAAS5a,EAAQ4a,WACrBgD,EAAUrD,QACVlB,QAAQC,MACRD,QAAQwB,MAAM,IAAML,EAAKvZ,KAAO,IAAK6Z,KAAKC,UAAUP,IACpDnB,QAAQC,IAAI,YAAa,WAAYvY,EAAQP,OAAQsa,KAAKC,UAAUha,IACpEsY,QAAQC,IAAI,YAAa,WAAYtZ,EAAQ4a,OAAOpa,OAAQsa,KAAKC,UAAU/a,IAC3EqZ,QAAQC,IAAI,YAAa,WAAYwB,KAAKC,UAAUsD,IAExD,IAAIrD,GAAYhb,EAAQ4a,OAAOpa,MAY/B,OAXAC,MAAK+Z,EAAKvZ,MAAMuZ,EAAMzZ,EAASf,EAASma,EAASC,EAAUiE,GACvDT,EAAUrD,OACVlB,QAAQC,IAAI,YAAa,WAAYtZ,EAAQ4a,UAE5CyD,EAAMC,MAA8B,kBAAfD,GAAMC,OAAwBD,EAAMC,KAAK9D,EAAMxa,EAASe,KAC9Ef,EAAQ4a,OAAOtH,OAAO0H,GAEtB4C,EAAUrD,QACVlB,QAAQC,IAAI,YAAa,WAAYvY,EAAQP,OAAQsa,KAAKC,UAAUha,IACpEsY,QAAQ4B,YAELla,EAAQA,EAAQP,OAAS,KAEpCod,EAAUjD,aAAe,SAAST,EAAOla,GACrC,GACgDO,GAAG2a,EAAIC,EADnDC,EAAW,2CACXC,EAAWnB,EAAM3Y,MAAM6Z,GAAWhY,IACtC,KAAK7C,EAAI,EAAG8a,GAAY9a,EAAI8a,EAAS7a,OAAQD,IACzC6a,EAASE,UAAY,EACrBJ,EAAKE,EAAS5D,KAAK6D,EAAS9a,IACxB2a,IACAC,EAAS,GAAII,UAAS,UAAYL,EAAG,IACrCC,EAASA,IACTrb,EAAKC,OAAOqD,EAAK+X,GAGzB,OAAOrb,GAAKC,OAAOqD,EAAKpD,IAE5B4d,EAAUW,SAAW,SAASC,EAAMxH,GAChC,QAASyH,GAAWC,EAAM3d,GACtB,GAAuB,gBAAZA,IAAwB2d,IAAQ3d,GAAS,OAASA,EAAQ2d,GAErE,KAAK,GADDtb,MACK7C,EAAI,EAAGA,EAAIQ,EAAQP,OAAQD,IAChC6C,EAAIwD,KAAKqB,MAAM7E,EAAKub,EAAMD,GAAQ3d,EAAQR,KAE9C,OAAO6C,GAEX,QAASwb,GAAYF,EAAM3d,GACvB,GAAuB,gBAAZA,IAAwB2d,IAAQ3d,GAAS,OAASA,EAAQ2d,GACrE,IAAItb,KACJ,KAAK,GAAIpC,KAAOD,GACZqC,EAAIwD,KAAKqB,MAAM7E,EAAKub,EAAMD,GAAQ3d,EAAQC,KAE9C,OAAOoC,GAEX,QAASub,GAAMD,EAAMG,GAEjB,IAAK,GADDzb,MACK7C,EAAI,EAAGA,EAAIse,EAAIre,OAAQD,IACN,gBAAXse,GAAIte,KACXme,IAAQG,GAAIte,GAAI6C,EAAIwD,KAAKiY,EAAIte,GAAGme,IAChCtb,EAAIwD,KAAKqB,MAAM7E,EAAKtD,EAAKY,QAAQme,EAAIte,IAAMke,EAAWC,EAAMG,EAAIte,IAAMqe,EAAYF,EAAMG,EAAIte,KAGpG,OAAO6C,GAEX,QAASiX,GAAMmE,EAAMzd,GAEjB,IADA,GAAIkW,GAAwB,gBAATuH,GAAoBA,EAAK/c,MAAM,KAAO+c,EAAKxZ,MAAM,GAAI6Z,GAAQ9d,GACzEkW,EAAMzW,QACTqe,EAAMF,EAAM1H,EAAMwF,QAASoC,EAE/B,OAAOA,GAEX,MAAOxE,GAAMmE,EAAMxH,IAEvB4G,EAAUpC,IAAM,SAASvb,EAAMD,EAASe,EAAS0a,GAC7C,GAAIxb,IAASD,EAAQ4a,OAAO5a,EAAQ4a,OAAOpa,OAAS,GAAI,KAAM,IAAIkb,OAAMzb,EAAO,MAAQD,EAAQ4a,OAE/F,IADIa,IAAQ/b,IAAW+b,EAAM9b,EAAKyW,KAAKqF,IACnCzb,EAAS,CACT,GAAI2b,GAAShc,EAAKyW,KAAKpW,EACvB,IAAIF,EAAK2a,SAASkB,GAAS,MAAOA,EAClC,IAAIvY,GAAMwa,EAAUW,SAASve,EAAQ4a,OAAQe,EAC7C,IAAIvY,EAAI5C,OAAS,EAAG,MAAO4C,GAAI,EAC/B,IAAInD,IAAQ0b,GACR,MAAOA,GAAO1b,GAGtB,MAAIH,GAAKY,QAAQK,EAAQ,OAClB0a,IAAQ/b,EAAY+b,EAAMxb,GAErC2d,EAAUhC,QAAU,SAASpB,EAAMzZ,EAASf,EAASma,EAASC,EAAUiE,GACpE,IAAK,GAAI9d,GAAI,EAAGA,EAAIia,EAAKqB,WAAWrb,OAAQD,IACxCE,KAAKgW,IAAI+D,EAAKqB,WAAWtb,GAAIQ,EAASf,EAASma,EAASC,EAAUiE,EAEtE,KAAK,GAAItH,GAAI,EAAGyD,EAAK6B,SAAWtF,EAAIyD,EAAK6B,QAAQ7b,OAAQuW,IACrDtW,KAAKgW,IAAI+D,EAAK6B,QAAQtF,GAAIhW,EAASf,EAASma,EAASC,EAAUiE,IAGvET,EAAUxB,MAAQ,SAAS5B,EAAMzZ,EAASf,EAASma,EAASC,EAAUiE,GAClE,GAAIrC,GAAgBjb,EAAQP,MAC5BC,MAAKgW,IAAI+D,EAAKP,IAAKlZ,EAASf,EAASma,EAASC,EAAUta,EAAKC,UAAWse,GACpE5C,OACA6C,MAAM,IAEV,IAAiC3C,GAAQpb,EAAGgE,EAAxCwX,EAAiBhb,EAAQ,EAC7B,IAAkC,UAA9BjB,EAAKmB,KAAK8a,GAGV,IAFAJ,EAASlb,KAAK+a,IAAIxb,EAAQ4a,OAAO5a,EAAQ4a,OAAOpa,OAAS,GAAIR,EAASe,GACtEwD,EAAMoX,GAAUA,EAAOnb,QAAU4B,EAAOW,QAAQ,EAAG,GAC9CxC,EAAI,EAAOgE,EAAJhE,EAASA,IACjBwb,EAAenV,KAAK+U,GAAUA,EAAOpb,KAAOb,EAAYic,EAAOpb,OAC/DP,EAAQ4a,OAAOhU,KAAKrG,GACpBQ,EAAQkb,QAAQF,EAAeA,EAAevb,OAAS,IACvDC,KAAKgW,IAAI+D,EAAKoB,QAAS7a,EAASf,EAASma,EAASC,EAAUiE,GAC5Dre,EAAQ4a,OAAO4B,MACfzb,EAAQ0b,YAEThc,MAAKgW,IAAI+D,EAAKoB,QAAS7a,EAASf,EAASma,EAASC,EAAUiE,KAC9DA,EAAMC,MAA8B,kBAAfD,GAAMC,OAAwBD,EAAMC,KAAK9D,EAAMxa,EAASe,KAC9EA,EAAQuS,OAAO,EAAGvS,EAAQP,OAASwb,IAG3C4B,EAAU3D,IAAM,SAASO,EAAMzZ,EAASf,EAASma,EAASC,EAAUiE,GAChE,GAAI7D,EAAK7C,QAAU6C,EAAK7C,OAAOnX,OAAQ,CACnC6d,EAAQve,EAAKC,UAAWse,GACpB5C,KACI7a,QACAke,KAAM,kBACNpB,OAAQ,mBACRqB,WACFvE,EAAKwE,KAAKhb,QACZsa,MACI1d,MAAM,EACNke,KAAM,SAASG,EAAGC,EAAIC,EAAKlf,EAAMyB,GAC7B,MAAwB,gBAAVA,IAElBgc,OAAQ,SAASuB,EAAGC,EAAIC,EAAKlf,EAAMyB,GAC/B,MAAwB,gBAAVA,IAElBqd,QAAQ,EACRK,SAAS,GACX5E,EAAKwE,KAAKhb,SAEhB,KAAK,GAAWkW,GAAP3Z,EAAI,EAAUA,EAAIia,EAAK7C,OAAOnX,OAAQD,IAEvC2Z,EADqB,YAArBM,EAAKwE,KAAKhb,OACFoW,GAAYA,EAASI,EAAK7C,OAAOpX,GAAGmB,OACjC8Y,EAAK7C,OAAOpX,GACvB2Z,GAAOzZ,KAAKgW,IAAIyD,EAAOnZ,EAASf,EAASma,EAASC,EAAUiE,EAEhE7D,GAAK2B,MACL1b,KAAKgW,IAAI+D,EAAK2B,KAAMpb,EAASf,EAASma,EAASC,EAAUiE,OAG7D5d,MAAKgW,IAAI+D,EAAKwE,KAAMje,EAASf,EAASma,EAASC,EAAUiE,IAGjET,EAAUyB,cAAgB,SAAS7E,EAAMzZ,EAASf,EAASma,EAASC,EAAUiE,GAC1E5d,KAAKgW,IAAI+D,EAAK8E,WAAYve,EAASf,EAASma,EAASC,EAAUiE,IAEnET,EAAUT,QAAUrd,EAAKqC,KACzByb,EAAU2B,gBAAkBzf,EAAKqC,KACjCyb,EAAU4B,yBAA2B5B,EAAU6B,mBAAqB,SAASjF,EAAMzZ,EAASf,EAASma,EAASC,EAAUiE,GACpH5d,KAAKgW,IAAI+D,EAAKkF,IAAK3e,EAASf,EAASma,EAASC,EAAUta,EAAKC,UAAWse,GACpE5C,IAAK,WACD,MAAyB,WAAlBjB,EAAKmF,IAAI1e,KAAoBuZ,EAAKmF,IAAIje,MAAMqG,QAAQ,KAAO,GAAK3F,EAAOa,OAAOP,KAAKkd,IAAI,GAAI,IAAKld,KAAKkd,IAAI,GAAI,IAAK,EAAGld,KAAKkd,IAAI,GAAI,IAAMxd,EAAOW,UAAYrD,QAG1Ke,KAAKgW,IAAI+D,EAAKmF,IAAK5e,EAASf,EAASma,EAASC,EAAUta,EAAKC,UAAWse,GACpE5C,IAAK,WACD,MAAyB,WAAlBjB,EAAKkF,IAAIze,KAAoBuZ,EAAKkF,IAAIhe,MAAMqG,QAAQ,KAAO,GAAK3F,EAAOa,OAAOP,KAAKkd,IAAI,GAAI,IAAKld,KAAKkd,IAAI,GAAI,IAAK,EAAGld,KAAKkd,IAAI,GAAI,IAAMxd,EAAOW,UAAYrD,SAI9Kke,EAAUiC,qBAAuB,SAASrF,EAAMzZ,EAASf,EAASma,EAASC,EAAUiE,GACjF5d,KAAKgW,IAAI+D,EAAKkF,IAAK3e,EAASf,EAASma,EAASC,EAAUiE,GACxD5d,KAAKgW,IAAI+D,EAAKmF,IAAK5e,EAASf,EAASma,EAASC,EAAUiE,IAE5DT,EAAUkC,mBAAqBhgB,EAAKqC,KACpCyb,EAAUmC,yBAA2BjgB,EAAKqC,KAC1Cyb,EAAUoC,wBAA0BlgB,EAAKqC,KACzCyb,EAAU5Z,OAASlE,EAAKqC,KACxByb,EAAUja,OAAS7D,EAAKqC,KACxByb,EAAUvb,QAAUvC,EAAKqC,KACzByb,EAAUzB,KAAO,SAAS3B,EAAMzZ,EAASf,EAASma,EAASC,EAAUiE,GACjE,GAAwBrd,GAApB2b,EAAQnC,EAAK9Y,KACjB,KAAKV,IAAO2b,GACRlc,KAAKgW,IAAIkG,EAAM3b,GAAMD,EAASf,EAASma,EAASC,EAAUiE,IAGlET,EAAUjI,GAAK,SAAS6E,EAAMzZ,EAASf,EAASma,EAASC,EAAUiE,GAG/D,QAAS4B,GAAIlE,EAAgB1I,EAAO7S,EAAQP,EAAMub,GAC9C,GAAIva,GAAOnB,EAAKmB,KAAK8a,EAAe9b,IAAQ6c,EAAUhd,EAAKmB,KAAKua,EAiBhE,OAhBAA,GAAc,SAARA,GAAiB,EAAe,UAARA,GAAkB,EAAQA,EAC3C,cAATva,EAEI8a,EAAe9b,GADPO,EAAS,EAAjB6S,IAAuBvT,EAAK6B,gBAAgB6Z,MAGrB1b,EAAKY,QAAQ8a,QAAcA,EAG1Chb,EAAS,EAAjB6S,GAA+B,WAATpS,GAA8B,UAATA,EAC3C8a,EAAe9b,GAAQH,EAAKY,QAAQ8a,WAEvB,WAATva,GAA8B,UAATA,GAAgC,WAAZ6b,GAAoC,UAAZA,IACjEf,EAAe9b,GAAQub,GAI5BO,EAAe9b,GApB1B,GAC8DM,GAAGgE,EAAK/B,EAAKiZ,EAAKD,EAD5EQ,EAAgBjb,EAAQP,OACxByW,EAAQuD,EAAKvD,MAAO8E,EAAiBhb,EAAQyZ,EAAKwC,MAsBtD,KADIld,EAAKY,QAAQqb,KAAiBA,EAAiBhb,EAAQyZ,EAAKwC,MAAQ,IACnEzc,EAAI,EAAGgE,EAAM0S,EAAMzW,OAAY+D,EAAJhE,EAASA,KAC3B,IAANA,GAAwB,SAAb0W,EAAM1W,MACjB,yBAAyB8W,KAAKJ,EAAM1W,KAC9B,IAANA,GAAmB,IAARgE,GAAa0S,EAAM1W,IAAM4Z,KACxCna,EAAQ4a,OAAOhU,KAAKqQ,EAAM1W,IAC1BiC,EAAMyU,EAAM1W,GACZkb,EAAMlb,IAAMgE,EAAM,EAAI8Z,EAAM5C,MAAQ/b,EAAY2e,EAAM5C,IAAM1a,EAAQ,GAAGyB,MACvEgZ,EAAM/a,KAAK+a,IAAIhZ,EAAKxC,EAASe,EAAS0a,GAClCmC,EAAUrD,QACVlB,QAAQC,IAAI,YAAawB,KAAKC,UAAUU,IACxCpC,QAAQC,IAAI,YAAawB,KAAKC,UAAUS,KAE5CA,EAAMyE,EAAIlE,EAAgBxb,EAAGgE,EAAK/B,EAAKgZ,GACnC1b,EAAK6B,gBAAgBoa,EAAevZ,KACpCzB,EAAQkb,QAAQF,EAAiBA,EAAevZ,QAGnD6b,EAAMC,MAA8B,kBAAfD,GAAMC,OAAwBD,EAAMC,KAAK9D,EAAMxa,EAASe,EAASyB,EAAKgZ,KAC5Fza,EAAQuS,OAAO,EAAGvS,EAAQP,OAASwb,MAG5C9a,KAAKT,QACTS,KAAKT"} \ No newline at end of file diff --git a/src/main/webapp/stat/js/util/jquery-rapped.js b/src/main/webapp/stat/js/util/jquery-rapped.js new file mode 100644 index 000000000..ebbc3da41 --- /dev/null +++ b/src/main/webapp/stat/js/util/jquery-rapped.js @@ -0,0 +1,2807 @@ +define('jquery', [], function (require) { + + /*! jQuery v1.8.2 jquery.com | jquery.org/license */ + (function (a, b) { + function G(a) { + var b = F[a] = {}; + return p.each(a.split(s), function (a, c) { + b[c] = !0 + }), b + } + + function J(a, c, d) { + if (d === b && a.nodeType === 1) { + var e = "data-" + c.replace(I, "-$1").toLowerCase(); + d = a.getAttribute(e); + if (typeof d == "string") { + try { + d = d === "true" ? !0 : d === "false" ? !1 : d === "null" ? null : +d + "" === d ? +d : H.test(d) ? p.parseJSON(d) : d + } catch (f) { + } + p.data(a, c, d) + } else d = b + } + return d + } + + function K(a) { + var b; + for (b in a) { + if (b === "data" && p.isEmptyObject(a[b]))continue; + if (b !== "toJSON")return !1 + } + return !0 + } + + function ba() { + return !1 + } + + function bb() { + return !0 + } + + function bh(a) { + return !a || !a.parentNode || a.parentNode.nodeType === 11 + } + + function bi(a, b) { + do a = a[b]; while (a && a.nodeType !== 1); + return a + } + + function bj(a, b, c) { + b = b || 0; + if (p.isFunction(b))return p.grep(a, function (a, d) { + var e = !!b.call(a, d, a); + return e === c + }); + if (b.nodeType)return p.grep(a, function (a, d) { + return a === b === c + }); + if (typeof b == "string") { + var d = p.grep(a, function (a) { + return a.nodeType === 1 + }); + if (be.test(b))return p.filter(b, d, !c); + b = p.filter(b, d) + } + return p.grep(a, function (a, d) { + return p.inArray(a, b) >= 0 === c + }) + } + + function bk(a) { + var b = bl.split("|"), c = a.createDocumentFragment(); + if (c.createElement)while (b.length)c.createElement(b.pop()); + return c + } + + function bC(a, b) { + return a.getElementsByTagName(b)[0] || a.appendChild(a.ownerDocument.createElement(b)) + } + + function bD(a, b) { + if (b.nodeType !== 1 || !p.hasData(a))return; + var c, d, e, f = p._data(a), g = p._data(b, f), h = f.events; + if (h) { + delete g.handle, g.events = {}; + for (c in h)for (d = 0, e = h[c].length; d < e; d++)p.event.add(b, c, h[c][d]) + } + g.data && (g.data = p.extend({}, g.data)) + } + + function bE(a, b) { + var c; + if (b.nodeType !== 1)return; + b.clearAttributes && b.clearAttributes(), b.mergeAttributes && b.mergeAttributes(a), c = b.nodeName.toLowerCase(), c === "object" ? (b.parentNode && (b.outerHTML = a.outerHTML), p.support.html5Clone && a.innerHTML && !p.trim(b.innerHTML) && (b.innerHTML = a.innerHTML)) : c === "input" && bv.test(a.type) ? (b.defaultChecked = b.checked = a.checked, b.value !== a.value && (b.value = a.value)) : c === "option" ? b.selected = a.defaultSelected : c === "input" || c === "textarea" ? b.defaultValue = a.defaultValue : c === "script" && b.text !== a.text && (b.text = a.text), b.removeAttribute(p.expando) + } + + function bF(a) { + return typeof a.getElementsByTagName != "undefined" ? a.getElementsByTagName("*") : typeof a.querySelectorAll != "undefined" ? a.querySelectorAll("*") : [] + } + + function bG(a) { + bv.test(a.type) && (a.defaultChecked = a.checked) + } + + function bY(a, b) { + if (b in a)return b; + var c = b.charAt(0).toUpperCase() + b.slice(1), d = b, e = bW.length; + while (e--) { + b = bW[e] + c; + if (b in a)return b + } + return d + } + + function bZ(a, b) { + return a = b || a, p.css(a, "display") === "none" || !p.contains(a.ownerDocument, a) + } + + function b$(a, b) { + var c, d, e = [], f = 0, g = a.length; + for (; f < g; f++) { + c = a[f]; + if (!c.style)continue; + e[f] = p._data(c, "olddisplay"), b ? (!e[f] && c.style.display === "none" && (c.style.display = ""), c.style.display === "" && bZ(c) && (e[f] = p._data(c, "olddisplay", cc(c.nodeName)))) : (d = bH(c, "display"), !e[f] && d !== "none" && p._data(c, "olddisplay", d)) + } + for (f = 0; f < g; f++) { + c = a[f]; + if (!c.style)continue; + if (!b || c.style.display === "none" || c.style.display === "")c.style.display = b ? e[f] || "" : "none" + } + return a + } + + function b_(a, b, c) { + var d = bP.exec(b); + return d ? Math.max(0, d[1] - (c || 0)) + (d[2] || "px") : b + } + + function ca(a, b, c, d) { + var e = c === (d ? "border" : "content") ? 4 : b === "width" ? 1 : 0, f = 0; + for (; e < 4; e += 2)c === "margin" && (f += p.css(a, c + bV[e], !0)), d ? (c === "content" && (f -= parseFloat(bH(a, "padding" + bV[e])) || 0), c !== "margin" && (f -= parseFloat(bH(a, "border" + bV[e] + "Width")) || 0)) : (f += parseFloat(bH(a, "padding" + bV[e])) || 0, c !== "padding" && (f += parseFloat(bH(a, "border" + bV[e] + "Width")) || 0)); + return f + } + + function cb(a, b, c) { + var d = b === "width" ? a.offsetWidth : a.offsetHeight, e = !0, f = p.support.boxSizing && p.css(a, "boxSizing") === "border-box"; + if (d <= 0 || d == null) { + d = bH(a, b); + if (d < 0 || d == null)d = a.style[b]; + if (bQ.test(d))return d; + e = f && (p.support.boxSizingReliable || d === a.style[b]), d = parseFloat(d) || 0 + } + return d + ca(a, b, c || (f ? "border" : "content"), e) + "px" + } + + function cc(a) { + if (bS[a])return bS[a]; + var b = p("<" + a + ">").appendTo(e.body), c = b.css("display"); + b.remove(); + if (c === "none" || c === "") { + bI = e.body.appendChild(bI || p.extend(e.createElement("iframe"), { + frameBorder: 0, + width: 0, + height: 0 + })); + if (!bJ || !bI.createElement)bJ = (bI.contentWindow || bI.contentDocument).document, bJ.write(""), bJ.close(); + b = bJ.body.appendChild(bJ.createElement(a)), c = bH(b, "display"), e.body.removeChild(bI) + } + return bS[a] = c, c + } + + function ci(a, b, c, d) { + var e; + if (p.isArray(b))p.each(b, function (b, e) { + c || ce.test(a) ? d(a, e) : ci(a + "[" + (typeof e == "object" ? b : "") + "]", e, c, d) + }); else if (!c && p.type(b) === "object")for (e in b)ci(a + "[" + e + "]", b[e], c, d); else d(a, b) + } + + function cz(a) { + return function (b, c) { + typeof b != "string" && (c = b, b = "*"); + var d, e, f, g = b.toLowerCase().split(s), h = 0, i = g.length; + if (p.isFunction(c))for (; h < i; h++)d = g[h], f = /^\+/.test(d), f && (d = d.substr(1) || "*"), e = a[d] = a[d] || [], e[f ? "unshift" : "push"](c) + } + } + + function cA(a, c, d, e, f, g) { + f = f || c.dataTypes[0], g = g || {}, g[f] = !0; + var h, i = a[f], j = 0, k = i ? i.length : 0, l = a === cv; + for (; j < k && (l || !h); j++)h = i[j](c, d, e), typeof h == "string" && (!l || g[h] ? h = b : (c.dataTypes.unshift(h), h = cA(a, c, d, e, h, g))); + return (l || !h) && !g["*"] && (h = cA(a, c, d, e, "*", g)), h + } + + function cB(a, c) { + var d, e, f = p.ajaxSettings.flatOptions || {}; + for (d in c)c[d] !== b && ((f[d] ? a : e || (e = {}))[d] = c[d]); + e && p.extend(!0, a, e) + } + + function cC(a, c, d) { + var e, f, g, h, i = a.contents, j = a.dataTypes, k = a.responseFields; + for (f in k)f in d && (c[k[f]] = d[f]); + while (j[0] === "*")j.shift(), e === b && (e = a.mimeType || c.getResponseHeader("content-type")); + if (e)for (f in i)if (i[f] && i[f].test(e)) { + j.unshift(f); + break + } + if (j[0]in d)g = j[0]; else { + for (f in d) { + if (!j[0] || a.converters[f + " " + j[0]]) { + g = f; + break + } + h || (h = f) + } + g = g || h + } + if (g)return g !== j[0] && j.unshift(g), d[g] + } + + function cD(a, b) { + var c, d, e, f, g = a.dataTypes.slice(), h = g[0], i = {}, j = 0; + a.dataFilter && (b = a.dataFilter(b, a.dataType)); + if (g[1])for (c in a.converters)i[c.toLowerCase()] = a.converters[c]; + for (; e = g[++j];)if (e !== "*") { + if (h !== "*" && h !== e) { + c = i[h + " " + e] || i["* " + e]; + if (!c)for (d in i) { + f = d.split(" "); + if (f[1] === e) { + c = i[h + " " + f[0]] || i["* " + f[0]]; + if (c) { + c === !0 ? c = i[d] : i[d] !== !0 && (e = f[0], g.splice(j--, 0, e)); + break + } + } + } + if (c !== !0)if (c && a["throws"])b = c(b); else try { + b = c(b) + } catch (k) { + return {state: "parsererror", error: c ? k : "No conversion from " + h + " to " + e} + } + } + h = e + } + return {state: "success", data: b} + } + + function cL() { + try { + return new a.XMLHttpRequest + } catch (b) { + } + } + + function cM() { + try { + return new a.ActiveXObject("Microsoft.XMLHTTP") + } catch (b) { + } + } + + function cU() { + return setTimeout(function () { + cN = b + }, 0), cN = p.now() + } + + function cV(a, b) { + p.each(b, function (b, c) { + var d = (cT[b] || []).concat(cT["*"]), e = 0, f = d.length; + for (; e < f; e++)if (d[e].call(a, b, c))return + }) + } + + function cW(a, b, c) { + var d, e = 0, f = 0, g = cS.length, h = p.Deferred().always(function () { + delete i.elem + }), i = function () { + var b = cN || cU(), c = Math.max(0, j.startTime + j.duration - b), d = 1 - (c / j.duration || 0), e = 0, f = j.tweens.length; + for (; e < f; e++)j.tweens[e].run(d); + return h.notifyWith(a, [j, d, c]), d < 1 && f ? c : (h.resolveWith(a, [j]), !1) + }, j = h.promise({ + elem: a, + props: p.extend({}, b), + opts: p.extend(!0, {specialEasing: {}}, c), + originalProperties: b, + originalOptions: c, + startTime: cN || cU(), + duration: c.duration, + tweens: [], + createTween: function (b, c, d) { + var e = p.Tween(a, j.opts, b, c, j.opts.specialEasing[b] || j.opts.easing); + return j.tweens.push(e), e + }, + stop: function (b) { + var c = 0, d = b ? j.tweens.length : 0; + for (; c < d; c++)j.tweens[c].run(1); + return b ? h.resolveWith(a, [j, b]) : h.rejectWith(a, [j, b]), this + } + }), k = j.props; + cX(k, j.opts.specialEasing); + for (; e < g; e++) { + d = cS[e].call(j, a, k, j.opts); + if (d)return d + } + return cV(j, k), p.isFunction(j.opts.start) && j.opts.start.call(a, j), p.fx.timer(p.extend(i, { + anim: j, + queue: j.opts.queue, + elem: a + })), j.progress(j.opts.progress).done(j.opts.done, j.opts.complete).fail(j.opts.fail).always(j.opts.always) + } + + function cX(a, b) { + var c, d, e, f, g; + for (c in a) { + d = p.camelCase(c), e = b[d], f = a[c], p.isArray(f) && (e = f[1], f = a[c] = f[0]), c !== d && (a[d] = f, delete a[c]), g = p.cssHooks[d]; + if (g && "expand"in g) { + f = g.expand(f), delete a[d]; + for (c in f)c in a || (a[c] = f[c], b[c] = e) + } else b[d] = e + } + } + + function cY(a, b, c) { + var d, e, f, g, h, i, j, k, l = this, m = a.style, n = {}, o = [], q = a.nodeType && bZ(a); + c.queue || (j = p._queueHooks(a, "fx"), j.unqueued == null && (j.unqueued = 0, k = j.empty.fire, j.empty.fire = function () { + j.unqueued || k() + }), j.unqueued++, l.always(function () { + l.always(function () { + j.unqueued--, p.queue(a, "fx").length || j.empty.fire() + }) + })), a.nodeType === 1 && ("height"in b || "width"in b) && (c.overflow = [m.overflow, m.overflowX, m.overflowY], p.css(a, "display") === "inline" && p.css(a, "float") === "none" && (!p.support.inlineBlockNeedsLayout || cc(a.nodeName) === "inline" ? m.display = "inline-block" : m.zoom = 1)), c.overflow && (m.overflow = "hidden", p.support.shrinkWrapBlocks || l.done(function () { + m.overflow = c.overflow[0], m.overflowX = c.overflow[1], m.overflowY = c.overflow[2] + })); + for (d in b) { + f = b[d]; + if (cP.exec(f)) { + delete b[d]; + if (f === (q ? "hide" : "show"))continue; + o.push(d) + } + } + g = o.length; + if (g) { + h = p._data(a, "fxshow") || p._data(a, "fxshow", {}), q ? p(a).show() : l.done(function () { + p(a).hide() + }), l.done(function () { + var b; + p.removeData(a, "fxshow", !0); + for (b in n)p.style(a, b, n[b]) + }); + for (d = 0; d < g; d++)e = o[d], i = l.createTween(e, q ? h[e] : 0), n[e] = h[e] || p.style(a, e), e in h || (h[e] = i.start, q && (i.end = i.start, i.start = e === "width" || e === "height" ? 1 : 0)) + } + } + + function cZ(a, b, c, d, e) { + return new cZ.prototype.init(a, b, c, d, e) + } + + function c$(a, b) { + var c, d = {height: a}, e = 0; + b = b ? 1 : 0; + for (; e < 4; e += 2 - b)c = bV[e], d["margin" + c] = d["padding" + c] = a; + return b && (d.opacity = d.width = a), d + } + + function da(a) { + return p.isWindow(a) ? a : a.nodeType === 9 ? a.defaultView || a.parentWindow : !1 + } + + var c, d, e = a.document, f = a.location, g = a.navigator, h = a.jQuery, i = a.$, j = Array.prototype.push, k = Array.prototype.slice, l = Array.prototype.indexOf, m = Object.prototype.toString, n = Object.prototype.hasOwnProperty, o = String.prototype.trim, p = function (a, b) { + return new p.fn.init(a, b, c) + }, q = /[\-+]?(?:\d*\.|)\d+(?:[eE][\-+]?\d+|)/.source, r = /\S/, s = /\s+/, t = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, u = /^(?:[^#<]*(<[\w\W]+>)[^>]*$|#([\w\-]*)$)/, v = /^<(\w+)\s*\/?>(?:<\/\1>|)$/, w = /^[\],:{}\s]*$/, x = /(?:^|:|,)(?:\s*\[)+/g, y = /\\(?:["\\\/bfnrt]|u[\da-fA-F]{4})/g, z = /"[^"\\\r\n]*"|true|false|null|-?(?:\d\d*\.|)\d+(?:[eE][\-+]?\d+|)/g, A = /^-ms-/, B = /-([\da-z])/gi, C = function (a, b) { + return (b + "").toUpperCase() + }, D = function () { + e.addEventListener ? (e.removeEventListener("DOMContentLoaded", D, !1), p.ready()) : e.readyState === "complete" && (e.detachEvent("onreadystatechange", D), p.ready()) + }, E = {}; + p.fn = p.prototype = { + constructor: p, init: function (a, c, d) { + var f, g, h, i; + if (!a)return this; + if (a.nodeType)return this.context = this[0] = a, this.length = 1, this; + if (typeof a == "string") { + a.charAt(0) === "<" && a.charAt(a.length - 1) === ">" && a.length >= 3 ? f = [null, a, null] : f = u.exec(a); + if (f && (f[1] || !c)) { + if (f[1])return c = c instanceof p ? c[0] : c, i = c && c.nodeType ? c.ownerDocument || c : e, a = p.parseHTML(f[1], i, !0), v.test(f[1]) && p.isPlainObject(c) && this.attr.call(a, c, !0), p.merge(this, a); + g = e.getElementById(f[2]); + if (g && g.parentNode) { + if (g.id !== f[2])return d.find(a); + this.length = 1, this[0] = g + } + return this.context = e, this.selector = a, this + } + return !c || c.jquery ? (c || d).find(a) : this.constructor(c).find(a) + } + return p.isFunction(a) ? d.ready(a) : (a.selector !== b && (this.selector = a.selector, this.context = a.context), p.makeArray(a, this)) + }, selector: "", jquery: "1.8.2", length: 0, size: function () { + return this.length + }, toArray: function () { + return k.call(this) + }, get: function (a) { + return a == null ? this.toArray() : a < 0 ? this[this.length + a] : this[a] + }, pushStack: function (a, b, c) { + var d = p.merge(this.constructor(), a); + return d.prevObject = this, d.context = this.context, b === "find" ? d.selector = this.selector + (this.selector ? " " : "") + c : b && (d.selector = this.selector + "." + b + "(" + c + ")"), d + }, each: function (a, b) { + return p.each(this, a, b) + }, ready: function (a) { + return p.ready.promise().done(a), this + }, eq: function (a) { + return a = +a, a === -1 ? this.slice(a) : this.slice(a, a + 1) + }, first: function () { + return this.eq(0) + }, last: function () { + return this.eq(-1) + }, slice: function () { + return this.pushStack(k.apply(this, arguments), "slice", k.call(arguments).join(",")) + }, map: function (a) { + return this.pushStack(p.map(this, function (b, c) { + return a.call(b, c, b) + })) + }, end: function () { + return this.prevObject || this.constructor(null) + }, push: j, sort: [].sort, splice: [].splice + }, p.fn.init.prototype = p.fn, p.extend = p.fn.extend = function () { + var a, c, d, e, f, g, h = arguments[0] || {}, i = 1, j = arguments.length, k = !1; + typeof h == "boolean" && (k = h, h = arguments[1] || {}, i = 2), typeof h != "object" && !p.isFunction(h) && (h = {}), j === i && (h = this, --i); + for (; i < j; i++)if ((a = arguments[i]) != null)for (c in a) { + d = h[c], e = a[c]; + if (h === e)continue; + k && e && (p.isPlainObject(e) || (f = p.isArray(e))) ? (f ? (f = !1, g = d && p.isArray(d) ? d : []) : g = d && p.isPlainObject(d) ? d : {}, h[c] = p.extend(k, g, e)) : e !== b && (h[c] = e) + } + return h + }, p.extend({ + noConflict: function (b) { + return a.$ === p && (a.$ = i), b && a.jQuery === p && (a.jQuery = h), p + }, isReady: !1, readyWait: 1, holdReady: function (a) { + a ? p.readyWait++ : p.ready(!0) + }, ready: function (a) { + if (a === !0 ? --p.readyWait : p.isReady)return; + if (!e.body)return setTimeout(p.ready, 1); + p.isReady = !0; + if (a !== !0 && --p.readyWait > 0)return; + d.resolveWith(e, [p]), p.fn.trigger && p(e).trigger("ready").off("ready") + }, isFunction: function (a) { + return p.type(a) === "function" + }, isArray: Array.isArray || function (a) { + return p.type(a) === "array" + }, isWindow: function (a) { + return a != null && a == a.window + }, isNumeric: function (a) { + return !isNaN(parseFloat(a)) && isFinite(a) + }, type: function (a) { + return a == null ? String(a) : E[m.call(a)] || "object" + }, isPlainObject: function (a) { + if (!a || p.type(a) !== "object" || a.nodeType || p.isWindow(a))return !1; + try { + if (a.constructor && !n.call(a, "constructor") && !n.call(a.constructor.prototype, "isPrototypeOf"))return !1 + } catch (c) { + return !1 + } + var d; + for (d in a); + return d === b || n.call(a, d) + }, isEmptyObject: function (a) { + var b; + for (b in a)return !1; + return !0 + }, error: function (a) { + throw new Error(a) + }, parseHTML: function (a, b, c) { + var d; + return !a || typeof a != "string" ? null : (typeof b == "boolean" && (c = b, b = 0), b = b || e, (d = v.exec(a)) ? [b.createElement(d[1])] : (d = p.buildFragment([a], b, c ? null : []), p.merge([], (d.cacheable ? p.clone(d.fragment) : d.fragment).childNodes))) + }, parseJSON: function (b) { + if (!b || typeof b != "string")return null; + b = p.trim(b); + if (a.JSON && a.JSON.parse)return a.JSON.parse(b); + if (w.test(b.replace(y, "@").replace(z, "]").replace(x, "")))return (new Function("return " + b))(); + p.error("Invalid JSON: " + b) + }, parseXML: function (c) { + var d, e; + if (!c || typeof c != "string")return null; + try { + a.DOMParser ? (e = new DOMParser, d = e.parseFromString(c, "text/xml")) : (d = new ActiveXObject("Microsoft.XMLDOM"), d.async = "false", d.loadXML(c)) + } catch (f) { + d = b + } + return (!d || !d.documentElement || d.getElementsByTagName("parsererror").length) && p.error("Invalid XML: " + c), d + }, noop: function () { + }, globalEval: function (b) { + b && r.test(b) && (a.execScript || function (b) { + a.eval.call(a, b) + })(b) + }, camelCase: function (a) { + return a.replace(A, "ms-").replace(B, C) + }, nodeName: function (a, b) { + return a.nodeName && a.nodeName.toLowerCase() === b.toLowerCase() + }, each: function (a, c, d) { + var e, f = 0, g = a.length, h = g === b || p.isFunction(a); + if (d) { + if (h) { + for (e in a)if (c.apply(a[e], d) === !1)break + } else for (; f < g;)if (c.apply(a[f++], d) === !1)break + } else if (h) { + for (e in a)if (c.call(a[e], e, a[e]) === !1)break + } else for (; f < g;)if (c.call(a[f], f, a[f++]) === !1)break; + return a + }, trim: o && !o.call("聽") ? function (a) { + return a == null ? "" : o.call(a) + } : function (a) { + return a == null ? "" : (a + "").replace(t, "") + }, makeArray: function (a, b) { + var c, d = b || []; + return a != null && (c = p.type(a), a.length == null || c === "string" || c === "function" || c === "regexp" || p.isWindow(a) ? j.call(d, a) : p.merge(d, a)), d + }, inArray: function (a, b, c) { + var d; + if (b) { + if (l)return l.call(b, a, c); + d = b.length, c = c ? c < 0 ? Math.max(0, d + c) : c : 0; + for (; c < d; c++)if (c in b && b[c] === a)return c + } + return -1 + }, merge: function (a, c) { + var d = c.length, e = a.length, f = 0; + if (typeof d == "number")for (; f < d; f++)a[e++] = c[f]; else while (c[f] !== b)a[e++] = c[f++]; + return a.length = e, a + }, grep: function (a, b, c) { + var d, e = [], f = 0, g = a.length; + c = !!c; + for (; f < g; f++)d = !!b(a[f], f), c !== d && e.push(a[f]); + return e + }, map: function (a, c, d) { + var e, f, g = [], h = 0, i = a.length, j = a instanceof p || i !== b && typeof i == "number" && (i > 0 && a[0] && a[i - 1] || i === 0 || p.isArray(a)); + if (j)for (; h < i; h++)e = c(a[h], h, d), e != null && (g[g.length] = e); else for (f in a)e = c(a[f], f, d), e != null && (g[g.length] = e); + return g.concat.apply([], g) + }, guid: 1, proxy: function (a, c) { + var d, e, f; + return typeof c == "string" && (d = a[c], c = a, a = d), p.isFunction(a) ? (e = k.call(arguments, 2), f = function () { + return a.apply(c, e.concat(k.call(arguments))) + }, f.guid = a.guid = a.guid || p.guid++, f) : b + }, access: function (a, c, d, e, f, g, h) { + var i, j = d == null, k = 0, l = a.length; + if (d && typeof d == "object") { + for (k in d)p.access(a, c, k, d[k], 1, g, e); + f = 1 + } else if (e !== b) { + i = h === b && p.isFunction(e), j && (i ? (i = c, c = function (a, b, c) { + return i.call(p(a), c) + }) : (c.call(a, e), c = null)); + if (c)for (; k < l; k++)c(a[k], d, i ? e.call(a[k], k, c(a[k], d)) : e, h); + f = 1 + } + return f ? a : j ? c.call(a) : l ? c(a[0], d) : g + }, now: function () { + return (new Date).getTime() + } + }), p.ready.promise = function (b) { + if (!d) { + d = p.Deferred(); + if (e.readyState === "complete")setTimeout(p.ready, 1); else if (e.addEventListener)e.addEventListener("DOMContentLoaded", D, !1), a.addEventListener("load", p.ready, !1); else { + e.attachEvent("onreadystatechange", D), a.attachEvent("onload", p.ready); + var c = !1; + try { + c = a.frameElement == null && e.documentElement + } catch (f) { + } + c && c.doScroll && function g() { + if (!p.isReady) { + try { + c.doScroll("left") + } catch (a) { + return setTimeout(g, 50) + } + p.ready() + } + }() + } + } + return d.promise(b) + }, p.each("Boolean Number String Function Array Date RegExp Object".split(" "), function (a, b) { + E["[object " + b + "]"] = b.toLowerCase() + }), c = p(e); + var F = {}; + p.Callbacks = function (a) { + a = typeof a == "string" ? F[a] || G(a) : p.extend({}, a); + var c, d, e, f, g, h, i = [], j = !a.once && [], k = function (b) { + c = a.memory && b, d = !0, h = f || 0, f = 0, g = i.length, e = !0; + for (; i && h < g; h++)if (i[h].apply(b[0], b[1]) === !1 && a.stopOnFalse) { + c = !1; + break + } + e = !1, i && (j ? j.length && k(j.shift()) : c ? i = [] : l.disable()) + }, l = { + add: function () { + if (i) { + var b = i.length; + (function d(b) { + p.each(b, function (b, c) { + var e = p.type(c); + e === "function" && (!a.unique || !l.has(c)) ? i.push(c) : c && c.length && e !== "string" && d(c) + }) + })(arguments), e ? g = i.length : c && (f = b, k(c)) + } + return this + }, remove: function () { + return i && p.each(arguments, function (a, b) { + var c; + while ((c = p.inArray(b, i, c)) > -1)i.splice(c, 1), e && (c <= g && g--, c <= h && h--) + }), this + }, has: function (a) { + return p.inArray(a, i) > -1 + }, empty: function () { + return i = [], this + }, disable: function () { + return i = j = c = b, this + }, disabled: function () { + return !i + }, lock: function () { + return j = b, c || l.disable(), this + }, locked: function () { + return !j + }, fireWith: function (a, b) { + return b = b || [], b = [a, b.slice ? b.slice() : b], i && (!d || j) && (e ? j.push(b) : k(b)), this + }, fire: function () { + return l.fireWith(this, arguments), this + }, fired: function () { + return !!d + } + }; + return l + }, p.extend({ + Deferred: function (a) { + var b = [["resolve", "done", p.Callbacks("once memory"), "resolved"], ["reject", "fail", p.Callbacks("once memory"), "rejected"], ["notify", "progress", p.Callbacks("memory")]], c = "pending", d = { + state: function () { + return c + }, always: function () { + return e.done(arguments).fail(arguments), this + }, then: function () { + var a = arguments; + return p.Deferred(function (c) { + p.each(b, function (b, d) { + var f = d[0], g = a[b]; + e[d[1]](p.isFunction(g) ? function () { + var a = g.apply(this, arguments); + a && p.isFunction(a.promise) ? a.promise().done(c.resolve).fail(c.reject).progress(c.notify) : c[f + "With"](this === e ? c : this, [a]) + } : c[f]) + }), a = null + }).promise() + }, promise: function (a) { + return a != null ? p.extend(a, d) : d + } + }, e = {}; + return d.pipe = d.then, p.each(b, function (a, f) { + var g = f[2], h = f[3]; + d[f[1]] = g.add, h && g.add(function () { + c = h + }, b[a ^ 1][2].disable, b[2][2].lock), e[f[0]] = g.fire, e[f[0] + "With"] = g.fireWith + }), d.promise(e), a && a.call(e, e), e + }, when: function (a) { + var b = 0, c = k.call(arguments), d = c.length, e = d !== 1 || a && p.isFunction(a.promise) ? d : 0, f = e === 1 ? a : p.Deferred(), g = function (a, b, c) { + return function (d) { + b[a] = this, c[a] = arguments.length > 1 ? k.call(arguments) : d, c === h ? f.notifyWith(b, c) : --e || f.resolveWith(b, c) + } + }, h, i, j; + if (d > 1) { + h = new Array(d), i = new Array(d), j = new Array(d); + for (; b < d; b++)c[b] && p.isFunction(c[b].promise) ? c[b].promise().done(g(b, j, c)).fail(f.reject).progress(g(b, i, h)) : --e + } + return e || f.resolveWith(j, c), f.promise() + } + }), p.support = function () { + var b, c, d, f, g, h, i, j, k, l, m, n = e.createElement("div"); + n.setAttribute("className", "t"), n.innerHTML = "
    a", c = n.getElementsByTagName("*"), d = n.getElementsByTagName("a")[0], d.style.cssText = "top:1px;float:left;opacity:.5"; + if (!c || !c.length)return {}; + f = e.createElement("select"), g = f.appendChild(e.createElement("option")), h = n.getElementsByTagName("input")[0], b = { + leadingWhitespace: n.firstChild.nodeType === 3, + tbody: !n.getElementsByTagName("tbody").length, + htmlSerialize: !!n.getElementsByTagName("link").length, + style: /top/.test(d.getAttribute("style")), + hrefNormalized: d.getAttribute("href") === "/a", + opacity: /^0.5/.test(d.style.opacity), + cssFloat: !!d.style.cssFloat, + checkOn: h.value === "on", + optSelected: g.selected, + getSetAttribute: n.className !== "t", + enctype: !!e.createElement("form").enctype, + html5Clone: e.createElement("nav").cloneNode(!0).outerHTML !== "<:nav>", + boxModel: e.compatMode === "CSS1Compat", + submitBubbles: !0, + changeBubbles: !0, + focusinBubbles: !1, + deleteExpando: !0, + noCloneEvent: !0, + inlineBlockNeedsLayout: !1, + shrinkWrapBlocks: !1, + reliableMarginRight: !0, + boxSizingReliable: !0, + pixelPosition: !1 + }, h.checked = !0, b.noCloneChecked = h.cloneNode(!0).checked, f.disabled = !0, b.optDisabled = !g.disabled; + try { + delete n.test + } catch (o) { + b.deleteExpando = !1 + } + !n.addEventListener && n.attachEvent && n.fireEvent && (n.attachEvent("onclick", m = function () { + b.noCloneEvent = !1 + }), n.cloneNode(!0).fireEvent("onclick"), n.detachEvent("onclick", m)), h = e.createElement("input"), h.value = "t", h.setAttribute("type", "radio"), b.radioValue = h.value === "t", h.setAttribute("checked", "checked"), h.setAttribute("name", "t"), n.appendChild(h), i = e.createDocumentFragment(), i.appendChild(n.lastChild), b.checkClone = i.cloneNode(!0).cloneNode(!0).lastChild.checked, b.appendChecked = h.checked, i.removeChild(h), i.appendChild(n); + if (n.attachEvent)for (k in{ + submit: !0, + change: !0, + focusin: !0 + })j = "on" + k, l = j in n, l || (n.setAttribute(j, "return;"), l = typeof n[j] == "function"), b[k + "Bubbles"] = l; + return p(function () { + var c, d, f, g, h = "padding:0;margin:0;border:0;display:block;overflow:hidden;", i = e.getElementsByTagName("body")[0]; + if (!i)return; + c = e.createElement("div"), c.style.cssText = "visibility:hidden;border:0;width:0;height:0;position:static;top:0;margin-top:1px", i.insertBefore(c, i.firstChild), d = e.createElement("div"), c.appendChild(d), d.innerHTML = "
    t
    ", f = d.getElementsByTagName("td"), f[0].style.cssText = "padding:0;margin:0;border:0;display:none", l = f[0].offsetHeight === 0, f[0].style.display = "", f[1].style.display = "none", b.reliableHiddenOffsets = l && f[0].offsetHeight === 0, d.innerHTML = "", d.style.cssText = "box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;padding:1px;border:1px;display:block;width:4px;margin-top:1%;position:absolute;top:1%;", b.boxSizing = d.offsetWidth === 4, b.doesNotIncludeMarginInBodyOffset = i.offsetTop !== 1, a.getComputedStyle && (b.pixelPosition = (a.getComputedStyle(d, null) || {}).top !== "1%", b.boxSizingReliable = (a.getComputedStyle(d, null) || {width: "4px"}).width === "4px", g = e.createElement("div"), g.style.cssText = d.style.cssText = h, g.style.marginRight = g.style.width = "0", d.style.width = "1px", d.appendChild(g), b.reliableMarginRight = !parseFloat((a.getComputedStyle(g, null) || {}).marginRight)), typeof d.style.zoom != "undefined" && (d.innerHTML = "", d.style.cssText = h + "width:1px;padding:1px;display:inline;zoom:1", b.inlineBlockNeedsLayout = d.offsetWidth === 3, d.style.display = "block", d.style.overflow = "visible", d.innerHTML = "
    ", d.firstChild.style.width = "5px", b.shrinkWrapBlocks = d.offsetWidth !== 3, c.style.zoom = 1), i.removeChild(c), c = d = f = g = null + }), i.removeChild(n), c = d = f = g = h = i = n = null, b + }(); + var H = /(?:\{[\s\S]*\}|\[[\s\S]*\])$/, I = /([A-Z])/g; + p.extend({ + cache: {}, + deletedIds: [], + uuid: 0, + expando: "jQuery" + (p.fn.jquery + Math.random()).replace(/\D/g, ""), + noData: {embed: !0, object: "clsid:D27CDB6E-AE6D-11cf-96B8-444553540000", applet: !0}, + hasData: function (a) { + return a = a.nodeType ? p.cache[a[p.expando]] : a[p.expando], !!a && !K(a) + }, + data: function (a, c, d, e) { + if (!p.acceptData(a))return; + var f, g, h = p.expando, i = typeof c == "string", j = a.nodeType, k = j ? p.cache : a, l = j ? a[h] : a[h] && h; + if ((!l || !k[l] || !e && !k[l].data) && i && d === b)return; + l || (j ? a[h] = l = p.deletedIds.pop() || p.guid++ : l = h), k[l] || (k[l] = {}, j || (k[l].toJSON = p.noop)); + if (typeof c == "object" || typeof c == "function")e ? k[l] = p.extend(k[l], c) : k[l].data = p.extend(k[l].data, c); + return f = k[l], e || (f.data || (f.data = {}), f = f.data), d !== b && (f[p.camelCase(c)] = d), i ? (g = f[c], g == null && (g = f[p.camelCase(c)])) : g = f, g + }, + removeData: function (a, b, c) { + if (!p.acceptData(a))return; + var d, e, f, g = a.nodeType, h = g ? p.cache : a, i = g ? a[p.expando] : p.expando; + if (!h[i])return; + if (b) { + d = c ? h[i] : h[i].data; + if (d) { + p.isArray(b) || (b in d ? b = [b] : (b = p.camelCase(b), b in d ? b = [b] : b = b.split(" "))); + for (e = 0, f = b.length; e < f; e++)delete d[b[e]]; + if (!(c ? K : p.isEmptyObject)(d))return + } + } + if (!c) { + delete h[i].data; + if (!K(h[i]))return + } + g ? p.cleanData([a], !0) : p.support.deleteExpando || h != h.window ? delete h[i] : h[i] = null + }, + _data: function (a, b, c) { + return p.data(a, b, c, !0) + }, + acceptData: function (a) { + var b = a.nodeName && p.noData[a.nodeName.toLowerCase()]; + return !b || b !== !0 && a.getAttribute("classid") === b + } + }), p.fn.extend({ + data: function (a, c) { + var d, e, f, g, h, i = this[0], j = 0, k = null; + if (a === b) { + if (this.length) { + k = p.data(i); + if (i.nodeType === 1 && !p._data(i, "parsedAttrs")) { + f = i.attributes; + for (h = f.length; j < h; j++)g = f[j].name, g.indexOf("data-") || (g = p.camelCase(g.substring(5)), J(i, g, k[g])); + p._data(i, "parsedAttrs", !0) + } + } + return k + } + return typeof a == "object" ? this.each(function () { + p.data(this, a) + }) : (d = a.split(".", 2), d[1] = d[1] ? "." + d[1] : "", e = d[1] + "!", p.access(this, function (c) { + if (c === b)return k = this.triggerHandler("getData" + e, [d[0]]), k === b && i && (k = p.data(i, a), k = J(i, a, k)), k === b && d[1] ? this.data(d[0]) : k; + d[1] = c, this.each(function () { + var b = p(this); + b.triggerHandler("setData" + e, d), p.data(this, a, c), b.triggerHandler("changeData" + e, d) + }) + }, null, c, arguments.length > 1, null, !1)) + }, removeData: function (a) { + return this.each(function () { + p.removeData(this, a) + }) + } + }), p.extend({ + queue: function (a, b, c) { + var d; + if (a)return b = (b || "fx") + "queue", d = p._data(a, b), c && (!d || p.isArray(c) ? d = p._data(a, b, p.makeArray(c)) : d.push(c)), d || [] + }, dequeue: function (a, b) { + b = b || "fx"; + var c = p.queue(a, b), d = c.length, e = c.shift(), f = p._queueHooks(a, b), g = function () { + p.dequeue(a, b) + }; + e === "inprogress" && (e = c.shift(), d--), e && (b === "fx" && c.unshift("inprogress"), delete f.stop, e.call(a, g, f)), !d && f && f.empty.fire() + }, _queueHooks: function (a, b) { + var c = b + "queueHooks"; + return p._data(a, c) || p._data(a, c, { + empty: p.Callbacks("once memory").add(function () { + p.removeData(a, b + "queue", !0), p.removeData(a, c, !0) + }) + }) + } + }), p.fn.extend({ + queue: function (a, c) { + var d = 2; + return typeof a != "string" && (c = a, a = "fx", d--), arguments.length < d ? p.queue(this[0], a) : c === b ? this : this.each(function () { + var b = p.queue(this, a, c); + p._queueHooks(this, a), a === "fx" && b[0] !== "inprogress" && p.dequeue(this, a) + }) + }, dequeue: function (a) { + return this.each(function () { + p.dequeue(this, a) + }) + }, delay: function (a, b) { + return a = p.fx ? p.fx.speeds[a] || a : a, b = b || "fx", this.queue(b, function (b, c) { + var d = setTimeout(b, a); + c.stop = function () { + clearTimeout(d) + } + }) + }, clearQueue: function (a) { + return this.queue(a || "fx", []) + }, promise: function (a, c) { + var d, e = 1, f = p.Deferred(), g = this, h = this.length, i = function () { + --e || f.resolveWith(g, [g]) + }; + typeof a != "string" && (c = a, a = b), a = a || "fx"; + while (h--)d = p._data(g[h], a + "queueHooks"), d && d.empty && (e++, d.empty.add(i)); + return i(), f.promise(c) + } + }); + var L, M, N, O = /[\t\r\n]/g, P = /\r/g, Q = /^(?:button|input)$/i, R = /^(?:button|input|object|select|textarea)$/i, S = /^a(?:rea|)$/i, T = /^(?:autofocus|autoplay|async|checked|controls|defer|disabled|hidden|loop|multiple|open|readonly|required|scoped|selected)$/i, U = p.support.getSetAttribute; + p.fn.extend({ + attr: function (a, b) { + return p.access(this, p.attr, a, b, arguments.length > 1) + }, removeAttr: function (a) { + return this.each(function () { + p.removeAttr(this, a) + }) + }, prop: function (a, b) { + return p.access(this, p.prop, a, b, arguments.length > 1) + }, removeProp: function (a) { + return a = p.propFix[a] || a, this.each(function () { + try { + this[a] = b, delete this[a] + } catch (c) { + } + }) + }, addClass: function (a) { + var b, c, d, e, f, g, h; + if (p.isFunction(a))return this.each(function (b) { + p(this).addClass(a.call(this, b, this.className)) + }); + if (a && typeof a == "string") { + b = a.split(s); + for (c = 0, d = this.length; c < d; c++) { + e = this[c]; + if (e.nodeType === 1)if (!e.className && b.length === 1)e.className = a; else { + f = " " + e.className + " "; + for (g = 0, h = b.length; g < h; g++)f.indexOf(" " + b[g] + " ") < 0 && (f += b[g] + " "); + e.className = p.trim(f) + } + } + } + return this + }, removeClass: function (a) { + var c, d, e, f, g, h, i; + if (p.isFunction(a))return this.each(function (b) { + p(this).removeClass(a.call(this, b, this.className)) + }); + if (a && typeof a == "string" || a === b) { + c = (a || "").split(s); + for (h = 0, i = this.length; h < i; h++) { + e = this[h]; + if (e.nodeType === 1 && e.className) { + d = (" " + e.className + " ").replace(O, " "); + for (f = 0, g = c.length; f < g; f++)while (d.indexOf(" " + c[f] + " ") >= 0)d = d.replace(" " + c[f] + " ", " "); + e.className = a ? p.trim(d) : "" + } + } + } + return this + }, toggleClass: function (a, b) { + var c = typeof a, d = typeof b == "boolean"; + return p.isFunction(a) ? this.each(function (c) { + p(this).toggleClass(a.call(this, c, this.className, b), b) + }) : this.each(function () { + if (c === "string") { + var e, f = 0, g = p(this), h = b, i = a.split(s); + while (e = i[f++])h = d ? h : !g.hasClass(e), g[h ? "addClass" : "removeClass"](e) + } else if (c === "undefined" || c === "boolean")this.className && p._data(this, "__className__", this.className), this.className = this.className || a === !1 ? "" : p._data(this, "__className__") || "" + }) + }, hasClass: function (a) { + var b = " " + a + " ", c = 0, d = this.length; + for (; c < d; c++)if (this[c].nodeType === 1 && (" " + this[c].className + " ").replace(O, " ").indexOf(b) >= 0)return !0; + return !1 + }, val: function (a) { + var c, d, e, f = this[0]; + if (!arguments.length) { + if (f)return c = p.valHooks[f.type] || p.valHooks[f.nodeName.toLowerCase()], c && "get"in c && (d = c.get(f, "value")) !== b ? d : (d = f.value, typeof d == "string" ? d.replace(P, "") : d == null ? "" : d); + return + } + return e = p.isFunction(a), this.each(function (d) { + var f, g = p(this); + if (this.nodeType !== 1)return; + e ? f = a.call(this, d, g.val()) : f = a, f == null ? f = "" : typeof f == "number" ? f += "" : p.isArray(f) && (f = p.map(f, function (a) { + return a == null ? "" : a + "" + })), c = p.valHooks[this.type] || p.valHooks[this.nodeName.toLowerCase()]; + if (!c || !("set"in c) || c.set(this, f, "value") === b)this.value = f + }) + } + }), p.extend({ + valHooks: { + option: { + get: function (a) { + var b = a.attributes.value; + return !b || b.specified ? a.value : a.text + } + }, select: { + get: function (a) { + var b, c, d, e, f = a.selectedIndex, g = [], h = a.options, i = a.type === "select-one"; + if (f < 0)return null; + c = i ? f : 0, d = i ? f + 1 : h.length; + for (; c < d; c++) { + e = h[c]; + if (e.selected && (p.support.optDisabled ? !e.disabled : e.getAttribute("disabled") === null) && (!e.parentNode.disabled || !p.nodeName(e.parentNode, "optgroup"))) { + b = p(e).val(); + if (i)return b; + g.push(b) + } + } + return i && !g.length && h.length ? p(h[f]).val() : g + }, set: function (a, b) { + var c = p.makeArray(b); + return p(a).find("option").each(function () { + this.selected = p.inArray(p(this).val(), c) >= 0 + }), c.length || (a.selectedIndex = -1), c + } + } + }, + attrFn: {}, + attr: function (a, c, d, e) { + var f, g, h, i = a.nodeType; + if (!a || i === 3 || i === 8 || i === 2)return; + if (e && p.isFunction(p.fn[c]))return p(a)[c](d); + if (typeof a.getAttribute == "undefined")return p.prop(a, c, d); + h = i !== 1 || !p.isXMLDoc(a), h && (c = c.toLowerCase(), g = p.attrHooks[c] || (T.test(c) ? M : L)); + if (d !== b) { + if (d === null) { + p.removeAttr(a, c); + return + } + return g && "set"in g && h && (f = g.set(a, d, c)) !== b ? f : (a.setAttribute(c, d + ""), d) + } + return g && "get"in g && h && (f = g.get(a, c)) !== null ? f : (f = a.getAttribute(c), f === null ? b : f) + }, + removeAttr: function (a, b) { + var c, d, e, f, g = 0; + if (b && a.nodeType === 1) { + d = b.split(s); + for (; g < d.length; g++)e = d[g], e && (c = p.propFix[e] || e, f = T.test(e), f || p.attr(a, e, ""), a.removeAttribute(U ? e : c), f && c in a && (a[c] = !1)) + } + }, + attrHooks: { + type: { + set: function (a, b) { + if (Q.test(a.nodeName) && a.parentNode)p.error("type property can't be changed"); else if (!p.support.radioValue && b === "radio" && p.nodeName(a, "input")) { + var c = a.value; + return a.setAttribute("type", b), c && (a.value = c), b + } + } + }, value: { + get: function (a, b) { + return L && p.nodeName(a, "button") ? L.get(a, b) : b in a ? a.value : null + }, set: function (a, b, c) { + if (L && p.nodeName(a, "button"))return L.set(a, b, c); + a.value = b + } + } + }, + propFix: { + tabindex: "tabIndex", + readonly: "readOnly", + "for": "htmlFor", + "class": "className", + maxlength: "maxLength", + cellspacing: "cellSpacing", + cellpadding: "cellPadding", + rowspan: "rowSpan", + colspan: "colSpan", + usemap: "useMap", + frameborder: "frameBorder", + contenteditable: "contentEditable" + }, + prop: function (a, c, d) { + var e, f, g, h = a.nodeType; + if (!a || h === 3 || h === 8 || h === 2)return; + return g = h !== 1 || !p.isXMLDoc(a), g && (c = p.propFix[c] || c, f = p.propHooks[c]), d !== b ? f && "set"in f && (e = f.set(a, d, c)) !== b ? e : a[c] = d : f && "get"in f && (e = f.get(a, c)) !== null ? e : a[c] + }, + propHooks: { + tabIndex: { + get: function (a) { + var c = a.getAttributeNode("tabindex"); + return c && c.specified ? parseInt(c.value, 10) : R.test(a.nodeName) || S.test(a.nodeName) && a.href ? 0 : b + } + } + } + }), M = { + get: function (a, c) { + var d, e = p.prop(a, c); + return e === !0 || typeof e != "boolean" && (d = a.getAttributeNode(c)) && d.nodeValue !== !1 ? c.toLowerCase() : b + }, set: function (a, b, c) { + var d; + return b === !1 ? p.removeAttr(a, c) : (d = p.propFix[c] || c, d in a && (a[d] = !0), a.setAttribute(c, c.toLowerCase())), c + } + }, U || (N = {name: !0, id: !0, coords: !0}, L = p.valHooks.button = { + get: function (a, c) { + var d; + return d = a.getAttributeNode(c), d && (N[c] ? d.value !== "" : d.specified) ? d.value : b + }, set: function (a, b, c) { + var d = a.getAttributeNode(c); + return d || (d = e.createAttribute(c), a.setAttributeNode(d)), d.value = b + "" + } + }, p.each(["width", "height"], function (a, b) { + p.attrHooks[b] = p.extend(p.attrHooks[b], { + set: function (a, c) { + if (c === "")return a.setAttribute(b, "auto"), c + } + }) + }), p.attrHooks.contenteditable = { + get: L.get, set: function (a, b, c) { + b === "" && (b = "false"), L.set(a, b, c) + } + }), p.support.hrefNormalized || p.each(["href", "src", "width", "height"], function (a, c) { + p.attrHooks[c] = p.extend(p.attrHooks[c], { + get: function (a) { + var d = a.getAttribute(c, 2); + return d === null ? b : d + } + }) + }), p.support.style || (p.attrHooks.style = { + get: function (a) { + return a.style.cssText.toLowerCase() || b + }, set: function (a, b) { + return a.style.cssText = b + "" + } + }), p.support.optSelected || (p.propHooks.selected = p.extend(p.propHooks.selected, { + get: function (a) { + var b = a.parentNode; + return b && (b.selectedIndex, b.parentNode && b.parentNode.selectedIndex), null + } + })), p.support.enctype || (p.propFix.enctype = "encoding"), p.support.checkOn || p.each(["radio", "checkbox"], function () { + p.valHooks[this] = { + get: function (a) { + return a.getAttribute("value") === null ? "on" : a.value + } + } + }), p.each(["radio", "checkbox"], function () { + p.valHooks[this] = p.extend(p.valHooks[this], { + set: function (a, b) { + if (p.isArray(b))return a.checked = p.inArray(p(a).val(), b) >= 0 + } + }) + }); + var V = /^(?:textarea|input|select)$/i, W = /^([^\.]*|)(?:\.(.+)|)$/, X = /(?:^|\s)hover(\.\S+|)\b/, Y = /^key/, Z = /^(?:mouse|contextmenu)|click/, $ = /^(?:focusinfocus|focusoutblur)$/, _ = function (a) { + return p.event.special.hover ? a : a.replace(X, "mouseenter$1 mouseleave$1") + }; + p.event = { + add: function (a, c, d, e, f) { + var g, h, i, j, k, l, m, n, o, q, r; + if (a.nodeType === 3 || a.nodeType === 8 || !c || !d || !(g = p._data(a)))return; + d.handler && (o = d, d = o.handler, f = o.selector), d.guid || (d.guid = p.guid++), i = g.events, i || (g.events = i = {}), h = g.handle, h || (g.handle = h = function (a) { + return typeof p != "undefined" && (!a || p.event.triggered !== a.type) ? p.event.dispatch.apply(h.elem, arguments) : b + }, h.elem = a), c = p.trim(_(c)).split(" "); + for (j = 0; j < c.length; j++) { + k = W.exec(c[j]) || [], l = k[1], m = (k[2] || "").split(".").sort(), r = p.event.special[l] || {}, l = (f ? r.delegateType : r.bindType) || l, r = p.event.special[l] || {}, n = p.extend({ + type: l, + origType: k[1], + data: e, + handler: d, + guid: d.guid, + selector: f, + needsContext: f && p.expr.match.needsContext.test(f), + namespace: m.join(".") + }, o), q = i[l]; + if (!q) { + q = i[l] = [], q.delegateCount = 0; + if (!r.setup || r.setup.call(a, e, m, h) === !1)a.addEventListener ? a.addEventListener(l, h, !1) : a.attachEvent && a.attachEvent("on" + l, h) + } + r.add && (r.add.call(a, n), n.handler.guid || (n.handler.guid = d.guid)), f ? q.splice(q.delegateCount++, 0, n) : q.push(n), p.event.global[l] = !0 + } + a = null + }, + global: {}, + remove: function (a, b, c, d, e) { + var f, g, h, i, j, k, l, m, n, o, q, r = p.hasData(a) && p._data(a); + if (!r || !(m = r.events))return; + b = p.trim(_(b || "")).split(" "); + for (f = 0; f < b.length; f++) { + g = W.exec(b[f]) || [], h = i = g[1], j = g[2]; + if (!h) { + for (h in m)p.event.remove(a, h + b[f], c, d, !0); + continue + } + n = p.event.special[h] || {}, h = (d ? n.delegateType : n.bindType) || h, o = m[h] || [], k = o.length, j = j ? new RegExp("(^|\\.)" + j.split(".").sort().join("\\.(?:.*\\.|)") + "(\\.|$)") : null; + for (l = 0; l < o.length; l++)q = o[l], (e || i === q.origType) && (!c || c.guid === q.guid) && (!j || j.test(q.namespace)) && (!d || d === q.selector || d === "**" && q.selector) && (o.splice(l--, 1), q.selector && o.delegateCount--, n.remove && n.remove.call(a, q)); + o.length === 0 && k !== o.length && ((!n.teardown || n.teardown.call(a, j, r.handle) === !1) && p.removeEvent(a, h, r.handle), delete m[h]) + } + p.isEmptyObject(m) && (delete r.handle, p.removeData(a, "events", !0)) + }, + customEvent: {getData: !0, setData: !0, changeData: !0}, + trigger: function (c, d, f, g) { + if (!f || f.nodeType !== 3 && f.nodeType !== 8) { + var h, i, j, k, l, m, n, o, q, r, s = c.type || c, t = []; + if ($.test(s + p.event.triggered))return; + s.indexOf("!") >= 0 && (s = s.slice(0, -1), i = !0), s.indexOf(".") >= 0 && (t = s.split("."), s = t.shift(), t.sort()); + if ((!f || p.event.customEvent[s]) && !p.event.global[s])return; + c = typeof c == "object" ? c[p.expando] ? c : new p.Event(s, c) : new p.Event(s), c.type = s, c.isTrigger = !0, c.exclusive = i, c.namespace = t.join("."), c.namespace_re = c.namespace ? new RegExp("(^|\\.)" + t.join("\\.(?:.*\\.|)") + "(\\.|$)") : null, m = s.indexOf(":") < 0 ? "on" + s : ""; + if (!f) { + h = p.cache; + for (j in h)h[j].events && h[j].events[s] && p.event.trigger(c, d, h[j].handle.elem, !0); + return + } + c.result = b, c.target || (c.target = f), d = d != null ? p.makeArray(d) : [], d.unshift(c), n = p.event.special[s] || {}; + if (n.trigger && n.trigger.apply(f, d) === !1)return; + q = [[f, n.bindType || s]]; + if (!g && !n.noBubble && !p.isWindow(f)) { + r = n.delegateType || s, k = $.test(r + s) ? f : f.parentNode; + for (l = f; k; k = k.parentNode)q.push([k, r]), l = k; + l === (f.ownerDocument || e) && q.push([l.defaultView || l.parentWindow || a, r]) + } + for (j = 0; j < q.length && !c.isPropagationStopped(); j++)k = q[j][0], c.type = q[j][1], o = (p._data(k, "events") || {})[c.type] && p._data(k, "handle"), o && o.apply(k, d), o = m && k[m], o && p.acceptData(k) && o.apply && o.apply(k, d) === !1 && c.preventDefault(); + return c.type = s, !g && !c.isDefaultPrevented() && (!n._default || n._default.apply(f.ownerDocument, d) === !1) && (s !== "click" || !p.nodeName(f, "a")) && p.acceptData(f) && m && f[s] && (s !== "focus" && s !== "blur" || c.target.offsetWidth !== 0) && !p.isWindow(f) && (l = f[m], l && (f[m] = null), p.event.triggered = s, f[s](), p.event.triggered = b, l && (f[m] = l)), c.result + } + return + }, + dispatch: function (c) { + c = p.event.fix(c || a.event); + var d, e, f, g, h, i, j, l, m, n, o = (p._data(this, "events") || {})[c.type] || [], q = o.delegateCount, r = k.call(arguments), s = !c.exclusive && !c.namespace, t = p.event.special[c.type] || {}, u = []; + r[0] = c, c.delegateTarget = this; + if (t.preDispatch && t.preDispatch.call(this, c) === !1)return; + if (q && (!c.button || c.type !== "click"))for (f = c.target; f != this; f = f.parentNode || this)if (f.disabled !== !0 || c.type !== "click") { + h = {}, j = []; + for (d = 0; d < q; d++)l = o[d], m = l.selector, h[m] === b && (h[m] = l.needsContext ? p(m, this).index(f) >= 0 : p.find(m, this, null, [f]).length), h[m] && j.push(l); + j.length && u.push({elem: f, matches: j}) + } + o.length > q && u.push({elem: this, matches: o.slice(q)}); + for (d = 0; d < u.length && !c.isPropagationStopped(); d++) { + i = u[d], c.currentTarget = i.elem; + for (e = 0; e < i.matches.length && !c.isImmediatePropagationStopped(); e++) { + l = i.matches[e]; + if (s || !c.namespace && !l.namespace || c.namespace_re && c.namespace_re.test(l.namespace))c.data = l.data, c.handleObj = l, g = ((p.event.special[l.origType] || {}).handle || l.handler).apply(i.elem, r), g !== b && (c.result = g, g === !1 && (c.preventDefault(), c.stopPropagation())) + } + } + return t.postDispatch && t.postDispatch.call(this, c), c.result + }, + props: "attrChange attrName relatedNode srcElement altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "), + fixHooks: {}, + keyHooks: { + props: "char charCode key keyCode".split(" "), filter: function (a, b) { + return a.which == null && (a.which = b.charCode != null ? b.charCode : b.keyCode), a + } + }, + mouseHooks: { + props: "button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement".split(" "), + filter: function (a, c) { + var d, f, g, h = c.button, i = c.fromElement; + return a.pageX == null && c.clientX != null && (d = a.target.ownerDocument || e, f = d.documentElement, g = d.body, a.pageX = c.clientX + (f && f.scrollLeft || g && g.scrollLeft || 0) - (f && f.clientLeft || g && g.clientLeft || 0), a.pageY = c.clientY + (f && f.scrollTop || g && g.scrollTop || 0) - (f && f.clientTop || g && g.clientTop || 0)), !a.relatedTarget && i && (a.relatedTarget = i === a.target ? c.toElement : i), !a.which && h !== b && (a.which = h & 1 ? 1 : h & 2 ? 3 : h & 4 ? 2 : 0), a + } + }, + fix: function (a) { + if (a[p.expando])return a; + var b, c, d = a, f = p.event.fixHooks[a.type] || {}, g = f.props ? this.props.concat(f.props) : this.props; + a = p.Event(d); + for (b = g.length; b;)c = g[--b], a[c] = d[c]; + return a.target || (a.target = d.srcElement || e), a.target.nodeType === 3 && (a.target = a.target.parentNode), a.metaKey = !!a.metaKey, f.filter ? f.filter(a, d) : a + }, + special: { + load: {noBubble: !0}, + focus: {delegateType: "focusin"}, + blur: {delegateType: "focusout"}, + beforeunload: { + setup: function (a, b, c) { + p.isWindow(this) && (this.onbeforeunload = c) + }, teardown: function (a, b) { + this.onbeforeunload === b && (this.onbeforeunload = null) + } + } + }, + simulate: function (a, b, c, d) { + var e = p.extend(new p.Event, c, {type: a, isSimulated: !0, originalEvent: {}}); + d ? p.event.trigger(e, null, b) : p.event.dispatch.call(b, e), e.isDefaultPrevented() && c.preventDefault() + } + }, p.event.handle = p.event.dispatch, p.removeEvent = e.removeEventListener ? function (a, b, c) { + a.removeEventListener && a.removeEventListener(b, c, !1) + } : function (a, b, c) { + var d = "on" + b; + a.detachEvent && (typeof a[d] == "undefined" && (a[d] = null), a.detachEvent(d, c)) + }, p.Event = function (a, b) { + if (this instanceof p.Event)a && a.type ? (this.originalEvent = a, this.type = a.type, this.isDefaultPrevented = a.defaultPrevented || a.returnValue === !1 || a.getPreventDefault && a.getPreventDefault() ? bb : ba) : this.type = a, b && p.extend(this, b), this.timeStamp = a && a.timeStamp || p.now(), this[p.expando] = !0; else return new p.Event(a, b) + }, p.Event.prototype = { + preventDefault: function () { + this.isDefaultPrevented = bb; + var a = this.originalEvent; + if (!a)return; + a.preventDefault ? a.preventDefault() : a.returnValue = !1 + }, stopPropagation: function () { + this.isPropagationStopped = bb; + var a = this.originalEvent; + if (!a)return; + a.stopPropagation && a.stopPropagation(), a.cancelBubble = !0 + }, stopImmediatePropagation: function () { + this.isImmediatePropagationStopped = bb, this.stopPropagation() + }, isDefaultPrevented: ba, isPropagationStopped: ba, isImmediatePropagationStopped: ba + }, p.each({mouseenter: "mouseover", mouseleave: "mouseout"}, function (a, b) { + p.event.special[a] = { + delegateType: b, bindType: b, handle: function (a) { + var c, d = this, e = a.relatedTarget, f = a.handleObj, g = f.selector; + if (!e || e !== d && !p.contains(d, e))a.type = f.origType, c = f.handler.apply(this, arguments), a.type = b; + return c + } + } + }), p.support.submitBubbles || (p.event.special.submit = { + setup: function () { + if (p.nodeName(this, "form"))return !1; + p.event.add(this, "click._submit keypress._submit", function (a) { + var c = a.target, d = p.nodeName(c, "input") || p.nodeName(c, "button") ? c.form : b; + d && !p._data(d, "_submit_attached") && (p.event.add(d, "submit._submit", function (a) { + a._submit_bubble = !0 + }), p._data(d, "_submit_attached", !0)) + }) + }, postDispatch: function (a) { + a._submit_bubble && (delete a._submit_bubble, this.parentNode && !a.isTrigger && p.event.simulate("submit", this.parentNode, a, !0)) + }, teardown: function () { + if (p.nodeName(this, "form"))return !1; + p.event.remove(this, "._submit") + } + }), p.support.changeBubbles || (p.event.special.change = { + setup: function () { + if (V.test(this.nodeName)) { + if (this.type === "checkbox" || this.type === "radio")p.event.add(this, "propertychange._change", function (a) { + a.originalEvent.propertyName === "checked" && (this._just_changed = !0) + }), p.event.add(this, "click._change", function (a) { + this._just_changed && !a.isTrigger && (this._just_changed = !1), p.event.simulate("change", this, a, !0) + }); + return !1 + } + p.event.add(this, "beforeactivate._change", function (a) { + var b = a.target; + V.test(b.nodeName) && !p._data(b, "_change_attached") && (p.event.add(b, "change._change", function (a) { + this.parentNode && !a.isSimulated && !a.isTrigger && p.event.simulate("change", this.parentNode, a, !0) + }), p._data(b, "_change_attached", !0)) + }) + }, handle: function (a) { + var b = a.target; + if (this !== b || a.isSimulated || a.isTrigger || b.type !== "radio" && b.type !== "checkbox")return a.handleObj.handler.apply(this, arguments) + }, teardown: function () { + return p.event.remove(this, "._change"), !V.test(this.nodeName) + } + }), p.support.focusinBubbles || p.each({focus: "focusin", blur: "focusout"}, function (a, b) { + var c = 0, d = function (a) { + p.event.simulate(b, a.target, p.event.fix(a), !0) + }; + p.event.special[b] = { + setup: function () { + c++ === 0 && e.addEventListener(a, d, !0) + }, teardown: function () { + --c === 0 && e.removeEventListener(a, d, !0) + } + } + }), p.fn.extend({ + on: function (a, c, d, e, f) { + var g, h; + if (typeof a == "object") { + typeof c != "string" && (d = d || c, c = b); + for (h in a)this.on(h, c, d, a[h], f); + return this + } + d == null && e == null ? (e = c, d = c = b) : e == null && (typeof c == "string" ? (e = d, d = b) : (e = d, d = c, c = b)); + if (e === !1)e = ba; else if (!e)return this; + return f === 1 && (g = e, e = function (a) { + return p().off(a), g.apply(this, arguments) + }, e.guid = g.guid || (g.guid = p.guid++)), this.each(function () { + p.event.add(this, a, e, d, c) + }) + }, one: function (a, b, c, d) { + return this.on(a, b, c, d, 1) + }, off: function (a, c, d) { + var e, f; + if (a && a.preventDefault && a.handleObj)return e = a.handleObj, p(a.delegateTarget).off(e.namespace ? e.origType + "." + e.namespace : e.origType, e.selector, e.handler), this; + if (typeof a == "object") { + for (f in a)this.off(f, c, a[f]); + return this + } + if (c === !1 || typeof c == "function")d = c, c = b; + return d === !1 && (d = ba), this.each(function () { + p.event.remove(this, a, d, c) + }) + }, bind: function (a, b, c) { + return this.on(a, null, b, c) + }, unbind: function (a, b) { + return this.off(a, null, b) + }, live: function (a, b, c) { + return p(this.context).on(a, this.selector, b, c), this + }, die: function (a, b) { + return p(this.context).off(a, this.selector || "**", b), this + }, delegate: function (a, b, c, d) { + return this.on(b, a, c, d) + }, undelegate: function (a, b, c) { + return arguments.length === 1 ? this.off(a, "**") : this.off(b, a || "**", c) + }, trigger: function (a, b) { + return this.each(function () { + p.event.trigger(a, b, this) + }) + }, triggerHandler: function (a, b) { + if (this[0])return p.event.trigger(a, b, this[0], !0) + }, toggle: function (a) { + var b = arguments, c = a.guid || p.guid++, d = 0, e = function (c) { + var e = (p._data(this, "lastToggle" + a.guid) || 0) % d; + return p._data(this, "lastToggle" + a.guid, e + 1), c.preventDefault(), b[e].apply(this, arguments) || !1 + }; + e.guid = c; + while (d < b.length)b[d++].guid = c; + return this.click(e) + }, hover: function (a, b) { + return this.mouseenter(a).mouseleave(b || a) + } + }), p.each("blur focus focusin focusout load resize scroll unload click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup error contextmenu".split(" "), function (a, b) { + p.fn[b] = function (a, c) { + return c == null && (c = a, a = null), arguments.length > 0 ? this.on(b, null, a, c) : this.trigger(b) + }, Y.test(b) && (p.event.fixHooks[b] = p.event.keyHooks), Z.test(b) && (p.event.fixHooks[b] = p.event.mouseHooks) + }), function (a, b) { + function bc(a, b, c, d) { + c = c || [], b = b || r; + var e, f, i, j, k = b.nodeType; + if (!a || typeof a != "string")return c; + if (k !== 1 && k !== 9)return []; + i = g(b); + if (!i && !d)if (e = P.exec(a))if (j = e[1]) { + if (k === 9) { + f = b.getElementById(j); + if (!f || !f.parentNode)return c; + if (f.id === j)return c.push(f), c + } else if (b.ownerDocument && (f = b.ownerDocument.getElementById(j)) && h(b, f) && f.id === j)return c.push(f), c + } else { + if (e[2])return w.apply(c, x.call(b.getElementsByTagName(a), 0)), c; + if ((j = e[3]) && _ && b.getElementsByClassName)return w.apply(c, x.call(b.getElementsByClassName(j), 0)), c + } + return bp(a.replace(L, "$1"), b, c, d, i) + } + + function bd(a) { + return function (b) { + var c = b.nodeName.toLowerCase(); + return c === "input" && b.type === a + } + } + + function be(a) { + return function (b) { + var c = b.nodeName.toLowerCase(); + return (c === "input" || c === "button") && b.type === a + } + } + + function bf(a) { + return z(function (b) { + return b = +b, z(function (c, d) { + var e, f = a([], c.length, b), g = f.length; + while (g--)c[e = f[g]] && (c[e] = !(d[e] = c[e])) + }) + }) + } + + function bg(a, b, c) { + if (a === b)return c; + var d = a.nextSibling; + while (d) { + if (d === b)return -1; + d = d.nextSibling + } + return 1 + } + + function bh(a, b) { + var c, d, f, g, h, i, j, k = C[o][a]; + if (k)return b ? 0 : k.slice(0); + h = a, i = [], j = e.preFilter; + while (h) { + if (!c || (d = M.exec(h)))d && (h = h.slice(d[0].length)), i.push(f = []); + c = !1; + if (d = N.exec(h))f.push(c = new q(d.shift())), h = h.slice(c.length), c.type = d[0].replace(L, " "); + for (g in e.filter)(d = W[g].exec(h)) && (!j[g] || (d = j[g](d, r, !0))) && (f.push(c = new q(d.shift())), h = h.slice(c.length), c.type = g, c.matches = d); + if (!c)break + } + return b ? h.length : h ? bc.error(a) : C(a, i).slice(0) + } + + function bi(a, b, d) { + var e = b.dir, f = d && b.dir === "parentNode", g = u++; + return b.first ? function (b, c, d) { + while (b = b[e])if (f || b.nodeType === 1)return a(b, c, d) + } : function (b, d, h) { + if (!h) { + var i, j = t + " " + g + " ", k = j + c; + while (b = b[e])if (f || b.nodeType === 1) { + if ((i = b[o]) === k)return b.sizset; + if (typeof i == "string" && i.indexOf(j) === 0) { + if (b.sizset)return b + } else { + b[o] = k; + if (a(b, d, h))return b.sizset = !0, b; + b.sizset = !1 + } + } + } else while (b = b[e])if (f || b.nodeType === 1)if (a(b, d, h))return b + } + } + + function bj(a) { + return a.length > 1 ? function (b, c, d) { + var e = a.length; + while (e--)if (!a[e](b, c, d))return !1; + return !0 + } : a[0] + } + + function bk(a, b, c, d, e) { + var f, g = [], h = 0, i = a.length, j = b != null; + for (; h < i; h++)if (f = a[h])if (!c || c(f, d, e))g.push(f), j && b.push(h); + return g + } + + function bl(a, b, c, d, e, f) { + return d && !d[o] && (d = bl(d)), e && !e[o] && (e = bl(e, f)), z(function (f, g, h, i) { + if (f && e)return; + var j, k, l, m = [], n = [], o = g.length, p = f || bo(b || "*", h.nodeType ? [h] : h, [], f), q = a && (f || !b) ? bk(p, m, a, h, i) : p, r = c ? e || (f ? a : o || d) ? [] : g : q; + c && c(q, r, h, i); + if (d) { + l = bk(r, n), d(l, [], h, i), j = l.length; + while (j--)if (k = l[j])r[n[j]] = !(q[n[j]] = k) + } + if (f) { + j = a && r.length; + while (j--)if (k = r[j])f[m[j]] = !(g[m[j]] = k) + } else r = bk(r === g ? r.splice(o, r.length) : r), e ? e(null, g, r, i) : w.apply(g, r) + }) + } + + function bm(a) { + var b, c, d, f = a.length, g = e.relative[a[0].type], h = g || e.relative[" "], i = g ? 1 : 0, j = bi(function (a) { + return a === b + }, h, !0), k = bi(function (a) { + return y.call(b, a) > -1 + }, h, !0), m = [function (a, c, d) { + return !g && (d || c !== l) || ((b = c).nodeType ? j(a, c, d) : k(a, c, d)) + }]; + for (; i < f; i++)if (c = e.relative[a[i].type])m = [bi(bj(m), c)]; else { + c = e.filter[a[i].type].apply(null, a[i].matches); + if (c[o]) { + d = ++i; + for (; d < f; d++)if (e.relative[a[d].type])break; + return bl(i > 1 && bj(m), i > 1 && a.slice(0, i - 1).join("").replace(L, "$1"), c, i < d && bm(a.slice(i, d)), d < f && bm(a = a.slice(d)), d < f && a.join("")) + } + m.push(c) + } + return bj(m) + } + + function bn(a, b) { + var d = b.length > 0, f = a.length > 0, g = function (h, i, j, k, m) { + var n, o, p, q = [], s = 0, u = "0", x = h && [], y = m != null, z = l, A = h || f && e.find.TAG("*", m && i.parentNode || i), B = t += z == null ? 1 : Math.E; + y && (l = i !== r && i, c = g.el); + for (; (n = A[u]) != null; u++) { + if (f && n) { + for (o = 0; p = a[o]; o++)if (p(n, i, j)) { + k.push(n); + break + } + y && (t = B, c = ++g.el) + } + d && ((n = !p && n) && s--, h && x.push(n)) + } + s += u; + if (d && u !== s) { + for (o = 0; p = b[o]; o++)p(x, q, i, j); + if (h) { + if (s > 0)while (u--)!x[u] && !q[u] && (q[u] = v.call(k)); + q = bk(q) + } + w.apply(k, q), y && !h && q.length > 0 && s + b.length > 1 && bc.uniqueSort(k) + } + return y && (t = B, l = z), x + }; + return g.el = 0, d ? z(g) : g + } + + function bo(a, b, c, d) { + var e = 0, f = b.length; + for (; e < f; e++)bc(a, b[e], c, d); + return c + } + + function bp(a, b, c, d, f) { + var g, h, j, k, l, m = bh(a), n = m.length; + if (!d && m.length === 1) { + h = m[0] = m[0].slice(0); + if (h.length > 2 && (j = h[0]).type === "ID" && b.nodeType === 9 && !f && e.relative[h[1].type]) { + b = e.find.ID(j.matches[0].replace(V, ""), b, f)[0]; + if (!b)return c; + a = a.slice(h.shift().length) + } + for (g = W.POS.test(a) ? -1 : h.length - 1; g >= 0; g--) { + j = h[g]; + if (e.relative[k = j.type])break; + if (l = e.find[k])if (d = l(j.matches[0].replace(V, ""), R.test(h[0].type) && b.parentNode || b, f)) { + h.splice(g, 1), a = d.length && h.join(""); + if (!a)return w.apply(c, x.call(d, 0)), c; + break + } + } + } + return i(a, m)(d, b, f, c, R.test(a)), c + } + + function bq() { + } + + var c, d, e, f, g, h, i, j, k, l, m = !0, n = "undefined", o = ("sizcache" + Math.random()).replace(".", ""), q = String, r = a.document, s = r.documentElement, t = 0, u = 0, v = [].pop, w = [].push, x = [].slice, y = [].indexOf || function (a) { + var b = 0, c = this.length; + for (; b < c; b++)if (this[b] === a)return b; + return -1 + }, z = function (a, b) { + return a[o] = b == null || b, a + }, A = function () { + var a = {}, b = []; + return z(function (c, d) { + return b.push(c) > e.cacheLength && delete a[b.shift()], a[c] = d + }, a) + }, B = A(), C = A(), D = A(), E = "[\\x20\\t\\r\\n\\f]", F = "(?:\\\\.|[-\\w]|[^\\x00-\\xa0])+", G = F.replace("w", "w#"), H = "([*^$|!~]?=)", I = "\\[" + E + "*(" + F + ")" + E + "*(?:" + H + E + "*(?:(['\"])((?:\\\\.|[^\\\\])*?)\\3|(" + G + ")|)|)" + E + "*\\]", J = ":(" + F + ")(?:\\((?:(['\"])((?:\\\\.|[^\\\\])*?)\\2|([^()[\\]]*|(?:(?:" + I + ")|[^:]|\\\\.)*|.*))\\)|)", K = ":(even|odd|eq|gt|lt|nth|first|last)(?:\\(" + E + "*((?:-\\d)?\\d*)" + E + "*\\)|)(?=[^-]|$)", L = new RegExp("^" + E + "+|((?:^|[^\\\\])(?:\\\\.)*)" + E + "+$", "g"), M = new RegExp("^" + E + "*," + E + "*"), N = new RegExp("^" + E + "*([\\x20\\t\\r\\n\\f>+~])" + E + "*"), O = new RegExp(J), P = /^(?:#([\w\-]+)|(\w+)|\.([\w\-]+))$/, Q = /^:not/, R = /[\x20\t\r\n\f]*[+~]/, S = /:not\($/, T = /h\d/i, U = /input|select|textarea|button/i, V = /\\(?!\\)/g, W = { + ID: new RegExp("^#(" + F + ")"), + CLASS: new RegExp("^\\.(" + F + ")"), + NAME: new RegExp("^\\[name=['\"]?(" + F + ")['\"]?\\]"), + TAG: new RegExp("^(" + F.replace("w", "w*") + ")"), + ATTR: new RegExp("^" + I), + PSEUDO: new RegExp("^" + J), + POS: new RegExp(K, "i"), + CHILD: new RegExp("^:(only|nth|first|last)-child(?:\\(" + E + "*(even|odd|(([+-]|)(\\d*)n|)" + E + "*(?:([+-]|)" + E + "*(\\d+)|))" + E + "*\\)|)", "i"), + needsContext: new RegExp("^" + E + "*[>+~]|" + K, "i") + }, X = function (a) { + var b = r.createElement("div"); + try { + return a(b) + } catch (c) { + return !1 + } finally { + b = null + } + }, Y = X(function (a) { + return a.appendChild(r.createComment("")), !a.getElementsByTagName("*").length + }), Z = X(function (a) { + return a.innerHTML = "", a.firstChild && typeof a.firstChild.getAttribute !== n && a.firstChild.getAttribute("href") === "#" + }), $ = X(function (a) { + a.innerHTML = ""; + var b = typeof a.lastChild.getAttribute("multiple"); + return b !== "boolean" && b !== "string" + }), _ = X(function (a) { + return a.innerHTML = "", !a.getElementsByClassName || !a.getElementsByClassName("e").length ? !1 : (a.lastChild.className = "e", a.getElementsByClassName("e").length === 2) + }), ba = X(function (a) { + a.id = o + 0, a.innerHTML = "
    ", s.insertBefore(a, s.firstChild); + var b = r.getElementsByName && r.getElementsByName(o).length === 2 + r.getElementsByName(o + 0).length; + return d = !r.getElementById(o), s.removeChild(a), b + }); + try { + x.call(s.childNodes, 0)[0].nodeType + } catch (bb) { + x = function (a) { + var b, c = []; + for (; b = this[a]; a++)c.push(b); + return c + } + } + bc.matches = function (a, b) { + return bc(a, null, null, b) + }, bc.matchesSelector = function (a, b) { + return bc(b, null, null, [a]).length > 0 + }, f = bc.getText = function (a) { + var b, c = "", d = 0, e = a.nodeType; + if (e) { + if (e === 1 || e === 9 || e === 11) { + if (typeof a.textContent == "string")return a.textContent; + for (a = a.firstChild; a; a = a.nextSibling)c += f(a) + } else if (e === 3 || e === 4)return a.nodeValue + } else for (; b = a[d]; d++)c += f(b); + return c + }, g = bc.isXML = function (a) { + var b = a && (a.ownerDocument || a).documentElement; + return b ? b.nodeName !== "HTML" : !1 + }, h = bc.contains = s.contains ? function (a, b) { + var c = a.nodeType === 9 ? a.documentElement : a, d = b && b.parentNode; + return a === d || !!(d && d.nodeType === 1 && c.contains && c.contains(d)) + } : s.compareDocumentPosition ? function (a, b) { + return b && !!(a.compareDocumentPosition(b) & 16) + } : function (a, b) { + while (b = b.parentNode)if (b === a)return !0; + return !1 + }, bc.attr = function (a, b) { + var c, d = g(a); + return d || (b = b.toLowerCase()), (c = e.attrHandle[b]) ? c(a) : d || $ ? a.getAttribute(b) : (c = a.getAttributeNode(b), c ? typeof a[b] == "boolean" ? a[b] ? b : null : c.specified ? c.value : null : null) + }, e = bc.selectors = { + cacheLength: 50, + createPseudo: z, + match: W, + attrHandle: Z ? {} : { + href: function (a) { + return a.getAttribute("href", 2) + }, type: function (a) { + return a.getAttribute("type") + } + }, + find: { + ID: d ? function (a, b, c) { + if (typeof b.getElementById !== n && !c) { + var d = b.getElementById(a); + return d && d.parentNode ? [d] : [] + } + } : function (a, c, d) { + if (typeof c.getElementById !== n && !d) { + var e = c.getElementById(a); + return e ? e.id === a || typeof e.getAttributeNode !== n && e.getAttributeNode("id").value === a ? [e] : b : [] + } + }, TAG: Y ? function (a, b) { + if (typeof b.getElementsByTagName !== n)return b.getElementsByTagName(a) + } : function (a, b) { + var c = b.getElementsByTagName(a); + if (a === "*") { + var d, e = [], f = 0; + for (; d = c[f]; f++)d.nodeType === 1 && e.push(d); + return e + } + return c + }, NAME: ba && function (a, b) { + if (typeof b.getElementsByName !== n)return b.getElementsByName(name) + }, CLASS: _ && function (a, b, c) { + if (typeof b.getElementsByClassName !== n && !c)return b.getElementsByClassName(a) + } + }, + relative: { + ">": {dir: "parentNode", first: !0}, + " ": {dir: "parentNode"}, + "+": {dir: "previousSibling", first: !0}, + "~": {dir: "previousSibling"} + }, + preFilter: { + ATTR: function (a) { + return a[1] = a[1].replace(V, ""), a[3] = (a[4] || a[5] || "").replace(V, ""), a[2] === "~=" && (a[3] = " " + a[3] + " "), a.slice(0, 4) + }, CHILD: function (a) { + return a[1] = a[1].toLowerCase(), a[1] === "nth" ? (a[2] || bc.error(a[0]), a[3] = +(a[3] ? a[4] + (a[5] || 1) : 2 * (a[2] === "even" || a[2] === "odd")), a[4] = +(a[6] + a[7] || a[2] === "odd")) : a[2] && bc.error(a[0]), a + }, PSEUDO: function (a) { + var b, c; + if (W.CHILD.test(a[0]))return null; + if (a[3])a[2] = a[3]; else if (b = a[4])O.test(b) && (c = bh(b, !0)) && (c = b.indexOf(")", b.length - c) - b.length) && (b = b.slice(0, c), a[0] = a[0].slice(0, c)), a[2] = b; + return a.slice(0, 3) + } + }, + filter: { + ID: d ? function (a) { + return a = a.replace(V, ""), function (b) { + return b.getAttribute("id") === a + } + } : function (a) { + return a = a.replace(V, ""), function (b) { + var c = typeof b.getAttributeNode !== n && b.getAttributeNode("id"); + return c && c.value === a + } + }, TAG: function (a) { + return a === "*" ? function () { + return !0 + } : (a = a.replace(V, "").toLowerCase(), function (b) { + return b.nodeName && b.nodeName.toLowerCase() === a + }) + }, CLASS: function (a) { + var b = B[o][a]; + return b || (b = B(a, new RegExp("(^|" + E + ")" + a + "(" + E + "|$)"))), function (a) { + return b.test(a.className || typeof a.getAttribute !== n && a.getAttribute("class") || "") + } + }, ATTR: function (a, b, c) { + return function (d, e) { + var f = bc.attr(d, a); + return f == null ? b === "!=" : b ? (f += "", b === "=" ? f === c : b === "!=" ? f !== c : b === "^=" ? c && f.indexOf(c) === 0 : b === "*=" ? c && f.indexOf(c) > -1 : b === "$=" ? c && f.substr(f.length - c.length) === c : b === "~=" ? (" " + f + " ").indexOf(c) > -1 : b === "|=" ? f === c || f.substr(0, c.length + 1) === c + "-" : !1) : !0 + } + }, CHILD: function (a, b, c, d) { + return a === "nth" ? function (a) { + var b, e, f = a.parentNode; + if (c === 1 && d === 0)return !0; + if (f) { + e = 0; + for (b = f.firstChild; b; b = b.nextSibling)if (b.nodeType === 1) { + e++; + if (a === b)break + } + } + return e -= d, e === c || e % c === 0 && e / c >= 0 + } : function (b) { + var c = b; + switch (a) { + case"only": + case"first": + while (c = c.previousSibling)if (c.nodeType === 1)return !1; + if (a === "first")return !0; + c = b; + case"last": + while (c = c.nextSibling)if (c.nodeType === 1)return !1; + return !0 + } + } + }, PSEUDO: function (a, b) { + var c, d = e.pseudos[a] || e.setFilters[a.toLowerCase()] || bc.error("unsupported pseudo: " + a); + return d[o] ? d(b) : d.length > 1 ? (c = [a, a, "", b], e.setFilters.hasOwnProperty(a.toLowerCase()) ? z(function (a, c) { + var e, f = d(a, b), g = f.length; + while (g--)e = y.call(a, f[g]), a[e] = !(c[e] = f[g]) + }) : function (a) { + return d(a, 0, c) + }) : d + } + }, + pseudos: { + not: z(function (a) { + var b = [], c = [], d = i(a.replace(L, "$1")); + return d[o] ? z(function (a, b, c, e) { + var f, g = d(a, null, e, []), h = a.length; + while (h--)if (f = g[h])a[h] = !(b[h] = f) + }) : function (a, e, f) { + return b[0] = a, d(b, null, f, c), !c.pop() + } + }), + has: z(function (a) { + return function (b) { + return bc(a, b).length > 0 + } + }), + contains: z(function (a) { + return function (b) { + return (b.textContent || b.innerText || f(b)).indexOf(a) > -1 + } + }), + enabled: function (a) { + return a.disabled === !1 + }, + disabled: function (a) { + return a.disabled === !0 + }, + checked: function (a) { + var b = a.nodeName.toLowerCase(); + return b === "input" && !!a.checked || b === "option" && !!a.selected + }, + selected: function (a) { + return a.parentNode && a.parentNode.selectedIndex, a.selected === !0 + }, + parent: function (a) { + return !e.pseudos.empty(a) + }, + empty: function (a) { + var b; + a = a.firstChild; + while (a) { + if (a.nodeName > "@" || (b = a.nodeType) === 3 || b === 4)return !1; + a = a.nextSibling + } + return !0 + }, + header: function (a) { + return T.test(a.nodeName) + }, + text: function (a) { + var b, c; + return a.nodeName.toLowerCase() === "input" && (b = a.type) === "text" && ((c = a.getAttribute("type")) == null || c.toLowerCase() === b) + }, + radio: bd("radio"), + checkbox: bd("checkbox"), + file: bd("file"), + password: bd("password"), + image: bd("image"), + submit: be("submit"), + reset: be("reset"), + button: function (a) { + var b = a.nodeName.toLowerCase(); + return b === "input" && a.type === "button" || b === "button" + }, + input: function (a) { + return U.test(a.nodeName) + }, + focus: function (a) { + var b = a.ownerDocument; + return a === b.activeElement && (!b.hasFocus || b.hasFocus()) && (!!a.type || !!a.href) + }, + active: function (a) { + return a === a.ownerDocument.activeElement + }, + first: bf(function (a, b, c) { + return [0] + }), + last: bf(function (a, b, c) { + return [b - 1] + }), + eq: bf(function (a, b, c) { + return [c < 0 ? c + b : c] + }), + even: bf(function (a, b, c) { + for (var d = 0; d < b; d += 2)a.push(d); + return a + }), + odd: bf(function (a, b, c) { + for (var d = 1; d < b; d += 2)a.push(d); + return a + }), + lt: bf(function (a, b, c) { + for (var d = c < 0 ? c + b : c; --d >= 0;)a.push(d); + return a + }), + gt: bf(function (a, b, c) { + for (var d = c < 0 ? c + b : c; ++d < b;)a.push(d); + return a + }) + } + }, j = s.compareDocumentPosition ? function (a, b) { + return a === b ? (k = !0, 0) : (!a.compareDocumentPosition || !b.compareDocumentPosition ? a.compareDocumentPosition : a.compareDocumentPosition(b) & 4) ? -1 : 1 + } : function (a, b) { + if (a === b)return k = !0, 0; + if (a.sourceIndex && b.sourceIndex)return a.sourceIndex - b.sourceIndex; + var c, d, e = [], f = [], g = a.parentNode, h = b.parentNode, i = g; + if (g === h)return bg(a, b); + if (!g)return -1; + if (!h)return 1; + while (i)e.unshift(i), i = i.parentNode; + i = h; + while (i)f.unshift(i), i = i.parentNode; + c = e.length, d = f.length; + for (var j = 0; j < c && j < d; j++)if (e[j] !== f[j])return bg(e[j], f[j]); + return j === c ? bg(a, f[j], -1) : bg(e[j], b, 1) + }, [0, 0].sort(j), m = !k, bc.uniqueSort = function (a) { + var b, c = 1; + k = m, a.sort(j); + if (k)for (; b = a[c]; c++)b === a[c - 1] && a.splice(c--, 1); + return a + }, bc.error = function (a) { + throw new Error("Syntax error, unrecognized expression: " + a) + }, i = bc.compile = function (a, b) { + var c, d = [], e = [], f = D[o][a]; + if (!f) { + b || (b = bh(a)), c = b.length; + while (c--)f = bm(b[c]), f[o] ? d.push(f) : e.push(f); + f = D(a, bn(e, d)) + } + return f + }, r.querySelectorAll && function () { + var a, b = bp, c = /'|\\/g, d = /\=[\x20\t\r\n\f]*([^'"\]]*)[\x20\t\r\n\f]*\]/g, e = [":focus"], f = [":active", ":focus"], h = s.matchesSelector || s.mozMatchesSelector || s.webkitMatchesSelector || s.oMatchesSelector || s.msMatchesSelector; + X(function (a) { + a.innerHTML = "", a.querySelectorAll("[selected]").length || e.push("\\[" + E + "*(?:checked|disabled|ismap|multiple|readonly|selected|value)"), a.querySelectorAll(":checked").length || e.push(":checked") + }), X(function (a) { + a.innerHTML = "

    ", a.querySelectorAll("[test^='']").length && e.push("[*^$]=" + E + "*(?:\"\"|'')"), a.innerHTML = "", a.querySelectorAll(":enabled").length || e.push(":enabled", ":disabled") + }), e = new RegExp(e.join("|")), bp = function (a, d, f, g, h) { + if (!g && !h && (!e || !e.test(a))) { + var i, j, k = !0, l = o, m = d, n = d.nodeType === 9 && a; + if (d.nodeType === 1 && d.nodeName.toLowerCase() !== "object") { + i = bh(a), (k = d.getAttribute("id")) ? l = k.replace(c, "\\$&") : d.setAttribute("id", l), l = "[id='" + l + "'] ", j = i.length; + while (j--)i[j] = l + i[j].join(""); + m = R.test(a) && d.parentNode || d, n = i.join(",") + } + if (n)try { + return w.apply(f, x.call(m.querySelectorAll(n), 0)), f + } catch (p) { + } finally { + k || d.removeAttribute("id") + } + } + return b(a, d, f, g, h) + }, h && (X(function (b) { + a = h.call(b, "div"); + try { + h.call(b, "[test!='']:sizzle"), f.push("!=", J) + } catch (c) { + } + }), f = new RegExp(f.join("|")), bc.matchesSelector = function (b, c) { + c = c.replace(d, "='$1']"); + if (!g(b) && !f.test(c) && (!e || !e.test(c)))try { + var i = h.call(b, c); + if (i || a || b.document && b.document.nodeType !== 11)return i + } catch (j) { + } + return bc(c, null, null, [b]).length > 0 + }) + }(), e.pseudos.nth = e.pseudos.eq, e.filters = bq.prototype = e.pseudos, e.setFilters = new bq, bc.attr = p.attr, p.find = bc, p.expr = bc.selectors, p.expr[":"] = p.expr.pseudos, p.unique = bc.uniqueSort, p.text = bc.getText, p.isXMLDoc = bc.isXML, p.contains = bc.contains + }(a); + var bc = /Until$/, bd = /^(?:parents|prev(?:Until|All))/, be = /^.[^:#\[\.,]*$/, bf = p.expr.match.needsContext, bg = { + children: !0, + contents: !0, + next: !0, + prev: !0 + }; + p.fn.extend({ + find: function (a) { + var b, c, d, e, f, g, h = this; + if (typeof a != "string")return p(a).filter(function () { + for (b = 0, c = h.length; b < c; b++)if (p.contains(h[b], this))return !0 + }); + g = this.pushStack("", "find", a); + for (b = 0, c = this.length; b < c; b++) { + d = g.length, p.find(a, this[b], g); + if (b > 0)for (e = d; e < g.length; e++)for (f = 0; f < d; f++)if (g[f] === g[e]) { + g.splice(e--, 1); + break + } + } + return g + }, has: function (a) { + var b, c = p(a, this), d = c.length; + return this.filter(function () { + for (b = 0; b < d; b++)if (p.contains(this, c[b]))return !0 + }) + }, not: function (a) { + return this.pushStack(bj(this, a, !1), "not", a) + }, filter: function (a) { + return this.pushStack(bj(this, a, !0), "filter", a) + }, is: function (a) { + return !!a && (typeof a == "string" ? bf.test(a) ? p(a, this.context).index(this[0]) >= 0 : p.filter(a, this).length > 0 : this.filter(a).length > 0) + }, closest: function (a, b) { + var c, d = 0, e = this.length, f = [], g = bf.test(a) || typeof a != "string" ? p(a, b || this.context) : 0; + for (; d < e; d++) { + c = this[d]; + while (c && c.ownerDocument && c !== b && c.nodeType !== 11) { + if (g ? g.index(c) > -1 : p.find.matchesSelector(c, a)) { + f.push(c); + break + } + c = c.parentNode + } + } + return f = f.length > 1 ? p.unique(f) : f, this.pushStack(f, "closest", a) + }, index: function (a) { + return a ? typeof a == "string" ? p.inArray(this[0], p(a)) : p.inArray(a.jquery ? a[0] : a, this) : this[0] && this[0].parentNode ? this.prevAll().length : -1 + }, add: function (a, b) { + var c = typeof a == "string" ? p(a, b) : p.makeArray(a && a.nodeType ? [a] : a), d = p.merge(this.get(), c); + return this.pushStack(bh(c[0]) || bh(d[0]) ? d : p.unique(d)) + }, addBack: function (a) { + return this.add(a == null ? this.prevObject : this.prevObject.filter(a)) + } + }), p.fn.andSelf = p.fn.addBack, p.each({ + parent: function (a) { + var b = a.parentNode; + return b && b.nodeType !== 11 ? b : null + }, parents: function (a) { + return p.dir(a, "parentNode") + }, parentsUntil: function (a, b, c) { + return p.dir(a, "parentNode", c) + }, next: function (a) { + return bi(a, "nextSibling") + }, prev: function (a) { + return bi(a, "previousSibling") + }, nextAll: function (a) { + return p.dir(a, "nextSibling") + }, prevAll: function (a) { + return p.dir(a, "previousSibling") + }, nextUntil: function (a, b, c) { + return p.dir(a, "nextSibling", c) + }, prevUntil: function (a, b, c) { + return p.dir(a, "previousSibling", c) + }, siblings: function (a) { + return p.sibling((a.parentNode || {}).firstChild, a) + }, children: function (a) { + return p.sibling(a.firstChild) + }, contents: function (a) { + return p.nodeName(a, "iframe") ? a.contentDocument || a.contentWindow.document : p.merge([], a.childNodes) + } + }, function (a, b) { + p.fn[a] = function (c, d) { + var e = p.map(this, b, c); + return bc.test(a) || (d = c), d && typeof d == "string" && (e = p.filter(d, e)), e = this.length > 1 && !bg[a] ? p.unique(e) : e, this.length > 1 && bd.test(a) && (e = e.reverse()), this.pushStack(e, a, k.call(arguments).join(",")) + } + }), p.extend({ + filter: function (a, b, c) { + return c && (a = ":not(" + a + ")"), b.length === 1 ? p.find.matchesSelector(b[0], a) ? [b[0]] : [] : p.find.matches(a, b) + }, dir: function (a, c, d) { + var e = [], f = a[c]; + while (f && f.nodeType !== 9 && (d === b || f.nodeType !== 1 || !p(f).is(d)))f.nodeType === 1 && e.push(f), f = f[c]; + return e + }, sibling: function (a, b) { + var c = []; + for (; a; a = a.nextSibling)a.nodeType === 1 && a !== b && c.push(a); + return c + } + }); + var bl = "abbr|article|aside|audio|bdi|canvas|data|datalist|details|figcaption|figure|footer|header|hgroup|mark|meter|nav|output|progress|section|summary|time|video", bm = / jQuery\d+="(?:null|\d+)"/g, bn = /^\s+/, bo = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi, bp = /<([\w:]+)/, bq = /
    ", "
    "], + tr: [2, "", "
    "], + td: [3, "", "
    "], + col: [2, "", "
    "], + area: [1, "", ""], + _default: [0, "", ""] + }, bA = bk(e), bB = bA.appendChild(e.createElement("div")); + bz.optgroup = bz.option, bz.tbody = bz.tfoot = bz.colgroup = bz.caption = bz.thead, bz.th = bz.td, p.support.htmlSerialize || (bz._default = [1, "X
    ", "
    "]), p.fn.extend({ + text: function (a) { + return p.access(this, function (a) { + return a === b ? p.text(this) : this.empty().append((this[0] && this[0].ownerDocument || e).createTextNode(a)) + }, null, a, arguments.length) + }, wrapAll: function (a) { + if (p.isFunction(a))return this.each(function (b) { + p(this).wrapAll(a.call(this, b)) + }); + if (this[0]) { + var b = p(a, this[0].ownerDocument).eq(0).clone(!0); + this[0].parentNode && b.insertBefore(this[0]), b.map(function () { + var a = this; + while (a.firstChild && a.firstChild.nodeType === 1)a = a.firstChild; + return a + }).append(this) + } + return this + }, wrapInner: function (a) { + return p.isFunction(a) ? this.each(function (b) { + p(this).wrapInner(a.call(this, b)) + }) : this.each(function () { + var b = p(this), c = b.contents(); + c.length ? c.wrapAll(a) : b.append(a) + }) + }, wrap: function (a) { + var b = p.isFunction(a); + return this.each(function (c) { + p(this).wrapAll(b ? a.call(this, c) : a) + }) + }, unwrap: function () { + return this.parent().each(function () { + p.nodeName(this, "body") || p(this).replaceWith(this.childNodes) + }).end() + }, append: function () { + return this.domManip(arguments, !0, function (a) { + (this.nodeType === 1 || this.nodeType === 11) && this.appendChild(a) + }) + }, prepend: function () { + return this.domManip(arguments, !0, function (a) { + (this.nodeType === 1 || this.nodeType === 11) && this.insertBefore(a, this.firstChild) + }) + }, before: function () { + if (!bh(this[0]))return this.domManip(arguments, !1, function (a) { + this.parentNode.insertBefore(a, this) + }); + if (arguments.length) { + var a = p.clean(arguments); + return this.pushStack(p.merge(a, this), "before", this.selector) + } + }, after: function () { + if (!bh(this[0]))return this.domManip(arguments, !1, function (a) { + this.parentNode.insertBefore(a, this.nextSibling) + }); + if (arguments.length) { + var a = p.clean(arguments); + return this.pushStack(p.merge(this, a), "after", this.selector) + } + }, remove: function (a, b) { + var c, d = 0; + for (; (c = this[d]) != null; d++)if (!a || p.filter(a, [c]).length)!b && c.nodeType === 1 && (p.cleanData(c.getElementsByTagName("*")), p.cleanData([c])), c.parentNode && c.parentNode.removeChild(c); + return this + }, empty: function () { + var a, b = 0; + for (; (a = this[b]) != null; b++) { + a.nodeType === 1 && p.cleanData(a.getElementsByTagName("*")); + while (a.firstChild)a.removeChild(a.firstChild) + } + return this + }, clone: function (a, b) { + return a = a == null ? !1 : a, b = b == null ? a : b, this.map(function () { + return p.clone(this, a, b) + }) + }, html: function (a) { + return p.access(this, function (a) { + var c = this[0] || {}, d = 0, e = this.length; + if (a === b)return c.nodeType === 1 ? c.innerHTML.replace(bm, "") : b; + if (typeof a == "string" && !bs.test(a) && (p.support.htmlSerialize || !bu.test(a)) && (p.support.leadingWhitespace || !bn.test(a)) && !bz[(bp.exec(a) || ["", ""])[1].toLowerCase()]) { + a = a.replace(bo, "<$1>"); + try { + for (; d < e; d++)c = this[d] || {}, c.nodeType === 1 && (p.cleanData(c.getElementsByTagName("*")), c.innerHTML = a); + c = 0 + } catch (f) { + } + } + c && this.empty().append(a) + }, null, a, arguments.length) + }, replaceWith: function (a) { + return bh(this[0]) ? this.length ? this.pushStack(p(p.isFunction(a) ? a() : a), "replaceWith", a) : this : p.isFunction(a) ? this.each(function (b) { + var c = p(this), d = c.html(); + c.replaceWith(a.call(this, b, d)) + }) : (typeof a != "string" && (a = p(a).detach()), this.each(function () { + var b = this.nextSibling, c = this.parentNode; + p(this).remove(), b ? p(b).before(a) : p(c).append(a) + })) + }, detach: function (a) { + return this.remove(a, !0) + }, domManip: function (a, c, d) { + a = [].concat.apply([], a); + var e, f, g, h, i = 0, j = a[0], k = [], l = this.length; + if (!p.support.checkClone && l > 1 && typeof j == "string" && bw.test(j))return this.each(function () { + p(this).domManip(a, c, d) + }); + if (p.isFunction(j))return this.each(function (e) { + var f = p(this); + a[0] = j.call(this, e, c ? f.html() : b), f.domManip(a, c, d) + }); + if (this[0]) { + e = p.buildFragment(a, this, k), g = e.fragment, f = g.firstChild, g.childNodes.length === 1 && (g = f); + if (f) { + c = c && p.nodeName(f, "tr"); + for (h = e.cacheable || l - 1; i < l; i++)d.call(c && p.nodeName(this[i], "table") ? bC(this[i], "tbody") : this[i], i === h ? g : p.clone(g, !0, !0)) + } + g = f = null, k.length && p.each(k, function (a, b) { + b.src ? p.ajax ? p.ajax({ + url: b.src, + type: "GET", + dataType: "script", + async: !1, + global: !1, + "throws": !0 + }) : p.error("no ajax") : p.globalEval((b.text || b.textContent || b.innerHTML || "").replace(by, "")), b.parentNode && b.parentNode.removeChild(b) + }) + } + return this + } + }), p.buildFragment = function (a, c, d) { + var f, g, h, i = a[0]; + return c = c || e, c = !c.nodeType && c[0] || c, c = c.ownerDocument || c, a.length === 1 && typeof i == "string" && i.length < 512 && c === e && i.charAt(0) === "<" && !bt.test(i) && (p.support.checkClone || !bw.test(i)) && (p.support.html5Clone || !bu.test(i)) && (g = !0, f = p.fragments[i], h = f !== b), f || (f = c.createDocumentFragment(), p.clean(a, c, f, d), g && (p.fragments[i] = h && f)), { + fragment: f, + cacheable: g + } + }, p.fragments = {}, p.each({ + appendTo: "append", + prependTo: "prepend", + insertBefore: "before", + insertAfter: "after", + replaceAll: "replaceWith" + }, function (a, b) { + p.fn[a] = function (c) { + var d, e = 0, f = [], g = p(c), h = g.length, i = this.length === 1 && this[0].parentNode; + if ((i == null || i && i.nodeType === 11 && i.childNodes.length === 1) && h === 1)return g[b](this[0]), this; + for (; e < h; e++)d = (e > 0 ? this.clone(!0) : this).get(), p(g[e])[b](d), f = f.concat(d); + return this.pushStack(f, a, g.selector) + } + }), p.extend({ + clone: function (a, b, c) { + var d, e, f, g; + p.support.html5Clone || p.isXMLDoc(a) || !bu.test("<" + a.nodeName + ">") ? g = a.cloneNode(!0) : (bB.innerHTML = a.outerHTML, bB.removeChild(g = bB.firstChild)); + if ((!p.support.noCloneEvent || !p.support.noCloneChecked) && (a.nodeType === 1 || a.nodeType === 11) && !p.isXMLDoc(a)) { + bE(a, g), d = bF(a), e = bF(g); + for (f = 0; d[f]; ++f)e[f] && bE(d[f], e[f]) + } + if (b) { + bD(a, g); + if (c) { + d = bF(a), e = bF(g); + for (f = 0; d[f]; ++f)bD(d[f], e[f]) + } + } + return d = e = null, g + }, clean: function (a, b, c, d) { + var f, g, h, i, j, k, l, m, n, o, q, r, s = b === e && bA, t = []; + if (!b || typeof b.createDocumentFragment == "undefined")b = e; + for (f = 0; (h = a[f]) != null; f++) { + typeof h == "number" && (h += ""); + if (!h)continue; + if (typeof h == "string")if (!br.test(h))h = b.createTextNode(h); else { + s = s || bk(b), l = b.createElement("div"), s.appendChild(l), h = h.replace(bo, "<$1>"), i = (bp.exec(h) || ["", ""])[1].toLowerCase(), j = bz[i] || bz._default, k = j[0], l.innerHTML = j[1] + h + j[2]; + while (k--)l = l.lastChild; + if (!p.support.tbody) { + m = bq.test(h), n = i === "table" && !m ? l.firstChild && l.firstChild.childNodes : j[1] === "" && !m ? l.childNodes : []; + for (g = n.length - 1; g >= 0; --g)p.nodeName(n[g], "tbody") && !n[g].childNodes.length && n[g].parentNode.removeChild(n[g]) + } + !p.support.leadingWhitespace && bn.test(h) && l.insertBefore(b.createTextNode(bn.exec(h)[0]), l.firstChild), h = l.childNodes, l.parentNode.removeChild(l) + } + h.nodeType ? t.push(h) : p.merge(t, h) + } + l && (h = l = s = null); + if (!p.support.appendChecked)for (f = 0; (h = t[f]) != null; f++)p.nodeName(h, "input") ? bG(h) : typeof h.getElementsByTagName != "undefined" && p.grep(h.getElementsByTagName("input"), bG); + if (c) { + q = function (a) { + if (!a.type || bx.test(a.type))return d ? d.push(a.parentNode ? a.parentNode.removeChild(a) : a) : c.appendChild(a) + }; + for (f = 0; (h = t[f]) != null; f++)if (!p.nodeName(h, "script") || !q(h))c.appendChild(h), typeof h.getElementsByTagName != "undefined" && (r = p.grep(p.merge([], h.getElementsByTagName("script")), q), t.splice.apply(t, [f + 1, 0].concat(r)), f += r.length) + } + return t + }, cleanData: function (a, b) { + var c, d, e, f, g = 0, h = p.expando, i = p.cache, j = p.support.deleteExpando, k = p.event.special; + for (; (e = a[g]) != null; g++)if (b || p.acceptData(e)) { + d = e[h], c = d && i[d]; + if (c) { + if (c.events)for (f in c.events)k[f] ? p.event.remove(e, f) : p.removeEvent(e, f, c.handle); + i[d] && (delete i[d], j ? delete e[h] : e.removeAttribute ? e.removeAttribute(h) : e[h] = null, p.deletedIds.push(d)) + } + } + } + }), function () { + var a, b; + p.uaMatch = function (a) { + a = a.toLowerCase(); + var b = /(chrome)[ \/]([\w.]+)/.exec(a) || /(webkit)[ \/]([\w.]+)/.exec(a) || /(opera)(?:.*version|)[ \/]([\w.]+)/.exec(a) || /(msie) ([\w.]+)/.exec(a) || a.indexOf("compatible") < 0 && /(mozilla)(?:.*? rv:([\w.]+)|)/.exec(a) || []; + return {browser: b[1] || "", version: b[2] || "0"} + }, a = p.uaMatch(g.userAgent), b = {}, a.browser && (b[a.browser] = !0, b.version = a.version), b.chrome ? b.webkit = !0 : b.webkit && (b.safari = !0), p.browser = b, p.sub = function () { + function a(b, c) { + return new a.fn.init(b, c) + } + + p.extend(!0, a, this), a.superclass = this, a.fn = a.prototype = this(), a.fn.constructor = a, a.sub = this.sub, a.fn.init = function c(c, d) { + return d && d instanceof p && !(d instanceof a) && (d = a(d)), p.fn.init.call(this, c, d, b) + }, a.fn.init.prototype = a.fn; + var b = a(e); + return a + } + }(); + var bH, bI, bJ, bK = /alpha\([^)]*\)/i, bL = /opacity=([^)]*)/, bM = /^(top|right|bottom|left)$/, bN = /^(none|table(?!-c[ea]).+)/, bO = /^margin/, bP = new RegExp("^(" + q + ")(.*)$", "i"), bQ = new RegExp("^(" + q + ")(?!px)[a-z%]+$", "i"), bR = new RegExp("^([-+])=(" + q + ")", "i"), bS = {}, bT = { + position: "absolute", + visibility: "hidden", + display: "block" + }, bU = { + letterSpacing: 0, + fontWeight: 400 + }, bV = ["Top", "Right", "Bottom", "Left"], bW = ["Webkit", "O", "Moz", "ms"], bX = p.fn.toggle; + p.fn.extend({ + css: function (a, c) { + return p.access(this, function (a, c, d) { + return d !== b ? p.style(a, c, d) : p.css(a, c) + }, a, c, arguments.length > 1) + }, show: function () { + return b$(this, !0) + }, hide: function () { + return b$(this) + }, toggle: function (a, b) { + var c = typeof a == "boolean"; + return p.isFunction(a) && p.isFunction(b) ? bX.apply(this, arguments) : this.each(function () { + (c ? a : bZ(this)) ? p(this).show() : p(this).hide() + }) + } + }), p.extend({ + cssHooks: { + opacity: { + get: function (a, b) { + if (b) { + var c = bH(a, "opacity"); + return c === "" ? "1" : c + } + } + } + }, + cssNumber: { + fillOpacity: !0, + fontWeight: !0, + lineHeight: !0, + opacity: !0, + orphans: !0, + widows: !0, + zIndex: !0, + zoom: !0 + }, + cssProps: {"float": p.support.cssFloat ? "cssFloat" : "styleFloat"}, + style: function (a, c, d, e) { + if (!a || a.nodeType === 3 || a.nodeType === 8 || !a.style)return; + var f, g, h, i = p.camelCase(c), j = a.style; + c = p.cssProps[i] || (p.cssProps[i] = bY(j, i)), h = p.cssHooks[c] || p.cssHooks[i]; + if (d === b)return h && "get"in h && (f = h.get(a, !1, e)) !== b ? f : j[c]; + g = typeof d, g === "string" && (f = bR.exec(d)) && (d = (f[1] + 1) * f[2] + parseFloat(p.css(a, c)), g = "number"); + if (d == null || g === "number" && isNaN(d))return; + g === "number" && !p.cssNumber[i] && (d += "px"); + if (!h || !("set"in h) || (d = h.set(a, d, e)) !== b)try { + j[c] = d + } catch (k) { + } + }, + css: function (a, c, d, e) { + var f, g, h, i = p.camelCase(c); + return c = p.cssProps[i] || (p.cssProps[i] = bY(a.style, i)), h = p.cssHooks[c] || p.cssHooks[i], h && "get"in h && (f = h.get(a, !0, e)), f === b && (f = bH(a, c)), f === "normal" && c in bU && (f = bU[c]), d || e !== b ? (g = parseFloat(f), d || p.isNumeric(g) ? g || 0 : f) : f + }, + swap: function (a, b, c) { + var d, e, f = {}; + for (e in b)f[e] = a.style[e], a.style[e] = b[e]; + d = c.call(a); + for (e in b)a.style[e] = f[e]; + return d + } + }), a.getComputedStyle ? bH = function (b, c) { + var d, e, f, g, h = a.getComputedStyle(b, null), i = b.style; + return h && (d = h[c], d === "" && !p.contains(b.ownerDocument, b) && (d = p.style(b, c)), bQ.test(d) && bO.test(c) && (e = i.width, f = i.minWidth, g = i.maxWidth, i.minWidth = i.maxWidth = i.width = d, d = h.width, i.width = e, i.minWidth = f, i.maxWidth = g)), d + } : e.documentElement.currentStyle && (bH = function (a, b) { + var c, d, e = a.currentStyle && a.currentStyle[b], f = a.style; + return e == null && f && f[b] && (e = f[b]), bQ.test(e) && !bM.test(b) && (c = f.left, d = a.runtimeStyle && a.runtimeStyle.left, d && (a.runtimeStyle.left = a.currentStyle.left), f.left = b === "fontSize" ? "1em" : e, e = f.pixelLeft + "px", f.left = c, d && (a.runtimeStyle.left = d)), e === "" ? "auto" : e + }), p.each(["height", "width"], function (a, b) { + p.cssHooks[b] = { + get: function (a, c, d) { + if (c)return a.offsetWidth === 0 && bN.test(bH(a, "display")) ? p.swap(a, bT, function () { + return cb(a, b, d) + }) : cb(a, b, d) + }, set: function (a, c, d) { + return b_(a, c, d ? ca(a, b, d, p.support.boxSizing && p.css(a, "boxSizing") === "border-box") : 0) + } + } + }), p.support.opacity || (p.cssHooks.opacity = { + get: function (a, b) { + return bL.test((b && a.currentStyle ? a.currentStyle.filter : a.style.filter) || "") ? .01 * parseFloat(RegExp.$1) + "" : b ? "1" : "" + }, set: function (a, b) { + var c = a.style, d = a.currentStyle, e = p.isNumeric(b) ? "alpha(opacity=" + b * 100 + ")" : "", f = d && d.filter || c.filter || ""; + c.zoom = 1; + if (b >= 1 && p.trim(f.replace(bK, "")) === "" && c.removeAttribute) { + c.removeAttribute("filter"); + if (d && !d.filter)return + } + c.filter = bK.test(f) ? f.replace(bK, e) : f + " " + e + } + }), p(function () { + p.support.reliableMarginRight || (p.cssHooks.marginRight = { + get: function (a, b) { + return p.swap(a, {display: "inline-block"}, function () { + if (b)return bH(a, "marginRight") + }) + } + }), !p.support.pixelPosition && p.fn.position && p.each(["top", "left"], function (a, b) { + p.cssHooks[b] = { + get: function (a, c) { + if (c) { + var d = bH(a, b); + return bQ.test(d) ? p(a).position()[b] + "px" : d + } + } + } + }) + }), p.expr && p.expr.filters && (p.expr.filters.hidden = function (a) { + return a.offsetWidth === 0 && a.offsetHeight === 0 || !p.support.reliableHiddenOffsets && (a.style && a.style.display || bH(a, "display")) === "none" + }, p.expr.filters.visible = function (a) { + return !p.expr.filters.hidden(a) + }), p.each({margin: "", padding: "", border: "Width"}, function (a, b) { + p.cssHooks[a + b] = { + expand: function (c) { + var d, e = typeof c == "string" ? c.split(" ") : [c], f = {}; + for (d = 0; d < 4; d++)f[a + bV[d] + b] = e[d] || e[d - 2] || e[0]; + return f + } + }, bO.test(a) || (p.cssHooks[a + b].set = b_) + }); + var cd = /%20/g, ce = /\[\]$/, cf = /\r?\n/g, cg = /^(?:color|date|datetime|datetime-local|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i, ch = /^(?:select|textarea)/i; + p.fn.extend({ + serialize: function () { + return p.param(this.serializeArray()) + }, serializeArray: function () { + return this.map(function () { + return this.elements ? p.makeArray(this.elements) : this + }).filter(function () { + return this.name && !this.disabled && (this.checked || ch.test(this.nodeName) || cg.test(this.type)) + }).map(function (a, b) { + var c = p(this).val(); + return c == null ? null : p.isArray(c) ? p.map(c, function (a, c) { + return {name: b.name, value: a.replace(cf, "\r\n")} + }) : {name: b.name, value: c.replace(cf, "\r\n")} + }).get() + } + }), p.param = function (a, c) { + var d, e = [], f = function (a, b) { + b = p.isFunction(b) ? b() : b == null ? "" : b, e[e.length] = encodeURIComponent(a) + "=" + encodeURIComponent(b) + }; + c === b && (c = p.ajaxSettings && p.ajaxSettings.traditional); + if (p.isArray(a) || a.jquery && !p.isPlainObject(a))p.each(a, function () { + f(this.name, this.value) + }); else for (d in a)ci(d, a[d], c, f); + return e.join("&").replace(cd, "+") + }; + var cj, ck, cl = /#.*$/, cm = /^(.*?):[ \t]*([^\r\n]*)\r?$/mg, cn = /^(?:about|app|app\-storage|.+\-extension|file|res|widget):$/, co = /^(?:GET|HEAD)$/, cp = /^\/\//, cq = /\?/, cr = /)<[^<]*)*<\/script>/gi, cs = /([?&])_=[^&]*/, ct = /^([\w\+\.\-]+:)(?:\/\/([^\/?#:]*)(?::(\d+)|)|)/, cu = p.fn.load, cv = {}, cw = {}, cx = ["*/"] + ["*"]; + try { + ck = f.href + } catch (cy) { + ck = e.createElement("a"), ck.href = "", ck = ck.href + } + cj = ct.exec(ck.toLowerCase()) || [], p.fn.load = function (a, c, d) { + if (typeof a != "string" && cu)return cu.apply(this, arguments); + if (!this.length)return this; + var e, f, g, h = this, i = a.indexOf(" "); + return i >= 0 && (e = a.slice(i, a.length), a = a.slice(0, i)), p.isFunction(c) ? (d = c, c = b) : c && typeof c == "object" && (f = "POST"), p.ajax({ + url: a, + type: f, + dataType: "html", + data: c, + complete: function (a, b) { + d && h.each(d, g || [a.responseText, b, a]) + } + }).done(function (a) { + g = arguments, h.html(e ? p("
    ").append(a.replace(cr, "")).find(e) : a) + }), this + }, p.each("ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "), function (a, b) { + p.fn[b] = function (a) { + return this.on(b, a) + } + }), p.each(["get", "post"], function (a, c) { + p[c] = function (a, d, e, f) { + return p.isFunction(d) && (f = f || e, e = d, d = b), p.ajax({ + type: c, + url: a, + data: d, + success: e, + dataType: f + }) + } + }), p.extend({ + getScript: function (a, c) { + return p.get(a, b, c, "script") + }, + getJSON: function (a, b, c) { + return p.get(a, b, c, "json") + }, + ajaxSetup: function (a, b) { + return b ? cB(a, p.ajaxSettings) : (b = a, a = p.ajaxSettings), cB(a, b), a + }, + ajaxSettings: { + url: ck, + isLocal: cn.test(cj[1]), + global: !0, + type: "GET", + contentType: "application/x-www-form-urlencoded; charset=UTF-8", + processData: !0, + async: !0, + accepts: { + xml: "application/xml, text/xml", + html: "text/html", + text: "text/plain", + json: "application/json, text/javascript", + "*": cx + }, + contents: {xml: /xml/, html: /html/, json: /json/}, + responseFields: {xml: "responseXML", text: "responseText"}, + converters: {"* text": a.String, "text html": !0, "text json": p.parseJSON, "text xml": p.parseXML}, + flatOptions: {context: !0, url: !0} + }, + ajaxPrefilter: cz(cv), + ajaxTransport: cz(cw), + ajax: function (a, c) { + function y(a, c, f, i) { + var k, s, t, u, w, y = c; + if (v === 2)return; + v = 2, h && clearTimeout(h), g = b, e = i || "", x.readyState = a > 0 ? 4 : 0, f && (u = cC(l, x, f)); + if (a >= 200 && a < 300 || a === 304)l.ifModified && (w = x.getResponseHeader("Last-Modified"), w && (p.lastModified[d] = w), w = x.getResponseHeader("Etag"), w && (p.etag[d] = w)), a === 304 ? (y = "notmodified", k = !0) : (k = cD(l, u), y = k.state, s = k.data, t = k.error, k = !t); else { + t = y; + if (!y || a)y = "error", a < 0 && (a = 0) + } + x.status = a, x.statusText = (c || y) + "", k ? o.resolveWith(m, [s, y, x]) : o.rejectWith(m, [x, y, t]), x.statusCode(r), r = b, j && n.trigger("ajax" + (k ? "Success" : "Error"), [x, l, k ? s : t]), q.fireWith(m, [x, y]), j && (n.trigger("ajaxComplete", [x, l]), --p.active || p.event.trigger("ajaxStop")) + } + + typeof a == "object" && (c = a, a = b), c = c || {}; + var d, e, f, g, h, i, j, k, l = p.ajaxSetup({}, c), m = l.context || l, n = m !== l && (m.nodeType || m instanceof p) ? p(m) : p.event, o = p.Deferred(), q = p.Callbacks("once memory"), r = l.statusCode || {}, t = {}, u = {}, v = 0, w = "canceled", x = { + readyState: 0, + setRequestHeader: function (a, b) { + if (!v) { + var c = a.toLowerCase(); + a = u[c] = u[c] || a, t[a] = b + } + return this + }, + getAllResponseHeaders: function () { + return v === 2 ? e : null + }, + getResponseHeader: function (a) { + var c; + if (v === 2) { + if (!f) { + f = {}; + while (c = cm.exec(e))f[c[1].toLowerCase()] = c[2] + } + c = f[a.toLowerCase()] + } + return c === b ? null : c + }, + overrideMimeType: function (a) { + return v || (l.mimeType = a), this + }, + abort: function (a) { + return a = a || w, g && g.abort(a), y(0, a), this + } + }; + o.promise(x), x.success = x.done, x.error = x.fail, x.complete = q.add, x.statusCode = function (a) { + if (a) { + var b; + if (v < 2)for (b in a)r[b] = [r[b], a[b]]; else b = a[x.status], x.always(b) + } + return this + }, l.url = ((a || l.url) + "").replace(cl, "").replace(cp, cj[1] + "//"), l.dataTypes = p.trim(l.dataType || "*").toLowerCase().split(s), l.crossDomain == null && (i = ct.exec(l.url.toLowerCase()) || !1, l.crossDomain = i && i.join(":") + (i[3] ? "" : i[1] === "http:" ? 80 : 443) !== cj.join(":") + (cj[3] ? "" : cj[1] === "http:" ? 80 : 443)), l.data && l.processData && typeof l.data != "string" && (l.data = p.param(l.data, l.traditional)), cA(cv, l, c, x); + if (v === 2)return x; + j = l.global, l.type = l.type.toUpperCase(), l.hasContent = !co.test(l.type), j && p.active++ === 0 && p.event.trigger("ajaxStart"); + if (!l.hasContent) { + l.data && (l.url += (cq.test(l.url) ? "&" : "?") + l.data, delete l.data), d = l.url; + if (l.cache === !1) { + var z = p.now(), A = l.url.replace(cs, "$1_=" + z); + l.url = A + (A === l.url ? (cq.test(l.url) ? "&" : "?") + "_=" + z : "") + } + } + (l.data && l.hasContent && l.contentType !== !1 || c.contentType) && x.setRequestHeader("Content-Type", l.contentType), l.ifModified && (d = d || l.url, p.lastModified[d] && x.setRequestHeader("If-Modified-Since", p.lastModified[d]), p.etag[d] && x.setRequestHeader("If-None-Match", p.etag[d])), x.setRequestHeader("Accept", l.dataTypes[0] && l.accepts[l.dataTypes[0]] ? l.accepts[l.dataTypes[0]] + (l.dataTypes[0] !== "*" ? ", " + cx + "; q=0.01" : "") : l.accepts["*"]); + for (k in l.headers)x.setRequestHeader(k, l.headers[k]); + if (!l.beforeSend || l.beforeSend.call(m, x, l) !== !1 && v !== 2) { + w = "abort"; + for (k in{success: 1, error: 1, complete: 1})x[k](l[k]); + g = cA(cw, l, c, x); + if (!g)y(-1, "No Transport"); else { + x.readyState = 1, j && n.trigger("ajaxSend", [x, l]), l.async && l.timeout > 0 && (h = setTimeout(function () { + x.abort("timeout") + }, l.timeout)); + try { + v = 1, g.send(t, y) + } catch (B) { + if (v < 2)y(-1, B); else throw B + } + } + return x + } + return x.abort() + }, + active: 0, + lastModified: {}, + etag: {} + }); + var cE = [], cF = /\?/, cG = /(=)\?(?=&|$)|\?\?/, cH = p.now(); + p.ajaxSetup({ + jsonp: "callback", jsonpCallback: function () { + var a = cE.pop() || p.expando + "_" + cH++; + return this[a] = !0, a + } + }), p.ajaxPrefilter("json jsonp", function (c, d, e) { + var f, g, h, i = c.data, j = c.url, k = c.jsonp !== !1, l = k && cG.test(j), m = k && !l && typeof i == "string" && !(c.contentType || "").indexOf("application/x-www-form-urlencoded") && cG.test(i); + if (c.dataTypes[0] === "jsonp" || l || m)return f = c.jsonpCallback = p.isFunction(c.jsonpCallback) ? c.jsonpCallback() : c.jsonpCallback, g = a[f], l ? c.url = j.replace(cG, "$1" + f) : m ? c.data = i.replace(cG, "$1" + f) : k && (c.url += (cF.test(j) ? "&" : "?") + c.jsonp + "=" + f), c.converters["script json"] = function () { + return h || p.error(f + " was not called"), h[0] + }, c.dataTypes[0] = "json", a[f] = function () { + h = arguments + }, e.always(function () { + a[f] = g, c[f] && (c.jsonpCallback = d.jsonpCallback, cE.push(f)), h && p.isFunction(g) && g(h[0]), h = g = b + }), "script" + }), p.ajaxSetup({ + accepts: {script: "text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"}, + contents: {script: /javascript|ecmascript/}, + converters: { + "text script": function (a) { + return p.globalEval(a), a + } + } + }), p.ajaxPrefilter("script", function (a) { + a.cache === b && (a.cache = !1), a.crossDomain && (a.type = "GET", a.global = !1) + }), p.ajaxTransport("script", function (a) { + if (a.crossDomain) { + var c, d = e.head || e.getElementsByTagName("head")[0] || e.documentElement; + return { + send: function (f, g) { + c = e.createElement("script"), c.async = "async", a.scriptCharset && (c.charset = a.scriptCharset), c.src = a.url, c.onload = c.onreadystatechange = function (a, e) { + if (e || !c.readyState || /loaded|complete/.test(c.readyState))c.onload = c.onreadystatechange = null, d && c.parentNode && d.removeChild(c), c = b, e || g(200, "success") + }, d.insertBefore(c, d.firstChild) + }, abort: function () { + c && c.onload(0, 1) + } + } + } + }); + var cI, cJ = a.ActiveXObject ? function () { + for (var a in cI)cI[a](0, 1) + } : !1, cK = 0; + p.ajaxSettings.xhr = a.ActiveXObject ? function () { + return !this.isLocal && cL() || cM() + } : cL, function (a) { + p.extend(p.support, {ajax: !!a, cors: !!a && "withCredentials"in a}) + }(p.ajaxSettings.xhr()), p.support.ajax && p.ajaxTransport(function (c) { + if (!c.crossDomain || p.support.cors) { + var d; + return { + send: function (e, f) { + var g, h, i = c.xhr(); + c.username ? i.open(c.type, c.url, c.async, c.username, c.password) : i.open(c.type, c.url, c.async); + if (c.xhrFields)for (h in c.xhrFields)i[h] = c.xhrFields[h]; + c.mimeType && i.overrideMimeType && i.overrideMimeType(c.mimeType), !c.crossDomain && !e["X-Requested-With"] && (e["X-Requested-With"] = "XMLHttpRequest"); + try { + for (h in e)i.setRequestHeader(h, e[h]) + } catch (j) { + } + i.send(c.hasContent && c.data || null), d = function (a, e) { + var h, j, k, l, m; + try { + if (d && (e || i.readyState === 4)) { + d = b, g && (i.onreadystatechange = p.noop, cJ && delete cI[g]); + if (e)i.readyState !== 4 && i.abort(); else { + h = i.status, k = i.getAllResponseHeaders(), l = {}, m = i.responseXML, m && m.documentElement && (l.xml = m); + try { + l.text = i.responseText + } catch (a) { + } + try { + j = i.statusText + } catch (n) { + j = "" + } + !h && c.isLocal && !c.crossDomain ? h = l.text ? 200 : 404 : h === 1223 && (h = 204) + } + } + } catch (o) { + e || f(-1, o) + } + l && f(h, j, l, k) + }, c.async ? i.readyState === 4 ? setTimeout(d, 0) : (g = ++cK, cJ && (cI || (cI = {}, p(a).unload(cJ)), cI[g] = d), i.onreadystatechange = d) : d() + }, abort: function () { + d && d(0, 1) + } + } + } + }); + var cN, cO, cP = /^(?:toggle|show|hide)$/, cQ = new RegExp("^(?:([-+])=|)(" + q + ")([a-z%]*)$", "i"), cR = /queueHooks$/, cS = [cY], cT = { + "*": [function (a, b) { + var c, d, e = this.createTween(a, b), f = cQ.exec(b), g = e.cur(), h = +g || 0, i = 1, j = 20; + if (f) { + c = +f[2], d = f[3] || (p.cssNumber[a] ? "" : "px"); + if (d !== "px" && h) { + h = p.css(e.elem, a, !0) || c || 1; + do i = i || ".5", h = h / i, p.style(e.elem, a, h + d); while (i !== (i = e.cur() / g) && i !== 1 && --j) + } + e.unit = d, e.start = h, e.end = f[1] ? h + (f[1] + 1) * c : c + } + return e + }] + }; + p.Animation = p.extend(cW, { + tweener: function (a, b) { + p.isFunction(a) ? (b = a, a = ["*"]) : a = a.split(" "); + var c, d = 0, e = a.length; + for (; d < e; d++)c = a[d], cT[c] = cT[c] || [], cT[c].unshift(b) + }, prefilter: function (a, b) { + b ? cS.unshift(a) : cS.push(a) + } + }), p.Tween = cZ, cZ.prototype = { + constructor: cZ, init: function (a, b, c, d, e, f) { + this.elem = a, this.prop = c, this.easing = e || "swing", this.options = b, this.start = this.now = this.cur(), this.end = d, this.unit = f || (p.cssNumber[c] ? "" : "px") + }, cur: function () { + var a = cZ.propHooks[this.prop]; + return a && a.get ? a.get(this) : cZ.propHooks._default.get(this) + }, run: function (a) { + var b, c = cZ.propHooks[this.prop]; + return this.options.duration ? this.pos = b = p.easing[this.easing](a, this.options.duration * a, 0, 1, this.options.duration) : this.pos = b = a, this.now = (this.end - this.start) * b + this.start, this.options.step && this.options.step.call(this.elem, this.now, this), c && c.set ? c.set(this) : cZ.propHooks._default.set(this), this + } + }, cZ.prototype.init.prototype = cZ.prototype, cZ.propHooks = { + _default: { + get: function (a) { + var b; + return a.elem[a.prop] == null || !!a.elem.style && a.elem.style[a.prop] != null ? (b = p.css(a.elem, a.prop, !1, ""), !b || b === "auto" ? 0 : b) : a.elem[a.prop] + }, set: function (a) { + p.fx.step[a.prop] ? p.fx.step[a.prop](a) : a.elem.style && (a.elem.style[p.cssProps[a.prop]] != null || p.cssHooks[a.prop]) ? p.style(a.elem, a.prop, a.now + a.unit) : a.elem[a.prop] = a.now + } + } + }, cZ.propHooks.scrollTop = cZ.propHooks.scrollLeft = { + set: function (a) { + a.elem.nodeType && a.elem.parentNode && (a.elem[a.prop] = a.now) + } + }, p.each(["toggle", "show", "hide"], function (a, b) { + var c = p.fn[b]; + p.fn[b] = function (d, e, f) { + return d == null || typeof d == "boolean" || !a && p.isFunction(d) && p.isFunction(e) ? c.apply(this, arguments) : this.animate(c$(b, !0), d, e, f) + } + }), p.fn.extend({ + fadeTo: function (a, b, c, d) { + return this.filter(bZ).css("opacity", 0).show().end().animate({opacity: b}, a, c, d) + }, animate: function (a, b, c, d) { + var e = p.isEmptyObject(a), f = p.speed(b, c, d), g = function () { + var b = cW(this, p.extend({}, a), f); + e && b.stop(!0) + }; + return e || f.queue === !1 ? this.each(g) : this.queue(f.queue, g) + }, stop: function (a, c, d) { + var e = function (a) { + var b = a.stop; + delete a.stop, b(d) + }; + return typeof a != "string" && (d = c, c = a, a = b), c && a !== !1 && this.queue(a || "fx", []), this.each(function () { + var b = !0, c = a != null && a + "queueHooks", f = p.timers, g = p._data(this); + if (c)g[c] && g[c].stop && e(g[c]); else for (c in g)g[c] && g[c].stop && cR.test(c) && e(g[c]); + for (c = f.length; c--;)f[c].elem === this && (a == null || f[c].queue === a) && (f[c].anim.stop(d), b = !1, f.splice(c, 1)); + (b || !d) && p.dequeue(this, a) + }) + } + }), p.each({ + slideDown: c$("show"), + slideUp: c$("hide"), + slideToggle: c$("toggle"), + fadeIn: {opacity: "show"}, + fadeOut: {opacity: "hide"}, + fadeToggle: {opacity: "toggle"} + }, function (a, b) { + p.fn[a] = function (a, c, d) { + return this.animate(b, a, c, d) + } + }), p.speed = function (a, b, c) { + var d = a && typeof a == "object" ? p.extend({}, a) : { + complete: c || !c && b || p.isFunction(a) && a, + duration: a, + easing: c && b || b && !p.isFunction(b) && b + }; + d.duration = p.fx.off ? 0 : typeof d.duration == "number" ? d.duration : d.duration in p.fx.speeds ? p.fx.speeds[d.duration] : p.fx.speeds._default; + if (d.queue == null || d.queue === !0)d.queue = "fx"; + return d.old = d.complete, d.complete = function () { + p.isFunction(d.old) && d.old.call(this), d.queue && p.dequeue(this, d.queue) + }, d + }, p.easing = { + linear: function (a) { + return a + }, swing: function (a) { + return .5 - Math.cos(a * Math.PI) / 2 + } + }, p.timers = [], p.fx = cZ.prototype.init, p.fx.tick = function () { + var a, b = p.timers, c = 0; + for (; c < b.length; c++)a = b[c], !a() && b[c] === a && b.splice(c--, 1); + b.length || p.fx.stop() + }, p.fx.timer = function (a) { + a() && p.timers.push(a) && !cO && (cO = setInterval(p.fx.tick, p.fx.interval)) + }, p.fx.interval = 13, p.fx.stop = function () { + clearInterval(cO), cO = null + }, p.fx.speeds = { + slow: 600, + fast: 200, + _default: 400 + }, p.fx.step = {}, p.expr && p.expr.filters && (p.expr.filters.animated = function (a) { + return p.grep(p.timers, function (b) { + return a === b.elem + }).length + }); + var c_ = /^(?:body|html)$/i; + p.fn.offset = function (a) { + if (arguments.length)return a === b ? this : this.each(function (b) { + p.offset.setOffset(this, a, b) + }); + var c, d, e, f, g, h, i, j = {top: 0, left: 0}, k = this[0], l = k && k.ownerDocument; + if (!l)return; + return (d = l.body) === k ? p.offset.bodyOffset(k) : (c = l.documentElement, p.contains(c, k) ? (typeof k.getBoundingClientRect != "undefined" && (j = k.getBoundingClientRect()), e = da(l), f = c.clientTop || d.clientTop || 0, g = c.clientLeft || d.clientLeft || 0, h = e.pageYOffset || c.scrollTop, i = e.pageXOffset || c.scrollLeft, { + top: j.top + h - f, + left: j.left + i - g + }) : j) + }, p.offset = { + bodyOffset: function (a) { + var b = a.offsetTop, c = a.offsetLeft; + return p.support.doesNotIncludeMarginInBodyOffset && (b += parseFloat(p.css(a, "marginTop")) || 0, c += parseFloat(p.css(a, "marginLeft")) || 0), { + top: b, + left: c + } + }, setOffset: function (a, b, c) { + var d = p.css(a, "position"); + d === "static" && (a.style.position = "relative"); + var e = p(a), f = e.offset(), g = p.css(a, "top"), h = p.css(a, "left"), i = (d === "absolute" || d === "fixed") && p.inArray("auto", [g, h]) > -1, j = {}, k = {}, l, m; + i ? (k = e.position(), l = k.top, m = k.left) : (l = parseFloat(g) || 0, m = parseFloat(h) || 0), p.isFunction(b) && (b = b.call(a, c, f)), b.top != null && (j.top = b.top - f.top + l), b.left != null && (j.left = b.left - f.left + m), "using"in b ? b.using.call(a, j) : e.css(j) + } + }, p.fn.extend({ + position: function () { + if (!this[0])return; + var a = this[0], b = this.offsetParent(), c = this.offset(), d = c_.test(b[0].nodeName) ? { + top: 0, + left: 0 + } : b.offset(); + return c.top -= parseFloat(p.css(a, "marginTop")) || 0, c.left -= parseFloat(p.css(a, "marginLeft")) || 0, d.top += parseFloat(p.css(b[0], "borderTopWidth")) || 0, d.left += parseFloat(p.css(b[0], "borderLeftWidth")) || 0, { + top: c.top - d.top, + left: c.left - d.left + } + }, offsetParent: function () { + return this.map(function () { + var a = this.offsetParent || e.body; + while (a && !c_.test(a.nodeName) && p.css(a, "position") === "static")a = a.offsetParent; + return a || e.body + }) + } + }), p.each({scrollLeft: "pageXOffset", scrollTop: "pageYOffset"}, function (a, c) { + var d = /Y/.test(c); + p.fn[a] = function (e) { + return p.access(this, function (a, e, f) { + var g = da(a); + if (f === b)return g ? c in g ? g[c] : g.document.documentElement[e] : a[e]; + g ? g.scrollTo(d ? p(g).scrollLeft() : f, d ? f : p(g).scrollTop()) : a[e] = f + }, a, e, arguments.length, null) + } + }), p.each({Height: "height", Width: "width"}, function (a, c) { + p.each({padding: "inner" + a, content: c, "": "outer" + a}, function (d, e) { + p.fn[e] = function (e, f) { + var g = arguments.length && (d || typeof e != "boolean"), h = d || (e === !0 || f === !0 ? "margin" : "border"); + return p.access(this, function (c, d, e) { + var f; + return p.isWindow(c) ? c.document.documentElement["client" + a] : c.nodeType === 9 ? (f = c.documentElement, Math.max(c.body["scroll" + a], f["scroll" + a], c.body["offset" + a], f["offset" + a], f["client" + a])) : e === b ? p.css(c, d, e, h) : p.style(c, d, e, h) + }, c, g ? e : b, g, null) + } + }) + }), a.jQuery = a.$ = p, typeof define == "function" && define.amd && define.amd.jQuery && define("jquery", [], function () { + return p + }) + })(window); + + // wrap for RAP + if (window.wrapJQueryForRAP) { + window.wrapJQueryForRAP($); + } + $.providedByRAP = true; + return $.noConflict(true); +}); \ No newline at end of file diff --git a/src/main/webapp/stat/js/util/jsformat.js b/src/main/webapp/stat/js/util/jsformat.js new file mode 100644 index 000000000..d34cb0adb --- /dev/null +++ b/src/main/webapp/stat/js/util/jsformat.js @@ -0,0 +1,57 @@ +String.prototype.toHtml = function () { + return this.replace(/\&/g, '&').replace(/\/g, '>').replace(/\x20/g, ' ').replace(/(\r\n|\r|\n)/g, '
    ') +}; +String.prototype.formatJS = function () { + var s = this; + var index = 0, brch = 0; + var keywords = ['abstract', 'boolean', 'break', 'byte', 'case', 'catch', 'char', 'class', 'const', 'continue', 'default', 'delete', 'do', 'double', 'else', 'extends', 'false', 'final', 'finally', 'float', 'for', 'function', 'goto', 'if', 'implements', 'import', 'in', 'instanceof', 'int', 'interface', 'long', 'native', 'new', 'null', 'package', 'private', 'protected', 'public', 'return', 'short', 'static', 'super', 'switch', 'synchronized', 'this', 'throw', 'throws', 'transient', 'true', 'try', 'typeof', 'var', 'void', 'while', 'with']; + var objects = ['Anchor', 'anchors', 'Applet', 'applets', 'Area', 'Array', 'arguments', 'Button', 'Checkbox', 'Date', 'document', 'FileUpload', 'Form', 'forms', 'Frame', 'frames', 'Function', 'Hidden', 'history', 'Image', 'images', 'Link', 'links', 'Area', 'location', 'Math', 'MimeType', 'mimeTypes', 'navigator', 'options', 'Password', 'Plugin', 'plugins', 'Radio', 'Reset', 'RegExp', 'Select', 'String', 'Submit', 'Text', 'Textarea', 'window']; + var specials = ['prototype', 'callee', 'caller', 'apply', 'call', 'encodeURIComponent', 'decodeURIComponent', 'parseInt', 'parseFloat', '__defineGetter__', '__defineSetter__']; + var blocks = []; + var indent = "", indent_fix = ""; + s = s.replace(/\t/g, ' ').replace(/\r\n|\r/g, "\n").replace(/(\/\/[^\n]*(\n|$)|\/\*(\*(?!\/)|[^\*])*\*+\/|\"(\\\"|\\\\|[^\"\n])*\"|\'(\\\'|\\\\|[^\'\n])*\'|([=!\(\:\{\[\;&|^]\s*)\/(\\.|[^\/\n])+\/[igm]*)/g, function ($0) { + var color = "#CCCCCC", ret = "'"; + var kkk = $0; + if (kkk.charAt(0) == '"')color = "#FF00FF"; else if (kkk.charAt(0) == "'")color = "#9900FF"; else if (kkk.match(/^(?:[=!\(\:\{\[&|^]\s*)(\/(\\.|[^\/\n])+\/[igm]*$)/)) { + ret = kkk.replace(/^([=!\(\:\{\[&|^]\s*)(\/(\\.|[^\/\n])+\/[igm]*$)/, "$1'"); + kkk = kkk.replace(/^([=!\(\:\{\[&|^]\s*)(\/(\\.|[^\/\n])+\/[igm]*$)/, "$2"); + color = "#6666CC" + } + blocks[blocks.length] = "" + kkk.toHtml() + ""; + return ret + }).replace(/(\}?[\n ]*;[\n ]*)/g, function ($0, $1) { + return $1.replace(/[\n ]/g, '') + "\n" + }).replace(/\b(else)\b/g, "$1\n").replace(/\b((case|default)[^:]*\:)/g, "$1\n").replace(/(\{[\n ]*)((([A-Za-z\$\_][0-9A-Za-z\$\_]*|`)[\n ]*\:[\n ]*[^,\}]+,?)+)([\n ]*\})/g, function ($0, $1, $2, $3, $4, $5) { + return $1 + $2.replace(/[\n ]+/g, ' ').replace(/(([A-Za-z\$\_][0-9A-Za-z\$\_]*|`)\:[^,\}]+,?)/g, "$1\n") + $5 + }).replace(/[\n ]*(\{|\};?)[\n ]*/g, function ($0, $1) { + if ($1.charAt(0) == '}')brch--; + var ss = "\n"; + for (var i = 0; i < brch; i++)ss += " "; + if ($1 == '{')brch++; + return ss + $1 + "\n" + }).replace(/[\n ]*\{[\n ]*\}/g, '{}').replace(/^[ ]*([^\{\}])/g, "$1").replace(/(\n\s*for\b[^\n]*\;\s*)\n/g, '$1').replace(/(\n\s*for\b[^\n]*\;\s*)\n/g, '$1').replace(/\n\s*(for|while|if|switch)\b[^\n]*; *\n/g, function ($0, $1) { + var le = 0; + for (var i = 0; i < $0.length; i++)if ($0.charAt(i) == '(')le++; else if ($0.charAt(i) == ')') { + le--; + if (le == 0)return $0.substr(0, i + 1) + "\n" + $0.substr(i + 1, $0.length) + } + }).replace(/(\n *)*(\n *)/g, "$2").replace(/(`\s*)\+(?=\s*`)/g, "$1\n+").replace(/( *)([^\n]*)\n/g, function ($0, space, text) { + var ret = $0; + if (text.match(/^\{/)) { + indent = space + " "; + indent_fix = "" + } else if (text.match(/^\}/)) { + indent = space; + indent_fix = "" + } else { + if (text.match(/^(case|default)\b/))ret = indent.substr(0, indent.length - 4) + text; else ret = indent + indent_fix + text; + if (text.match(/^(if|for|else|var|while)\b/) && !text.match(/\;\s*$/))indent_fix = " "; else if (!text.match(/[^\;]\s*$/))indent_fix = ""; + if (text.charAt(0) == '+')ret = " " + ret; + ret += "\n" + } + return ret + }).replace(/\&/g, '&').replace(/\/g, '>').replace(/\x20/g, ' ').replace(eval('/\\b(' + keywords.join('|') + ')\\b/g'), '$1').replace(eval('/\\b(' + objects.join('|') + ')\\b/g'), '$1').replace(eval('/\\b(' + specials.join('|') + ')\\b/g'), '$1').replace(/\n/g, '
    ').replace(/\'/g, function ($0) { + return blocks[index++] + }); + return s +} diff --git a/WebContent/stat/js/util/mock-min.js b/src/main/webapp/stat/js/util/mock-min.js similarity index 99% rename from WebContent/stat/js/util/mock-min.js rename to src/main/webapp/stat/js/util/mock-min.js index 1c757730f..fdf3ac71c 100644 --- a/WebContent/stat/js/util/mock-min.js +++ b/src/main/webapp/stat/js/util/mock-min.js @@ -1,10 +1,3 @@ -/*! mockjs 13-04-2015 14:32:27 */ -/*! src/mock-prefix.js */ -/*! - Mock - 模拟请求 & 模拟数据 - https://github.com/nuysoft/Mock - 墨智 nuysoft@gmail.com - */ (function(undefined) { var Mock = { version: "0.1.9", diff --git a/WebContent/stat/js/util/mock.plugin.js b/src/main/webapp/stat/js/util/mock.plugin.js similarity index 87% rename from WebContent/stat/js/util/mock.plugin.js rename to src/main/webapp/stat/js/util/mock.plugin.js index 0416bb284..50747b971 100644 --- a/WebContent/stat/js/util/mock.plugin.js +++ b/src/main/webapp/stat/js/util/mock.plugin.js @@ -1,15 +1,8 @@ -/** - * RAP plugin for browsers - * Functions: 1). IO mock data, 2). IO format check, 3). route manage - * Supports: 1). jQuery, 2). KISSY - * - * @createDate Mar. 10th 2014 - * @updateDate Apr. 14th 2015 - */ -(function(window, undefined) { + +(function (window, undefined) { var node = null; var blackList = []; - var whiteList = [#foreach($url in $urlList)#if($velocityCount>1),#end"$url"#end]; + var whiteList = [#foreach($url in $urlList)#if ($velocityCount > 1),#end"$url"#end]; var ROOT = "$!consts.DOMAIN_URL"; var LOST = "LOST"; @@ -47,7 +40,7 @@ jQuery._rap_wrapped = true; var ajax = jQuery.ajax; - jQuery.ajax = function() { + jQuery.ajax = function () { var oOptions = arguments[0]; // process ajax(url, options) condition @@ -59,10 +52,10 @@ oOptions.url = arguments[0]; arguments[0] = oOptions; - } else if(typeof arguments[0] === 'string' && + } else if (typeof arguments[0] === 'string' && typeof arguments[1] === undefined) { oOptions = arguments[0] = { - url : arguments[0] + url: arguments[0] }; } @@ -71,7 +64,7 @@ if (routePassed) { rapUrlConverterJQuery(oOptions); var oldSuccess1 = oOptions.success; - oldSuccess1 && (oOptions.success = function(data) { + oldSuccess1 && (oOptions.success = function (data) { if (PREFIX == '/mockjs/') { data = Mock.mock(data); if (data.__root__) { @@ -87,7 +80,7 @@ }); var oldComplete = oOptions.complete; - oldComplete && (oOptions.complete = function(data) { + oldComplete && (oOptions.complete = function (data) { if (PREFIX == '/mockjs/') { data = Mock.mock(data); if (data.__root__) { @@ -101,32 +94,32 @@ } oldComplete.apply(this, arguments); }); - } else if(isInWhiteList(url) && !oOptions.RAP_NOT_TRACK) { - var checkerOptions = {url : oOptions.url}; + } else if (isInWhiteList(url) && !oOptions.RAP_NOT_TRACK) { + var checkerOptions = {url: oOptions.url}; rapUrlConverterJQuery(checkerOptions); checkerOptions.RAP_NOT_TRACK = true; checkerOptions.success = checkerHandler; // real data checking var oldSuccess2 = oOptions.success; - oOptions.success = function() { + oOptions.success = function () { var realData = arguments[0]; checkerOptions.context = { - data : realData, - url : oOptions.url + data: realData, + url: oOptions.url }; // perform real data check ajax.apply(jQuery, [checkerOptions]); - oldSuccess2.apply(this,arguments); + oldSuccess2.apply(this, arguments); }; } var rv = ajax.apply(this, arguments); if (routePassed) { var oldDone = rv.done; - oldDone && (rv.done = function(data) { + oldDone && (rv.done = function (data) { var oldCb = arguments[0]; var args = arguments; if (oldCb) { - args[0] = function(data) { + args[0] = function (data) { if (PREFIX == '/mockjs/') { data = Mock.mock(data); if (data.__root__) { @@ -167,10 +160,10 @@ KISSY.oldUse = KISSY.use; KISSY.oldAdd = KISSY.add; - KISSY.add('rap_io', function(S, IO) { + KISSY.add('rap_io', function (S, IO) { var oldIO = IO; var key; - var fn = KISSY.io = KISSY.IO = KISSY.ajax = function(options) { + var fn = KISSY.io = KISSY.IO = KISSY.ajax = function (options) { var oOptions, url; if (arguments[0]) { oOptions = arguments[0]; @@ -178,7 +171,7 @@ if (route(url) && !oOptions.RAP_NOT_TRACK) { rapUrlConverterKissy(oOptions); var oldSuccess1 = oOptions.success; - oldSuccess1 && (oOptions.success = function(data) { + oldSuccess1 && (oOptions.success = function (data) { if (PREFIX == '/mockjs/') { data = Mock.mock(data); if (data.__root__) { @@ -192,7 +185,7 @@ oldSuccess1.apply(this, arguments); }); var oldComplete = oOptions.complete; - oldComplete && (oOptions.complete = function(data) { + oldComplete && (oOptions.complete = function (data) { if (PREFIX == '/mockjs/') { data = Mock.mock(data); if (data.__root__) { @@ -206,22 +199,22 @@ } oldComplete.apply(this, arguments); }); - } else if(isInWhiteList(url) && !oOptions.RAP_NOT_TRACK) { - var checkerOptions = {url:oOptions.url}; + } else if (isInWhiteList(url) && !oOptions.RAP_NOT_TRACK) { + var checkerOptions = {url: oOptions.url}; rapUrlConverterKissy(checkerOptions); checkerOptions.RAP_NOT_TRACK = true; checkerOptions.success = checkerHandler; // real data checking var oldSuccess2 = oOptions.success; - oOptions.success = function() { + oOptions.success = function () { var realData = arguments[0]; checkerOptions.context = { - data : realData, - url : oOptions.url + data: realData, + url: oOptions.url }; // perform real data check IO(checkerOptions); - oldSuccess2.apply(this,arguments); + oldSuccess2.apply(this, arguments); }; } @@ -241,7 +234,7 @@ }); - KISSY.use = function(modules, callback) { + KISSY.use = function (modules, callback) { var args = arguments; if (modules instanceof Array || typeof modules === 'string') { args[0] = replace(modules); @@ -249,10 +242,10 @@ KISSY.oldUse.apply(this, args); }; - KISSY.add = function(name, fn, options) { + KISSY.add = function (name, fn, options) { if (options && options.requires) { - for(var i = 0, l = options.requires.length; i < l; i++) { + for (var i = 0, l = options.requires.length; i < l; i++) { var current = options.requires[i].toLowerCase(); if (current == 'io' || current == 'ajax') { @@ -265,7 +258,8 @@ }; if (KISSY.IO || KISSY.io || KISSY.ajax) { - KISSY.use('rap_io', function() {}); + KISSY.use('rap_io', function () { + }); } } @@ -273,12 +267,12 @@ if (window.seajs && window.seajs.use && window.define && window.define.cmd && seajsEnabled != 'false') { - !function() { + !function () { var oldSeajsUse = seajs.use; var initialized = false; - seajs.use = function() { + seajs.use = function () { var handler = arguments[arguments.length - 1]; - arguments[arguments.length - 1] = function() { + arguments[arguments.length - 1] = function () { if (!initialized) { for (var i = 0; i < arguments.length; i++) { if (arguments[i] && typeof arguments[i] === 'function' && arguments[i].prototype && @@ -297,7 +291,6 @@ }(); - var data = seajs.config().data; data.alias = data.alias || {}; var path = 'http://' + ROOT + '/stat/js/util/jquery-rapped.js'; @@ -504,7 +497,7 @@ } window.RAP = { - initList : function(list) { + initList: function (list) { var PARAM_REG = /\/:[^\/]*/g; var i, n = list.length, item; for (i = 0; i < n; i++) { @@ -522,26 +515,26 @@ } return list; }, - setBlackList : function(arr) { + setBlackList: function (arr) { if (arr && arr instanceof Array) { blackList = this.initList(arr); } }, - setWhiteList : function(arr) { + setWhiteList: function (arr) { if (arr && arr instanceof Array) { whiteList = this.initList(arr); } }, - getBlackList : function() { + getBlackList: function () { return blackList; }, - getWhiteList : function() { + getWhiteList: function () { return whiteList; }, - getMode : function() { + getMode: function () { return mode; }, - setMode : function(m) { + setMode: function (m) { m = +m; if (m in modeList) { mode = m; @@ -550,28 +543,28 @@ console.warn('Illegal mode id. Please check.'); } }, - setHost : function(h) { + setHost: function (h) { ROOT = h; }, - getHost : function() { + getHost: function () { return ROOT; }, - setPrefix: function(p) { + setPrefix: function (p) { PREFIX = p; }, - getPrefix: function(p) { + getPrefix: function (p) { return PREFIX; }, - setProjectId: function(id) { + setProjectId: function (id) { projectId = id; }, - getProjectId: function() { + getProjectId: function () { return projectId; }, - router: function(url) { + router: function (url) { return route(url); }, - checkerHandler: function() { + checkerHandler: function () { return checkerHandler.apply(this, arguments); } }; diff --git a/WebContent/stat/js/util/mock.plugin.js.backup b/src/main/webapp/stat/js/util/mock.plugin.js.backup similarity index 100% rename from WebContent/stat/js/util/mock.plugin.js.backup rename to src/main/webapp/stat/js/util/mock.plugin.js.backup diff --git a/WebContent/stat/js/util/structureValidator.js b/src/main/webapp/stat/js/util/structureValidator.js similarity index 79% rename from WebContent/stat/js/util/structureValidator.js rename to src/main/webapp/stat/js/util/structureValidator.js index e1bfe3192..aee698943 100644 --- a/WebContent/stat/js/util/structureValidator.js +++ b/src/main/webapp/stat/js/util/structureValidator.js @@ -1,4 +1,4 @@ -!function() { +!function () { var global = this; var LOST = "LOST"; var EMPTY_ARRAY = "EMPTY_ARRAY"; @@ -8,12 +8,14 @@ if (typeof o1 === 'string') { try { o1 = JSON.parse(o1); - } catch(ex) {} + } catch (ex) { + } } if (typeof o2 === 'string') { try { o2 = JSON.parse(o2); - } catch(ex) {} + } catch (ex) { + } } if (!leftName) { @@ -31,14 +33,14 @@ this._check(o1, o2, 'right', rightName); } - StructureValidator.prototype.getResult = function() { + StructureValidator.prototype.getResult = function () { return { - left : this.left, - right : this.right + left: this.left, + right: this.right }; }; - StructureValidator.prototype.getResultStr = function() { + StructureValidator.prototype.getResultStr = function () { var result = this.getResult(); var left = result.left; var right = result.right; @@ -75,7 +77,7 @@ } } - StructureValidator.prototype._check = function(o1, o2, key, keyName, isReverseCheck) { + StructureValidator.prototype._check = function (o1, o2, key, keyName, isReverseCheck) { var result = []; function typeEqual(a, b) { @@ -104,16 +106,16 @@ if (oa.hasOwnProperty(p)) { if (!ob.hasOwnProperty(p)) { result.push({ - type : LOST, - property : p, - namespace : ns + type: LOST, + property: p, + namespace: ns }); } else if (!typeEqual(oa[p], ob[p])) { if (!isReverseCheck) { result.push({ - type : TYPE_NOT_EQUAL, - property : p, - namespace : ns + type: TYPE_NOT_EQUAL, + property: p, + namespace: ns }); } } else if (isArrayObject(oa[p]) && isArrayObject(ob[p])) { @@ -131,9 +133,9 @@ checkStructure(l, r, ns + '.' + p + '[' + i + ']'); } else if (l && !r) { result.push({ - type : EMPTY_ARRAY, - property : p, - namespace : ns + type: EMPTY_ARRAY, + property: p, + namespace: ns }); } } @@ -154,26 +156,30 @@ function tester() { var o1 = { - p1 : 1, - p2 : 2, - p3 : 3, - p4 : 8, - obj : [{ - op3 : 3, - op6 : 6, - op7 : 7 + p1: 1, + p2: 2, + p3: 3, + p4: 8, + obj: [{ + op3: 3, + op6: 6, + op7: 7 }] }; var o2 = { - p1 : 1, - p2 : 5, - p3 : 3, - p4 : 4, - obj : [{ op3 : 3, - op6 : 6, - op7 : 7}, { op3 : 3, - op6 : 6, - op77 : 7}] + p1: 1, + p2: 5, + p3: 3, + p4: 4, + obj: [{ + op3: 3, + op6: 6, + op7: 7 + }, { + op3: 3, + op6: 6, + op77: 7 + }] }; var validator = new StructureValidator(o1, o2); diff --git a/WebContent/stat/qunit/async.js b/src/main/webapp/stat/qunit/async.js similarity index 87% rename from WebContent/stat/qunit/async.js rename to src/main/webapp/stat/qunit/async.js index 899bd3e99..934505327 100644 --- a/WebContent/stat/qunit/async.js +++ b/src/main/webapp/stat/qunit/async.js @@ -7,7 +7,7 @@ root = this; if (root != null) { - previous_async = root.async; + previous_async = root.async; } async.noConflict = function () { @@ -17,7 +17,7 @@ function only_once(fn) { var called = false; - return function() { + return function () { if (called) throw new Error("Callback was already called."); called = true; fn.apply(root, arguments); @@ -91,8 +91,8 @@ async.nextTick = process.nextTick; if (typeof setImmediate !== 'undefined') { async.setImmediate = function (fn) { - // not a direct alias for IE10 compatibility - setImmediate(fn); + // not a direct alias for IE10 compatibility + setImmediate(fn); }; } else { @@ -101,7 +101,8 @@ } async.each = function (arr, iterator, callback) { - callback = callback || function () {}; + callback = callback || function () { + }; if (!arr.length) { return callback(); } @@ -110,7 +111,8 @@ iterator(x, only_once(function (err) { if (err) { callback(err); - callback = function () {}; + callback = function () { + }; } else { completed += 1; @@ -124,7 +126,8 @@ async.forEach = async.each; async.eachSeries = function (arr, iterator, callback) { - callback = callback || function () {}; + callback = callback || function () { + }; if (!arr.length) { return callback(); } @@ -133,7 +136,8 @@ iterator(arr[completed], function (err) { if (err) { callback(err); - callback = function () {}; + callback = function () { + }; } else { completed += 1; @@ -159,7 +163,8 @@ var _eachLimit = function (limit) { return function (arr, iterator, callback) { - callback = callback || function () {}; + callback = callback || function () { + }; if (!arr.length || limit <= 0) { return callback(); } @@ -167,7 +172,7 @@ var started = 0; var running = 0; - (function replenish () { + (function replenish() { if (completed >= arr.length) { return callback(); } @@ -178,7 +183,8 @@ iterator(arr[started - 1], function (err) { if (err) { callback(err); - callback = function () {}; + callback = function () { + }; } else { completed += 1; @@ -203,7 +209,7 @@ return fn.apply(null, [async.each].concat(args)); }; }; - var doParallelLimit = function(limit, fn) { + var doParallelLimit = function (limit, fn) { return function () { var args = Array.prototype.slice.call(arguments); return fn.apply(null, [_eachLimit(limit)].concat(args)); @@ -237,7 +243,7 @@ return _mapLimit(limit)(arr, iterator, callback); }; - var _mapLimit = function(limit) { + var _mapLimit = function (limit) { return doParallelLimit(limit, _asyncMap); }; @@ -321,7 +327,8 @@ iterator(x, function (result) { if (result) { main_callback(x); - main_callback = function () {}; + main_callback = function () { + }; } else { callback(); @@ -339,7 +346,8 @@ iterator(x, function (v) { if (v) { main_callback(true); - main_callback = function () {}; + main_callback = function () { + }; } callback(); }); @@ -355,7 +363,8 @@ iterator(x, function (v) { if (!v) { main_callback(false); - main_callback = function () {}; + main_callback = function () { + }; } callback(); }); @@ -393,7 +402,8 @@ }; async.auto = function (tasks, callback) { - callback = callback || function () {}; + callback = callback || function () { + }; var keys = _keys(tasks); if (!keys.length) { return callback(null); @@ -422,12 +432,13 @@ addListener(function () { if (_keys(results).length === keys.length) { callback(null, results); - callback = function () {}; + callback = function () { + }; } }); _each(keys, function (k) { - var task = (tasks[k] instanceof Function) ? [tasks[k]]: tasks[k]; + var task = (tasks[k] instanceof Function) ? [tasks[k]] : tasks[k]; var taskCallback = function (err) { var args = Array.prototype.slice.call(arguments, 1); if (args.length <= 1) { @@ -435,13 +446,14 @@ } if (err) { var safeResults = {}; - _each(_keys(results), function(rkey) { + _each(_keys(results), function (rkey) { safeResults[rkey] = results[rkey]; }); safeResults[k] = args; callback(err, safeResults); // stop subsequent errors hitting callback multiple times - callback = function () {}; + callback = function () { + }; } else { results[k] = args; @@ -451,8 +463,8 @@ var requires = task.slice(0, Math.abs(task.length - 1)) || []; var ready = function () { return _reduce(requires, function (a, x) { - return (a && results.hasOwnProperty(x)); - }, true) && !results.hasOwnProperty(k); + return (a && results.hasOwnProperty(x)); + }, true) && !results.hasOwnProperty(k); }; if (ready()) { task[task.length - 1](taskCallback, results); @@ -470,10 +482,11 @@ }; async.waterfall = function (tasks, callback) { - callback = callback || function () {}; + callback = callback || function () { + }; if (tasks.constructor !== Array) { - var err = new Error('First argument to waterfall must be an array of functions'); - return callback(err); + var err = new Error('First argument to waterfall must be an array of functions'); + return callback(err); } if (!tasks.length) { return callback(); @@ -482,7 +495,8 @@ return function (err) { if (err) { callback.apply(null, arguments); - callback = function () {}; + callback = function () { + }; } else { var args = Array.prototype.slice.call(arguments, 1); @@ -502,8 +516,9 @@ wrapIterator(async.iterator(tasks))(); }; - var _parallel = function(eachfn, tasks, callback) { - callback = callback || function () {}; + var _parallel = function (eachfn, tasks, callback) { + callback = callback || function () { + }; if (tasks.constructor === Array) { eachfn.map(tasks, function (fn, callback) { if (fn) { @@ -535,15 +550,16 @@ }; async.parallel = function (tasks, callback) { - _parallel({ map: async.map, each: async.each }, tasks, callback); + _parallel({map: async.map, each: async.each}, tasks, callback); }; - async.parallelLimit = function(tasks, limit, callback) { - _parallel({ map: _mapLimit(limit), each: _eachLimit(limit) }, tasks, callback); + async.parallelLimit = function (tasks, limit, callback) { + _parallel({map: _mapLimit(limit), each: _eachLimit(limit)}, tasks, callback); }; async.series = function (tasks, callback) { - callback = callback || function () {}; + callback = callback || function () { + }; if (tasks.constructor === Array) { async.mapSeries(tasks, function (fn, callback) { if (fn) { @@ -583,7 +599,7 @@ return fn.next(); }; fn.next = function () { - return (index < tasks.length - 1) ? makeCallback(index + 1): null; + return (index < tasks.length - 1) ? makeCallback(index + 1) : null; }; return fn; }; @@ -674,26 +690,26 @@ concurrency = 1; } function _insert(q, data, pos, callback) { - if(data.constructor !== Array) { - data = [data]; - } - _each(data, function(task) { - var item = { - data: task, - callback: typeof callback === 'function' ? callback : null - }; - - if (pos) { - q.tasks.unshift(item); - } else { - q.tasks.push(item); - } - - if (q.saturated && q.tasks.length === concurrency) { - q.saturated(); - } - async.setImmediate(q.process); - }); + if (data.constructor !== Array) { + data = [data]; + } + _each(data, function (task) { + var item = { + data: task, + callback: typeof callback === 'function' ? callback : null + }; + + if (pos) { + q.tasks.unshift(item); + } else { + q.tasks.push(item); + } + + if (q.saturated && q.tasks.length === concurrency) { + q.saturated(); + } + async.setImmediate(q.process); + }); } var workers = 0; @@ -704,10 +720,10 @@ empty: null, drain: null, push: function (data, callback) { - _insert(q, data, false, callback); + _insert(q, data, false, callback); }, unshift: function (data, callback) { - _insert(q, data, true, callback); + _insert(q, data, true, callback); }, process: function () { if (workers < q.concurrency && q.tasks.length) { @@ -741,8 +757,8 @@ }; async.cargo = function (worker, payload) { - var working = false, - tasks = []; + var working = false, + tasks = []; var cargo = { tasks: tasks, @@ -751,10 +767,10 @@ empty: null, drain: null, push: function (data, callback) { - if(data.constructor !== Array) { + if (data.constructor !== Array) { data = [data]; } - _each(data, function(task) { + _each(data, function (task) { tasks.push({ data: task, callback: typeof callback === 'function' ? callback : null @@ -768,19 +784,19 @@ process: function process() { if (working) return; if (tasks.length === 0) { - if(cargo.drain) cargo.drain(); + if (cargo.drain) cargo.drain(); return; } var ts = typeof payload === 'number' - ? tasks.splice(0, payload) - : tasks.splice(0); + ? tasks.splice(0, payload) + : tasks.splice(0); var ds = _map(ts, function (task) { return task.data; }); - if(cargo.empty) cargo.empty(); + if (cargo.empty) cargo.empty(); working = true; worker(ds, function () { working = false; @@ -828,15 +844,15 @@ async.log = _console_fn('log'); async.dir = _console_fn('dir'); /*async.info = _console_fn('info'); - async.warn = _console_fn('warn'); - async.error = _console_fn('error');*/ + async.warn = _console_fn('warn'); + async.error = _console_fn('error');*/ async.memoize = function (fn, hasher) { var memo = {}; var queues = {}; hasher = hasher || function (x) { - return x; - }; + return x; + }; var memoized = function () { var args = Array.prototype.slice.call(arguments); var callback = args.pop(); @@ -854,7 +870,7 @@ var q = queues[key]; delete queues[key]; for (var i = 0, l = q.length; i < l; i++) { - q[i].apply(null, arguments); + q[i].apply(null, arguments); } }])); } @@ -865,9 +881,9 @@ }; async.unmemoize = function (fn) { - return function () { - return (fn.unmemoized || fn).apply(null, arguments); - }; + return function () { + return (fn.unmemoized || fn).apply(null, arguments); + }; }; async.times = function (count, iterator, callback) { @@ -893,15 +909,15 @@ var args = Array.prototype.slice.call(arguments); var callback = args.pop(); async.reduce(fns, args, function (newargs, fn, cb) { - fn.apply(that, newargs.concat([function () { - var err = arguments[0]; - var nextargs = Array.prototype.slice.call(arguments, 1); - cb(err, nextargs); - }])) - }, - function (err, results) { - callback.apply(that, [err].concat(results)); - }); + fn.apply(that, newargs.concat([function () { + var err = arguments[0]; + var nextargs = Array.prototype.slice.call(arguments, 1); + cb(err, nextargs); + }])) + }, + function (err, results) { + callback.apply(that, [err].concat(results)); + }); }; }; @@ -911,9 +927,9 @@ var args = Array.prototype.slice.call(arguments); var callback = args.pop(); return eachfn(fns, function (fn, cb) { - fn.apply(that, args.concat([cb])); - }, - callback); + fn.apply(that, args.concat([cb])); + }, + callback); }; if (arguments.length > 2) { var args = Array.prototype.slice.call(arguments, 2); @@ -936,6 +952,7 @@ } fn(next); } + next(); }; diff --git a/src/main/webapp/stat/qunit/qunit.css b/src/main/webapp/stat/qunit/qunit.css new file mode 100644 index 000000000..b6c7c443b --- /dev/null +++ b/src/main/webapp/stat/qunit/qunit.css @@ -0,0 +1,272 @@ +/*! + * QUnit 1.14.1pre + * http://qunitjs.com/ + * + * Copyright 2014 jQuery Foundation and other contributors + * Released under the MIT license + * http://jquery.org/license + * + * Date: 2014-03-12T10:25Z + */ + +/** Font Family and Sizes */ + +#qunit-tests, #qunit-header, #qunit-banner, #qunit-testrunner-toolbar, #qunit-userAgent, #qunit-testresult { + font-family: "Helvetica Neue Light", "HelveticaNeue-Light", "Helvetica Neue", Calibri, Helvetica, Arial, sans-serif; +} + +#qunit-testrunner-toolbar, #qunit-userAgent, #qunit-testresult, #qunit-tests li { + font-size: small; +} + +#qunit-tests { + font-size: smaller; +} + +/** Resets */ + +#qunit-tests, #qunit-header, #qunit-banner, #qunit-userAgent, #qunit-testresult, #qunit-modulefilter { + margin: 0; + padding: 0; +} + +/** Header */ + +#qunit-header { + padding: 0.5em 0 0.5em 1em; + + color: #8699A4; + background-color: #0D3349; + + font-size: 1.5em; + line-height: 1em; + font-weight: 400; + + border-radius: 5px 5px 0 0; +} + +#qunit-header a { + text-decoration: none; + color: #C2CCD1; +} + +#qunit-header a:hover, +#qunit-header a:focus { + color: #FFF; +} + +#qunit-testrunner-toolbar label { + display: inline-block; + padding: 0 0.5em 0 0.1em; +} + +#qunit-banner { + height: 5px; +} + +#qunit-testrunner-toolbar { + padding: 0.5em 1em 0.5em 1em; + color: #5E740B; + background-color: #EEE; + overflow: hidden; +} + +#qunit-userAgent { + padding: 0.5em 1em 0.5em 1em; + background-color: #2B81AF; + color: #FFF; + text-shadow: rgba(0, 0, 0, 0.5) 2px 2px 1px; +} + +#qunit-modulefilter-container { + float: right; +} + +/** Tests: Pass/Fail */ + +#qunit-tests { + list-style-position: inside; +} + +#qunit-tests li { + padding: 0.4em 1em 0.4em 1em; + border-bottom: 1px solid #FFF; + list-style-position: inside; +} + +#qunit-tests.hidepass li.pass, #qunit-tests.hidepass li.running { + display: none; +} + +#qunit-tests li strong { + cursor: pointer; +} + +#qunit-tests li a { + padding: 0.5em; + color: #C2CCD1; + text-decoration: none; +} + +#qunit-tests li a:hover, +#qunit-tests li a:focus { + color: #000; +} + +#qunit-tests li .runtime { + float: right; + font-size: smaller; +} + +.qunit-assert-list { + margin-top: 0.5em; + padding: 0.5em; + + background-color: #FFF; + + border-radius: 5px; +} + +.qunit-collapsed { + display: none; +} + +#qunit-tests table { + border-collapse: collapse; + margin-top: 0.2em; +} + +#qunit-tests th { + text-align: right; + vertical-align: top; + padding: 0 0.5em 0 0; +} + +#qunit-tests td { + vertical-align: top; +} + +#qunit-tests pre { + margin: 0; + white-space: pre-wrap; + word-wrap: break-word; +} + +#qunit-tests del { + background-color: #E0F2BE; + color: #374E0C; + text-decoration: none; +} + +#qunit-tests ins { + background-color: #FFCACA; + color: #500; + text-decoration: none; +} + +/*** Test Counts */ + +#qunit-tests b.counts { + color: #000; +} + +#qunit-tests b.passed { + color: #5E740B; +} + +#qunit-tests b.failed { + color: #710909; +} + +#qunit-tests li li { + padding: 5px; + background-color: #FFF; + border-bottom: none; + list-style-position: inside; +} + +/*** Passing Styles */ + +#qunit-tests li li.pass { + color: #3C510C; + background-color: #FFF; + border-left: 10px solid #C6E746; +} + +#qunit-tests .pass { + color: #528CE0; + background-color: #D2E0E6; +} + +#qunit-tests .pass .test-name { + color: #366097; +} + +#qunit-tests .pass .test-actual, +#qunit-tests .pass .test-expected { + color: #999; +} + +#qunit-banner.qunit-pass { + background-color: #C6E746; +} + +/*** Failing Styles */ + +#qunit-tests li li.fail { + color: #710909; + background-color: #FFF; + border-left: 10px solid #EE5757; + white-space: pre; +} + +#qunit-tests > li:last-child { + border-radius: 0 0 5px 5px; +} + +#qunit-tests .fail { + color: #000; + background-color: #EE5757; +} + +#qunit-tests .fail .test-name, +#qunit-tests .fail .module-name { + color: #000; +} + +#qunit-tests .fail .test-actual { + color: #EE5757; +} + +#qunit-tests .fail .test-expected { + color: #008000; +} + +#qunit-banner.qunit-fail { + background-color: #EE5757; +} + +/** Result */ + +#qunit-testresult { + padding: 0.5em 1em 0.5em 1em; + + color: #2B81AF; + background-color: #D2E0E6; + + border-bottom: 1px solid #FFF; +} + +#qunit-testresult .module-name { + font-weight: 700; +} + +/** Fixture */ + +#qunit-fixture { + position: absolute; + top: -10000px; + left: -10000px; + width: 1000px; + height: 1000px; +} \ No newline at end of file diff --git a/src/main/webapp/stat/qunit/qunit.js b/src/main/webapp/stat/qunit/qunit.js new file mode 100644 index 000000000..71db38396 --- /dev/null +++ b/src/main/webapp/stat/qunit/qunit.js @@ -0,0 +1,2301 @@ +/*! + * QUnit 1.14.1pre + * http://qunitjs.com/ + * + * Copyright 2014 jQuery Foundation and other contributors + * Released under the MIT license + * http://jquery.org/license + * + * Date: 2014-03-12T10:25Z + */ + + +(function (window) { + + var QUnit, + assert, + config, + onErrorFnPrev, + testId = 0, + fileName = (sourceFromStacktrace(0) || "" ).replace(/(:\d+)+\)?/, "").replace(/.+\//, ""), + toString = Object.prototype.toString, + hasOwn = Object.prototype.hasOwnProperty, + // Keep a local reference to Date (GH-283) + Date = window.Date, + setTimeout = window.setTimeout, + clearTimeout = window.clearTimeout, + defined = { + document: typeof window.document !== "undefined", + setTimeout: typeof window.setTimeout !== "undefined", + sessionStorage: (function () { + var x = "qunit-test-string"; + try { + sessionStorage.setItem(x, x); + sessionStorage.removeItem(x); + return true; + } catch (e) { + return false; + } + }()) + }, + /** + * Provides a normalized error string, correcting an issue + * with IE 7 (and prior) where Error.prototype.toString is + * not properly implemented + * + * Based on http://es5.github.com/#x15.11.4.4 + * + * @param {String|Error} error + * @return {String} error message + */ + errorString = function (error) { + var name, message, + errorString = error.toString(); + if (errorString.substring(0, 7) === "[object") { + name = error.name ? error.name.toString() : "Error"; + message = error.message ? error.message.toString() : ""; + if (name && message) { + return name + ": " + message; + } else if (name) { + return name; + } else if (message) { + return message; + } else { + return "Error"; + } + } else { + return errorString; + } + }, + /** + * Makes a clone of an object using only Array or Object as base, + * and copies over the own enumerable properties. + * + * @param {Object} obj + * @return {Object} New object with only the own properties (recursively). + */ + objectValues = function (obj) { + // Grunt 0.3.x uses an older version of jshint that still has jshint/jshint#392. + /*jshint newcap: false */ + var key, val, + vals = QUnit.is("array", obj) ? [] : {}; + for (key in obj) { + if (hasOwn.call(obj, key)) { + val = obj[key]; + vals[key] = val === Object(val) ? objectValues(val) : val; + } + } + return vals; + }; + + +// Root QUnit object. +// `QUnit` initialized at top of scope + QUnit = { + + // call on start of module test to prepend name to all tests + module: function (name, testEnvironment) { + config.currentModule = name; + config.currentModuleTestEnvironment = testEnvironment; + config.modules[name] = true; + }, + + asyncTest: function (testName, expected, callback) { + if (arguments.length === 2) { + callback = expected; + expected = null; + } + + QUnit.test(testName, expected, callback, true); + }, + + test: function (testName, expected, callback, async) { + var test, + nameHtml = "" + escapeText(testName) + ""; + + if (arguments.length === 2) { + callback = expected; + expected = null; + } + + if (config.currentModule) { + nameHtml = "" + escapeText(config.currentModule) + ": " + nameHtml; + } + + test = new Test({ + nameHtml: nameHtml, + testName: testName, + expected: expected, + async: async, + callback: callback, + module: config.currentModule, + moduleTestEnvironment: config.currentModuleTestEnvironment, + stack: sourceFromStacktrace(2) + }); + + if (!validTest(test)) { + return; + } + + test.queue(); + }, + + // Specify the number of expected assertions to guarantee that failed test (no assertions are run at all) don't slip through. + expect: function (asserts) { + if (arguments.length === 1) { + config.current.expected = asserts; + } else { + return config.current.expected; + } + }, + + start: function (count) { + // QUnit hasn't been initialized yet. + // Note: RequireJS (et al) may delay onLoad + if (config.semaphore === undefined) { + QUnit.begin(function () { + // This is triggered at the top of QUnit.load, push start() to the event loop, to allow QUnit.load to finish first + setTimeout(function () { + QUnit.start(count); + }); + }); + return; + } + + config.semaphore -= count || 1; + // don't start until equal number of stop-calls + if (config.semaphore > 0) { + return; + } + // ignore if start is called more often then stop + if (config.semaphore < 0) { + config.semaphore = 0; + QUnit.pushFailure("Called start() while already started (QUnit.config.semaphore was 0 already)", null, sourceFromStacktrace(2)); + return; + } + // A slight delay, to avoid any current callbacks + if (defined.setTimeout) { + setTimeout(function () { + if (config.semaphore > 0) { + return; + } + if (config.timeout) { + clearTimeout(config.timeout); + } + + config.blocking = false; + process(true); + }, 13); + } else { + config.blocking = false; + process(true); + } + }, + + stop: function (count) { + config.semaphore += count || 1; + config.blocking = true; + + if (config.testTimeout && defined.setTimeout) { + clearTimeout(config.timeout); + config.timeout = setTimeout(function () { + QUnit.ok(false, "Test timed out"); + config.semaphore = 1; + QUnit.start(); + }, config.testTimeout); + } + } + }; + +// We use the prototype to distinguish between properties that should +// be exposed as globals (and in exports) and those that shouldn't + (function () { + function F() { + } + + F.prototype = QUnit; + QUnit = new F(); + // Make F QUnit's constructor so that we can add to the prototype later + QUnit.constructor = F; + }()); + + /** + * Config object: Maintain internal state + * Later exposed as QUnit.config + * `config` initialized at top of scope + */ + config = { + // The queue of tests to run + queue: [], + + // block until document ready + blocking: true, + + // when enabled, show only failing tests + // gets persisted through sessionStorage and can be changed in UI via checkbox + hidepassed: false, + + // by default, run previously failed tests first + // very useful in combination with "Hide passed tests" checked + reorder: true, + + // by default, modify document.title when suite is done + altertitle: true, + + // by default, scroll to top of the page when suite is done + scrolltop: true, + + // when enabled, all tests must call expect() + requireExpects: false, + + // add checkboxes that are persisted in the query-string + // when enabled, the id is set to `true` as a `QUnit.config` property + urlConfig: [ + { + id: "noglobals", + label: "Check for Globals", + tooltip: "Enabling this will test if any test introduces new properties on the `window` object. Stored as query-strings." + }, + { + id: "notrycatch", + label: "No try-catch", + tooltip: "Enabling this will run tests outside of a try-catch block. Makes debugging exceptions in IE reasonable. Stored as query-strings." + } + ], + + // Set of all modules. + modules: {}, + + // logging callback queues + begin: [], + done: [], + log: [], + testStart: [], + testDone: [], + moduleStart: [], + moduleDone: [] + }; + +// Initialize more QUnit.config and QUnit.urlParams + (function () { + var i, current, + location = window.location || {search: "", protocol: "file:"}, + params = location.search.slice(1).split("&"), + length = params.length, + urlParams = {}; + + if (params[0]) { + for (i = 0; i < length; i++) { + current = params[i].split("="); + current[0] = decodeURIComponent(current[0]); + + // allow just a key to turn on a flag, e.g., test.html?noglobals + current[1] = current[1] ? decodeURIComponent(current[1]) : true; + if (urlParams[current[0]]) { + urlParams[current[0]] = [].concat(urlParams[current[0]], current[1]); + } else { + urlParams[current[0]] = current[1]; + } + } + } + + QUnit.urlParams = urlParams; + + // String search anywhere in moduleName+testName + config.filter = urlParams.filter; + + // Exact match of the module name + config.module = urlParams.module; + + config.testNumber = []; + if (urlParams.testNumber) { + + // Ensure that urlParams.testNumber is an array + urlParams.testNumber = [].concat(urlParams.testNumber); + for (i = 0; i < urlParams.testNumber.length; i++) { + current = urlParams.testNumber[i]; + config.testNumber.push(parseInt(current, 10)); + } + } + + // Figure out if we're running the tests from a server or not + QUnit.isLocal = location.protocol === "file:"; + }()); + + extend(QUnit, { + + config: config, + + // Initialize the configuration options + init: function () { + extend(config, { + stats: {all: 0, bad: 0}, + moduleStats: {all: 0, bad: 0}, + started: +new Date(), + updateRate: 1000, + blocking: false, + autostart: true, + autorun: false, + filter: "", + queue: [], + semaphore: 1 + }); + + var tests, banner, result, + qunit = id("qunit"); + + if (qunit) { + qunit.innerHTML = + "

    " + escapeText(document.title) + "

    " + + "

    " + + "
    " + + "

    " + + "
      "; + } + + tests = id("qunit-tests"); + banner = id("qunit-banner"); + result = id("qunit-testresult"); + + if (tests) { + tests.innerHTML = ""; + } + + if (banner) { + banner.className = ""; + } + + if (result) { + result.parentNode.removeChild(result); + } + + if (tests) { + result = document.createElement("p"); + result.id = "qunit-testresult"; + result.className = "result"; + tests.parentNode.insertBefore(result, tests); + result.innerHTML = "Running...
       "; + } + }, + + // Resets the test setup. Useful for tests that modify the DOM. + /* + DEPRECATED: Use multiple tests instead of resetting inside a test. + Use testStart or testDone for custom cleanup. + This method will throw an error in 2.0, and will be removed in 2.1 + */ + reset: function () { + var fixture = id("qunit-fixture"); + if (fixture) { + fixture.innerHTML = config.fixture; + } + }, + + // Safe object type checking + is: function (type, obj) { + return QUnit.objectType(obj) === type; + }, + + objectType: function (obj) { + if (typeof obj === "undefined") { + return "undefined"; + } + + // Consider: typeof null === object + if (obj === null) { + return "null"; + } + + var match = toString.call(obj).match(/^\[object\s(.*)\]$/), + type = match && match[1] || ""; + + switch (type) { + case "Number": + if (isNaN(obj)) { + return "nan"; + } + return "number"; + case "String": + case "Boolean": + case "Array": + case "Date": + case "RegExp": + case "Function": + return type.toLowerCase(); + } + if (typeof obj === "object") { + return "object"; + } + return undefined; + }, + + push: function (result, actual, expected, message) { + if (!config.current) { + throw new Error("assertion outside test context, was " + sourceFromStacktrace()); + } + + var output, source, + details = { + module: config.current.module, + name: config.current.testName, + result: result, + message: message, + actual: actual, + expected: expected + }; + + message = escapeText(message) || ( result ? "okay" : "failed" ); + message = "" + message + ""; + output = message; + + if (!result) { + expected = escapeText(QUnit.jsDump.parse(expected)); + actual = escapeText(QUnit.jsDump.parse(actual)); + output += "
      "; + + if (actual !== expected) { + output += ""; + output += ""; + } + + source = sourceFromStacktrace(); + + if (source) { + details.source = source; + output += ""; + } + + output += "
      Expected:
      " + expected + "
      Result:
      " + actual + "
      Diff:
      " + QUnit.diff(expected, actual) + "
      Source:
      " + escapeText(source) + "
      "; + } + + runLoggingCallbacks("log", QUnit, details); + + config.current.assertions.push({ + result: !!result, + message: output + }); + }, + + pushFailure: function (message, source, actual) { + if (!config.current) { + throw new Error("pushFailure() assertion outside test context, was " + sourceFromStacktrace(2)); + } + + var output, + details = { + module: config.current.module, + name: config.current.testName, + result: false, + message: message + }; + + message = escapeText(message) || "error"; + message = "" + message + ""; + output = message; + + output += ""; + + if (actual) { + output += ""; + } + + if (source) { + details.source = source; + output += ""; + } + + output += "
      Result:
      " + escapeText(actual) + "
      Source:
      " + escapeText(source) + "
      "; + + runLoggingCallbacks("log", QUnit, details); + + config.current.assertions.push({ + result: false, + message: output + }); + }, + + url: function (params) { + params = extend(extend({}, QUnit.urlParams), params); + var key, + querystring = "?"; + + for (key in params) { + if (hasOwn.call(params, key)) { + querystring += encodeURIComponent(key) + "=" + + encodeURIComponent(params[key]) + "&"; + } + } + return window.location.protocol + "//" + window.location.host + + window.location.pathname + querystring.slice(0, -1); + }, + + extend: extend, + id: id, + addEvent: addEvent, + addClass: addClass, + hasClass: hasClass, + removeClass: removeClass + // load, equiv, jsDump, diff: Attached later + }); + + /** + * @deprecated: Created for backwards compatibility with test runner that set the hook function + * into QUnit.{hook}, instead of invoking it and passing the hook function. + * QUnit.constructor is set to the empty F() above so that we can add to it's prototype here. + * Doing this allows us to tell if the following methods have been overwritten on the actual + * QUnit object. + */ + extend(QUnit.constructor.prototype, { + + // Logging callbacks; all receive a single argument with the listed properties + // run test/logs.html for any related changes + begin: registerLoggingCallback("begin"), + + // done: { failed, passed, total, runtime } + done: registerLoggingCallback("done"), + + // log: { result, actual, expected, message } + log: registerLoggingCallback("log"), + + // testStart: { name } + testStart: registerLoggingCallback("testStart"), + + // testDone: { name, failed, passed, total, runtime } + testDone: registerLoggingCallback("testDone"), + + // moduleStart: { name } + moduleStart: registerLoggingCallback("moduleStart"), + + // moduleDone: { name, failed, passed, total } + moduleDone: registerLoggingCallback("moduleDone") + }); + + if (!defined.document || document.readyState === "complete") { + config.autorun = true; + } + + QUnit.load = function () { + runLoggingCallbacks("begin", QUnit, {}); + + // Initialize the config, saving the execution queue + var banner, filter, i, j, label, len, main, ol, toolbar, val, selection, + urlConfigContainer, moduleFilter, userAgent, + numModules = 0, + moduleNames = [], + moduleFilterHtml = "", + urlConfigHtml = "", + oldconfig = extend({}, config); + + QUnit.init(); + extend(config, oldconfig); + + config.blocking = false; + + len = config.urlConfig.length; + + for (i = 0; i < len; i++) { + val = config.urlConfig[i]; + if (typeof val === "string") { + val = { + id: val, + label: val + }; + } + config[val.id] = QUnit.urlParams[val.id]; + if (!val.value || typeof val.value === "string") { + urlConfigHtml += ""; + } else { + urlConfigHtml += ""; + } + } + for (i in config.modules) { + if (config.modules.hasOwnProperty(i)) { + moduleNames.push(i); + } + } + numModules = moduleNames.length; + moduleNames.sort(function (a, b) { + return a.localeCompare(b); + }); + moduleFilterHtml += ""; + + // `userAgent` initialized at top of scope + userAgent = id("qunit-userAgent"); + if (userAgent) { + userAgent.innerHTML = navigator.userAgent; + } + + // `banner` initialized at top of scope + banner = id("qunit-header"); + if (banner) { + banner.innerHTML = "" + banner.innerHTML + " "; + } + + // `toolbar` initialized at top of scope + toolbar = id("qunit-testrunner-toolbar"); + if (toolbar) { + // `filter` initialized at top of scope + filter = document.createElement("input"); + filter.type = "checkbox"; + filter.id = "qunit-filter-pass"; + + addEvent(filter, "click", function () { + var tmp, + ol = id("qunit-tests"); + + if (filter.checked) { + ol.className = ol.className + " hidepass"; + } else { + tmp = " " + ol.className.replace(/[\n\t\r]/g, " ") + " "; + ol.className = tmp.replace(/ hidepass /, " "); + } + if (defined.sessionStorage) { + if (filter.checked) { + sessionStorage.setItem("qunit-filter-passed-tests", "true"); + } else { + sessionStorage.removeItem("qunit-filter-passed-tests"); + } + } + }); + + if (config.hidepassed || defined.sessionStorage && sessionStorage.getItem("qunit-filter-passed-tests")) { + filter.checked = true; + // `ol` initialized at top of scope + ol = id("qunit-tests"); + ol.className = ol.className + " hidepass"; + } + toolbar.appendChild(filter); + + // `label` initialized at top of scope + label = document.createElement("label"); + label.setAttribute("for", "qunit-filter-pass"); + label.setAttribute("title", "Only show tests and assertions that fail. Stored in sessionStorage."); + label.innerHTML = "Hide passed tests"; + toolbar.appendChild(label); + + urlConfigContainer = document.createElement("span"); + urlConfigContainer.innerHTML = urlConfigHtml; + // For oldIE support: + // * Add handlers to the individual elements instead of the container + // * Use "click" instead of "change" for checkboxes + // * Fallback from event.target to event.srcElement + addEvents(urlConfigContainer.getElementsByTagName("input"), "click", function (event) { + var params = {}, + target = event.target || event.srcElement; + params[target.name] = target.checked ? + target.defaultValue || true : + undefined; + window.location = QUnit.url(params); + }); + addEvents(urlConfigContainer.getElementsByTagName("select"), "change", function (event) { + var params = {}, + target = event.target || event.srcElement; + params[target.name] = target.options[target.selectedIndex].value || undefined; + window.location = QUnit.url(params); + }); + toolbar.appendChild(urlConfigContainer); + + if (numModules > 1) { + moduleFilter = document.createElement("span"); + moduleFilter.setAttribute("id", "qunit-modulefilter-container"); + moduleFilter.innerHTML = moduleFilterHtml; + addEvent(moduleFilter.lastChild, "change", function () { + var selectBox = moduleFilter.getElementsByTagName("select")[0], + selectedModule = decodeURIComponent(selectBox.options[selectBox.selectedIndex].value); + + window.location = QUnit.url({ + module: ( selectedModule === "" ) ? undefined : selectedModule, + // Remove any existing filters + filter: undefined, + testNumber: undefined + }); + }); + toolbar.appendChild(moduleFilter); + } + } + + // `main` initialized at top of scope + main = id("qunit-fixture"); + if (main) { + config.fixture = main.innerHTML; + } + + if (config.autostart) { + QUnit.start(); + } + }; + + if (defined.document) { + addEvent(window, "load", QUnit.load); + } + +// `onErrorFnPrev` initialized at top of scope +// Preserve other handlers + onErrorFnPrev = window.onerror; + +// Cover uncaught exceptions +// Returning true will suppress the default browser handler, +// returning false will let it run. + window.onerror = function (error, filePath, linerNr) { + var ret = false; + if (onErrorFnPrev) { + ret = onErrorFnPrev(error, filePath, linerNr); + } + + // Treat return value as window.onerror itself does, + // Only do our handling if not suppressed. + if (ret !== true) { + if (QUnit.config.current) { + if (QUnit.config.current.ignoreGlobalErrors) { + return true; + } + QUnit.pushFailure(error, filePath + ":" + linerNr); + } else { + QUnit.test("global failure", extend(function () { + QUnit.pushFailure(error, filePath + ":" + linerNr); + }, {validTest: validTest})); + } + return false; + } + + return ret; + }; + + function done() { + config.autorun = true; + + // Log the last module results + if (config.previousModule) { + runLoggingCallbacks("moduleDone", QUnit, { + name: config.previousModule, + failed: config.moduleStats.bad, + passed: config.moduleStats.all - config.moduleStats.bad, + total: config.moduleStats.all + }); + } + delete config.previousModule; + + var i, key, + banner = id("qunit-banner"), + tests = id("qunit-tests"), + runtime = +new Date() - config.started, + passed = config.stats.all - config.stats.bad, + html = [ + "Tests completed in ", + runtime, + " milliseconds.
      ", + "", + passed, + " assertions of ", + config.stats.all, + " passed, ", + config.stats.bad, + " failed." + ].join(""); + + if (banner) { + banner.className = ( config.stats.bad ? "qunit-fail" : "qunit-pass" ); + } + + if (tests) { + id("qunit-testresult").innerHTML = html; + } + + if (config.altertitle && defined.document && document.title) { + // show ✖ for good, ✔ for bad suite result in title + // use escape sequences in case file gets loaded with non-utf-8-charset + document.title = [ + ( config.stats.bad ? "\u2716" : "\u2714" ), + document.title.replace(/^[\u2714\u2716] /i, "") + ].join(" "); + } + + // clear own sessionStorage items if all tests passed + if (config.reorder && defined.sessionStorage && config.stats.bad === 0) { + // `key` & `i` initialized at top of scope + for (i = 0; i < sessionStorage.length; i++) { + key = sessionStorage.key(i++); + if (key.indexOf("qunit-test-") === 0) { + sessionStorage.removeItem(key); + } + } + } + + // scroll back to top to show results + if (config.scrolltop && window.scrollTo) { + window.scrollTo(0, 0); + } + + runLoggingCallbacks("done", QUnit, { + failed: config.stats.bad, + passed: passed, + total: config.stats.all, + runtime: runtime + }); + } + + /** @return Boolean: true if this test should be ran */ + function validTest(test) { + var include, + filter = config.filter && config.filter.toLowerCase(), + module = config.module && config.module.toLowerCase(), + fullName = ( test.module + ": " + test.testName ).toLowerCase(); + + // Internally-generated tests are always valid + if (test.callback && test.callback.validTest === validTest) { + delete test.callback.validTest; + return true; + } + + if (config.testNumber.length > 0) { + if (inArray(test.testNumber, config.testNumber) < 0) { + return false; + } + } + + if (module && ( !test.module || test.module.toLowerCase() !== module )) { + return false; + } + + if (!filter) { + return true; + } + + include = filter.charAt(0) !== "!"; + if (!include) { + filter = filter.slice(1); + } + + // If the filter matches, we need to honour include + if (fullName.indexOf(filter) !== -1) { + return include; + } + + // Otherwise, do the opposite + return !include; + } + +// so far supports only Firefox, Chrome and Opera (buggy), Safari (for real exceptions) +// Later Safari and IE10 are supposed to support error.stack as well +// See also https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error/Stack + function extractStacktrace(e, offset) { + offset = offset === undefined ? 3 : offset; + + var stack, include, i; + + if (e.stacktrace) { + // Opera + return e.stacktrace.split("\n")[offset + 3]; + } else if (e.stack) { + // Firefox, Chrome + stack = e.stack.split("\n"); + if (/^error$/i.test(stack[0])) { + stack.shift(); + } + if (fileName) { + include = []; + for (i = offset; i < stack.length; i++) { + if (stack[i].indexOf(fileName) !== -1) { + break; + } + include.push(stack[i]); + } + if (include.length) { + return include.join("\n"); + } + } + return stack[offset]; + } else if (e.sourceURL) { + // Safari, PhantomJS + // hopefully one day Safari provides actual stacktraces + // exclude useless self-reference for generated Error objects + if (/qunit.js$/.test(e.sourceURL)) { + return; + } + // for actual exceptions, this is useful + return e.sourceURL + ":" + e.line; + } + } + + function sourceFromStacktrace(offset) { + try { + throw new Error(); + } catch (e) { + return extractStacktrace(e, offset); + } + } + + /** + * Escape text for attribute or text content. + */ + function escapeText(s) { + if (!s) { + return ""; + } + s = s + ""; + // Both single quotes and double quotes (for attributes) + return s.replace(/['"<>&]/g, function (s) { + switch (s) { + case "'": + return "'"; + case "\"": + return """; + case "<": + return "<"; + case ">": + return ">"; + case "&": + return "&"; + } + }); + } + + function synchronize(callback, last) { + config.queue.push(callback); + + if (config.autorun && !config.blocking) { + process(last); + } + } + + function process(last) { + function next() { + process(last); + } + + var start = new Date().getTime(); + config.depth = config.depth ? config.depth + 1 : 1; + + while (config.queue.length && !config.blocking) { + if (!defined.setTimeout || config.updateRate <= 0 || ( ( new Date().getTime() - start ) < config.updateRate )) { + config.queue.shift()(); + } else { + setTimeout(next, 13); + break; + } + } + config.depth--; + if (last && !config.blocking && !config.queue.length && config.depth === 0) { + done(); + } + } + + function saveGlobal() { + config.pollution = []; + + if (config.noglobals) { + for (var key in window) { + if (hasOwn.call(window, key)) { + // in Opera sometimes DOM element ids show up here, ignore them + if (/^qunit-test-output/.test(key)) { + continue; + } + config.pollution.push(key); + } + } + } + } + + function checkPollution() { + var newGlobals, + deletedGlobals, + old = config.pollution; + + saveGlobal(); + + newGlobals = diff(config.pollution, old); + if (newGlobals.length > 0) { + QUnit.pushFailure("Introduced global variable(s): " + newGlobals.join(", ")); + } + + deletedGlobals = diff(old, config.pollution); + if (deletedGlobals.length > 0) { + QUnit.pushFailure("Deleted global variable(s): " + deletedGlobals.join(", ")); + } + } + +// returns a new Array with the elements that are in a but not in b + function diff(a, b) { + var i, j, + result = a.slice(); + + for (i = 0; i < result.length; i++) { + for (j = 0; j < b.length; j++) { + if (result[i] === b[j]) { + result.splice(i, 1); + i--; + break; + } + } + } + return result; + } + + function extend(a, b) { + for (var prop in b) { + if (hasOwn.call(b, prop)) { + // Avoid "Member not found" error in IE8 caused by messing with window.constructor + if (!( prop === "constructor" && a === window )) { + if (b[prop] === undefined) { + delete a[prop]; + } else { + a[prop] = b[prop]; + } + } + } + } + + return a; + } + + /** + * @param {HTMLElement} elem + * @param {string} type + * @param {Function} fn + */ + function addEvent(elem, type, fn) { + if (elem.addEventListener) { + + // Standards-based browsers + elem.addEventListener(type, fn, false); + } else if (elem.attachEvent) { + + // support: IE <9 + elem.attachEvent("on" + type, fn); + } else { + + // Caller must ensure support for event listeners is present + throw new Error("addEvent() was called in a context without event listener support"); + } + } + + /** + * @param {Array|NodeList} elems + * @param {string} type + * @param {Function} fn + */ + function addEvents(elems, type, fn) { + var i = elems.length; + while (i--) { + addEvent(elems[i], type, fn); + } + } + + function hasClass(elem, name) { + return (" " + elem.className + " ").indexOf(" " + name + " ") > -1; + } + + function addClass(elem, name) { + if (!hasClass(elem, name)) { + elem.className += (elem.className ? " " : "") + name; + } + } + + function removeClass(elem, name) { + var set = " " + elem.className + " "; + // Class name may appear multiple times + while (set.indexOf(" " + name + " ") > -1) { + set = set.replace(" " + name + " ", " "); + } + // If possible, trim it for prettiness, but not necessarily + elem.className = typeof set.trim === "function" ? set.trim() : set.replace(/^\s+|\s+$/g, ""); + } + + function id(name) { + return defined.document && document.getElementById && document.getElementById(name); + } + + function registerLoggingCallback(key) { + return function (callback) { + config[key].push(callback); + }; + } + +// Supports deprecated method of completely overwriting logging callbacks + function runLoggingCallbacks(key, scope, args) { + var i, callbacks; + if (QUnit.hasOwnProperty(key)) { + QUnit[key].call(scope, args); + } else { + callbacks = config[key]; + for (i = 0; i < callbacks.length; i++) { + callbacks[i].call(scope, args); + } + } + } + +// from jquery.js + function inArray(elem, array) { + if (array.indexOf) { + return array.indexOf(elem); + } + + for (var i = 0, length = array.length; i < length; i++) { + if (array[i] === elem) { + return i; + } + } + + return -1; + } + + function Test(settings) { + extend(this, settings); + this.assertions = []; + this.testNumber = ++Test.count; + } + + Test.count = 0; + + Test.prototype = { + init: function () { + var a, b, li, + tests = id("qunit-tests"); + + if (tests) { + b = document.createElement("strong"); + b.innerHTML = this.nameHtml; + + // `a` initialized at top of scope + a = document.createElement("a"); + a.innerHTML = "Rerun"; + a.href = QUnit.url({testNumber: this.testNumber}); + + li = document.createElement("li"); + li.appendChild(b); + li.appendChild(a); + li.className = "running"; + li.id = this.id = "qunit-test-output" + testId++; + + tests.appendChild(li); + } + }, + setup: function () { + if ( + // Emit moduleStart when we're switching from one module to another + this.module !== config.previousModule || + // They could be equal (both undefined) but if the previousModule property doesn't + // yet exist it means this is the first test in a suite that isn't wrapped in a + // module, in which case we'll just emit a moduleStart event for 'undefined'. + // Without this, reporters can get testStart before moduleStart which is a problem. + !hasOwn.call(config, "previousModule") + ) { + if (hasOwn.call(config, "previousModule")) { + runLoggingCallbacks("moduleDone", QUnit, { + name: config.previousModule, + failed: config.moduleStats.bad, + passed: config.moduleStats.all - config.moduleStats.bad, + total: config.moduleStats.all + }); + } + config.previousModule = this.module; + config.moduleStats = {all: 0, bad: 0}; + runLoggingCallbacks("moduleStart", QUnit, { + name: this.module + }); + } + + config.current = this; + + this.testEnvironment = extend({ + setup: function () { + }, + teardown: function () { + } + }, this.moduleTestEnvironment); + + this.started = +new Date(); + runLoggingCallbacks("testStart", QUnit, { + name: this.testName, + module: this.module + }); + + /*jshint camelcase:false */ + + + /** + * Expose the current test environment. + * + * @deprecated since 1.12.0: Use QUnit.config.current.testEnvironment instead. + */ + QUnit.current_testEnvironment = this.testEnvironment; + + /*jshint camelcase:true */ + + if (!config.pollution) { + saveGlobal(); + } + if (config.notrycatch) { + this.testEnvironment.setup.call(this.testEnvironment, QUnit.assert); + return; + } + try { + this.testEnvironment.setup.call(this.testEnvironment, QUnit.assert); + } catch (e) { + QUnit.pushFailure("Setup failed on " + this.testName + ": " + ( e.message || e ), extractStacktrace(e, 1)); + } + }, + run: function () { + config.current = this; + + var running = id("qunit-testresult"); + + if (running) { + running.innerHTML = "Running:
      " + this.nameHtml; + } + + if (this.async) { + QUnit.stop(); + } + + this.callbackStarted = +new Date(); + + if (config.notrycatch) { + this.callback.call(this.testEnvironment, QUnit.assert); + this.callbackRuntime = +new Date() - this.callbackStarted; + return; + } + + try { + this.callback.call(this.testEnvironment, QUnit.assert); + this.callbackRuntime = +new Date() - this.callbackStarted; + } catch (e) { + this.callbackRuntime = +new Date() - this.callbackStarted; + + QUnit.pushFailure("Died on test #" + (this.assertions.length + 1) + " " + this.stack + ": " + ( e.message || e ), extractStacktrace(e, 0)); + // else next test will carry the responsibility + saveGlobal(); + + // Restart the tests if they're blocking + if (config.blocking) { + QUnit.start(); + } + } + }, + teardown: function () { + config.current = this; + if (config.notrycatch) { + if (typeof this.callbackRuntime === "undefined") { + this.callbackRuntime = +new Date() - this.callbackStarted; + } + this.testEnvironment.teardown.call(this.testEnvironment, QUnit.assert); + return; + } else { + try { + this.testEnvironment.teardown.call(this.testEnvironment, QUnit.assert); + } catch (e) { + QUnit.pushFailure("Teardown failed on " + this.testName + ": " + ( e.message || e ), extractStacktrace(e, 1)); + } + } + checkPollution(); + }, + finish: function () { + config.current = this; + if (config.requireExpects && this.expected === null) { + QUnit.pushFailure("Expected number of assertions to be defined, but expect() was not called.", this.stack); + } else if (this.expected !== null && this.expected !== this.assertions.length) { + QUnit.pushFailure("Expected " + this.expected + " assertions, but " + this.assertions.length + " were run", this.stack); + } else if (this.expected === null && !this.assertions.length) { + QUnit.pushFailure("Expected at least one assertion, but none were run - call expect(0) to accept zero assertions.", this.stack); + } + + var i, assertion, a, b, time, li, ol, + test = this, + good = 0, + bad = 0, + tests = id("qunit-tests"); + + this.runtime = +new Date() - this.started; + config.stats.all += this.assertions.length; + config.moduleStats.all += this.assertions.length; + + if (tests) { + ol = document.createElement("ol"); + ol.className = "qunit-assert-list"; + + for (i = 0; i < this.assertions.length; i++) { + assertion = this.assertions[i]; + + li = document.createElement("li"); + li.className = assertion.result ? "pass" : "fail"; + li.innerHTML = assertion.message || ( assertion.result ? "okay" : "failed" ); + ol.appendChild(li); + + if (assertion.result) { + good++; + } else { + bad++; + config.stats.bad++; + config.moduleStats.bad++; + } + } + + // store result when possible + if (QUnit.config.reorder && defined.sessionStorage) { + if (bad) { + sessionStorage.setItem("qunit-test-" + this.module + "-" + this.testName, bad); + } else { + sessionStorage.removeItem("qunit-test-" + this.module + "-" + this.testName); + } + } + + if (bad === 0) { + addClass(ol, "qunit-collapsed"); + } + + // `b` initialized at top of scope + b = document.createElement("strong"); + b.innerHTML = this.nameHtml + " (" + bad + ", " + good + ", " + this.assertions.length + ")"; + + addEvent(b, "click", function () { + var next = b.parentNode.lastChild, + collapsed = hasClass(next, "qunit-collapsed"); + ( collapsed ? removeClass : addClass )(next, "qunit-collapsed"); + }); + + addEvent(b, "dblclick", function (e) { + var target = e && e.target ? e.target : window.event.srcElement; + if (target.nodeName.toLowerCase() === "span" || target.nodeName.toLowerCase() === "b") { + target = target.parentNode; + } + if (window.location && target.nodeName.toLowerCase() === "strong") { + window.location = QUnit.url({testNumber: test.testNumber}); + } + }); + + // `time` initialized at top of scope + time = document.createElement("span"); + time.className = "runtime"; + time.innerHTML = this.runtime + " ms"; + + // `li` initialized at top of scope + li = id(this.id); + li.className = bad ? "fail" : "pass"; + li.removeChild(li.firstChild); + a = li.firstChild; + li.appendChild(b); + li.appendChild(a); + li.appendChild(time); + li.appendChild(ol); + + } else { + for (i = 0; i < this.assertions.length; i++) { + if (!this.assertions[i].result) { + bad++; + config.stats.bad++; + config.moduleStats.bad++; + } + } + } + + runLoggingCallbacks("testDone", QUnit, { + name: this.testName, + module: this.module, + failed: bad, + passed: this.assertions.length - bad, + total: this.assertions.length, + runtime: this.runtime, + // DEPRECATED: this property will be removed in 2.0.0, use runtime instead + duration: this.runtime + }); + + QUnit.reset(); + + config.current = undefined; + }, + + queue: function () { + var bad, + test = this; + + synchronize(function () { + test.init(); + }); + function run() { + // each of these can by async + synchronize(function () { + test.setup(); + }); + synchronize(function () { + test.run(); + }); + synchronize(function () { + test.teardown(); + }); + synchronize(function () { + test.finish(); + }); + } + + // `bad` initialized at top of scope + // defer when previous test run passed, if storage is available + bad = QUnit.config.reorder && defined.sessionStorage && +sessionStorage.getItem("qunit-test-" + this.module + "-" + this.testName); + + if (bad) { + run(); + } else { + synchronize(run, true); + } + } + }; + +// `assert` initialized at top of scope +// Assert helpers +// All of these must either call QUnit.push() or manually do: +// - runLoggingCallbacks( "log", .. ); +// - config.current.assertions.push({ .. }); + assert = QUnit.assert = { + /** + * Asserts rough true-ish result. + * @name ok + * @function + * @example ok( "asdfasdf".length > 5, "There must be at least 5 chars" ); + */ + ok: function (result, msg) { + if (!config.current) { + throw new Error("ok() assertion outside test context, was " + sourceFromStacktrace(2)); + } + result = !!result; + msg = msg || ( result ? "okay" : "failed" ); + + var source, + details = { + module: config.current.module, + name: config.current.testName, + result: result, + message: msg + }; + + msg = "" + escapeText(msg) + ""; + + if (!result) { + source = sourceFromStacktrace(2); + if (source) { + details.source = source; + msg += "
      Source:
      " +
      +                        escapeText(source) +
      +                        "
      "; + } + } + runLoggingCallbacks("log", QUnit, details); + config.current.assertions.push({ + result: result, + message: msg + }); + }, + + /** + * Assert that the first two arguments are equal, with an optional message. + * Prints out both actual and expected values. + * @name equal + * @function + * @example equal( format( "Received {0} bytes.", 2), "Received 2 bytes.", "format() replaces {0} with next argument" ); + */ + equal: function (actual, expected, message) { + /*jshint eqeqeq:false */ + QUnit.push(expected == actual, actual, expected, message); + }, + + /** + * @name notEqual + * @function + */ + notEqual: function (actual, expected, message) { + /*jshint eqeqeq:false */ + QUnit.push(expected != actual, actual, expected, message); + }, + + /** + * @name propEqual + * @function + */ + propEqual: function (actual, expected, message) { + actual = objectValues(actual); + expected = objectValues(expected); + QUnit.push(QUnit.equiv(actual, expected), actual, expected, message); + }, + + /** + * @name notPropEqual + * @function + */ + notPropEqual: function (actual, expected, message) { + actual = objectValues(actual); + expected = objectValues(expected); + QUnit.push(!QUnit.equiv(actual, expected), actual, expected, message); + }, + + /** + * @name deepEqual + * @function + */ + deepEqual: function (actual, expected, message) { + QUnit.push(QUnit.equiv(actual, expected), actual, expected, message); + }, + + /** + * @name notDeepEqual + * @function + */ + notDeepEqual: function (actual, expected, message) { + QUnit.push(!QUnit.equiv(actual, expected), actual, expected, message); + }, + + /** + * @name strictEqual + * @function + */ + strictEqual: function (actual, expected, message) { + QUnit.push(expected === actual, actual, expected, message); + }, + + /** + * @name notStrictEqual + * @function + */ + notStrictEqual: function (actual, expected, message) { + QUnit.push(expected !== actual, actual, expected, message); + }, + + "throws": function (block, expected, message) { + var actual, + expectedOutput = expected, + ok = false; + + // 'expected' is optional + if (!message && typeof expected === "string") { + message = expected; + expected = null; + } + + config.current.ignoreGlobalErrors = true; + try { + block.call(config.current.testEnvironment); + } catch (e) { + actual = e; + } + config.current.ignoreGlobalErrors = false; + + if (actual) { + + // we don't want to validate thrown error + if (!expected) { + ok = true; + expectedOutput = null; + + // expected is an Error object + } else if (expected instanceof Error) { + ok = actual instanceof Error && + actual.name === expected.name && + actual.message === expected.message; + + // expected is a regexp + } else if (QUnit.objectType(expected) === "regexp") { + ok = expected.test(errorString(actual)); + + // expected is a string + } else if (QUnit.objectType(expected) === "string") { + ok = expected === errorString(actual); + + // expected is a constructor + } else if (actual instanceof expected) { + ok = true; + + // expected is a validation function which returns true is validation passed + } else if (expected.call({}, actual) === true) { + expectedOutput = null; + ok = true; + } + + QUnit.push(ok, actual, expectedOutput, message); + } else { + QUnit.pushFailure(message, null, "No exception was thrown."); + } + } + }; + + /** + * @deprecated since 1.8.0 + * Kept assertion helpers in root for backwards compatibility. + */ + extend(QUnit.constructor.prototype, assert); + + /** + * @deprecated since 1.9.0 + * Kept to avoid TypeErrors for undefined methods. + */ + QUnit.constructor.prototype.raises = function () { + QUnit.push(false, false, false, "QUnit.raises has been deprecated since 2012 (fad3c1ea), use QUnit.throws instead"); + }; + + /** + * @deprecated since 1.0.0, replaced with error pushes since 1.3.0 + * Kept to avoid TypeErrors for undefined methods. + */ + QUnit.constructor.prototype.equals = function () { + QUnit.push(false, false, false, "QUnit.equals has been deprecated since 2009 (e88049a0), use QUnit.equal instead"); + }; + QUnit.constructor.prototype.same = function () { + QUnit.push(false, false, false, "QUnit.same has been deprecated since 2009 (e88049a0), use QUnit.deepEqual instead"); + }; + +// Test for equality any JavaScript type. +// Author: Philippe Rathé + QUnit.equiv = (function () { + + // Call the o related callback with the given arguments. + function bindCallbacks(o, callbacks, args) { + var prop = QUnit.objectType(o); + if (prop) { + if (QUnit.objectType(callbacks[prop]) === "function") { + return callbacks[prop].apply(callbacks, args); + } else { + return callbacks[prop]; // or undefined + } + } + } + + // the real equiv function + var innerEquiv, + // stack to decide between skip/abort functions + callers = [], + // stack to avoiding loops from circular referencing + parents = [], + parentsB = [], + + getProto = Object.getPrototypeOf || function (obj) { + /* jshint camelcase: false, proto: true */ + return obj.__proto__; + }, + callbacks = (function () { + + // for string, boolean, number and null + function useStrictEquality(b, a) { + /*jshint eqeqeq:false */ + if (b instanceof a.constructor || a instanceof b.constructor) { + // to catch short annotation VS 'new' annotation of a + // declaration + // e.g. var i = 1; + // var j = new Number(1); + return a == b; + } else { + return a === b; + } + } + + return { + "string": useStrictEquality, + "boolean": useStrictEquality, + "number": useStrictEquality, + "null": useStrictEquality, + "undefined": useStrictEquality, + + "nan": function (b) { + return isNaN(b); + }, + + "date": function (b, a) { + return QUnit.objectType(b) === "date" && a.valueOf() === b.valueOf(); + }, + + "regexp": function (b, a) { + return QUnit.objectType(b) === "regexp" && + // the regex itself + a.source === b.source && + // and its modifiers + a.global === b.global && + // (gmi) ... + a.ignoreCase === b.ignoreCase && + a.multiline === b.multiline && + a.sticky === b.sticky; + }, + + // - skip when the property is a method of an instance (OOP) + // - abort otherwise, + // initial === would have catch identical references anyway + "function": function () { + var caller = callers[callers.length - 1]; + return caller !== Object && typeof caller !== "undefined"; + }, + + "array": function (b, a) { + var i, j, len, loop, aCircular, bCircular; + + // b could be an object literal here + if (QUnit.objectType(b) !== "array") { + return false; + } + + len = a.length; + if (len !== b.length) { + // safe and faster + return false; + } + + // track reference to avoid circular references + parents.push(a); + parentsB.push(b); + for (i = 0; i < len; i++) { + loop = false; + for (j = 0; j < parents.length; j++) { + aCircular = parents[j] === a[i]; + bCircular = parentsB[j] === b[i]; + if (aCircular || bCircular) { + if (a[i] === b[i] || aCircular && bCircular) { + loop = true; + } else { + parents.pop(); + parentsB.pop(); + return false; + } + } + } + if (!loop && !innerEquiv(a[i], b[i])) { + parents.pop(); + parentsB.pop(); + return false; + } + } + parents.pop(); + parentsB.pop(); + return true; + }, + + "object": function (b, a) { + /*jshint forin:false */ + var i, j, loop, aCircular, bCircular, + // Default to true + eq = true, + aProperties = [], + bProperties = []; + + // comparing constructors is more strict than using + // instanceof + if (a.constructor !== b.constructor) { + // Allow objects with no prototype to be equivalent to + // objects with Object as their constructor. + if (!(( getProto(a) === null && getProto(b) === Object.prototype ) || + ( getProto(b) === null && getProto(a) === Object.prototype ) )) { + return false; + } + } + + // stack constructor before traversing properties + callers.push(a.constructor); + + // track reference to avoid circular references + parents.push(a); + parentsB.push(b); + + // be strict: don't ensure hasOwnProperty and go deep + for (i in a) { + loop = false; + for (j = 0; j < parents.length; j++) { + aCircular = parents[j] === a[i]; + bCircular = parentsB[j] === b[i]; + if (aCircular || bCircular) { + if (a[i] === b[i] || aCircular && bCircular) { + loop = true; + } else { + eq = false; + break; + } + } + } + aProperties.push(i); + if (!loop && !innerEquiv(a[i], b[i])) { + eq = false; + break; + } + } + + parents.pop(); + parentsB.pop(); + callers.pop(); // unstack, we are done + + for (i in b) { + bProperties.push(i); // collect b's properties + } + + // Ensures identical properties name + return eq && innerEquiv(aProperties.sort(), bProperties.sort()); + } + }; + }()); + + innerEquiv = function () { // can take multiple arguments + var args = [].slice.apply(arguments); + if (args.length < 2) { + return true; // end transition + } + + return (function (a, b) { + if (a === b) { + return true; // catch the most you can + } else if (a === null || b === null || typeof a === "undefined" || + typeof b === "undefined" || + QUnit.objectType(a) !== QUnit.objectType(b)) { + return false; // don't lose time with error prone cases + } else { + return bindCallbacks(a, callbacks, [b, a]); + } + + // apply transition with (1..n) arguments + }(args[0], args[1]) && innerEquiv.apply(this, args.splice(1, args.length - 1)) ); + }; + + return innerEquiv; + }()); + + /** + * jsDump Copyright (c) 2008 Ariel Flesler - aflesler(at)gmail(dot)com | + * http://flesler.blogspot.com Licensed under BSD + * (http://www.opensource.org/licenses/bsd-license.php) Date: 5/15/2008 + * + * @projectDescription Advanced and extensible data dumping for Javascript. + * @version 1.0.0 + * @author Ariel Flesler + * @link {http://flesler.blogspot.com/2008/05/jsdump-pretty-dump-of-any-javascript.html} + */ + QUnit.jsDump = (function () { + function quote(str) { + return "\"" + str.toString().replace(/"/g, "\\\"") + "\""; + } + + function literal(o) { + return o + ""; + } + + function join(pre, arr, post) { + var s = jsDump.separator(), + base = jsDump.indent(), + inner = jsDump.indent(1); + if (arr.join) { + arr = arr.join("," + s + inner); + } + if (!arr) { + return pre + post; + } + return [pre, inner + arr, base + post].join(s); + } + + function array(arr, stack) { + var i = arr.length, ret = new Array(i); + this.up(); + while (i--) { + ret[i] = this.parse(arr[i], undefined, stack); + } + this.down(); + return join("[", ret, "]"); + } + + var reName = /^function (\w+)/, + jsDump = { + // type is used mostly internally, you can fix a (custom)type in advance + parse: function (obj, type, stack) { + stack = stack || []; + var inStack, res, + parser = this.parsers[type || this.typeOf(obj)]; + + type = typeof parser; + inStack = inArray(obj, stack); + + if (inStack !== -1) { + return "recursion(" + (inStack - stack.length) + ")"; + } + if (type === "function") { + stack.push(obj); + res = parser.call(this, obj, stack); + stack.pop(); + return res; + } + return ( type === "string" ) ? parser : this.parsers.error; + }, + typeOf: function (obj) { + var type; + if (obj === null) { + type = "null"; + } else if (typeof obj === "undefined") { + type = "undefined"; + } else if (QUnit.is("regexp", obj)) { + type = "regexp"; + } else if (QUnit.is("date", obj)) { + type = "date"; + } else if (QUnit.is("function", obj)) { + type = "function"; + } else if (typeof obj.setInterval !== undefined && typeof obj.document !== "undefined" && typeof obj.nodeType === "undefined") { + type = "window"; + } else if (obj.nodeType === 9) { + type = "document"; + } else if (obj.nodeType) { + type = "node"; + } else if ( + // native arrays + toString.call(obj) === "[object Array]" || + // NodeList objects + ( typeof obj.length === "number" && typeof obj.item !== "undefined" && ( obj.length ? obj.item(0) === obj[0] : ( obj.item(0) === null && typeof obj[0] === "undefined" ) ) ) + ) { + type = "array"; + } else if (obj.constructor === Error.prototype.constructor) { + type = "error"; + } else { + type = typeof obj; + } + return type; + }, + separator: function () { + return this.multiline ? this.HTML ? "
      " : "\n" : this.HTML ? " " : " "; + }, + // extra can be a number, shortcut for increasing-calling-decreasing + indent: function (extra) { + if (!this.multiline) { + return ""; + } + var chr = this.indentChar; + if (this.HTML) { + chr = chr.replace(/\t/g, " ").replace(/ /g, " "); + } + return new Array(this.depth + ( extra || 0 )).join(chr); + }, + up: function (a) { + this.depth += a || 1; + }, + down: function (a) { + this.depth -= a || 1; + }, + setParser: function (name, parser) { + this.parsers[name] = parser; + }, + // The next 3 are exposed so you can use them + quote: quote, + literal: literal, + join: join, + // + depth: 1, + // This is the list of parsers, to modify them, use jsDump.setParser + parsers: { + window: "[Window]", + document: "[Document]", + error: function (error) { + return "Error(\"" + error.message + "\")"; + }, + unknown: "[Unknown]", + "null": "null", + "undefined": "undefined", + "function": function (fn) { + var ret = "function", + // functions never have name in IE + name = "name" in fn ? fn.name : (reName.exec(fn) || [])[1]; + + if (name) { + ret += " " + name; + } + ret += "( "; + + ret = [ret, QUnit.jsDump.parse(fn, "functionArgs"), "){"].join(""); + return join(ret, QUnit.jsDump.parse(fn, "functionCode"), "}"); + }, + array: array, + nodelist: array, + "arguments": array, + object: function (map, stack) { + /*jshint forin:false */ + var ret = [], keys, key, val, i; + QUnit.jsDump.up(); + keys = []; + for (key in map) { + keys.push(key); + } + keys.sort(); + for (i = 0; i < keys.length; i++) { + key = keys[i]; + val = map[key]; + ret.push(QUnit.jsDump.parse(key, "key") + ": " + QUnit.jsDump.parse(val, undefined, stack)); + } + QUnit.jsDump.down(); + return join("{", ret, "}"); + }, + node: function (node) { + var len, i, val, + open = QUnit.jsDump.HTML ? "<" : "<", + close = QUnit.jsDump.HTML ? ">" : ">", + tag = node.nodeName.toLowerCase(), + ret = open + tag, + attrs = node.attributes; + + if (attrs) { + for (i = 0, len = attrs.length; i < len; i++) { + val = attrs[i].nodeValue; + // IE6 includes all attributes in .attributes, even ones not explicitly set. + // Those have values like undefined, null, 0, false, "" or "inherit". + if (val && val !== "inherit") { + ret += " " + attrs[i].nodeName + "=" + QUnit.jsDump.parse(val, "attribute"); + } + } + } + ret += close; + + // Show content of TextNode or CDATASection + if (node.nodeType === 3 || node.nodeType === 4) { + ret += node.nodeValue; + } + + return ret + open + "/" + tag + close; + }, + // function calls it internally, it's the arguments part of the function + functionArgs: function (fn) { + var args, + l = fn.length; + + if (!l) { + return ""; + } + + args = new Array(l); + while (l--) { + // 97 is 'a' + args[l] = String.fromCharCode(97 + l); + } + return " " + args.join(", ") + " "; + }, + // object calls it internally, the key part of an item in a map + key: quote, + // function calls it internally, it's the content of the function + functionCode: "[code]", + // node calls it internally, it's an html attribute value + attribute: quote, + string: quote, + date: quote, + regexp: literal, + number: literal, + "boolean": literal + }, + // if true, entities are escaped ( <, >, \t, space and \n ) + HTML: false, + // indentation unit + indentChar: " ", + // if true, items in a collection, are separated by a \n, else just a space. + multiline: true + }; + + return jsDump; + }()); + + /* + * Javascript Diff Algorithm + * By John Resig (http://ejohn.org/) + * Modified by Chu Alan "sprite" + * + * Released under the MIT license. + * + * More Info: + * http://ejohn.org/projects/javascript-diff-algorithm/ + * + * Usage: QUnit.diff(expected, actual) + * + * QUnit.diff( "the quick brown fox jumped over", "the quick fox jumps over" ) == "the quick brown fox jumped jumps over" + */ + QUnit.diff = (function () { + /*jshint eqeqeq:false, eqnull:true */ + function diff(o, n) { + var i, + ns = {}, + os = {}; + + for (i = 0; i < n.length; i++) { + if (!hasOwn.call(ns, n[i])) { + ns[n[i]] = { + rows: [], + o: null + }; + } + ns[n[i]].rows.push(i); + } + + for (i = 0; i < o.length; i++) { + if (!hasOwn.call(os, o[i])) { + os[o[i]] = { + rows: [], + n: null + }; + } + os[o[i]].rows.push(i); + } + + for (i in ns) { + if (hasOwn.call(ns, i)) { + if (ns[i].rows.length === 1 && hasOwn.call(os, i) && os[i].rows.length === 1) { + n[ns[i].rows[0]] = { + text: n[ns[i].rows[0]], + row: os[i].rows[0] + }; + o[os[i].rows[0]] = { + text: o[os[i].rows[0]], + row: ns[i].rows[0] + }; + } + } + } + + for (i = 0; i < n.length - 1; i++) { + if (n[i].text != null && n[i + 1].text == null && n[i].row + 1 < o.length && o[n[i].row + 1].text == null && + n[i + 1] == o[n[i].row + 1]) { + + n[i + 1] = { + text: n[i + 1], + row: n[i].row + 1 + }; + o[n[i].row + 1] = { + text: o[n[i].row + 1], + row: i + 1 + }; + } + } + + for (i = n.length - 1; i > 0; i--) { + if (n[i].text != null && n[i - 1].text == null && n[i].row > 0 && o[n[i].row - 1].text == null && + n[i - 1] == o[n[i].row - 1]) { + + n[i - 1] = { + text: n[i - 1], + row: n[i].row - 1 + }; + o[n[i].row - 1] = { + text: o[n[i].row - 1], + row: i - 1 + }; + } + } + + return { + o: o, + n: n + }; + } + + return function (o, n) { + o = o.replace(/\s+$/, ""); + n = n.replace(/\s+$/, ""); + + var i, pre, + str = "", + out = diff(o === "" ? [] : o.split(/\s+/), n === "" ? [] : n.split(/\s+/)), + oSpace = o.match(/\s+/g), + nSpace = n.match(/\s+/g); + + if (oSpace == null) { + oSpace = [" "]; + } + else { + oSpace.push(" "); + } + + if (nSpace == null) { + nSpace = [" "]; + } + else { + nSpace.push(" "); + } + + if (out.n.length === 0) { + for (i = 0; i < out.o.length; i++) { + str += "" + out.o[i] + oSpace[i] + ""; + } + } + else { + if (out.n[0].text == null) { + for (n = 0; n < out.o.length && out.o[n].text == null; n++) { + str += "" + out.o[n] + oSpace[n] + ""; + } + } + + for (i = 0; i < out.n.length; i++) { + if (out.n[i].text == null) { + str += "" + out.n[i] + nSpace[i] + ""; + } + else { + // `pre` initialized at top of scope + pre = ""; + + for (n = out.n[i].row + 1; n < out.o.length && out.o[n].text == null; n++) { + pre += "" + out.o[n] + oSpace[n] + ""; + } + str += " " + out.n[i].text + nSpace[i] + pre; + } + } + } + + return str; + }; + }()); + +// For browser, export only select globals + if (typeof window !== "undefined") { + extend(window, QUnit.constructor.prototype); + window.QUnit = QUnit; + } + +// For CommonJS environments, export everything + if (typeof module !== "undefined" && module.exports) { + module.exports = QUnit; + } + + +// Get a reference to the global object, like window in browsers +}((function () { + return this; +})())); \ No newline at end of file diff --git a/WebContent/status.taobao b/src/main/webapp/status.taobao similarity index 100% rename from WebContent/status.taobao rename to src/main/webapp/status.taobao diff --git a/WebContent/systembusy.html b/src/main/webapp/systembusy.html similarity index 55% rename from WebContent/systembusy.html rename to src/main/webapp/systembusy.html index 6924b860f..5754f71af 100644 --- a/WebContent/systembusy.html +++ b/src/main/webapp/systembusy.html @@ -5,7 +5,7 @@ -系统繁忙,系统比你都忙。请谅解。
      快去 GitHub Issues 开贴提问... +系统繁忙,系统比你都忙。请谅解。
      快去 GitHub Issues 开贴提问... 木有设计师,开发又懒...所以这个页面酱紫 \ No newline at end of file diff --git a/WebContent/tcom/const.inc.vm b/src/main/webapp/tcom/const.inc.vm similarity index 97% rename from WebContent/tcom/const.inc.vm rename to src/main/webapp/tcom/const.inc.vm index b7ab073a0..3cdeda821 100644 --- a/WebContent/tcom/const.inc.vm +++ b/src/main/webapp/tcom/const.inc.vm @@ -11,7 +11,7 @@ ## 精确到天 #set($dateFormat = 'yyyy-MM-dd') ## 时间戳 -#set($timeStamp = '20151111.v0.12.sp1') +#set($timeStamp = '20151111.v0.13.0') ##----------------------页面请求action地址------------------------------- ## 配置工程的上下文路径 #set($projectContext = "$!link.getContextPath()") @@ -47,6 +47,7 @@ }) #set($workspaceUrl = { "myWorkspace":"$projectContext/workspace/myWorkspace.do", + "loadWorkspace":"$projectContext/workspace/loadWorkspace.do", "getModuleHtmlAjax":"$projectContext/workspace/getModuleHtmlAjax.do", "updateCurrentSave":"$projectContext/workspace/updateCurrentSave.do", "updateSave":"$projectContext/workspace/updateSave.do", diff --git a/src/main/webapp/tcom/mod.macro.vm b/src/main/webapp/tcom/mod.macro.vm new file mode 100644 index 000000000..ad6508223 --- /dev/null +++ b/src/main/webapp/tcom/mod.macro.vm @@ -0,0 +1,61 @@ +#macro (includeEditorStatic) + + + + +#end + +#macro (createEditor $suffix $textareaName $editorWidth $editorHeight $selfInit) + #set($editorAreaWidth = $editorWidth - 10) +
      + +
      +
      +
      +
      + + + + +
      +#end \ No newline at end of file diff --git a/WebContent/tcom/report.macro.vm b/src/main/webapp/tcom/report.macro.vm similarity index 58% rename from WebContent/tcom/report.macro.vm rename to src/main/webapp/tcom/report.macro.vm index ddead9a4b..291c8cc80 100644 --- a/WebContent/tcom/report.macro.vm +++ b/src/main/webapp/tcom/report.macro.vm @@ -1,7 +1,7 @@ #parse('/tcom/mod.macro.vm') #** - * @desc : 报表组件 + * @desc : 报表组件 * @param {String} id 标识, 相应的textarea和checkbox的id为textarea-{id}, checkbox-{id} * @param {String} checkboxName * @param {String} editorName @@ -13,88 +13,94 @@ *# #set($editorNO = 0) #macro (reportCom $id $checkboxName $editorName $title $type $data $content $isEnabled) -#if ($isEnabled) - #set( $isDisabled = false ) -#else - #set( $isDisabled = true ) -#end + #if ($isEnabled) + #set( $isDisabled = false ) + #else + #set( $isDisabled = true ) + #end -#if ($type == "") - #set( $hasFlash = false) -#else - #set( $hasFlash = true) -#end + #if ($type == "") + #set( $hasFlash = false) + #else + #set( $hasFlash = true) + #end -#if (!$flag) - #set( $flag = true ) - #initReportCom() -#end - - - -

      $!title

      -#if ($hasFlash)
      - -#end + #if (!$flag) + #set( $flag = true ) + #initReportCom() + #end + + + +

      $!title

      + #if ($hasFlash) +
      + + #end
       
      - #createEditor("$id" "$editorName" 650 215 true) + #createEditor("$id" "$editorName" 650 215 true) -#set($editorNO = $editorNO + 1) + #set($editorNO = $editorNO + 1) #end #macro (initReportCom) - #includeEditorStatic +#includeEditorStatic + + #if(!$hide) + + #end +
      +#end +## master page end +#macro (bodyEnd) +
      +

      - 人在使用RAP, 今日Mock服务被调用 - 次  旺旺群支持:582755829 + +

      +
      + +
      + + + + + + +#end diff --git a/src/main/webapp/tcom/utils.macro.vm b/src/main/webapp/tcom/utils.macro.vm new file mode 100644 index 000000000..3f1c2511f --- /dev/null +++ b/src/main/webapp/tcom/utils.macro.vm @@ -0,0 +1,566 @@ +#parse('/tcom/const.inc.vm') + + +## 权限字符串 + +#macro (getRoleStr $roleId)#if($roleId==1)超级管理员#elseif($roleId==2)管理员#else 普通用户 #end #end + +## 分页 +#macro (pager $curPagerNum $pagerSize $totalNum $url) +

      + #set($totalPage = ($totalNum - 1) / $pagerSize + 1) + + #set($currentPager = $curPagerNum) + + #set($pagerStart = 1) + #set($pagerEnd = $totalPage) + + #if($currentPager >= $totalPage) + #set($currentPager = $totalPage) + #set($pagerEnd = $totalPage) + #end + + #if($currentPager < 1) + #set($currentPager = 1) + #end + + #if($currentPager > 1) + 首页 + «上一页 + #else + 首页 + «上一页 + #end + + #if($totalPage > 11) + #if($currentPager > 5) + #set($pagerStart = $currentPager - 5) + #set($pagerEnd = $currentPager + 5) + #else + #set($pagerEnd = 10) + #end + #if($pagerEnd > $totalPage) + #set($pagerStart = $totalPage - 9) + #set($pagerEnd = $totalPage) + #end + #end + + #foreach($item in [${pageStart}..${pageEnd}]) + #if($item == $currentPager) + $item + #else + $item + #end + #end + + #if($currentPager < $totalPage) + 下一页» + 尾页 + #else + 下一页» + 尾页 + #end + 跳转 +       共$!totalPage页,$!totalNum条记录   +

      + #if($totalNum == 0) + + #end +#end +#macro (table $lstConfigs $data $options) +#* + * 表格控件 + * + * @params {List} $lstConfigs [必填]列表表头数据,列样式(宽度,自定义属性等) + * @params {List} $data [必填]表格内容数据 + * @params {List} $options 表格其他参数 + * lstTitles {list} [选填]表头, 可以由RD设置, 一般情况下就取${lstConfigs}的值 + * checkbox {String} [选填]用户自行选择的checkbox的name值 + * checkboxVal {String} [选填]用户自行选择的checkbox的id值 + * hasOp {Boolean} [选填]参数为true, 表示有操作列 + * custom {Boolean} [选填]全选是否可以针对整表,依赖于选项checkbox + * style {String} [选填]表格采用的样式, 默认为"default" + * url {String} [选填]分页请求的URL, 默认为"" + * id {String} [选填]列表的id, 命名建议[0-9a-zA-Z_]+ + * needPrint {Boolean} [选填]是否需要打印, 默认不需要打印 + * page {list} [选填]每页记录数 + * @todo 修改id - 固定 + *# + #if($options.id) + #set($tbId = $options.id) + #else + #if($tbId) + #set($tbId = $tbId + 1) + #else + #set($tbId = 0) + #end + #end + + #set($tbNoData = false) + #if(!$data || $data.size() == 0) + #set($tbNoData = true) + #end + + + + #if ($pager || $options.pager) +
      + #if($options.pager) + #pager($options.pager.curPagerNum + $options.pager.pagerSize + $options.pager.totalRecNum + $options.url) + #else + #pager($pager.curPagerNum + $pager.pagerSize + $pager.totalRecNum + $options.url) + #end + + #end + +#end +#** + * @desc : 适用于数据确定的下拉列表、单选组、多选组,数据类型为List型 + * @param {String} name 表单项name属性值 + * @param {List} data 填充表单项value和label属性的值 + * @param {String} curVal 当前选中值 + * @param {String} flag 哪个类型的表单项(radio/select/checkbox) + * @param {String} attrs 表单项其它的属性 + *# +#set($fieldIndex = 0) +#macro (list $name $data $curVal $flag $attrs) + #if($flag == "select") + + #elseif($flag == "checkbox") + #foreach($item in $data) + + #set($fieldIndex = $fieldIndex + 1) + #end + #elseif($flag == "radio") + #foreach($item in $data) + + #set($fieldIndex = $fieldIndex + 1) + #end + #end +#end +#** + * @desc : 层级下拉框 + * @param {String} fName 下拉框fName属性值 + * @param {List} fData 填充下拉框value和label属性及层级关系的值 + * @param {String} fCurVal 当前选中值 + * @param {String} fAttrs 表单项其它的属性 + *# +#macro (levelSelect $fName $fData $fCurVal $fAttrs) + +#end +#** + * @desc : 层级下拉框(数据源无序) + * @param {String} fName 下拉框fName属性值 + * @param {List} fData 填充下拉框value和label属性及层级关系的值 + * @param {String} fCurVal 当前选中值 + * @param {String} fAttrs 表单项其它的属性 + *# +#macro (levelSelect2 $fName $fData $fCurVal $fAttrs) + + +#end +#** + * @desc : 统一引入错误提示 + *# +#macro (globalMsg) + #if($errors && $errors.globalMsg) +
      +
      +
      +
      +
      $!errors.globalMsg
      +
      +
      +
      +
      + #end +#end +#** + * @desc : 单日历 + * @param {String} name 表单项name属性值 + * @param {String} value 默认时间 + * @param {list} options 可选项 支持的参数有 range设定可操作范围 ecid设置ecid + * @demo #singleCal("cal-demo" "2012-01-12") + *# +#macro (singleCal $name $value $options) + +#end +#** + * @desc : 双日历 + * @param {String} name 表单项name属性值 + * @param {String} value 默认时间 + * @param {list} options 可选项 支持的参数有 range设定可操作范围 ecid设置ecid + * @demo #rangeCal("2012-01-11" "2012-02-23") + *# +#macro (rangeCal $bVal $eVal $options) + +#end +#** + * @desc : 浮动层开头部分代码 + * @param {String} ecId ecui控件Id,在ecFloater.show(ecId)调用使用 + * @param {String} title 浮动层标题名称 + * @param {Number} width 浮动层的宽度值 + * @param {Number} height 浮动层的高度值 + * @demo + * #startFloater("floater1" "标题" 500 300) + * 浮动层里面的HTML代码 + * #endFloater + *# +#macro (startFloater $ecId $title $width $height) + +#end +#** + * @desc : 初始本地存储模块 + * @param {String} ecId 可选,默认为localStorage。ecui控件Id,用户获取ecui本地存储控件。 + * @demo #storageInit() 或 #storageInit("myLocalStorage") + *# +#macro (storageInit $ecId) + #if(!$ecId) + #set($ecId = "localStorage") + #end +
      +#end +#** + * @desc : 提交查询表单时本地保存内容 + * @param {String} ecId 可选,默认为localStorage。ecui控件Id,用户获取ecui本地存储控件。 + * @demo #storageSave() 或 #storageSave("myLocalStorage") + *# +#macro (storageSave $ecId) + #if(!$ecId) + #set($ecId = "localStorage") + #end +this.localDataId.value = ecui.get('$!ecId').save(this); +#end +#** + * @desc : navBar 方案制作导航条 + *# +#macro (navBar $curTab $curCTab) + #set($commURL = "$common.stepController?type=current&schemeId=$!schemeId¤tStep=") + + + +#end +#** + * @desc : includeNewRapStatic 新版统一引入静态资源 + *# +#macro (includeNewRapStatic) + + + + + + + + + + + + + + + + + + + + + +#end \ No newline at end of file diff --git a/WebContent/tester/pageTester.js b/src/main/webapp/tester/pageTester.js similarity index 84% rename from WebContent/tester/pageTester.js rename to src/main/webapp/tester/pageTester.js index 7f1800a10..03f9abc96 100644 --- a/WebContent/tester/pageTester.js +++ b/src/main/webapp/tester/pageTester.js @@ -1,8 +1,11 @@ if (!window.console) { window.console = { - log : function() {}, - warn : function() {}, - err : function() {} + log: function () { + }, + warn: function () { + }, + err: function () { + } }; } @@ -21,19 +24,19 @@ YUI().use('handlebars', 'node', 'event', 'jsonp', 'jsonp-url', 'json-stringify', log('tester initializing...'); Y.timeLog = {}; - Y.all('.form').each(function(form) { + Y.all('.form').each(function (form) { // form start - form.one('.btn-run').on('click', function(e) { + form.one('.btn-run').on('click', function (e) { Y.one('#divResBoardJson').setHTML('加载中,请稍后...'); - var url = ''; - var qArr = []; - var i = 0; - var fields = form.all('.field'); + var url = ''; + var qArr = []; + var i = 0; + var fields = form.all('.field'); var baseUrl = Y.one('#txtRootPath').get('value'); var baseUrlOrigin = Y.one('#txtRootPath').get('value'); - var rapUrl = RAP_ROOT; - var path = form.getAttribute('path'); + var rapUrl = RAP_ROOT; + var path = form.getAttribute('path'); if (~path.indexOf('http')) { path = path.substring(7); @@ -46,7 +49,7 @@ YUI().use('handlebars', 'node', 'event', 'jsonp', 'jsonp-url', 'json-stringify', baseUrl += path; rapUrl += path; - fields.each(function(field) { + fields.each(function (field) { var name = field.get('name'), value = field.get('value'); qArr[i++] = name + '=' + encodeURIComponent(value); @@ -65,8 +68,8 @@ YUI().use('handlebars', 'node', 'event', 'jsonp', 'jsonp-url', 'json-stringify', Y.timeLog.time = new Date().getTime(); try { Y.io('/mock/requestOnServer.do?url=' + encodeURIComponent(url), { - on : { - success : function() { + on: { + success: function () { var args = []; try { args = [eval('(' + arguments[1].responseText + ')')]; @@ -79,8 +82,8 @@ YUI().use('handlebars', 'node', 'event', 'jsonp', 'jsonp-url', 'json-stringify', } if (RAP_ROOT != baseUrlOrigin) { Y.jsonp(rapUrl, { - on : { - success : function(response) { + on: { + success: function (response) { function validatorResultLog(item, isReverse) { var LOST = "LOST"; var EMPTY_ARRAY = "EMPTY_ARRAY"; @@ -120,28 +123,28 @@ YUI().use('handlebars', 'node', 'event', 'jsonp', 'jsonp-url', 'json-stringify', validatorResultLog(rapDataResult[i], true); } }, - timeout : function() { + timeout: function () { log(color('timeout', RED) + '... so long time to response!'); }, - failure : function(e) { + failure: function (e) { console.log(color('error occurred!', RED) + color(', detail:' + e.errors[0].error, LIGHT_GRAY)); } }, - timeout : 10000 + timeout: 10000 }); } }, - timeout : function() { + timeout: function () { log(color('timeout', RED) + '... so long time to response!'); }, - failure : function(e) { + failure: function (e) { log(color('error occurred!', RED) + color(', detail:' + e.errors[0].error, LIGHT_GRAY)); } }, - timeout : 10000, - args : [form] + timeout: 10000, + args: [form] }); - } catch(ex) { + } catch (ex) { alert(ex); } }); @@ -155,19 +158,19 @@ YUI().use('handlebars', 'node', 'event', 'jsonp', 'jsonp-url', 'json-stringify', } if (jQuery.isArray(obj)) { var newArray = []; - for(var k = 0; k < obj.length; k++) { + for (var k = 0; k < obj.length; k++) { newArray.push(sortObj(obj[k])); } return newArray; } else if (jQuery.isPlainObject(obj)) { var result = {}, keys = []; - for(var prop in obj) { + for (var prop in obj) { if (obj.hasOwnProperty(prop)) { keys.push(prop); } } keys = keys.sort(); - for(var i = 0, l = keys.length; i < l; i++) { + for (var i = 0, l = keys.length; i < l; i++) { result[keys[i]] = sortObj(obj[keys[i]]); } return result; @@ -179,22 +182,22 @@ YUI().use('handlebars', 'node', 'event', 'jsonp', 'jsonp-url', 'json-stringify', function testResHandler(response, form, btn) { var obj = response; var jsonString; - + var path = Y.one('#txtRootPath').get('value'); obj = sortObj(obj); if (btn != 'rule' && path.indexOf('mockjs') != -1) { obj = Mock.mock(obj); } - - jsonString = JSON.stringify(obj, function(key, val) { + + jsonString = JSON.stringify(obj, function (key, val) { if (typeof val === 'function') { return ""; } else { return val; } }); - + var beginTime = Y.timeLog.time; if (!beginTime) return; var endTime = new Date().getTime(); @@ -236,36 +239,36 @@ YUI().use('handlebars', 'node', 'event', 'jsonp', 'jsonp-url', 'json-stringify', Y.one('#txtRootPath').on('change', initUrl); - setTimeout(function() { + setTimeout(function () { var logContainer = $('#divResBoardLog'); - $(document).delegate('#up-trigger', 'click', function() { + $(document).delegate('#up-trigger', 'click', function () { logContainer.animate({ 'height': 500 }); - }).delegate('#expand-trigger', 'click', function() { + }).delegate('#expand-trigger', 'click', function () { logContainer.animate({ 'width': '98%' }); $('body').css('padding-bottom', '110px'); - }).delegate('#down-trigger', 'click', function() { + }).delegate('#down-trigger', 'click', function () { logContainer.animate({ 'height': 100 }); - }).delegate('#close-trigger', 'click', function() { + }).delegate('#close-trigger', 'click', function () { logContainer.hide('slow'); $('#show-trigger').show('slow'); - }).delegate('#show-trigger', 'click', function() { + }).delegate('#show-trigger', 'click', function () { logContainer.show('slow'); $('#show-trigger').hide('slow'); }); }, 500); - $('.btn-run-real').on('click', function(e) { + $('.btn-run-real').on('click', function (e) { $(this).toggleClass('active'); $(this).parents('.tools').find('.real-options').toggle(); }); - $('.btn-run-do-real').on('click', function(e) { + $('.btn-run-do-real').on('click', function (e) { $('#divResBoardJson').html('正在进行测试,请稍候...'); }); log('tester ready.'); diff --git a/src/main/webapp/tester/pageTester.vm b/src/main/webapp/tester/pageTester.vm new file mode 100644 index 000000000..caf3e896c --- /dev/null +++ b/src/main/webapp/tester/pageTester.vm @@ -0,0 +1,101 @@ + + + #parse('/tcom/template.rap.vm') + + + RAP - $!utils.escapeInH($page.name)控制台 + + + #includeNewRapStatic + + + + + + + +#bodyNewStart +
      +

      +    + $!utils.escapeInH($page.name) 页面控制台 +

      + +
      + + +
      +
      + +
      + #foreach($action in $page.actionList) +
      +
      + + +
      +
      请求标识: $action.id
      +
      请求地址: $!utils.escapeInH($action.requestUrl)
      +
      +
      + #foreach($para in $action.requestParameterList) +
      + $!utils.escapeInH($para.identifier) + + 说明 +
      +
      - 变量名:$!utils.escapeInH($para.name)
      +
      - 备注:$!utils.escapeInH($para.remark)
      +
      +
      +
      + #end +
      +
      + +
      +
      +
      + #end +
      +
      +
      +
      ready
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      + + +
      +#bodyEnd + + + + + diff --git a/WebContent/tester/template/pageTester.tbl.html b/src/main/webapp/tester/template/pageTester.tbl.html similarity index 100% rename from WebContent/tester/template/pageTester.tbl.html rename to src/main/webapp/tester/template/pageTester.tbl.html diff --git a/src/main/webapp/unit-tests/errors/bugfix-list.js b/src/main/webapp/unit-tests/errors/bugfix-list.js new file mode 100644 index 000000000..d1a7a730c --- /dev/null +++ b/src/main/webapp/unit-tests/errors/bugfix-list.js @@ -0,0 +1,114 @@ +module('bugfix-BOSN', { + setup: function () { + this.oldProjectId = RAP.getProjectId(), + this.oldMode = RAP.getMode(); + // 项目ID设置为“Bosn修复BUG专用”的ID + RAP.setProjectId(189); + // 拦截所有请求 + RAP.setMode(1); + }, + teardown: function () { + RAP.setProjectId(this.oldProjectId); + RAP.setMode(this.oldMode); + } +}); + +test('dataTypeBug fix', function () { + stop(); + KISSY.use('io', function (S, IO) { + IO({ + url: 'dataTypeBug.do', + dataType: 'json', + success: function (data) { + ok(KISSY.isArray(data.numberArray), 'numberArray is array'); + ok(KISSY.isNumber(data.numberArray[0]), 'numberArray[0] is number'); + ok(KISSY.isArray(data.stringArray), 'stringArray is array'); + ok(KISSY.isString(data.stringArray[0]), 'stringArray[0] is string'); + start(); + } + }) + }) +}) + + +test('paramMockJsTemplate fix', function () { + stop(2); + KISSY.use('io', function (S, IO) { + IO({ + url: 'paramMockJsTemplate.do', + dataType: 'json', + success: function (data) { + console.log(data); + equal(data.result, 'page is 1008, num is okokok', 'data origin: page is 1008, num is okokok'); + equal(data.result2, '', 'data origin: 1') + start(1); + + IO({ + url: 'paramMockJsTemplate.do', + data: { + num: 111, + page: 222 + }, + dataType: 'json', + success: function (data) { + equal(data.result, 'page is 222, num is 111', 'data changed: page is 222, num is 111'); + equal(data.result2, 222, 'data changed: 222') + start(1); + } + }) + } + }) + }) +}) + + +test('unicode fix', function () { + stop(); + KISSY.use('io', function (S, IO) { + IO({ + url: 'unicode.do', + dataType: 'json', + success: function (data) { + ok(KISSY.isString(data.string1), 'params are string'); + ok(KISSY.isString(data.string2), 'params are string'); + ok(KISSY.isString(data.string3), 'params are string'); + equal(data.string1, '1233打发打发..*(&(@#*&@(*#&*(', 'string1 is ok'); + equal(data.string2, '9832749802374098324782937flakdsjfldaskjf啊死了都快放假啊老师的看风景阿斯蒂芬(*&(*&', 'string2 is ok'); + equal(data.string3, '哈哈深度开发回家啊说的发来了空间啊说的饭卡上的减肥快乐的撒娇放假', 'string3 is ok'); + start(); + } + }) + }) +}) + + +test('copyFunc fix', function () { + stop(); + KISSY.use('io', function (S, IO) { + IO({ + url: 'copyFunc', + dataType: 'json', + success: function (data) { + console.log(data); + ok(KISSY.isArray(data.obj), 'data.obj is array'); + ok(KISSY.isArray(data.objCopy), 'data.objCopy is array'); + var a = data.obj[0], b = data.objCopy[0]; + for (var prop in a) { + ok(prop in b, 'b has ' + prop + ' too'); + } + for (var prop in b) { + ok(prop in a, 'a has ' + prop + ' too'); + } + for (var prop in a.item) { + ok(prop in b.item, 'b.item has ' + prop + ' too'); + equal(typeof a.item[prop], typeof b.item[prop], 'value type is the same.') + } + for (var prop in b.item) { + ok(prop in a.item, 'a.item has ' + prop + ' too'); + equal(typeof a.item[prop], typeof b.item[prop], 'value type is the same.') + } + start(); + } + }) + }) +}) diff --git a/src/main/webapp/unit-tests/errors/rap-plugin-error.js b/src/main/webapp/unit-tests/errors/rap-plugin-error.js new file mode 100644 index 000000000..173304cd8 --- /dev/null +++ b/src/main/webapp/unit-tests/errors/rap-plugin-error.js @@ -0,0 +1,46 @@ +module('bugfix'); + +test('without io: KISSY.use("node", function(S, A) {})', function () { + stop(4); + KISSY.use('node', function (S, Node) { + start(1); + ok(S.config, 'still has S.config'); + }); + + KISSY.use('node, io', function (S, Node) { + start(1); + ok(S.config, 'still has S.config'); + }); + + KISSY.use('node, io', function (S, Node, IO) { + start(1); + ok(S.config, 'still has S.config'); + }); + + KISSY.use('node, io, node', function (S, Node, IO, Node) { + start(1); + ok(S.config, 'still has S.config'); + }); +}) + +test('KISSY.add using IO', function () { + stop(); + KISSY.add('tester/module', function (S, Node, IO) { + ok(KISSY.io != undefined, 'got KISSY.io'); + ok(KISSY.ajax != undefined, 'got KISSY.ajax'); + ok(KISSY.IO != undefined, 'got KISSY.IO'); + + IO({ + url: '/base', + dataType: 'json', + success: function (data) { + equal(typeof data.a, 'number', 'get data ok'); + start(); + } + }) + }, {requires: ['node', 'io']}) + + KISSY.use('tester/module', function (S, A) { + + }) +}) \ No newline at end of file diff --git a/src/main/webapp/unit-tests/getrule/base.js b/src/main/webapp/unit-tests/getrule/base.js new file mode 100644 index 000000000..f0121cdc4 --- /dev/null +++ b/src/main/webapp/unit-tests/getrule/base.js @@ -0,0 +1,39 @@ +module('get-mockjs-rule'); + +test('jQuery - getMockjsRule - /mockjs/projectId/action', function () { + stop(); + $.ajax({ + type: "get", + url: "/mockjs/114/mockjs/base", + dataType: "jsonp", + jsonp: "callback", + success: function (data) { + start(); + ok('a|1-10' in data, 'mockjs rule: a|1-10 is in data'); + ok(KISSY.isNumber(data['a|1-10']), 'and dataType is number'); + }, + error: function () { + } + }); +}); + + +test('KISSY - getMockjsRule - /mockjs/projectId/action', function () { + stop(); + var base = '/mockjs/114/mockjs/base'; + KISSY.oldUse('io', function (S, IO) { + IO({ + type: "get", + url: base, + dataType: "jsonp", + jsonp: "callback", + success: function (data) { + start(); + ok('a|1-10' in data, 'mockjs rule: a|1-10 is in data'); + ok(KISSY.isNumber(data['a|1-10']), 'and dataType is number'); + }, + error: function () { + } + }) + }); +}); \ No newline at end of file diff --git a/src/main/webapp/unit-tests/getruledata/base.js b/src/main/webapp/unit-tests/getruledata/base.js new file mode 100644 index 000000000..74b5cbe18 --- /dev/null +++ b/src/main/webapp/unit-tests/getruledata/base.js @@ -0,0 +1,127 @@ +module('get-mockjs-data'); + +test('jQuery.ajax[ORIGIN] - getMockjsData - get /mockjsdata/projectId/action', function () { + stop(); + $.ajax({ + type: "get", + url: "/mockjsdata/114/mockjs/base", + dataType: "jsonp", + jsonp: "callback", + success: function (data) { + start(); + ok('a' in data, 'property exists'); + ok(KISSY.isNumber(data.a), 'a is number'); + ok(data.a >= 1 && data.a <= 10, 'a between 1 and 10'); + }, + error: function () { + } + }); +}); + + +test('jQuery.ajax[RAPPED] - getMockjsData - Action : /mockjs/base', function () { + stop(); + equal(RAP.getPrefix(), '/mockjs/', 'PREFIX is /mockjs/'); + $.rapAjax({ + type: "get", + url: "/mockjs/base", + dataType: "jsonp", + jsonp: "callback", + success: function (data) { + start(); + ok('a' in data, 'mockjs : a is in data'); + ok(KISSY.isNumber(data['a']), 'and dataType is number'); + }, + error: function () { + } + }); +}); + + +test('jQuery.ajax[RAPPED] - getMockjsData - Prefix: /mockjsdata/, Action:/mockjs/base', function () { + stop(); + equal(RAP.getPrefix(), '/mockjs/', 'PREFIX is /mockjs/'); + var old = RAP.getPrefix(); + RAP.setPrefix('/mockjsdata/') + $.rapAjax({ + type: "get", + url: "/mockjs/base", + dataType: "jsonp", + jsonp: "callback", + success: function (data) { + RAP.setPrefix(old); + start(); + ok('a' in data, 'mockjs : a is in data'); + ok(KISSY.isNumber(data['a']), 'and dataType is number'); + }, + error: function () { + } + }); +}); + + +test('KISSY[ORIGIN] - getMockjsData - get /mockjsdata/projectId/action', function () { + stop(); + KISSY.oldUse('io', function (S, IO) { + IO({ + type: "get", + url: "/mockjsdata/114/mockjs/base", + dataType: "jsonp", + jsonp: "callback", + success: function (data) { + start(); + ok('a' in data, 'property exists'); + ok(KISSY.isNumber(data.a), 'a is number'); + ok(data.a >= 1 && data.a <= 10, 'a between 1 and 10'); + }, + error: function () { + } + }) + }); +}); + + +test('KISSY[RAPPED] - getMockjsData - Action: /mockjs/base', function () { + stop(); + var base = '/mockjs/base'; + KISSY.use('io', function (S, IO) { + IO({ + type: "get", + url: base, + dataType: "jsonp", + jsonp: "callback", + success: function (data) { + start(); + ok('a' in data, 'property exists'); + ok(KISSY.isNumber(data.a), 'a is number'); + ok(data.a >= 1 && data.a <= 10, 'a between 1 and 10'); + }, + error: function () { + } + }) + }); +}); + +test('KISSY[RAPPED] - getMockjsData - Prefix: /mockjsdata/, Action: /mockjs/base', function () { + stop(); + var base = '/mockjs/base'; + KISSY.use('io', function (S, IO) { + var old = RAP.getPrefix(); + RAP.setPrefix('/mockjsdata/'); + IO({ + type: "get", + url: base, + dataType: "jsonp", + jsonp: "callback", + success: function (data) { + start(); + ok('a' in data, 'property exists'); + ok(KISSY.isNumber(data.a), 'a is number'); + ok(data.a >= 1 && data.a <= 10, 'a between 1 and 10'); + }, + error: function () { + } + }) + RAP.setPrefix(old); + }); +}); \ No newline at end of file diff --git a/src/main/webapp/unit-tests/getruledata/datatypes.js b/src/main/webapp/unit-tests/getruledata/datatypes.js new file mode 100644 index 000000000..adb8a0c24 --- /dev/null +++ b/src/main/webapp/unit-tests/getruledata/datatypes.js @@ -0,0 +1,147 @@ +module('mockjs-data-validation'); + +test('DATA_TYPES: exist and type', function () { + stop(); + var base = '/datatypes'; + KISSY.use('io', function (S, IO) { + IO({ + type: "get", + url: base, + dataType: "jsonp", + jsonp: "callback", + success: function (data) { + start(); + + ok('boolean' in data, 'boolean in data'); + ok('string' in data, 'string in data'); + ok('object' in data, 'object in data'); + ok('number' in data, 'number in data'); + + ok(KISSY.isNumber(data.number), 'number is number'); + ok(KISSY.isObject(data.object), 'object is object'); + ok(KISSY.isString(data.string), 'string is string'); + ok(KISSY.isBoolean(data.boolean), 'boolean is boolean'); + var obj = data.object; + ok('d' in obj, 'sub prop'); + + ok(KISSY.isNumber(obj.a), 'sub prop is number'); + ok(KISSY.isString(obj.b), 'sub prop is string'); + ok(KISSY.isBoolean(obj.c), 'sub prop is boolean'); + ok(KISSY.isObject(obj.d), 'sub prop is object'); + + ok(obj.d.d1, 'd1 in obj.d'); + ok(KISSY.isNumber(obj.d.d1), 'obj.d.d1 is number'); + + ok('array_boolean' in data, 'array boolean in data'); + ok('array_string' in data, 'array string in data'); + ok('array_number' in data, 'array number in data'); + ok('array_object' in data, 'array object in data'); + + ok(KISSY.isBoolean(data.array_boolean[0]), 'booleans[0] is boolean'); + ok(KISSY.isString(data.array_string[0]), 'strings[0] is string'); + ok(KISSY.isNumber(data.array_number[0]), 'numbers[0] is number'); + ok(KISSY.isObject(data.array_object[0]), 'objects[0] is object'); + + var obj = data.array_object[0]; + ok('d' in obj, 'sub prop exist'); + ok(KISSY.isObject(obj.d), 'is object!'); + ok('d1' in obj.d, 'sub sub prop exist'); + ok(KISSY.isNumber(obj.d.d1), 'is number'); + }, + error: function () { + } + }) + }); +}); + + +test('DATA_TYPES: values', function () { + stop(); + var base = '/datatypes'; + KISSY.use('io', function (S, IO) { + IO({ + type: "get", + url: base, + dataType: "jsonp", + jsonp: "callback", + success: function (data) { + start(); + + ok(data.number >= 1 && data.number <= 20, 'number|1-20'); + ok(data.boolean === true || data.boolean === false, 'boolean is true or false'); + ok(/^B{1,5}$/.test(data.string), 'string is B{1-5}'); + + var obj = data.object; + ok('d' in obj, 'sub prop'); + + ok(obj.a >= 1 && obj.a <= 10, 'a|1-10'); + ok(/^A{3,5}$/.test(obj.b), 'string is A{3-5}'); + ok(obj.c === true || obj.c === false, 'sub prop is boolean'); + + ok(obj.d.d1 >= 3 && obj.d.d1 <= 10, 'obj.d.d1|3-10'); + + var arr = data.array_boolean; + ok(arr[0] === true, 'a[0] = true'); + ok(arr[1] === false, 'a[1] = false'); + + var arr = data.array_string; + ok(arr[0] == 'a', 'b[0] = a'); + ok(arr[1] == 'b', 'b[1] = b'); + ok(arr[2] == 'c', 'b[2] = c'); + + var arr = data.array_number; + ok(arr[0] == 1, 'b[0] = 1'); + ok(arr[1] == 2, 'b[1] = 2'); + ok(arr[2] == 3, 'b[2] = 3'); + + var arr = data.array_object; + ok(arr.length == 3, 'object length is 3'); + + var obj = data.array_object[0]; + ok(obj.a >= 3 && obj.a <= 7, 'a|3-7'); + ok(/^A{4}$/.test(obj.b), 'b is AAAA'); + ok(obj.c === true || obj.c === false, 'c is true or false'); + ok(obj.d.d1 >= 3 && obj.d.d1 <= 7, 'd.d1|3-7'); + }, + error: function () { + } + }) + }); +}); + +function propsIn(props, obj, name) { + for (var i = 0; i < props.length; i++) { + ok(props[i] in obj, props[i] + ' in ' + name); + } +} +test('DATA_TYPES: demo data from mockjs.com(import by JSON, Cool~)', function () { + stop(); + var base = '/mockjs/demo/from/site'; + KISSY.use('io', function (S, IO) { + IO({ + type: "get", + url: base, + dataType: "jsonp", + jsonp: "callback", + success: function (data) { + start(); + ok(data.data, 'data exists'); + ok(KISSY.isArray(data.data), 'data is array'); + ok(data.data.length >= 1 && data.data.length <= 10, 'data|1-10'); + var pick = data.data[0]; + propsIn(['cn', 'date', 'datetime', 'dummyimage', 'email', 'float1', 'float2', 'float3', + 'float4', 'grade1', 'grade2', 'img1', 'img2', 'method', 'param', 'published', 'repeat', 'size', + 'star', 'time'], pick, 'data[0]'); + equal(pick.id, 1, 'id is 1'); + if (data.data.length > 1) { + equal(data.data[1].id, 2, 'id increment'); + } + } + }) + }); +}); + +// TODO +// @mock=@value@prop test +// 各种mockjs的规则编辑测试 +// @mock=和直接写的测试 diff --git a/WebContent/unit-tests/index.js b/src/main/webapp/unit-tests/index.js similarity index 82% rename from WebContent/unit-tests/index.js rename to src/main/webapp/unit-tests/index.js index e9e25ad7a..20fd0652c 100644 --- a/WebContent/unit-tests/index.js +++ b/src/main/webapp/unit-tests/index.js @@ -1,5 +1,5 @@ module('env confirm'); -test('no KISSY.io when kissy seed inited', function() { +test('no KISSY.io when kissy seed inited', function () { ok(KISSY.io === undefined, 'KISSY.io is undefined when kissy seed loaded'); }); @@ -21,4 +21,5 @@ var scripts = [ 'errors/bugfix-list.js' ]; -loadScripts(scripts, function() {}); +loadScripts(scripts, function () { +}); diff --git a/src/main/webapp/unit-tests/prepare.js b/src/main/webapp/unit-tests/prepare.js new file mode 100644 index 000000000..c958c5569 --- /dev/null +++ b/src/main/webapp/unit-tests/prepare.js @@ -0,0 +1,22 @@ +var root = /unit-tests/; +RAP.setHost(window.location.host); + +function loadScript(s, callback) { + $.getScript(root + s + '?' + (+new Date)).done(callback); +} + + +function loadScripts(scripts, callback) { + // keep in order + var i = 0; + loadScript(scripts[i], function () { + i++; + if (i == scripts.length) { + callback(); + return; + } + else { + loadScript(scripts[i], arguments.callee); + } + }); +} \ No newline at end of file diff --git a/src/main/webapp/unit-tests/rap-plugin/base.js b/src/main/webapp/unit-tests/rap-plugin/base.js new file mode 100644 index 000000000..9177accff --- /dev/null +++ b/src/main/webapp/unit-tests/rap-plugin/base.js @@ -0,0 +1,132 @@ +module('rap-plugin-base'); + +test('KISSY.use("rap_io"), to see KISSY.io|KISSY.IO|KISSY.ajax', function () { + stop(); + action = '/base'; + KISSY.use('rap_io', function (S, IO) { + ok(KISSY.io != undefined, 'got KISSY.io'); + ok(KISSY.ajax != undefined, 'got KISSY.ajax'); + ok(KISSY.IO != undefined, 'got KISSY.IO'); + + ok(KISSY.io == IO, 'KISSY.io is rap_io'); + ok(KISSY.ajax == IO, 'KISSY.io is rap_io'); + ok(KISSY.IO == IO, 'KISSY.io is rap_io'); + + IO({ + url: action, + dataType: 'json', + success: function (data) { + equal(typeof data.a, 'number', 'get data ok by KISSY.use("io")'); + start(); + } + }) + }) +}) + + +test('get data from KISSY.use("io")', function () { + stop(); + action = '/base'; + KISSY.use('io', function (S, IO) { + ok(KISSY.io != undefined, 'got KISSY.io'); + ok(KISSY.ajax != undefined, 'got KISSY.ajax'); + ok(KISSY.IO != undefined, 'got KISSY.IO'); + IO({ + url: action, + dataType: 'json', + success: function (data) { + equal(typeof data.a, 'number', 'get data ok by KISSY.use("io")'); + start(); + } + }) + }) +}); + +test('get data from KISSY.use("ajax")', function () { + stop(); + action = '/base'; + KISSY.use('ajax', function (S, IO) { + IO({ + url: action, + dataType: 'json', + success: function (data) { + equal(typeof data.a, 'number', 'get data ok by KISSY.use("ajax")'); + start(); + } + }) + }) +}); + +test('get Data from KISSY.io', function () { + action = '/base'; + stop(); + KISSY.io({ + url: action, + dataType: 'json', + success: function (data) { + equal(typeof data.a, 'number', 'KISSY.io get data ok: a'); + equal(typeof data.b, 'string', 'KISSY.io get data ok: b'); + ok(KISSY.isObject(data.c), 'c is object'); + start(); + } + }); +}); + + +test('get Data from KISSY.ajax', function () { + action = '/base'; + stop(); + KISSY.io({ + url: action, + dataType: 'json', + success: function (data) { + equal(typeof data.a, 'number', 'KISSY.ajax get data ok: a'); + equal(typeof data.b, 'string', 'KISSY.ajax get data ok: b'); + ok(KISSY.isObject(data.c), 'c is object'); + start(); + } + }); +}); + +test('KISSY.use("io", {success: function(S, IO) {}})', function () { + action = '/base'; + stop(); + KISSY.use("io", { + success: function (S, IO) { + ok(KISSY.io != undefined, 'got KISSY.io'); + ok(KISSY.ajax != undefined, 'got KISSY.ajax'); + ok(KISSY.IO != undefined, 'got KISSY.IO'); + + IO({ + url: action, + dataType: 'json', + success: function (data) { + equal(typeof data.a, 'number', 'get data ok'); + start(); + } + }) + } + }) +}); + + +test('KISSY.use("ajax", {success: function(S, IO) {}})', function () { + action = '/base'; + stop(); + KISSY.use("ajax", { + success: function (S, IO) { + ok(KISSY.io != undefined, 'got KISSY.io'); + ok(KISSY.ajax != undefined, 'got KISSY.ajax'); + ok(KISSY.IO != undefined, 'got KISSY.IO'); + + IO({ + url: action, + dataType: 'json', + success: function (data) { + equal(typeof data.a, 'number', 'get data ok'); + start(); + } + }) + } + }) +}); \ No newline at end of file diff --git a/src/main/webapp/unit-tests/rap-plugin/for-seajs.js b/src/main/webapp/unit-tests/rap-plugin/for-seajs.js new file mode 100644 index 000000000..836d3e90f --- /dev/null +++ b/src/main/webapp/unit-tests/rap-plugin/for-seajs.js @@ -0,0 +1,66 @@ +module('Seajs-jQuery-RAP'); + +test('Seajs+jQuery: basic check', function () { + stop(4); + ok(window.wrapJQueryForRAP, 'wrap method exists'); + define('a', function (require) { + start(1); + var jq = require('jquery'); + ok(jq.providedByRAP, 'provided by rap'); + ok(jq._rap_wrapped, 'ajax wrapped') + ok(jq('body')[0] == document.body, 'jquery is loaded by seajs'); + }) + + define('b', function (require) { + start(1); + var jq = require('jQuery'); + ok(jq.providedByRAP, 'provided by rap'); + ok(jq._rap_wrapped, 'ajax wrapped') + ok(jq('body')[0] == document.body, 'jQuery is loaded by seajs'); + }) + + define('c', function (require) { + start(1); + var jq = require('jq'); + ok(jq.providedByRAP, 'provided by rap'); + ok(jq._rap_wrapped, 'ajax wrapped') + ok(jq('body')[0] == document.body, 'jq is loaded by seajs'); + }) + + define('d', function (require) { + start(1); + var jq = require('jQ'); + ok(jq.providedByRAP, 'provided by rap'); + ok(jq._rap_wrapped, 'ajax wrapped') + ok(jq('body')[0] == document.body, 'jQ is loaded by seajs'); + }) + + seajs.use(['a', 'b', 'c', 'd'], function (a, b, c, d) { + }); +}); + + +test('Seajs+jQuery: get rap data', function () { + stop() + var action = '/base'; + define('e', function (require) { + var $ = require('jquery'); + equal(RAP.getPrefix(), '/mockjs/', 'PREFIX is /mockjs/'); + $.ajax({ + type: "get", + url: "/mockjs/base", + dataType: "jsonp", + jsonp: "callback", + success: function (data) { + start(); + ok('a' in data, 'mockjs : a is in data'); + ok(KISSY.isNumber(data['a']), 'and dataType is number'); + }, + error: function () { + } + }); + }) + + seajs.use('e', function () { + }); +}) \ No newline at end of file diff --git a/WebContent/unit-tests/rap-plugin/jsapis.js b/src/main/webapp/unit-tests/rap-plugin/jsapis.js similarity index 84% rename from WebContent/unit-tests/rap-plugin/jsapis.js rename to src/main/webapp/unit-tests/rap-plugin/jsapis.js index 4c1682880..f32bf9a22 100644 --- a/WebContent/unit-tests/rap-plugin/jsapis.js +++ b/src/main/webapp/unit-tests/rap-plugin/jsapis.js @@ -1,6 +1,6 @@ module('rap-plugin-jsapis'); -test('RAP.set/getWhiteList', function() { +test('RAP.set/getWhiteList', function () { var old = RAP.getWhiteList(); var newList = ['a', 'b']; RAP.setWhiteList(newList); @@ -9,7 +9,7 @@ test('RAP.set/getWhiteList', function() { equal(RAP.getWhiteList(), old, 'recover ok'); }); -test('RAP.set/getHost', function() { +test('RAP.set/getHost', function () { var old = RAP.getHost(); equal(old, window.location.host, 'old is ok'); var newHost = 'rap2.ali' + 'bab' + 'a-inc.com'; @@ -19,7 +19,7 @@ test('RAP.set/getHost', function() { equal(RAP.getHost(), old, 'recover ok'); }); -test('RAP.set/getBlackList', function() { +test('RAP.set/getBlackList', function () { var old = RAP.getBlackList(); var newList = ['a', 'b']; RAP.setBlackList(newList); @@ -28,7 +28,7 @@ test('RAP.set/getBlackList', function() { equal(RAP.getBlackList(), old, 'recover ok'); }); -test('RAP.set/getMode', function() { +test('RAP.set/getMode', function () { var old = RAP.getMode(); var newMode = 3; RAP.setMode(newMode); @@ -37,7 +37,7 @@ test('RAP.set/getMode', function() { equal(RAP.getMode(), old, 'recover ok'); }); -test('RAP.set/getPrefix', function() { +test('RAP.set/getPrefix', function () { var old = RAP.getPrefix(); equal(old, '/mockjs/', 'old is /mockjs/'); var newPrefix = '/mockjsdata/'; @@ -47,8 +47,8 @@ test('RAP.set/getPrefix', function() { equal(RAP.getPrefix(), old, 'recover ok'); }); -test('RAP.set/white list & black list functions', function() { - var arr = ['a', 'b','c']; +test('RAP.set/white list & black list functions', function () { + var arr = ['a', 'b', 'c']; RAP.setWhiteList(arr); var whiteList = RAP.getWhiteList(); deepEqual(arr, whiteList, 'white list works fine'); @@ -59,7 +59,7 @@ test('RAP.set/white list & black list functions', function() { deepEqual(arr2, blackList, 'black list works fined'); }); -test('RAP.set/getProjectId', function() { +test('RAP.set/getProjectId', function () { var old = RAP.getProjectId(); equal(old, 114, 'old is 114'); var newProjectId = 121; diff --git a/src/main/webapp/unit-tests/rap-plugin/modes.js b/src/main/webapp/unit-tests/rap-plugin/modes.js new file mode 100644 index 000000000..0db2d4910 --- /dev/null +++ b/src/main/webapp/unit-tests/rap-plugin/modes.js @@ -0,0 +1,200 @@ +module('rap-plugin-modes'); + +//mode 0:不走rap,应该404 +test('setMode 0 - 404 [KISSY]', function () { + var old = RAP.getMode(); + RAP.setMode(0); + + stop(); + var action = '/base'; + KISSY.use('io', function (S, IO) { + IO({ + url: action, + dataType: 'json', + success: function (data) { + start(); + ok(0, 'in here, is not right in this case'); + RAP.setMode(old); + }, + error: function (data) { + start(); + ok(1, 'in here, 404 is right in this case'); + RAP.setMode(old); + } + }) + }) +}); + +//mode 0:不走rap,应该404 +test('setMode 0 - 404 [jQuery]', function () { + var old = RAP.getMode(); + RAP.setMode(0); + + stop(); + var action = '/base'; + $.rapAjax({ + type: "get", + url: action, + dataType: "jsonp", + jsonp: "callback", + success: function (data) { + start(); + ok(0, 'in here, is not right in this case'); + RAP.setMode(old); + }, + error: function () { + start(); + ok(1, 'in here, 404 is right in this case'); + RAP.setMode(old); + } + }); +}); + + +//mode 0:放行 +test('setMode 0 - 200 [KISSY]', function () { + var old = RAP.getMode(); + RAP.setMode(0); + + stop(); + var action = '/mockjsdata/114/mockjs/base'; + KISSY.use('io', function (S, IO) { + IO({ + url: action, + dataType: 'jsonp', + jsonp: 'callback', + success: function (data) { + start(); + ok(1, 'in here, is not right in this case'); + RAP.setMode(old); + }, + error: function (data) { + start(); + ok(0, 'in here, 404 is right in this case'); + RAP.setMode(old); + } + }) + }) +}); + +//mode 0:放行 +test('setMode 0 - 200 [jQuery]', function () { + var old = RAP.getMode(); + RAP.setMode(0); + + stop(); + var action = '/mockjsdata/114/mockjs/base'; + $.rapAjax({ + type: "get", + url: action, + dataType: "jsonp", + jsonp: "callback", + success: function (data) { + start(); + ok(1, 'in here, is not right in this case'); + RAP.setMode(old); + }, + error: function () { + start(); + ok(0, 'in here, 404 is right in this case'); + RAP.setMode(old); + } + }); +}); + +//mode 1:拦截所有请求 +test('setMode 1 - 200 [KISSY]', function () { + var old = RAP.getMode(); + RAP.setMode(1); + + stop(); + var action = '/base'; + KISSY.use('io', function (S, IO) { + IO({ + url: action, + dataType: 'json', + success: function (data) { + start(); + ok(1, 'in here, is right in this case'); + RAP.setMode(old); + }, + error: function (data) { + start(); + ok(0, 'in here, 404 is not right in this case'); + RAP.setMode(old); + } + }) + }) +}) + +// mode 1:拦截所有请求 +test('setMode 1 - 200 [jQuery]', function () { + var old = RAP.getMode(); + RAP.setMode(1); + + stop(); + var action = '/base'; + $.rapAjax({ + type: "get", + url: action, + dataType: "jsonp", + jsonp: "callback", + success: function (data) { + start(); + ok(1, 'in here, is right in this case'); + RAP.setMode(old); + }, + error: function () { + start(); + ok(0, 'in here, 404 is not right in this case'); + RAP.setMode(old); + } + }); +}) + + +//mode 1:拦截所有请求 +test('setMode 1 - 404 [KISSY]', function () { + var old = RAP.getMode(); + RAP.setMode(1); + + stop(); + var action = '/mockjsdata/114/mockjs/base'; + KISSY.use('io', function (S, IO) { + IO({ + url: action, + dataType: 'json', + success: function (data) { + start(); + ok(data.isOk === false, 'no matched action'); + equal(data.errMsg, 'no matched action', 'no matched action'); + RAP.setMode(old); + }, + error: function (data) { + } + }) + }) +}) + +// mode 1:拦截所有请求 +test('setMode 1 - 404 [jQuery]', function () { + var old = RAP.getMode(); + RAP.setMode(1); + + stop(); + var action = '/mockjsdata/114/mockjs/base'; + $.rapAjax({ + type: "get", + url: action, + dataType: "jsonp", + jsonp: "callback", + success: function (data) { + start(); + ok(data.isOk === false, 'no matched action'); + equal(data.errMsg, 'no matched action', 'no matched action'); + RAP.setMode(old); + }, + error: function () { + } + }); +}) \ No newline at end of file diff --git a/src/main/webapp/unit-tests/rap-plugin/whiteblack.js b/src/main/webapp/unit-tests/rap-plugin/whiteblack.js new file mode 100644 index 000000000..c368b1e0d --- /dev/null +++ b/src/main/webapp/unit-tests/rap-plugin/whiteblack.js @@ -0,0 +1,245 @@ +module('rap-plugin-whiteList'); + +test('setWhiteList[ok] in mode 3', function () { + var old = RAP.getMode(); + RAP.setMode(3); + var white = RAP.getWhiteList(); + RAP.setWhiteList(['/base']); + + stop(2); + var action = '/base'; + var counter = 0; + KISSY.use('io', function (S, IO) { + IO({ + url: action, + dataType: 'json', + success: function (data) { + counter++; + start(1); + ok(1, 'in here, is right in this case'); + if (counter == 2) { + RAP.setMode(old); + RAP.setWhiteList(white); + } + }, + error: function (data) { + counter++; + start(1); + ok(0, 'in here, 404 is not right in this case'); + if (counter == 2) { + RAP.setMode(old); + RAP.setWhiteList(white); + } + } + }) + }) + + $.rapAjax({ + type: "get", + url: action, + dataType: "jsonp", + jsonp: "callback", + success: function (data) { + counter++; + start(1); + ok(1, 'in here, is right in this case'); + if (counter == 2) { + RAP.setMode(old); + RAP.setWhiteList(white); + } + }, + error: function () { + counter++; + start(1); + ok(0, 'in here, 404 is not right in this case'); + if (counter == 2) { + RAP.setMode(old); + RAP.setWhiteList(white); + } + } + }); +}) + +test('setWhiteList[not ok] in mode 3', function () { + var old = RAP.getMode(); + RAP.setMode(3); + + var white = RAP.getWhiteList(); + RAP.setWhiteList(['/notExistsAction']); + + stop(2); + var action = '/base'; + var counter = 0; + KISSY.use('io', function (S, IO) { + IO({ + url: action, + dataType: 'json', + success: function (data) { + counter++; + start(1); + ok(0, 'whiteList mode, url node in list, should not 200'); + if (counter == 2) { + RAP.setMode(old); + RAP.setWhiteList(white); + } + }, + error: function (data) { + counter++; + start(1); + ok(1, 'whiteList mode, url node in list, should 404'); + if (counter == 2) { + RAP.setMode(old); + RAP.setWhiteList(white); + } + } + }) + }) + + $.rapAjax({ + type: "get", + url: action, + dataType: "jsonp", + jsonp: "callback", + success: function (data) { + counter++; + start(1); + ok(0, 'whiteList mode, url node in list, should not 200'); + if (counter == 2) { + RAP.setMode(old); + RAP.setWhiteList(white); + } + }, + error: function () { + counter++; + start(1); + ok(1, 'whiteList mode, url node in list, should 404'); + if (counter == 2) { + RAP.setMode(old); + RAP.setWhiteList(white); + } + } + }); +}) + + +module('rap-plugin-blackList'); + +test('setBlackList[not ok] in mode 2', function () { + var old = RAP.getMode(); + RAP.setMode(2); + + var black = RAP.getBlackList(); + RAP.setBlackList(['/notExistsAction']); + + stop(2); + var action = '/base'; + var counter = 0; + KISSY.use('io', function (S, IO) { + IO({ + url: action, + dataType: 'json', + success: function (data) { + counter++; + start(1); + ok(1, 'in here, is right in this case'); + if (counter == 2) { + RAP.setMode(old); + RAP.setBlackList(black); + } + }, + error: function (data) { + counter++; + start(1); + ok(0, 'in here, 404 is not right in this case'); + if (counter == 2) { + RAP.setMode(old); + RAP.setBlackList(black); + } + } + }) + }) + + $.rapAjax({ + type: "get", + url: action, + dataType: "jsonp", + jsonp: "callback", + success: function (data) { + counter++; + start(1); + ok(1, 'in here, is right in this case'); + if (counter == 2) { + RAP.setMode(old); + RAP.setBlackList(black); + } + }, + error: function () { + counter++; + start(1); + ok(0, 'in here, 404 is not right in this case'); + if (counter == 2) { + RAP.setMode(old); + RAP.setBlackList(black); + } + } + }); +}) + +test('setWhiteList[ok] in mode 2', function () { + var old = RAP.getMode(); + RAP.setMode(2); + + var black = RAP.getBlackList(); + RAP.setBlackList(['/base']); + + stop(2); + var action = '/base'; + var counter = 0; + KISSY.use('io', function (S, IO) { + IO({ + url: action, + dataType: 'json', + success: function (data) { + counter++; + start(1); + ok(0, 'whiteList mode, url node in list, should not 200'); + if (counter == 2) { + RAP.setMode(old); + RAP.setBlackList(black); + } + }, + error: function (data) { + counter++; + start(1); + ok(1, 'whiteList mode, url node in list, should 404'); + if (counter == 2) { + RAP.setMode(old); + RAP.setBlackList(black); + } + } + }) + }) + + $.rapAjax({ + type: "get", + url: action, + dataType: "jsonp", + jsonp: "callback", + success: function (data) { + counter++; + start(1); + ok(0, 'whiteList mode, url node in list, should not 200'); + if (counter == 2) { + RAP.setMode(old); + } + }, + error: function () { + counter++; + start(1); + ok(1, 'whiteList mode, url node in list, should 404'); + if (counter == 2) { + RAP.setMode(old); + } + } + }); +}) \ No newline at end of file diff --git a/src/main/webapp/unit-tests/utility/structureValidator.js b/src/main/webapp/unit-tests/utility/structureValidator.js new file mode 100644 index 000000000..00d58f0cb --- /dev/null +++ b/src/main/webapp/unit-tests/utility/structureValidator.js @@ -0,0 +1,35 @@ +module('utility-structureValidator'); + + +test('Utility: StructureValidator functions test', function () { + var o1 = { + p1: 1, + p2: 2, + p3: 3, + obj: [{ + op3: 3, + op6: 6, + op7: 7 + }] + }; + var o2 = { + p1: 1, + p3: 3, + p4: 4, + obj: [] + }; + + var validator = new StructureValidator(o1, o2); + + var correctData = { + "left": [{"type": "LOST", "property": "p4", "namespace": "obj"}], + "right": [{"type": "LOST", "property": "p2", "namespace": "obj"}, { + "type": "EMPTY_ARRAY", + "property": "obj", + "namespace": "obj" + }] + }; + var realData = validator.getResult(); + + deepEqual(correctData, realData, 'strcuture check complete'); +}); diff --git a/WebContent/workspace/myWorkspace.css b/src/main/webapp/workspace/myWorkspace.css similarity index 80% rename from WebContent/workspace/myWorkspace.css rename to src/main/webapp/workspace/myWorkspace.css index 0092a0ee5..1c67a2fc1 100644 --- a/WebContent/workspace/myWorkspace.css +++ b/src/main/webapp/workspace/myWorkspace.css @@ -1,28 +1,31 @@ body { - margin:0; - padding:0; + margin: 0; + padding: 0; color: #666; } -.add-link,.edit-link,.del-link,.test-link { - margin-top: 5px; - display: inline-block; - margin-left: 5px; - cursor: pointer; - text-decoration: none !important; - color: #999 !important; +.add-link, .edit-link, .del-link, .test-link { + margin-top: 5px; + display: inline-block; + margin-left: 5px; + cursor: pointer; + text-decoration: none !important; + color: #999 !important; } + .ec-tree .add-link, .ec-tree .edit-link, .ec-tree .del-link, .ec-tree .test-link { - margin-top: 2px; + margin-top: 2px; } -.add-link:hover,.edit-link:hover,.del-link:hover,.test-link:hover { - color: #666 !important; + +.add-link:hover, .edit-link:hover, .del-link:hover, .test-link:hover { + color: #666 !important; } + .add-link { - background-position: 0 -31px; + background-position: 0 -31px; } .air { @@ -183,13 +186,12 @@ body { } - #div-fixed-panel { width: 1170px; margin: 70px 0 0 0; background: #FFF; z-index: 1; - top:50px; + top: 50px; } .m { @@ -198,7 +200,6 @@ body { background-color: #F2F2F2; border: 1px solid #DDD; border-radius: 0 0 12px 12px; - height: 550px; overflow-y: auto; } @@ -334,7 +335,7 @@ body { border-bottom: 1px solid #DDD; width: 1157px; text-align: left; - margin-top:13px; + margin-top: 13px; } #div-mt-list .tab { @@ -397,7 +398,8 @@ body { } #div-control-panel { - float: right; margin-right: 13px; + float: right; + margin-right: 13px; } #div-control-panel .button { @@ -406,7 +408,7 @@ body { } #div-control-panel .btn { - outline: none; + outline: none; } #div-return { @@ -426,8 +428,7 @@ body { } -#div-save-floater-message,#div-checkin-floater-message,#div-checkout-floater-message,#div-version-floater-message,#div-saveVSS-floater-message - { +#div-save-floater-message, #div-checkin-floater-message, #div-checkout-floater-message, #div-version-floater-message, #div-saveVSS-floater-message { position: absolute; top: 40px; left: 28px; @@ -442,7 +443,7 @@ body { text-align: right; } -#div-checkin-floater-content,#div-checkout-floater-content { +#div-checkin-floater-content, #div-checkout-floater-content { margin: 8px; border: Gray 1px dashed; width: 550px; @@ -459,13 +460,13 @@ body { font-weight: bold; } -#floaterEditAFloater .radio-list label{ +#floaterEditAFloater .radio-list label { float: left; - margin:0 10px 0 4px; + margin: 0 10px 0 4px; cursor: pointer; } -#floaterEditAFloater .radio-list input{ +#floaterEditAFloater .radio-list input { float: left; } @@ -488,13 +489,13 @@ body { font-weight: bold; } -#div-saveVSS-floater-content .radio-list label{ +#div-saveVSS-floater-content .radio-list label { float: left; - margin:0 10px 0 4px; + margin: 0 10px 0 4px; cursor: pointer; } -#div-saveVSS-floater-content .radio-list input{ +#div-saveVSS-floater-content .radio-list input { float: left; } @@ -513,13 +514,14 @@ body { } #div-control-panel .btn { - margin-left:5px; + margin-left: 5px; } .td-param { border: white 1px solid; border-collapse: collapse; - height: 28px; padding-left: 5px; + height: 28px; + padding-left: 5px; } .table-a { @@ -537,7 +539,6 @@ body { margin: 8px; } - .param-level-0 { background-color: #b8def5; } @@ -572,13 +573,13 @@ body { .td-param .edit-input, .tab input { background: none; - margin:0; - font-style:italic; + margin: 0; + font-style: italic; } .tab input { - height:22px; - font-size:12px; + height: 22px; + font-size: 12px; } .item { @@ -587,9 +588,10 @@ body { } .item b { - display: inline-block; - width: 60px; + display: inline-block; + width: 60px; } + .select-dataType { background-color: #E6E6E6; border: none; @@ -677,24 +679,29 @@ body { } .ec-tree > .edit-link, .ec-tree > .del-link { - visibility: hidden; + visibility: hidden; } + .ec-tree:hover > .edit-link, .ec-tree:hover > .del-link { - visibility: visible; + visibility: visible; } + .div-op-container .del-link { - margin-left: 2px; + margin-left: 2px; } + .div-op-container .del-link i { - color: #d9534f; + color: #d9534f; } + .div-op-container .add-link i { - color: #5cb85c; + color: #5cb85c; } .div-op-container .del-link, .div-op-container .add-link { - margin-top: 0; + margin-top: 0; } + .div-add-param-link { margin-left: 12px; } @@ -714,59 +721,67 @@ body { } #div-workspace-search .glyphicon-search { - position: absolute; right: 8px; top: 10px; color: #999; + position: absolute; + right: 8px; + top: 10px; + color: #999; } #dropdown-workspace-search .dropdown-menu { - min-width: 300px; max-width: 687px; + min-width: 300px; + max-width: 687px; } #dropdown-workspace-search .dropdown-menu li a { - overflow: hidden; text-overflow: ellipsis; white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; } #pluginCodeInput { - display: block; - width: 100%; - height: 34px; - padding: 6px 12px; - font-size: 14px; - line-height: 1.42857143; - color: #555; - background-color: #fff; - background-image: none; - border: 1px solid #ccc; - border-radius: 4px; - -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075); - box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075); - -webkit-transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s; - transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s; + display: block; + width: 100%; + height: 34px; + padding: 6px 12px; + font-size: 14px; + line-height: 1.42857143; + color: #555; + background-color: #fff; + background-image: none; + border: 1px solid #ccc; + border-radius: 4px; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075); + -webkit-transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s; + transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s; } .table-version { - margin: 0 auto; + margin: 0 auto; } .myfloater textarea, .myfloater input[type=text], .myfloater input[type=password] { - border: 1px solid #DDD; - border-radius: 2px; - padding: 5px; - outline: none; + border: 1px solid #DDD; + border-radius: 2px; + padding: 5px; + outline: none; } + .myfloater textarea { - margin-top: 2px; - resize: none; + margin-top: 2px; + resize: none; } + #floaterEditAFloater input[type=text], #floaterEditAFloater input[type=password] { - margin-top: 3px; - margin-bottom: 3px; + margin-top: 3px; + margin-bottom: 3px; } #floaterEditAFloater .radio-list { - padding-top: 5px; - padding-bottom: 5px; + padding-top: 5px; + padding-bottom: 5px; } .glyphicon-remove { color:#d9534f -} \ No newline at end of file +} diff --git a/src/main/webapp/workspace/myWorkspace.vm b/src/main/webapp/workspace/myWorkspace.vm new file mode 100644 index 000000000..1d2291441 --- /dev/null +++ b/src/main/webapp/workspace/myWorkspace.vm @@ -0,0 +1,570 @@ + + #parse('/tcom/template.rap.vm') + + + + loading... + + #includeNewRapStatic + + + + + + +#bodyNewStart +
      +
      + + + +
      +
      + + +
      +
      +
      +
      + + Loading workspace... Please wait... +
      +
      +
      +
      +#bodyEnd + + +#startFloater("saveVSSFloater" "" 500 380) +
      + +
      + + + + + + + + + + + + + + + + + +
      推进版本 + + + + + + + + +
      变化预览: +
      +
      提交描述:
      + + +
      +
      +
      +#endFloater + +#startFloater("versionFloater" "" 600 400) +
      + +
      +
      + +     + +     + +
      +
      +#endFloater + + #startFloater("editAFloater" "编辑接口" 600 300) +
      +
      + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      名称 + +
      请求类型 + + + + + + + + +
      请求链接 + +
      回跳模板 + +
      说明 + +
      返回格式 + + + + +
      +
      + + +
      +
      +
      +#endFloater + +#startFloater("editPFloater" "编辑页面" 600 400) +
      +
      + + + + + + + + + + + + +
      名称 + +
      说明 + +
      +
      + + +
      +
      +
      +#endFloater + +#startFloater("importJSONFloater" "JSON导入" 600 350) +
      + +
      + + + + +
      + +
      +
      + + +
      +
      +
      +#endFloater + +#startFloater("exportRAPDataFloater" "JSON导入" 600 350) +
      +
      + + + + +
      + +
      +
      + +
      +
      +
      +#endFloater + +#startFloater("pluginCodeFloater" "FE工具箱" 600 230) +
      +
      +
      插件代码
      +
      + +
      +
      项目路由
      +
      + +
      +
      + + +
      +
      +
      + +
      +
      +#endFloater + +#startFloater("actionUrlFloater" "请求链接" 600 180) +
      +
      +
      + +
      +
      + +
      +
      +
      +#endFloater + +#startFloater("mockDataPreviewFloater" "Mock数据预览" 600 600) +
      +
      +
      Mock规则 + +
      + +
      +
      +
      Mock数据 + + + +
      + +
      +
      + +
      +
      +#endFloater + +#startFloater("actionOpFloater" "文档操作" 600 230) +
      +
      +
      + + +
      + + + +
      +
      +
      + +
        +
      • + +
      • +
      • + +
      • +
      +
      +
      + + +
      +
      +
      +#endFloater + + + + diff --git a/src/org/apache/struts2/views/velocity/RapVelocityResult.java b/src/org/apache/struts2/views/velocity/RapVelocityResult.java deleted file mode 100644 index fde48b00c..000000000 --- a/src/org/apache/struts2/views/velocity/RapVelocityResult.java +++ /dev/null @@ -1,17 +0,0 @@ -package org.apache.struts2.views.velocity; - -import org.apache.struts2.dispatcher.VelocityResult; - -public class RapVelocityResult extends VelocityResult { - - private static final long serialVersionUID = 1468647758035361308L; - private String contentType = "text/html"; - - public void setContentType(String contentType) { - this.contentType = contentType; - } - - protected String getContentType(String templateLocation) { - return contentType; - } - } diff --git a/src/resource/export.vm b/src/resource/export.vm deleted file mode 100644 index 7fa47f0b1..000000000 --- a/src/resource/export.vm +++ /dev/null @@ -1,64 +0,0 @@ - - - - - - - - -
      - #foreach($module in $project.moduleListOrdered) - #set($moduleNo = $velocityCount) -
      -

      $moduleNo $module.name

      - #foreach($page in $module.pageListOrdered) - #set($pageNo = $velocityCount) -
      -

      $moduleNo.$pageNo $page.name

      - #foreach($action in $page.actionListOrdered) - #set($actionNo = $velocityCount) -
      -

      $moduleNo.$pageNo.$actionNo $action.name

      -

      Description

      -
      $action.description
      -

      URL

      -
      $action.requestUrl
      -

      Request Param List

      - $action.requestParameterListHTML -

      Response Param List

      - $action.responseParameterListHTML -
      - #end -
      - #end -
      - #end -
      - - diff --git a/src/struts.xml b/src/struts.xml deleted file mode 100644 index f6ea2a8b8..000000000 --- a/src/struts.xml +++ /dev/null @@ -1,72 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - true - ERROR - - - - - - - /account/login.vm - /error.vm - /error.vm - /bcom/jsonError.cb.vm - /error.vm - /common/redirect.vm - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -