Mercurial > hg > NetworkVis
changeset 12:d67c5ad47709
implementation with dropdown popup, unfinished
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/popoto_dev/LICENSE.txt Fri Oct 02 01:08:46 2015 -0400 @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/> + 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 <http://www.gnu.org/licenses/>. + +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: + + <program> Copyright (C) <year> <name of author> + 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 +<http://www.gnu.org/licenses/>. + + 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 +<http://www.gnu.org/philosophy/why-not-lgpl.html>. \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/popoto_dev/css/font/asap/SIL Open Font License.txt Fri Oct 02 01:08:46 2015 -0400 @@ -0,0 +1,44 @@ +Copyright (c) 2011, Omnibus-Type (www.omnibus-type.com|omnibus.type@gmail.com), +with Reserved Font Name "Asap". + +This Font Software is licensed under the SIL Open Font License, Version 1.1. +This license is copied below, and is also available with a FAQ at: http://scripts.sil.org/OFL + +----------------------------------------------------------- +SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 +----------------------------------------------------------- + +PREAMBLE +The goals of the Open Font License (OFL) are to stimulate worldwide development of collaborative font projects, to support the font creation efforts of academic and linguistic communities, and to provide a free and open framework in which fonts may be shared and improved in partnership with others. + +The OFL allows the licensed fonts to be used, studied, modified and redistributed freely as long as they are not sold by themselves. The fonts, including any derivative works, can be bundled, embedded, redistributed and/or sold with any software provided that any reserved names are not used by derivative works. The fonts and derivatives, however, cannot be released under any other type of license. The requirement for fonts to remain under this license does not apply to any document created using the fonts or their derivatives. + +DEFINITIONS +"Font Software" refers to the set of files released by the Copyright Holder(s) under this license and clearly marked as such. This may include source files, build scripts and documentation. + +"Reserved Font Name" refers to any names specified as such after the copyright statement(s). + +"Original Version" refers to the collection of Font Software components as distributed by the Copyright Holder(s). + +"Modified Version" refers to any derivative made by adding to, deleting, or substituting -- in part or in whole -- any of the components of the Original Version, by changing formats or by porting the Font Software to a new environment. + +"Author" refers to any designer, engineer, programmer, technical writer or other person who contributed to the Font Software. + +PERMISSION & CONDITIONS +Permission is hereby granted, free of charge, to any person obtaining a copy of the Font Software, to use, study, copy, merge, embed, modify, redistribute, and sell modified and unmodified copies of the Font Software, subject to the following conditions: + +1) Neither the Font Software nor any of its individual components, in Original or Modified Versions, may be sold by itself. + +2) Original or Modified Versions of the Font Software may be bundled, redistributed and/or sold with any software, provided that each copy contains the above copyright notice and this license. These can be included either as stand-alone text files, human-readable headers or in the appropriate machine-readable metadata fields within text or binary files as long as those fields can be easily viewed by the user. + +3) No Modified Version of the Font Software may use the Reserved Font Name(s) unless explicit written permission is granted by the corresponding Copyright Holder. This restriction only applies to the primary font name as presented to the users. + +4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font Software shall not be used to promote, endorse or advertise any Modified Version, except to acknowledge the contribution(s) of the Copyright Holder(s) and the Author(s) or with their explicit written permission. + +5) The Font Software, modified or unmodified, in part or in whole, must be distributed entirely under this license, and must not be distributed under any other license. The requirement for fonts to remain under this license does not apply to any document created using the Font Software. + +TERMINATION +This license becomes null and void if any of the above conditions are not met. + +DISCLAIMER +THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM OTHER DEALINGS IN THE FONT SOFTWARE. \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/popoto_dev/css/popoto.min.css Fri Oct 02 01:08:46 2015 -0400 @@ -0,0 +1,1 @@ +@font-face{font-family:"Asap";src:url("font/asap/Asap-Regular.otf")}@font-face{font-family:"Asap";src:url("font/asap/Asap-Bold.otf");font-weight:bold}@font-face{font-family:"Asap";src:url("font/asap/Asap-Italic.otf");font-style:italic}@font-face{font-family:"Asap";src:url("font/asap/Asap-BoldItalic.otf");font-weight:bold;font-style:italic}.ppt-body{background-color:#2e3138;margin:22px;font-family:Asap,sans-serif;color:#fff}.ppt-container-graph{background-color:#22252a;height:750px;padding:0;border-bottom-right-radius:5px 5px;border-bottom-left-radius:5px 5px;overflow:hidden}.ppt-taxo-nav{overflow:auto;padding:18px 35px 18px 18px;background-color:#444951;height:100%;float:left;white-space:nowrap}.ppt-taxo-nav.disabled{display:none}.ppt-taxo-nav ul{list-style-type:none;display:block;vertical-align:top;padding:0 0 0 10px;margin:0}.ppt-taxo-nav li img{vertical-align:middle}.ppt-div-graph{position:relative;background-color:#22252a;height:100%;padding:0;border-bottom-right-radius:5px 5px;overflow:hidden}.ppt-div-graph:-webkit-full-screen,.ppt-div-graph:fullscreen{width:100%;height:100%}.ppt-header{padding-left:16px;padding-right:16px;background-color:#525863;border-radius:5px 5px;height:70px;min-width:560px;line-height:70px;font-weight:bold;font-size:22px}.ppt-section-header{min-width:560px;padding-left:18px;padding-right:18px;background-color:#525863;height:68px;line-height:67px;margin-top:22px;border-top-right-radius:5px 5px;border-top-left-radius:5px 5px;font-weight:bold}.ppt-section-tips{min-width:560px;padding-left:18px;padding-right:18px;background-color:#525863;margin-top:22px;border-top-left-radius:5px;border-top-right-radius:5px;font-size:14px;line-height:35px}.ppt-section-tips a{color:#8bb71a}.ppt-section-tips p{margin-bottom:0;margin-top:0}.ppt-toolbar{padding:12px;position:absolute;right:0}.ppt-header-span{color:#8bb71a}.ppt-container-query,.ppt-container-cypher{text-align:center;margin-top:22px;min-width:560px;background-color:#22252a;border-radius:5px 5px;padding:18px}.ppt-container-results{width:100%;float:left;min-width:300px;background-color:#22252a;padding:0;border-bottom-right-radius:5px 5px;border-bottom-left-radius:5px 5px;overflow:auto}.ppt-footer{padding-left:16px;padding-right:16px;background-color:#525863;border-radius:5px 5px;height:70px;min-width:560px;line-height:70px;font-weight:bold;font-size:22px}.ppt-menu{width:32px;height:32px;display:inline-block;vertical-align:middle;cursor:pointer;margin-left:12px;background:url("image/tools.png") no-repeat 0 0}.ppt-menu.taxonomy{background-position:0 0}.ppt-menu.reset{background-position:-288px 0}.ppt-menu.fullscreen{background-position:-256px 0}.ppt-menu.center{background-position:-96px 0}.ppt-menu.taxonomy:hover{background-position:0 -32px}.ppt-menu.reset:hover{background-position:-288px -32px}.ppt-menu.fullscreen:hover{background-position:-256px -32px}.ppt-menu.center:hover{background-position:-96px -32px}.ppt-count{cursor:pointer;color:#2aa1d3}.ppt-label{cursor:pointer}.ppt-label:hover{color:#f0b017}.ppt-result{background-color:#444951;padding:9px 18px;margin:1px 0 0}.ppt-result:hover{background-color:#525863}.ppt-result-table th,td{text-align:left}.ppt-span,.ppt-span-link{color:#fff}.ppt-span-root{color:#2aa1d3;cursor:pointer}.ppt-span-choose{color:#8bb71a;cursor:pointer}.ppt-span-group{color:#8e8e8e;cursor:pointer}.ppt-span-value{color:#f0b017;cursor:pointer}.ppt-span-link.hover,.ppt-span-root.hover,.ppt-span-choose.hover,.ppt-span-group.hover,.ppt-span-value.hover{color:#ee4e10;font-weight:bold}.ppt-svg-graph{cursor:move;min-height:100px;width:100%;height:100%;pointer-events:all}.ppt-node-ellipse{stroke:#fff;stroke-width:4px}.ppt-node-ellipse.root{fill:#2aa1d3}.ppt-node-ellipse.root.disabled{fill:#2e3138;stroke:#525863}.ppt-node-ellipse.choose{fill:#8bb71a}.ppt-node-ellipse.choose.disabled{fill:#2e3138;stroke:#525863}.ppt-node-ellipse.value{fill:#f0b017}.ppt-node-ellipse.selected-value{fill:#ee4e10}.ppt-node-ellipse.selected-root-value{fill:#8f5bcc}.ppt-node-ellipse.group{fill:#525863}.ppt-node-ellipse.disabled{fill:#2e3138;stroke:#525863}.ppt-g-node-background{cursor:pointer}.ppt-node-background-circle{fill-opacity:0}.ppt-node-background-circle.root{fill:#233e7e}.ppt-node-background-circle.choose{fill:#628b1a}.ppt-node-background-circle.value{fill:#c28a17}.ppt-node-background-circle.selected-value{fill:#c24b30}.ppt-node-background-circle.selected-root-value{fill:#765ab4}.ppt-node-background-circle.group,.ppt-node-background-circle.disabled{fill:#3f4450}.ppt-g-node-middleground,.ppt-g-node-foreground{cursor:pointer}.ppt-count-box.value{fill:#8bb71a;stroke:#fff;stroke-width:2px}.ppt-count-box.root{fill:#ee4e10;stroke:#fff;stroke-width:2px}.ppt-count-box.root.disabled,.ppt-count-box.value.disabled{fill:#2e3138;stroke:#525863}.ppt-count-text{fill:white}.ppt-count-text.disabled{fill:#525863}.ppt-rel-plus-icon.disabled{display:none}.ppt-rel-plus-background{fill:#f0b017;fill-opacity:0}.ppt-rel-plus-path{fill:#f00}.ppt-rel-minus-icon.disabled{display:none}.ppt-rel-minus-path{fill:#f00}.ppt-rel-minus-background{fill:#f0b017;fill-opacity:0}.ppt-node-foreground-g-arrows{display:none}.ppt-node-foreground-g-arrows.active{display:block}.ppt-arrow{fill:#fff}.ppt-larrow,.ppt-rarrow{stroke:#fff;stroke-width:4px;fill:#525863}.ppt-larrow.enabled,.ppt-rarrow.enabled{fill:#2aa1d3}.ppt-link-relation{stroke:#2aa1d3;stroke-width:2px;stroke-dasharray:9,5}.ppt-link-relation.value,.ppt-link-relation.value.ppt-link-hover{stroke:#ee4e10}.ppt-link-relation.disabled{stroke:#2e3138;stroke-width:2px;stroke-dasharray:9,5}.ppt-link-value{stroke:#525863;stroke-width:2px;stroke-dasharray:9,5}.ppt-link-hover{stroke:#ee4e10}.ppt-link-text-relation,.ppt-link-text-relation.value{fill:#fff}.ppt-link-text-relation.disabled,.ppt-link-text-value{fill:#525863}.ppt-node-text-root{fill:#fff}.ppt-node-text-root.disabled{fill:#525863}.ppt-node-text-choose{fill:#fff}.ppt-node-text-choose.disabled{fill:#525863}.ppt-node-text-value,.ppt-node-text-group{fill:#fff} \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/popoto_dev/index.html Fri Oct 02 01:08:46 2015 -0400 @@ -0,0 +1,61 @@ +<!DOCTYPE html> +<html> + +<head> + <meta http-equiv="Content-Type" content="text/html" charset="UTF-8"> + <title>Popoto Search</title> + <link rel="stylesheet" href="css/popoto.min.css"> +</head> +<body class="ppt-body"> + +<header class="ppt-header"> + <span class="ppt-header-span">POPOTO JS alpha version</span> +</header> + +<section class="ppt-section-main"> + <div class="ppt-section-header"> + <span class="ppt-header-span">Graph</span> search + </div> + + <div class="ppt-container-graph"> + <nav id="popoto-taxonomy" class="ppt-taxo-nav"> + <!-- Label/taxonomy filter will be generated here --> + </nav> + <div id="popoto-graph" class="ppt-div-graph"> + <!-- Graph will be generated here--> + </div> + </div> + + <div id="popoto-query" class="ppt-container-query"> + <!-- Query viewer will be generated here --> + </div> + + <!-- Cypher query viewer has been partially disabled for this alpha release and only display the query as text if enabled --> + <!--<div id="popoto-cypher" class="ppt-container-cypher">--> + <!--</div>--> + + <div class="ppt-section-header"> + <!-- The total results count is updated with a listener defined in app-template.js --> + RESULTS <span id="result-total-count" class="ppt-count"></span> + </div> + + <div id="popoto-results" class="ppt-container-results"> + <!-- Results will be generated here --> + </div> + +</section> + +<!----------------------> +<!-- Required scripts --> + +<!-- Jquery is only used in popoto.js to send ajax POST request on Neo4j REST API --> +<!-- This dependency will probably be removed in future releases --> +<script src="js/jquery-2.1.0.min.js" charset="utf-8"></script> + +<script src="js/d3.v3.min.js" charset="utf-8"></script> +<script src="js/popoto.min.js" charset="utf-8"></script> + +<!-- You can modify the parameters defined in this script to customize this application template --> +<script src="js/app-template.js" charset="utf-8"></script> +</body> +</html>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/popoto_dev/ismi.html Fri Oct 02 01:08:46 2015 -0400 @@ -0,0 +1,126 @@ +<!DOCTYPE html> +<html> + +<head> + <meta http-equiv="Content-Type" content="text/html" charset="UTF-8"> + <title>Popoto Search</title> + <link rel="stylesheet" href="css/popoto.min.css"> +</head> +<body class="ppt-body"> + +<header class="ppt-header"> + <span class="ppt-header-span">POPOTO JS alpha version</span> +</header> + +<section class="ppt-section-main"> + <div class="ppt-section-header" style="height: auto; line-height: 35px;"> + <span class="ppt-header-span">Graph</span> search + <form> + <table width="100%"> + <tr> + <th>Person Constraints</th> + <th>Codex Constraints</th> + <th>Witness Constraints</th> + </tr> + <tr> + <td> + <label> + <input id="person-constraint" type="text" style="width: 90%;" value='$identifier.label IN [""]'> + </label> + </td> + <td> + <label> + <input id="codex-constraint" type="text" style="width: 90%;" value='$identifier.label IN [""]'> + </label> + </td> + <td> + <label> + <input id="witness-constraint" type="text" style="width: 90%;" value='$identifier.label IN [""]'> + </label> + </td> + </tr> + <tr> + <td> + <label> + <input id="person-constraint2" type="text" style="width: 90%;" value='$identifier.label IN [""]'> + </label> + </td> + <td> + <label> + <input id="codex-constraint2" type="text" style="width: 90%;" value='$identifier.label IN [""]'> + </label> + </td> + <td> + <label> + <input id="witness-constraint2" type="text" style="width: 90%;" value='$identifier.label IN [""]'> + </label> + </td> + </tr> + </table> + <!-- fill labels conditionally and have a single filter button with one id--> + <input id="filter-button" type="button" value="Use these filters"> + <input id="clear-button" type="button" value="Reset"> + <!-- + use: + clickedNode.data = popoto.graph.node.parseResultData(data); + to get data to use in drop down boxes + where: + popoto.graph.node.nodeClick = function () { + has var: + var clickedNode = d3.select(this).data()[0]; // Clicked node data + + note: could just do that for all [i] if not null + should test to see whether the .data returns the attribute type or the actual attribute + just console.log results array in popoto.graph.node.parseResultData + --> + </form> + + <select id="dropdown" name="select12" style="visibility: hidden; overflow: scroll; position: fixed;"> + <option>- Select -</option> + </select> + + </div> + + <div class="ppt-container-graph"> + <nav id="popoto-taxonomy" class="ppt-taxo-nav"> + <!-- Label/taxonomy filter will be generated here --> + </nav> + <div id="popoto-graph" class="ppt-div-graph"> + <!-- Graph will be generated here--> + </div> + </div> + + <div id="popoto-query" class="ppt-container-query"> + <!-- Query viewer will be generated here --> + </div> + + <!-- Cypher query viewer has been partially disabled for this alpha release and only display the query as text if enabled --> + <!--<div id="popoto-cypher" class="ppt-container-cypher">--> + <!--</div>--> + + <div class="ppt-section-header"> + <!-- The total results count is updated with a listener defined in app-template.js --> + RESULTS <span id="result-total-count" class="ppt-count"></span> + </div> + + <div id="popoto-results" class="ppt-container-results"> + <!-- Results will be generated here --> + </div> + +</section> + +<!----------------------> +<!-- Required scripts --> + +<!-- Jquery is only used in popoto.js to send ajax POST request on Neo4j REST API --> +<!-- This dependency will probably be removed in future releases --> +<script src="js/jquery-2.1.0.min.js" charset="utf-8"></script> + +<script src="js/d3.v3.min.js" charset="utf-8"></script> +<!-- <script src="js/popoto.min.js" charset="utf-8"></script> --> +<script src="src/js/popoto.js" charset="utf-8"></script> + +<!-- You can modify the parameters defined in this script to customize this application template --> +<script src="js/app-ismi.js" charset="utf-8"></script> +</body> +</html>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/popoto_dev/js/LICENSES.txt Fri Oct 02 01:08:46 2015 -0400 @@ -0,0 +1,29 @@ + +d3.v3.min.js licence: + +Copyright (c) 2010-2014, Michael Bostock +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +* The name Michael Bostock may not be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL MICHAEL BOSTOCK BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/popoto_dev/js/app-ismi.js Fri Oct 02 01:08:46 2015 -0400 @@ -0,0 +1,401 @@ +/** + * URL used to access Neo4j REST API to execute queries. + * Update this parameter to your running server instance. + * + * For more information on Neo4J REST API the documentation is available here: http://neo4j.com/docs/stable/rest-api-cypher.html + */ +popoto.rest.CYPHER_URL = "https://ismi-dev.mpiwg-berlin.mpg.de/neo4j-ismi/db/data/transaction/commit"; +//popoto.rest.CYPHER_URL = "http://localhost:7474/db/data/transaction/commit"; + +/** + * Add this authorization property if your Neo4j server uses basic HTTP authentication. + * The value of this property must be "Basic <payload>", where "payload" is a base64 encoded string of "username:password". + * + * "btoa" is a JavaScript function that can be used to encode the user and password value in base64 but it is recommended to directly use the Base64 value. + * + * For example Base64 encoding value of "neo4j:password" is "bmVvNGo6cGFzc3dvcmQ=" + */ +popoto.rest.AUTHORIZATION = "Basic " + btoa("neo4j:neo5j"); +//popoto.rest.AUTHORIZATION = "Basic " + btoa("neo4j:eagrussell"); + +/** + * These functions fill the predefinedConstraints array for "PERSON" + * Called when the filter button is hit + * + * Uses the text box implementation currently + */ + // TODO: finish textbox implementation as backup + // have single filter button which on click sets constraints equal to d3.select("#constraintNUMBS)[0][0].value + // for a bunch of spots in the array + // will have to create only 1 d3.select + // the d3.select will need to know what constraints to pull from input boxes based on ids related to whether they + // are person/codex/witness/etc attributes and put them into the corresponding arrays + // personPredefinedConstraints codexPreDef +var personPredefinedConstraints = []; +var codexPredefinedConstraints = []; +var witnessPredefinedConstraints = []; +d3.select("#filter-button").on("click", function (d) { + personPredefinedConstraints = []; + codexPredefinedConstraints = []; + witnessPredefinedConstraints = []; + + var person1 = d3.select("#person-constraint")[0][0].value; + var person2 = d3.select("#person-constraint2")[0][0].value; + + var codex1 = d3.select("#codex-constraint")[0][0].value; + var codex2 = d3.select("#codex-constraint2")[0][0].value; + + var witness1 = d3.select("#witness-constraint")[0][0].value; + var witness2 = d3.select("#witness-constraint2")[0][0].value; + + if (person1.substring(person1.indexOf('"')+1,person1.lastIndexOf('"'))) personPredefinedConstraints.push(person1); + if (person2.substring(person2.indexOf('"')+1,person2.lastIndexOf('"'))) personPredefinedConstraints.push(person2); + + if (codex1.substring(codex1.indexOf('"')+1,codex1.lastIndexOf('"'))) codexPredefinedConstraints.push(codex1); + if (codex2.substring(codex2.indexOf('"')+1,codex2.lastIndexOf('"'))) codexPredefinedConstraints.push(codex2); + + if (witness1.substring(witness1.indexOf('"')+1,witness1.lastIndexOf('"'))) witnessPredefinedConstraints.push(witness1); + if (witness2.substring(witness2.indexOf('"')+1,witness2.lastIndexOf('"'))) witnessPredefinedConstraints.push(witness2); + + // Recreate taxonomies panel + d3.select("#" + popoto.taxonomy.containerId).selectAll("ul").data([]).exit().remove(); + popoto.taxonomy.createTaxonomyPanel(); + + popoto.tools.reset(); +}); + +d3.select("#clear-button").on("click", function (d) { + personPredefinedConstraints = []; + codexPredefinedConstraints = []; + witnessPredefinedConstraints = []; + + // Recreate taxonomies panel + d3.select("#" + popoto.taxonomy.containerId).selectAll("ul").data([]).exit().remove(); + popoto.taxonomy.createTaxonomyPanel(); + + popoto.tools.reset(); +}); + + +/** + * Define the Label provider you need for your application. + * This configuration is mandatory and should contain at least all the labels you could find in your graph model. + * + * In this alpha version only nodes with a label are supported. + * + * By default If no attributes are specified Neo4j internal ID will be used. + * These label provider configuration can be used to customize the node display in the graph. + * See www.popotojs.com or example for more details on available configuration options. + */ +// TODO: add in predefined constraint functions for other nodeProviders +popoto.provider.nodeProviders = { + "CODEX": { + "returnAttributes": ["label", "ismi_id", "identifier"], + "displayAttribute": "label", + "getPredefinedConstraints": function (node) { + return codexPredefinedConstraints; + }, + }, + "WITNESS": { + "returnAttributes": ["label", "ismi_id", "folios"], + "displayAttribute": "label", + "getPredefinedConstraints": function (node) { + return witnessPredefinedConstraints; + }, + }, + "TEXT": { + "returnAttributes": ["label", "full_title", "ismi_id"], + "displayAttribute": "label", + //"getPredefinedConstraints": function (node) { + // return textPredefinedConstraints; + //}, + }, + "PERSON": { + "returnAttributes": ["label", "ismi_id", "death_date_text", "url"], + "displayAttribute": "label", + "getPredefinedConstraints": function (node) { + return personPredefinedConstraints; + }, + }, + "REPOSITORY": { + "returnAttributes": ["label", "ismi_id"], + "displayAttribute": "label", + //"getPredefinedConstraints": function (node) { + // return repositoryPredefinedConstraints; + //}, + }, + "FLORUIT_DATE": { + "isSearchable": false, + //"getPredefinedConstraints": function (node) { + // return floruitPredefinedConstraints; + //}, + } +}; + +/** + * Popoto label provider + * Define the label provider used to customize the link displayed text: + */ +// TODO: ensure these cover all the different relations. Commented out for now. +/* +popoto.provider.linkProvider = { + + // Customize the text displayed on links: + "getLinkTextValue": function (link) { + + // The links labels are just changed in lower case in this example. + // But it is possible to use a localization mechanism here to replace values. + if (link.type === popoto.graph.link.LinkTypes.RELATION) { + + if (link.source.label == "PERSON") { + switch (link.label) { + case "was_student_of": + return "was student of"; + case "is_prime_alias_name_of": + return "is prime alias name of"; + case "was_born_in": + return "was born in"; + case "lived_in": + return "lived in"; + case "has_role": + return "has role"; + case "has_floruit_date": + return "has floruit date"; + case "died_in": + return "died in"; + default : + return "" + } + } + if (link.source.label == "CODEX") { + switch (link.label) { + case "owned_by": + return "owned by"; + case "is_alias_of": + return "is alias of"; + case "is_part_of": + return "is part of"; + } + } + if (link.source.label == "WITNESS") { + switch (link.label) { + case "was_copied_in": + return "was copied in"; + case "was_studied_by": + return "was studied by"; + case "had_patron": + return "had patron"; + case "is_part_of": + return "is part of"; + case "is_exemplar_of": + return "is exemplar of"; + case "has_title_written_as": + return "has title written as"; + case "has_author_written_as": + return "as author written as"; + case "was_copied_by": + return "was copied by"; + } + } + if (link.source.label == "PLACE") { + switch (link.label) { + case "is_part_of": + return "is part of"; + case "is_in": + return "is in"; + } + } + } else { + return popoto.provider.getSemanticValue(link.target); + } + } + +}; +*/ + + + + + + + +//d3.select("#clear-button").on("click", function (d) { +// popoto.graph.node.expandNode() +//}); + +//take d3.select of any click that calls popoto.graph.node.expandNode() +// make sure to search in popoto.js what kind of events trigger the expandNode fn +// +// on these events, instead of executing the normal expandNode function, call a modified function that will generate an +// html table with the required results. Still maintaining the info being sent to results but ensuring that what is +// displayed is thrown into a table. + +// to override the popoto.graph.node.expandNode() fn just use: + +// Expand Override +var tableArray = []; +(function() { + var oldVersionExpand = popoto.graph.node.expandNode; + popoto.graph.node.expandNode = function(clickedNode) { + console.log("NODES OPEN"); + //var result = oldVersionExpand.apply(this, arguments); + // do some more stuff + //return result; + + var dataToAdd = clickedNode.data; + // Then each node is created + var i = 1; + dataToAdd.forEach(function (d) { + // for each of these bits of data make sure to add the id and the attributes into the html list + var nx = clickedNode.x; + var ny = clickedNode.y; + + var node = { + "id": (++popoto.graph.node.idgen), + "parent": clickedNode, + "attributes": d, + "type": popoto.graph.node.NodeTypes.VALUE, + "label": clickedNode.label, + "count": d.count, + "x": nx, + "y": ny, + "internalID": d[popoto.query.NEO4J_INTERNAL_ID.queryInternalName] + }; + + popoto.graph.force.nodes().push(node); + // add this node to an array of node values + // popoto.graph.force.nodes().push(node); + tableArray.push(node); + + var dd = document.getElementById("dropdown"); + var newListOption = document.createElement("option"); + + // TODO: Haven't been able to + newListOption.text = node.internalID; + console.log(node.internalID); + dd.add(newListOption); + + i++; + }); + + $('#dropdown').attr('style','visibility: visible; overflow: scroll; position: fixed; left: '+clickedNode.x+'px; bottom: '+clickedNode.y+'px; z-index: 10;'); + //$('#dropdown').attr('style','visibility: visible; overflow: scroll; position: fixed;'); + + // Pin clicked node and its parent to avoid the graph to move for selection, only new value nodes will blossom around the clicked node. + clickedNode.fixed = true; + + if (clickedNode.parent && clickedNode.parent.type !== popoto.graph.node.NodeTypes.ROOT) { + clickedNode.parent.fixed = true; + } + // Change node state + clickedNode.valueExpanded = true; + popoto.update(); + + }; +})(); + +// Collapse Override +(function() { + popoto.graph.node.collapseNode = function(clickedNode) { + + if (clickedNode.valueExpanded) { // node is collapsed only if it has been expanded first + console.log("NODES CLOSED"); + + popoto.logger.debug("collapseNode (" + clickedNode.label + ")"); + + // Node has been fixed when expanded so we unfix it back here. + if (clickedNode.type !== popoto.graph.node.NodeTypes.ROOT) { + clickedNode.fixed = false; + } + + // Parent node too if not root + if (clickedNode.parent && clickedNode.parent.type !== popoto.graph.node.NodeTypes.ROOT) { + clickedNode.parent.fixed = false; + } + + clickedNode.valueExpanded = false; + popoto.update(); + + $('#dropdown').attr('style','visibility: hidden; overflow: scroll; position: fixed;'); + //TODO: need to delete existing options + var x = document.getElementById("dropdown"); + for (i=x.length; i > 0; i--) { + if (x.length > 1) { + x.remove(x.length-1); + } + } + + } else { + popoto.logger.debug("collapseNode called on an unexpanded node"); + } + }; +})(); + + +d3.select("#dropdown").on("change", function (d) { + if (document.getElementById('dropdown').value != '- Select -') { + console.log(document.getElementById('dropdown').value); + popoto.graph.node.valueNodeClick(document.getElementById('dropdown').value); + } +}); +// Value click override +(function() { + popoto.graph.node.valueNodeClick = function(selectValue) { + console.log("NODE SELECTED"); + + popoto.logger.debug("valueNodeClick (" + selectValue.label + ")"); + // change this next line to take the node id from the table and pull it from the nodes list + + var clickedNode; + for (i in tableArray) { + if (i.label == selectValue) { + clickedNode = i; + } + } + + clickedNode.parent.value = clickedNode; + popoto.result.hasChanged = true; + popoto.graph.hasGraphChanged = true; + + popoto.graph.node.collapseNode(clickedNode.parent); + }; +})(); + + +/** + * Here a listener is used to retrieve the total results count and update the page accordingly. + * This listener will be called on every graph modification. + */ +popoto.result.onTotalResultCount(function (count) { + document.getElementById("result-total-count").innerHTML = "(" + count + ")"; +}); + +/** + * The number of results returned can be changed with the following parameter. + * Default value is 100. + * + * Note that in this current alpha version no pagination mechanism is available in displayed results + */ +popoto.query.RESULTS_PAGE_SIZE = 1000; + + +/** + * For the alpha version, popoto.js has been generated with debug traces you can activate with the following properties: + * The value can be one in DEBUG, INFO, WARN, ERROR, NONE. + * + * With INFO level all the executed cypher query can be seen in the navigator console. + * Default is NONE + */ +popoto.logger.LEVEL = popoto.logger.LogLevels.INFO; + +/** + * Start popoto.js generation. + * The function requires the label to use as root element in the graph. + */ +popoto.start("PERSON"); + +/* do not zoom with scroll wheel */ +popoto.graph.WHEEL_ZOOM_ENABLED = false; + +/* show source and target relations */ +popoto.query.USE_RELATION_DIRECTION = true;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/popoto_dev/js/app-template.js Fri Oct 02 01:08:46 2015 -0400 @@ -0,0 +1,85 @@ +/** + * URL used to access Neo4j REST API to execute queries. + * Update this parameter to your running server instance. + * + * For more information on Neo4J REST API the documentation is available here: http://neo4j.com/docs/stable/rest-api-cypher.html + */ +popoto.rest.CYPHER_URL = "https://ismi-dev.mpiwg-berlin.mpg.de/neo4j-ismi/db/data/transaction/commit"; + +/** + * Add this authorization property if your Neo4j server uses basic HTTP authentication. + * The value of this property must be "Basic <payload>", where "payload" is a base64 encoded string of "username:password". + * + * "btoa" is a JavaScript function that can be used to encode the user and password value in base64 but it is recommended to directly use the Base64 value. + * + * For example Base64 encoding value of "neo4j:password" is "bmVvNGo6cGFzc3dvcmQ=" + */ +popoto.rest.AUTHORIZATION = "Basic " + btoa("neo4j:neo5j"); + +/** + * Define the Label provider you need for your application. + * This configuration is mandatory and should contain at least all the labels you could find in your graph model. + * + * In this alpha version only nodes with a label are supported. + * + * By default If no attributes are specified Neo4j internal ID will be used. + * These label provider configuration can be used to customize the node display in the graph. + * See www.popotojs.com or example for more details on available configuration options. + */ +popoto.provider.nodeProviders = { + "CODEX": { + "returnAttributes": ["label", "ismi_id", "identifier"], + "constraintAttribute": "ismi_id" + }, + "WITNESS": { + "returnAttributes": ["label", "ismi_id", "folios"], + "constraintAttribute": "ismi_id" + }, + "TEXT": { + "returnAttributes": ["label", "full_title", "ismi_id"], + "constraintAttribute": "ismi_id" + }, + "PERSON": { + "returnAttributes": ["label", "ismi_id", "death_date_text", "url"], + "constraintAttribute": "ismi_id" + }, + "REPOSITORY": { + "returnAttributes": ["label", "ismi_id"], + "constraintAttribute": "ismi_id" + } +}; + +/** + * Here a listener is used to retrieve the total results count and update the page accordingly. + * This listener will be called on every graph modification. + */ +popoto.result.onTotalResultCount(function (count) { + document.getElementById("result-total-count").innerHTML = "(" + count + ")"; +}); + +/** + * The number of results returned can be changed with the following parameter. + * Default value is 100. + * + * Note that in this current alpha version no pagination mechanism is available in displayed results + */ +//popoto.query.RESULTS_PAGE_SIZE = 100; + + +/** + * For the alpha version, popoto.js has been generated with debug traces you can activate with the following properties: + * The value can be one in DEBUG, INFO, WARN, ERROR, NONE. + * + * With INFO level all the executed cypher query can be seen in the navigator console. + * Default is NONE + */ +popoto.logger.LEVEL = popoto.logger.LogLevels.INFO; + +/** + * Start popoto.js generation. + * The function requires the label to use as root element in the graph. + */ +popoto.start("PERSON"); + +/* do not zoom with scroll wheel */ +popoto.graph.WHEEL_ZOOM_ENABLED = false;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/popoto_dev/js/d3.v3.min.js Fri Oct 02 01:08:46 2015 -0400 @@ -0,0 +1,5 @@ +d3=function(){function n(n){return null!=n&&!isNaN(n)}function t(n){return n.length}function e(n){for(var t=1;n*t%1;)t*=10;return t}function r(n,t){try{for(var e in t)Object.defineProperty(n.prototype,e,{value:t[e],enumerable:!1})}catch(r){n.prototype=t}}function u(){}function i(){}function o(n,t,e){return function(){var r=e.apply(t,arguments);return r===t?n:r}}function a(n,t){if(t in n)return t;t=t.charAt(0).toUpperCase()+t.substring(1);for(var e=0,r=fa.length;r>e;++e){var u=fa[e]+t;if(u in n)return u}}function c(){}function s(){}function l(n){function t(){for(var t,r=e,u=-1,i=r.length;++u<i;)(t=r[u].on)&&t.apply(this,arguments);return n}var e=[],r=new u;return t.on=function(t,u){var i,o=r.get(t);return arguments.length<2?o&&o.on:(o&&(o.on=null,e=e.slice(0,i=e.indexOf(o)).concat(e.slice(i+1)),r.remove(t)),u&&e.push(r.set(t,{on:u})),n)},t}function f(){Bo.event.preventDefault()}function h(){for(var n,t=Bo.event;n=t.sourceEvent;)t=n;return t}function g(n){for(var t=new s,e=0,r=arguments.length;++e<r;)t[arguments[e]]=l(t);return t.of=function(e,r){return function(u){try{var i=u.sourceEvent=Bo.event;u.target=n,Bo.event=u,t[u.type].apply(e,r)}finally{Bo.event=i}}},t}function p(n){return ga(n,ya),n}function v(n){return"function"==typeof n?n:function(){return pa(n,this)}}function d(n){return"function"==typeof n?n:function(){return va(n,this)}}function m(n,t){function e(){this.removeAttribute(n)}function r(){this.removeAttributeNS(n.space,n.local)}function u(){this.setAttribute(n,t)}function i(){this.setAttributeNS(n.space,n.local,t)}function o(){var e=t.apply(this,arguments);null==e?this.removeAttribute(n):this.setAttribute(n,e)}function a(){var e=t.apply(this,arguments);null==e?this.removeAttributeNS(n.space,n.local):this.setAttributeNS(n.space,n.local,e)}return n=Bo.ns.qualify(n),null==t?n.local?r:e:"function"==typeof t?n.local?a:o:n.local?i:u}function y(n){return n.trim().replace(/\s+/g," ")}function x(n){return new RegExp("(?:^|\\s+)"+Bo.requote(n)+"(?:\\s+|$)","g")}function M(n){return n.trim().split(/^|\s+/)}function _(n,t){function e(){for(var e=-1;++e<u;)n[e](this,t)}function r(){for(var e=-1,r=t.apply(this,arguments);++e<u;)n[e](this,r)}n=M(n).map(b);var u=n.length;return"function"==typeof t?r:e}function b(n){var t=x(n);return function(e,r){if(u=e.classList)return r?u.add(n):u.remove(n);var u=e.getAttribute("class")||"";r?(t.lastIndex=0,t.test(u)||e.setAttribute("class",y(u+" "+n))):e.setAttribute("class",y(u.replace(t," ")))}}function w(n,t,e){function r(){this.style.removeProperty(n)}function u(){this.style.setProperty(n,t,e)}function i(){var r=t.apply(this,arguments);null==r?this.style.removeProperty(n):this.style.setProperty(n,r,e)}return null==t?r:"function"==typeof t?i:u}function S(n,t){function e(){delete this[n]}function r(){this[n]=t}function u(){var e=t.apply(this,arguments);null==e?delete this[n]:this[n]=e}return null==t?e:"function"==typeof t?u:r}function k(n){return"function"==typeof n?n:(n=Bo.ns.qualify(n)).local?function(){return this.ownerDocument.createElementNS(n.space,n.local)}:function(){return this.ownerDocument.createElementNS(this.namespaceURI,n)}}function E(n){return{__data__:n}}function A(n){return function(){return ma(this,n)}}function C(n){return arguments.length||(n=Bo.ascending),function(t,e){return t&&e?n(t.__data__,e.__data__):!t-!e}}function N(n,t){for(var e=0,r=n.length;r>e;e++)for(var u,i=n[e],o=0,a=i.length;a>o;o++)(u=i[o])&&t(u,o,e);return n}function L(n){return ga(n,Ma),n}function T(n){var t,e;return function(r,u,i){var o,a=n[i].update,c=a.length;for(i!=e&&(e=i,t=0),u>=t&&(t=u+1);!(o=a[t])&&++t<c;);return o}}function q(){var n=this.__transition__;n&&++n.active}function z(n,t,e){function r(){var t=this[o];t&&(this.removeEventListener(n,t,t.$),delete this[o])}function u(){var u=s(t,Jo(arguments));r.call(this),this.addEventListener(n,this[o]=u,u.$=e),u._=t}function i(){var t,e=new RegExp("^__on([^.]+)"+Bo.requote(n)+"$");for(var r in this)if(t=r.match(e)){var u=this[r];this.removeEventListener(t[1],u,u.$),delete this[r]}}var o="__on"+n,a=n.indexOf("."),s=R;a>0&&(n=n.substring(0,a));var l=ba.get(n);return l&&(n=l,s=D),a?t?u:r:t?c:i}function R(n,t){return function(e){var r=Bo.event;Bo.event=e,t[0]=this.__data__;try{n.apply(this,t)}finally{Bo.event=r}}}function D(n,t){var e=R(n,t);return function(n){var t=this,r=n.relatedTarget;r&&(r===t||8&r.compareDocumentPosition(t))||e.call(t,n)}}function P(){var n=".dragsuppress-"+ ++Sa,t="click"+n,e=Bo.select(Qo).on("touchmove"+n,f).on("dragstart"+n,f).on("selectstart"+n,f);if(wa){var r=Ko.style,u=r[wa];r[wa]="none"}return function(i){function o(){e.on(t,null)}e.on(n,null),wa&&(r[wa]=u),i&&(e.on(t,function(){f(),o()},!0),setTimeout(o,0))}}function U(n,t){t.changedTouches&&(t=t.changedTouches[0]);var e=n.ownerSVGElement||n;if(e.createSVGPoint){var r=e.createSVGPoint();if(0>ka&&(Qo.scrollX||Qo.scrollY)){e=Bo.select("body").append("svg").style({position:"absolute",top:0,left:0,margin:0,padding:0,border:"none"},"important");var u=e[0][0].getScreenCTM();ka=!(u.f||u.e),e.remove()}return ka?(r.x=t.pageX,r.y=t.pageY):(r.x=t.clientX,r.y=t.clientY),r=r.matrixTransform(n.getScreenCTM().inverse()),[r.x,r.y]}var i=n.getBoundingClientRect();return[t.clientX-i.left-n.clientLeft,t.clientY-i.top-n.clientTop]}function j(n){return n>0?1:0>n?-1:0}function H(n){return n>1?0:-1>n?Ea:Math.acos(n)}function F(n){return n>1?Ca:-1>n?-Ca:Math.asin(n)}function O(n){return((n=Math.exp(n))-1/n)/2}function Y(n){return((n=Math.exp(n))+1/n)/2}function I(n){return((n=Math.exp(2*n))-1)/(n+1)}function Z(n){return(n=Math.sin(n/2))*n}function V(){}function X(n,t,e){return new $(n,t,e)}function $(n,t,e){this.h=n,this.s=t,this.l=e}function B(n,t,e){function r(n){return n>360?n-=360:0>n&&(n+=360),60>n?i+(o-i)*n/60:180>n?o:240>n?i+(o-i)*(240-n)/60:i}function u(n){return Math.round(255*r(n))}var i,o;return n=isNaN(n)?0:(n%=360)<0?n+360:n,t=isNaN(t)?0:0>t?0:t>1?1:t,e=0>e?0:e>1?1:e,o=.5>=e?e*(1+t):e+t-e*t,i=2*e-o,at(u(n+120),u(n),u(n-120))}function W(n,t,e){return new J(n,t,e)}function J(n,t,e){this.h=n,this.c=t,this.l=e}function G(n,t,e){return isNaN(n)&&(n=0),isNaN(t)&&(t=0),K(e,Math.cos(n*=Ta)*t,Math.sin(n)*t)}function K(n,t,e){return new Q(n,t,e)}function Q(n,t,e){this.l=n,this.a=t,this.b=e}function nt(n,t,e){var r=(n+16)/116,u=r+t/500,i=r-e/200;return u=et(u)*Ya,r=et(r)*Ia,i=et(i)*Za,at(ut(3.2404542*u-1.5371385*r-.4985314*i),ut(-.969266*u+1.8760108*r+.041556*i),ut(.0556434*u-.2040259*r+1.0572252*i))}function tt(n,t,e){return n>0?W(Math.atan2(e,t)*qa,Math.sqrt(t*t+e*e),n):W(0/0,0/0,n)}function et(n){return n>.206893034?n*n*n:(n-4/29)/7.787037}function rt(n){return n>.008856?Math.pow(n,1/3):7.787037*n+4/29}function ut(n){return Math.round(255*(.00304>=n?12.92*n:1.055*Math.pow(n,1/2.4)-.055))}function it(n){return at(n>>16,255&n>>8,255&n)}function ot(n){return it(n)+""}function at(n,t,e){return new ct(n,t,e)}function ct(n,t,e){this.r=n,this.g=t,this.b=e}function st(n){return 16>n?"0"+Math.max(0,n).toString(16):Math.min(255,n).toString(16)}function lt(n,t,e){var r,u,i,o=0,a=0,c=0;if(r=/([a-z]+)\((.*)\)/i.exec(n))switch(u=r[2].split(","),r[1]){case"hsl":return e(parseFloat(u[0]),parseFloat(u[1])/100,parseFloat(u[2])/100);case"rgb":return t(pt(u[0]),pt(u[1]),pt(u[2]))}return(i=$a.get(n))?t(i.r,i.g,i.b):(null!=n&&"#"===n.charAt(0)&&(4===n.length?(o=n.charAt(1),o+=o,a=n.charAt(2),a+=a,c=n.charAt(3),c+=c):7===n.length&&(o=n.substring(1,3),a=n.substring(3,5),c=n.substring(5,7)),o=parseInt(o,16),a=parseInt(a,16),c=parseInt(c,16)),t(o,a,c))}function ft(n,t,e){var r,u,i=Math.min(n/=255,t/=255,e/=255),o=Math.max(n,t,e),a=o-i,c=(o+i)/2;return a?(u=.5>c?a/(o+i):a/(2-o-i),r=n==o?(t-e)/a+(e>t?6:0):t==o?(e-n)/a+2:(n-t)/a+4,r*=60):(r=0/0,u=c>0&&1>c?0:r),X(r,u,c)}function ht(n,t,e){n=gt(n),t=gt(t),e=gt(e);var r=rt((.4124564*n+.3575761*t+.1804375*e)/Ya),u=rt((.2126729*n+.7151522*t+.072175*e)/Ia),i=rt((.0193339*n+.119192*t+.9503041*e)/Za);return K(116*u-16,500*(r-u),200*(u-i))}function gt(n){return(n/=255)<=.04045?n/12.92:Math.pow((n+.055)/1.055,2.4)}function pt(n){var t=parseFloat(n);return"%"===n.charAt(n.length-1)?Math.round(2.55*t):t}function vt(n){return"function"==typeof n?n:function(){return n}}function dt(n){return n}function mt(n){return function(t,e,r){return 2===arguments.length&&"function"==typeof e&&(r=e,e=null),yt(t,e,n,r)}}function yt(n,t,e,r){function u(){var n,t=c.status;if(!t&&c.responseText||t>=200&&300>t||304===t){try{n=e.call(i,c)}catch(r){return o.error.call(i,r),void 0}o.load.call(i,n)}else o.error.call(i,c)}var i={},o=Bo.dispatch("beforesend","progress","load","error"),a={},c=new XMLHttpRequest,s=null;return!Qo.XDomainRequest||"withCredentials"in c||!/^(http(s)?:)?\/\//.test(n)||(c=new XDomainRequest),"onload"in c?c.onload=c.onerror=u:c.onreadystatechange=function(){c.readyState>3&&u()},c.onprogress=function(n){var t=Bo.event;Bo.event=n;try{o.progress.call(i,c)}finally{Bo.event=t}},i.header=function(n,t){return n=(n+"").toLowerCase(),arguments.length<2?a[n]:(null==t?delete a[n]:a[n]=t+"",i)},i.mimeType=function(n){return arguments.length?(t=null==n?null:n+"",i):t},i.responseType=function(n){return arguments.length?(s=n,i):s},i.response=function(n){return e=n,i},["get","post"].forEach(function(n){i[n]=function(){return i.send.apply(i,[n].concat(Jo(arguments)))}}),i.send=function(e,r,u){if(2===arguments.length&&"function"==typeof r&&(u=r,r=null),c.open(e,n,!0),null==t||"accept"in a||(a.accept=t+",*/*"),c.setRequestHeader)for(var l in a)c.setRequestHeader(l,a[l]);return null!=t&&c.overrideMimeType&&c.overrideMimeType(t),null!=s&&(c.responseType=s),null!=u&&i.on("error",u).on("load",function(n){u(null,n)}),o.beforesend.call(i,c),c.send(null==r?null:r),i},i.abort=function(){return c.abort(),i},Bo.rebind(i,o,"on"),null==r?i:i.get(xt(r))}function xt(n){return 1===n.length?function(t,e){n(null==t?e:null)}:n}function Mt(){var n=_t(),t=bt()-n;t>24?(isFinite(t)&&(clearTimeout(Ga),Ga=setTimeout(Mt,t)),Ja=0):(Ja=1,Qa(Mt))}function _t(){var n=Date.now();for(Ka=Ba;Ka;)n>=Ka.t&&(Ka.f=Ka.c(n-Ka.t)),Ka=Ka.n;return n}function bt(){for(var n,t=Ba,e=1/0;t;)t.f?t=n?n.n=t.n:Ba=t.n:(t.t<e&&(e=t.t),t=(n=t).n);return Wa=n,e}function wt(n,t){var e=Math.pow(10,3*ca(8-t));return{scale:t>8?function(n){return n/e}:function(n){return n*e},symbol:n}}function St(n,t){return t-(n?Math.ceil(Math.log(n)/Math.LN10):1)}function kt(n){return n+""}function Et(){}function At(n,t,e){var r=e.s=n+t,u=r-n,i=r-u;e.t=n-i+(t-u)}function Ct(n,t){n&&fc.hasOwnProperty(n.type)&&fc[n.type](n,t)}function Nt(n,t,e){var r,u=-1,i=n.length-e;for(t.lineStart();++u<i;)r=n[u],t.point(r[0],r[1],r[2]);t.lineEnd()}function Lt(n,t){var e=-1,r=n.length;for(t.polygonStart();++e<r;)Nt(n[e],t,1);t.polygonEnd()}function Tt(){function n(n,t){n*=Ta,t=t*Ta/2+Ea/4;var e=n-r,o=Math.cos(t),a=Math.sin(t),c=i*a,s=u*o+c*Math.cos(e),l=c*Math.sin(e);gc.add(Math.atan2(l,s)),r=n,u=o,i=a}var t,e,r,u,i;pc.point=function(o,a){pc.point=n,r=(t=o)*Ta,u=Math.cos(a=(e=a)*Ta/2+Ea/4),i=Math.sin(a)},pc.lineEnd=function(){n(t,e)}}function qt(n){var t=n[0],e=n[1],r=Math.cos(e);return[r*Math.cos(t),r*Math.sin(t),Math.sin(e)]}function zt(n,t){return n[0]*t[0]+n[1]*t[1]+n[2]*t[2]}function Rt(n,t){return[n[1]*t[2]-n[2]*t[1],n[2]*t[0]-n[0]*t[2],n[0]*t[1]-n[1]*t[0]]}function Dt(n,t){n[0]+=t[0],n[1]+=t[1],n[2]+=t[2]}function Pt(n,t){return[n[0]*t,n[1]*t,n[2]*t]}function Ut(n){var t=Math.sqrt(n[0]*n[0]+n[1]*n[1]+n[2]*n[2]);n[0]/=t,n[1]/=t,n[2]/=t}function jt(n){return[Math.atan2(n[1],n[0]),F(n[2])]}function Ht(n,t){return ca(n[0]-t[0])<Na&&ca(n[1]-t[1])<Na}function Ft(n,t){n*=Ta;var e=Math.cos(t*=Ta);Ot(e*Math.cos(n),e*Math.sin(n),Math.sin(t))}function Ot(n,t,e){++vc,mc+=(n-mc)/vc,yc+=(t-yc)/vc,xc+=(e-xc)/vc}function Yt(){function n(n,u){n*=Ta;var i=Math.cos(u*=Ta),o=i*Math.cos(n),a=i*Math.sin(n),c=Math.sin(u),s=Math.atan2(Math.sqrt((s=e*c-r*a)*s+(s=r*o-t*c)*s+(s=t*a-e*o)*s),t*o+e*a+r*c);dc+=s,Mc+=s*(t+(t=o)),_c+=s*(e+(e=a)),bc+=s*(r+(r=c)),Ot(t,e,r)}var t,e,r;Ec.point=function(u,i){u*=Ta;var o=Math.cos(i*=Ta);t=o*Math.cos(u),e=o*Math.sin(u),r=Math.sin(i),Ec.point=n,Ot(t,e,r)}}function It(){Ec.point=Ft}function Zt(){function n(n,t){n*=Ta;var e=Math.cos(t*=Ta),o=e*Math.cos(n),a=e*Math.sin(n),c=Math.sin(t),s=u*c-i*a,l=i*o-r*c,f=r*a-u*o,h=Math.sqrt(s*s+l*l+f*f),g=r*o+u*a+i*c,p=h&&-H(g)/h,v=Math.atan2(h,g);wc+=p*s,Sc+=p*l,kc+=p*f,dc+=v,Mc+=v*(r+(r=o)),_c+=v*(u+(u=a)),bc+=v*(i+(i=c)),Ot(r,u,i)}var t,e,r,u,i;Ec.point=function(o,a){t=o,e=a,Ec.point=n,o*=Ta;var c=Math.cos(a*=Ta);r=c*Math.cos(o),u=c*Math.sin(o),i=Math.sin(a),Ot(r,u,i)},Ec.lineEnd=function(){n(t,e),Ec.lineEnd=It,Ec.point=Ft}}function Vt(){return!0}function Xt(n,t,e,r,u){var i=[],o=[];if(n.forEach(function(n){if(!((t=n.length-1)<=0)){var t,e=n[0],r=n[t];if(Ht(e,r)){u.lineStart();for(var a=0;t>a;++a)u.point((e=n[a])[0],e[1]);return u.lineEnd(),void 0}var c=new Bt(e,n,null,!0),s=new Bt(e,null,c,!1);c.o=s,i.push(c),o.push(s),c=new Bt(r,n,null,!1),s=new Bt(r,null,c,!0),c.o=s,i.push(c),o.push(s)}}),o.sort(t),$t(i),$t(o),i.length){for(var a=0,c=e,s=o.length;s>a;++a)o[a].e=c=!c;for(var l,f,h=i[0];;){for(var g=h,p=!0;g.v;)if((g=g.n)===h)return;l=g.z,u.lineStart();do{if(g.v=g.o.v=!0,g.e){if(p)for(var a=0,s=l.length;s>a;++a)u.point((f=l[a])[0],f[1]);else r(g.x,g.n.x,1,u);g=g.n}else{if(p){l=g.p.z;for(var a=l.length-1;a>=0;--a)u.point((f=l[a])[0],f[1])}else r(g.x,g.p.x,-1,u);g=g.p}g=g.o,l=g.z,p=!p}while(!g.v);u.lineEnd()}}}function $t(n){if(t=n.length){for(var t,e,r=0,u=n[0];++r<t;)u.n=e=n[r],e.p=u,u=e;u.n=e=n[0],e.p=u}}function Bt(n,t,e,r){this.x=n,this.z=t,this.o=e,this.e=r,this.v=!1,this.n=this.p=null}function Wt(n,t,e,r){return function(u,i){function o(t,e){var r=u(t,e);n(t=r[0],e=r[1])&&i.point(t,e)}function a(n,t){var e=u(n,t);d.point(e[0],e[1])}function c(){y.point=a,d.lineStart()}function s(){y.point=o,d.lineEnd()}function l(n,t){v.push([n,t]);var e=u(n,t);M.point(e[0],e[1])}function f(){M.lineStart(),v=[]}function h(){l(v[0][0],v[0][1]),M.lineEnd();var n,t=M.clean(),e=x.buffer(),r=e.length;if(v.pop(),p.push(v),v=null,r){if(1&t){n=e[0];var u,r=n.length-1,o=-1;for(i.lineStart();++o<r;)i.point((u=n[o])[0],u[1]);return i.lineEnd(),void 0}r>1&&2&t&&e.push(e.pop().concat(e.shift())),g.push(e.filter(Jt))}}var g,p,v,d=t(i),m=u.invert(r[0],r[1]),y={point:o,lineStart:c,lineEnd:s,polygonStart:function(){y.point=l,y.lineStart=f,y.lineEnd=h,g=[],p=[],i.polygonStart()},polygonEnd:function(){y.point=o,y.lineStart=c,y.lineEnd=s,g=Bo.merge(g);var n=Qt(m,p);g.length?Xt(g,Kt,n,e,i):n&&(i.lineStart(),e(null,null,1,i),i.lineEnd()),i.polygonEnd(),g=p=null},sphere:function(){i.polygonStart(),i.lineStart(),e(null,null,1,i),i.lineEnd(),i.polygonEnd()}},x=Gt(),M=t(x);return y}}function Jt(n){return n.length>1}function Gt(){var n,t=[];return{lineStart:function(){t.push(n=[])},point:function(t,e){n.push([t,e])},lineEnd:c,buffer:function(){var e=t;return t=[],n=null,e},rejoin:function(){t.length>1&&t.push(t.pop().concat(t.shift()))}}}function Kt(n,t){return((n=n.x)[0]<0?n[1]-Ca-Na:Ca-n[1])-((t=t.x)[0]<0?t[1]-Ca-Na:Ca-t[1])}function Qt(n,t){var e=n[0],r=n[1],u=[Math.sin(e),-Math.cos(e),0],i=0,o=0;gc.reset();for(var a=0,c=t.length;c>a;++a){var s=t[a],l=s.length;if(l)for(var f=s[0],h=f[0],g=f[1]/2+Ea/4,p=Math.sin(g),v=Math.cos(g),d=1;;){d===l&&(d=0),n=s[d];var m=n[0],y=n[1]/2+Ea/4,x=Math.sin(y),M=Math.cos(y),_=m-h,b=ca(_)>Ea,w=p*x;if(gc.add(Math.atan2(w*Math.sin(_),v*M+w*Math.cos(_))),i+=b?_+(_>=0?Aa:-Aa):_,b^h>=e^m>=e){var S=Rt(qt(f),qt(n));Ut(S);var k=Rt(u,S);Ut(k);var E=(b^_>=0?-1:1)*F(k[2]);(r>E||r===E&&(S[0]||S[1]))&&(o+=b^_>=0?1:-1)}if(!d++)break;h=m,p=x,v=M,f=n}}return(-Na>i||Na>i&&0>gc)^1&o}function ne(n){var t,e=0/0,r=0/0,u=0/0;return{lineStart:function(){n.lineStart(),t=1},point:function(i,o){var a=i>0?Ea:-Ea,c=ca(i-e);ca(c-Ea)<Na?(n.point(e,r=(r+o)/2>0?Ca:-Ca),n.point(u,r),n.lineEnd(),n.lineStart(),n.point(a,r),n.point(i,r),t=0):u!==a&&c>=Ea&&(ca(e-u)<Na&&(e-=u*Na),ca(i-a)<Na&&(i-=a*Na),r=te(e,r,i,o),n.point(u,r),n.lineEnd(),n.lineStart(),n.point(a,r),t=0),n.point(e=i,r=o),u=a},lineEnd:function(){n.lineEnd(),e=r=0/0},clean:function(){return 2-t}}}function te(n,t,e,r){var u,i,o=Math.sin(n-e);return ca(o)>Na?Math.atan((Math.sin(t)*(i=Math.cos(r))*Math.sin(e)-Math.sin(r)*(u=Math.cos(t))*Math.sin(n))/(u*i*o)):(t+r)/2}function ee(n,t,e,r){var u;if(null==n)u=e*Ca,r.point(-Ea,u),r.point(0,u),r.point(Ea,u),r.point(Ea,0),r.point(Ea,-u),r.point(0,-u),r.point(-Ea,-u),r.point(-Ea,0),r.point(-Ea,u);else if(ca(n[0]-t[0])>Na){var i=n[0]<t[0]?Ea:-Ea;u=e*i/2,r.point(-i,u),r.point(0,u),r.point(i,u)}else r.point(t[0],t[1])}function re(n){function t(n,t){return Math.cos(n)*Math.cos(t)>i}function e(n){var e,i,c,s,l;return{lineStart:function(){s=c=!1,l=1},point:function(f,h){var g,p=[f,h],v=t(f,h),d=o?v?0:u(f,h):v?u(f+(0>f?Ea:-Ea),h):0;if(!e&&(s=c=v)&&n.lineStart(),v!==c&&(g=r(e,p),(Ht(e,g)||Ht(p,g))&&(p[0]+=Na,p[1]+=Na,v=t(p[0],p[1]))),v!==c)l=0,v?(n.lineStart(),g=r(p,e),n.point(g[0],g[1])):(g=r(e,p),n.point(g[0],g[1]),n.lineEnd()),e=g;else if(a&&e&&o^v){var m;d&i||!(m=r(p,e,!0))||(l=0,o?(n.lineStart(),n.point(m[0][0],m[0][1]),n.point(m[1][0],m[1][1]),n.lineEnd()):(n.point(m[1][0],m[1][1]),n.lineEnd(),n.lineStart(),n.point(m[0][0],m[0][1])))}!v||e&&Ht(e,p)||n.point(p[0],p[1]),e=p,c=v,i=d},lineEnd:function(){c&&n.lineEnd(),e=null},clean:function(){return l|(s&&c)<<1}}}function r(n,t,e){var r=qt(n),u=qt(t),o=[1,0,0],a=Rt(r,u),c=zt(a,a),s=a[0],l=c-s*s;if(!l)return!e&&n;var f=i*c/l,h=-i*s/l,g=Rt(o,a),p=Pt(o,f),v=Pt(a,h);Dt(p,v);var d=g,m=zt(p,d),y=zt(d,d),x=m*m-y*(zt(p,p)-1);if(!(0>x)){var M=Math.sqrt(x),_=Pt(d,(-m-M)/y);if(Dt(_,p),_=jt(_),!e)return _;var b,w=n[0],S=t[0],k=n[1],E=t[1];w>S&&(b=w,w=S,S=b);var A=S-w,C=ca(A-Ea)<Na,N=C||Na>A;if(!C&&k>E&&(b=k,k=E,E=b),N?C?k+E>0^_[1]<(ca(_[0]-w)<Na?k:E):k<=_[1]&&_[1]<=E:A>Ea^(w<=_[0]&&_[0]<=S)){var L=Pt(d,(-m+M)/y);return Dt(L,p),[_,jt(L)]}}}function u(t,e){var r=o?n:Ea-n,u=0;return-r>t?u|=1:t>r&&(u|=2),-r>e?u|=4:e>r&&(u|=8),u}var i=Math.cos(n),o=i>0,a=ca(i)>Na,c=Te(n,6*Ta);return Wt(t,e,c,o?[0,-n]:[-Ea,n-Ea])}function ue(n,t,e,r){return function(u){var i,o=u.a,a=u.b,c=o.x,s=o.y,l=a.x,f=a.y,h=0,g=1,p=l-c,v=f-s;if(i=n-c,p||!(i>0)){if(i/=p,0>p){if(h>i)return;g>i&&(g=i)}else if(p>0){if(i>g)return;i>h&&(h=i)}if(i=e-c,p||!(0>i)){if(i/=p,0>p){if(i>g)return;i>h&&(h=i)}else if(p>0){if(h>i)return;g>i&&(g=i)}if(i=t-s,v||!(i>0)){if(i/=v,0>v){if(h>i)return;g>i&&(g=i)}else if(v>0){if(i>g)return;i>h&&(h=i)}if(i=r-s,v||!(0>i)){if(i/=v,0>v){if(i>g)return;i>h&&(h=i)}else if(v>0){if(h>i)return;g>i&&(g=i)}return h>0&&(u.a={x:c+h*p,y:s+h*v}),1>g&&(u.b={x:c+g*p,y:s+g*v}),u}}}}}}function ie(n,t,e,r){function u(r,u){return ca(r[0]-n)<Na?u>0?0:3:ca(r[0]-e)<Na?u>0?2:1:ca(r[1]-t)<Na?u>0?1:0:u>0?3:2}function i(n,t){return o(n.x,t.x)}function o(n,t){var e=u(n,1),r=u(t,1);return e!==r?e-r:0===e?t[1]-n[1]:1===e?n[0]-t[0]:2===e?n[1]-t[1]:t[0]-n[0]}return function(a){function c(n){for(var t=0,e=m.length,r=n[1],u=0;e>u;++u)for(var i,o=1,a=m[u],c=a.length,l=a[0];c>o;++o)i=a[o],l[1]<=r?i[1]>r&&s(l,i,n)>0&&++t:i[1]<=r&&s(l,i,n)<0&&--t,l=i;return 0!==t}function s(n,t,e){return(t[0]-n[0])*(e[1]-n[1])-(e[0]-n[0])*(t[1]-n[1])}function l(i,a,c,s){var l=0,f=0;if(null==i||(l=u(i,c))!==(f=u(a,c))||o(i,a)<0^c>0){do s.point(0===l||3===l?n:e,l>1?r:t);while((l=(l+c+4)%4)!==f)}else s.point(a[0],a[1])}function f(u,i){return u>=n&&e>=u&&i>=t&&r>=i}function h(n,t){f(n,t)&&a.point(n,t)}function g(){L.point=v,m&&m.push(y=[]),k=!0,S=!1,b=w=0/0}function p(){d&&(v(x,M),_&&S&&C.rejoin(),d.push(C.buffer())),L.point=h,S&&a.lineEnd()}function v(n,t){n=Math.max(-Cc,Math.min(Cc,n)),t=Math.max(-Cc,Math.min(Cc,t));var e=f(n,t);if(m&&y.push([n,t]),k)x=n,M=t,_=e,k=!1,e&&(a.lineStart(),a.point(n,t));else if(e&&S)a.point(n,t);else{var r={a:{x:b,y:w},b:{x:n,y:t}};N(r)?(S||(a.lineStart(),a.point(r.a.x,r.a.y)),a.point(r.b.x,r.b.y),e||a.lineEnd(),E=!1):e&&(a.lineStart(),a.point(n,t),E=!1)}b=n,w=t,S=e}var d,m,y,x,M,_,b,w,S,k,E,A=a,C=Gt(),N=ue(n,t,e,r),L={point:h,lineStart:g,lineEnd:p,polygonStart:function(){a=C,d=[],m=[],E=!0},polygonEnd:function(){a=A,d=Bo.merge(d);var t=c([n,r]),e=E&&t,u=d.length;(e||u)&&(a.polygonStart(),e&&(a.lineStart(),l(null,null,1,a),a.lineEnd()),u&&Xt(d,i,t,l,a),a.polygonEnd()),d=m=y=null}};return L}}function oe(n,t){function e(e,r){return e=n(e,r),t(e[0],e[1])}return n.invert&&t.invert&&(e.invert=function(e,r){return e=t.invert(e,r),e&&n.invert(e[0],e[1])}),e}function ae(n){var t=0,e=Ea/3,r=we(n),u=r(t,e);return u.parallels=function(n){return arguments.length?r(t=n[0]*Ea/180,e=n[1]*Ea/180):[180*(t/Ea),180*(e/Ea)]},u}function ce(n,t){function e(n,t){var e=Math.sqrt(i-2*u*Math.sin(t))/u;return[e*Math.sin(n*=u),o-e*Math.cos(n)]}var r=Math.sin(n),u=(r+Math.sin(t))/2,i=1+r*(2*u-r),o=Math.sqrt(i)/u;return e.invert=function(n,t){var e=o-t;return[Math.atan2(n,e)/u,F((i-(n*n+e*e)*u*u)/(2*u))]},e}function se(){function n(n,t){Lc+=u*n-r*t,r=n,u=t}var t,e,r,u;Dc.point=function(i,o){Dc.point=n,t=r=i,e=u=o},Dc.lineEnd=function(){n(t,e)}}function le(n,t){Tc>n&&(Tc=n),n>zc&&(zc=n),qc>t&&(qc=t),t>Rc&&(Rc=t)}function fe(){function n(n,t){o.push("M",n,",",t,i)}function t(n,t){o.push("M",n,",",t),a.point=e}function e(n,t){o.push("L",n,",",t)}function r(){a.point=n}function u(){o.push("Z")}var i=he(4.5),o=[],a={point:n,lineStart:function(){a.point=t},lineEnd:r,polygonStart:function(){a.lineEnd=u},polygonEnd:function(){a.lineEnd=r,a.point=n},pointRadius:function(n){return i=he(n),a},result:function(){if(o.length){var n=o.join("");return o=[],n}}};return a}function he(n){return"m0,"+n+"a"+n+","+n+" 0 1,1 0,"+-2*n+"a"+n+","+n+" 0 1,1 0,"+2*n+"z"}function ge(n,t){mc+=n,yc+=t,++xc}function pe(){function n(n,r){var u=n-t,i=r-e,o=Math.sqrt(u*u+i*i);Mc+=o*(t+n)/2,_c+=o*(e+r)/2,bc+=o,ge(t=n,e=r)}var t,e;Uc.point=function(r,u){Uc.point=n,ge(t=r,e=u)}}function ve(){Uc.point=ge}function de(){function n(n,t){var e=n-r,i=t-u,o=Math.sqrt(e*e+i*i);Mc+=o*(r+n)/2,_c+=o*(u+t)/2,bc+=o,o=u*n-r*t,wc+=o*(r+n),Sc+=o*(u+t),kc+=3*o,ge(r=n,u=t)}var t,e,r,u;Uc.point=function(i,o){Uc.point=n,ge(t=r=i,e=u=o)},Uc.lineEnd=function(){n(t,e)}}function me(n){function t(t,e){n.moveTo(t,e),n.arc(t,e,o,0,Aa)}function e(t,e){n.moveTo(t,e),a.point=r}function r(t,e){n.lineTo(t,e)}function u(){a.point=t}function i(){n.closePath()}var o=4.5,a={point:t,lineStart:function(){a.point=e},lineEnd:u,polygonStart:function(){a.lineEnd=i},polygonEnd:function(){a.lineEnd=u,a.point=t},pointRadius:function(n){return o=n,a},result:c};return a}function ye(n){function t(n){return(a?r:e)(n)}function e(t){return _e(t,function(e,r){e=n(e,r),t.point(e[0],e[1])})}function r(t){function e(e,r){e=n(e,r),t.point(e[0],e[1])}function r(){x=0/0,S.point=i,t.lineStart()}function i(e,r){var i=qt([e,r]),o=n(e,r);u(x,M,y,_,b,w,x=o[0],M=o[1],y=e,_=i[0],b=i[1],w=i[2],a,t),t.point(x,M)}function o(){S.point=e,t.lineEnd()}function c(){r(),S.point=s,S.lineEnd=l}function s(n,t){i(f=n,h=t),g=x,p=M,v=_,d=b,m=w,S.point=i}function l(){u(x,M,y,_,b,w,g,p,f,v,d,m,a,t),S.lineEnd=o,o()}var f,h,g,p,v,d,m,y,x,M,_,b,w,S={point:e,lineStart:r,lineEnd:o,polygonStart:function(){t.polygonStart(),S.lineStart=c},polygonEnd:function(){t.polygonEnd(),S.lineStart=r}};return S}function u(t,e,r,a,c,s,l,f,h,g,p,v,d,m){var y=l-t,x=f-e,M=y*y+x*x;if(M>4*i&&d--){var _=a+g,b=c+p,w=s+v,S=Math.sqrt(_*_+b*b+w*w),k=Math.asin(w/=S),E=ca(ca(w)-1)<Na||ca(r-h)<Na?(r+h)/2:Math.atan2(b,_),A=n(E,k),C=A[0],N=A[1],L=C-t,T=N-e,q=x*L-y*T;(q*q/M>i||ca((y*L+x*T)/M-.5)>.3||o>a*g+c*p+s*v)&&(u(t,e,r,a,c,s,C,N,E,_/=S,b/=S,w,d,m),m.point(C,N),u(C,N,E,_,b,w,l,f,h,g,p,v,d,m))}}var i=.5,o=Math.cos(30*Ta),a=16;return t.precision=function(n){return arguments.length?(a=(i=n*n)>0&&16,t):Math.sqrt(i)},t}function xe(n){var t=ye(function(t,e){return n([t*qa,e*qa])});return function(n){return Se(t(n))}}function Me(n){this.stream=n}function _e(n,t){return{point:t,sphere:function(){n.sphere()},lineStart:function(){n.lineStart()},lineEnd:function(){n.lineEnd()},polygonStart:function(){n.polygonStart()},polygonEnd:function(){n.polygonEnd()}}}function be(n){return we(function(){return n})()}function we(n){function t(n){return n=a(n[0]*Ta,n[1]*Ta),[n[0]*h+c,s-n[1]*h]}function e(n){return n=a.invert((n[0]-c)/h,(s-n[1])/h),n&&[n[0]*qa,n[1]*qa]}function r(){a=oe(o=Ae(m,y,x),i);var n=i(v,d);return c=g-n[0]*h,s=p+n[1]*h,u()}function u(){return l&&(l.valid=!1,l=null),t}var i,o,a,c,s,l,f=ye(function(n,t){return n=i(n,t),[n[0]*h+c,s-n[1]*h]}),h=150,g=480,p=250,v=0,d=0,m=0,y=0,x=0,M=Ac,_=dt,b=null,w=null;return t.stream=function(n){return l&&(l.valid=!1),l=Se(M(o,f(_(n)))),l.valid=!0,l},t.clipAngle=function(n){return arguments.length?(M=null==n?(b=n,Ac):re((b=+n)*Ta),u()):b},t.clipExtent=function(n){return arguments.length?(w=n,_=n?ie(n[0][0],n[0][1],n[1][0],n[1][1]):dt,u()):w},t.scale=function(n){return arguments.length?(h=+n,r()):h},t.translate=function(n){return arguments.length?(g=+n[0],p=+n[1],r()):[g,p]},t.center=function(n){return arguments.length?(v=n[0]%360*Ta,d=n[1]%360*Ta,r()):[v*qa,d*qa]},t.rotate=function(n){return arguments.length?(m=n[0]%360*Ta,y=n[1]%360*Ta,x=n.length>2?n[2]%360*Ta:0,r()):[m*qa,y*qa,x*qa]},Bo.rebind(t,f,"precision"),function(){return i=n.apply(this,arguments),t.invert=i.invert&&e,r()}}function Se(n){return _e(n,function(t,e){n.point(t*Ta,e*Ta)})}function ke(n,t){return[n,t]}function Ee(n,t){return[n>Ea?n-Aa:-Ea>n?n+Aa:n,t]}function Ae(n,t,e){return n?t||e?oe(Ne(n),Le(t,e)):Ne(n):t||e?Le(t,e):Ee}function Ce(n){return function(t,e){return t+=n,[t>Ea?t-Aa:-Ea>t?t+Aa:t,e]}}function Ne(n){var t=Ce(n);return t.invert=Ce(-n),t}function Le(n,t){function e(n,t){var e=Math.cos(t),a=Math.cos(n)*e,c=Math.sin(n)*e,s=Math.sin(t),l=s*r+a*u;return[Math.atan2(c*i-l*o,a*r-s*u),F(l*i+c*o)]}var r=Math.cos(n),u=Math.sin(n),i=Math.cos(t),o=Math.sin(t);return e.invert=function(n,t){var e=Math.cos(t),a=Math.cos(n)*e,c=Math.sin(n)*e,s=Math.sin(t),l=s*i-c*o;return[Math.atan2(c*i+s*o,a*r+l*u),F(l*r-a*u)]},e}function Te(n,t){var e=Math.cos(n),r=Math.sin(n);return function(u,i,o,a){var c=o*t;null!=u?(u=qe(e,u),i=qe(e,i),(o>0?i>u:u>i)&&(u+=o*Aa)):(u=n+o*Aa,i=n-.5*c);for(var s,l=u;o>0?l>i:i>l;l-=c)a.point((s=jt([e,-r*Math.cos(l),-r*Math.sin(l)]))[0],s[1])}}function qe(n,t){var e=qt(t);e[0]-=n,Ut(e);var r=H(-e[1]);return((-e[2]<0?-r:r)+2*Math.PI-Na)%(2*Math.PI)}function ze(n,t,e){var r=Bo.range(n,t-Na,e).concat(t);return function(n){return r.map(function(t){return[n,t]})}}function Re(n,t,e){var r=Bo.range(n,t-Na,e).concat(t);return function(n){return r.map(function(t){return[t,n]})}}function De(n){return n.source}function Pe(n){return n.target}function Ue(n,t,e,r){var u=Math.cos(t),i=Math.sin(t),o=Math.cos(r),a=Math.sin(r),c=u*Math.cos(n),s=u*Math.sin(n),l=o*Math.cos(e),f=o*Math.sin(e),h=2*Math.asin(Math.sqrt(Z(r-t)+u*o*Z(e-n))),g=1/Math.sin(h),p=h?function(n){var t=Math.sin(n*=h)*g,e=Math.sin(h-n)*g,r=e*c+t*l,u=e*s+t*f,o=e*i+t*a;return[Math.atan2(u,r)*qa,Math.atan2(o,Math.sqrt(r*r+u*u))*qa]}:function(){return[n*qa,t*qa]};return p.distance=h,p}function je(){function n(n,u){var i=Math.sin(u*=Ta),o=Math.cos(u),a=ca((n*=Ta)-t),c=Math.cos(a);jc+=Math.atan2(Math.sqrt((a=o*Math.sin(a))*a+(a=r*i-e*o*c)*a),e*i+r*o*c),t=n,e=i,r=o}var t,e,r;Hc.point=function(u,i){t=u*Ta,e=Math.sin(i*=Ta),r=Math.cos(i),Hc.point=n},Hc.lineEnd=function(){Hc.point=Hc.lineEnd=c}}function He(n,t){function e(t,e){var r=Math.cos(t),u=Math.cos(e),i=n(r*u);return[i*u*Math.sin(t),i*Math.sin(e)]}return e.invert=function(n,e){var r=Math.sqrt(n*n+e*e),u=t(r),i=Math.sin(u),o=Math.cos(u);return[Math.atan2(n*i,r*o),Math.asin(r&&e*i/r)]},e}function Fe(n,t){function e(n,t){var e=ca(ca(t)-Ca)<Na?0:o/Math.pow(u(t),i);return[e*Math.sin(i*n),o-e*Math.cos(i*n)]}var r=Math.cos(n),u=function(n){return Math.tan(Ea/4+n/2)},i=n===t?Math.sin(n):Math.log(r/Math.cos(t))/Math.log(u(t)/u(n)),o=r*Math.pow(u(n),i)/i;return i?(e.invert=function(n,t){var e=o-t,r=j(i)*Math.sqrt(n*n+e*e);return[Math.atan2(n,e)/i,2*Math.atan(Math.pow(o/r,1/i))-Ca]},e):Ye}function Oe(n,t){function e(n,t){var e=i-t;return[e*Math.sin(u*n),i-e*Math.cos(u*n)]}var r=Math.cos(n),u=n===t?Math.sin(n):(r-Math.cos(t))/(t-n),i=r/u+n;return ca(u)<Na?ke:(e.invert=function(n,t){var e=i-t;return[Math.atan2(n,e)/u,i-j(u)*Math.sqrt(n*n+e*e)]},e)}function Ye(n,t){return[n,Math.log(Math.tan(Ea/4+t/2))]}function Ie(n){var t,e=be(n),r=e.scale,u=e.translate,i=e.clipExtent;return e.scale=function(){var n=r.apply(e,arguments);return n===e?t?e.clipExtent(null):e:n},e.translate=function(){var n=u.apply(e,arguments);return n===e?t?e.clipExtent(null):e:n},e.clipExtent=function(n){var o=i.apply(e,arguments);if(o===e){if(t=null==n){var a=Ea*r(),c=u();i([[c[0]-a,c[1]-a],[c[0]+a,c[1]+a]])}}else t&&(o=null);return o},e.clipExtent(null)}function Ze(n,t){return[Math.log(Math.tan(Ea/4+t/2)),-n]}function Ve(n){return n[0]}function Xe(n){return n[1]}function $e(n,t,e,r){var u,i,o,a,c,s,l;return u=r[n],i=u[0],o=u[1],u=r[t],a=u[0],c=u[1],u=r[e],s=u[0],l=u[1],(l-o)*(a-i)-(c-o)*(s-i)>0}function Be(n,t,e){return(e[0]-t[0])*(n[1]-t[1])<(e[1]-t[1])*(n[0]-t[0])}function We(n,t,e,r){var u=n[0],i=e[0],o=t[0]-u,a=r[0]-i,c=n[1],s=e[1],l=t[1]-c,f=r[1]-s,h=(a*(c-s)-f*(u-i))/(f*o-a*l);return[u+h*o,c+h*l]}function Je(n){var t=n[0],e=n[n.length-1];return!(t[0]-e[0]||t[1]-e[1])}function Ge(){yr(this),this.edge=this.site=this.circle=null}function Ke(n){var t=Gc.pop()||new Ge;return t.site=n,t}function Qe(n){sr(n),Bc.remove(n),Gc.push(n),yr(n)}function nr(n){var t=n.circle,e=t.x,r=t.cy,u={x:e,y:r},i=n.P,o=n.N,a=[n];Qe(n);for(var c=i;c.circle&&ca(e-c.circle.x)<Na&&ca(r-c.circle.cy)<Na;)i=c.P,a.unshift(c),Qe(c),c=i;a.unshift(c),sr(c);for(var s=o;s.circle&&ca(e-s.circle.x)<Na&&ca(r-s.circle.cy)<Na;)o=s.N,a.push(s),Qe(s),s=o;a.push(s),sr(s);var l,f=a.length;for(l=1;f>l;++l)s=a[l],c=a[l-1],vr(s.edge,c.site,s.site,u);c=a[0],s=a[f-1],s.edge=gr(c.site,s.site,null,u),cr(c),cr(s)}function tr(n){for(var t,e,r,u,i=n.x,o=n.y,a=Bc._;a;)if(r=er(a,o)-i,r>Na)a=a.L;else{if(u=i-rr(a,o),!(u>Na)){r>-Na?(t=a.P,e=a):u>-Na?(t=a,e=a.N):t=e=a;break}if(!a.R){t=a;break}a=a.R}var c=Ke(n);if(Bc.insert(t,c),t||e){if(t===e)return sr(t),e=Ke(t.site),Bc.insert(c,e),c.edge=e.edge=gr(t.site,c.site),cr(t),cr(e),void 0;if(!e)return c.edge=gr(t.site,c.site),void 0;sr(t),sr(e);var s=t.site,l=s.x,f=s.y,h=n.x-l,g=n.y-f,p=e.site,v=p.x-l,d=p.y-f,m=2*(h*d-g*v),y=h*h+g*g,x=v*v+d*d,M={x:(d*y-g*x)/m+l,y:(h*x-v*y)/m+f};vr(e.edge,s,p,M),c.edge=gr(s,n,null,M),e.edge=gr(n,p,null,M),cr(t),cr(e)}}function er(n,t){var e=n.site,r=e.x,u=e.y,i=u-t;if(!i)return r;var o=n.P;if(!o)return-1/0;e=o.site;var a=e.x,c=e.y,s=c-t;if(!s)return a;var l=a-r,f=1/i-1/s,h=l/s;return f?(-h+Math.sqrt(h*h-2*f*(l*l/(-2*s)-c+s/2+u-i/2)))/f+r:(r+a)/2}function rr(n,t){var e=n.N;if(e)return er(e,t);var r=n.site;return r.y===t?r.x:1/0}function ur(n){this.site=n,this.edges=[]}function ir(n){for(var t,e,r,u,i,o,a,c,s,l,f=n[0][0],h=n[1][0],g=n[0][1],p=n[1][1],v=$c,d=v.length;d--;)if(i=v[d],i&&i.prepare())for(a=i.edges,c=a.length,o=0;c>o;)l=a[o].end(),r=l.x,u=l.y,s=a[++o%c].start(),t=s.x,e=s.y,(ca(r-t)>Na||ca(u-e)>Na)&&(a.splice(o,0,new dr(pr(i.site,l,ca(r-f)<Na&&p-u>Na?{x:f,y:ca(t-f)<Na?e:p}:ca(u-p)<Na&&h-r>Na?{x:ca(e-p)<Na?t:h,y:p}:ca(r-h)<Na&&u-g>Na?{x:h,y:ca(t-h)<Na?e:g}:ca(u-g)<Na&&r-f>Na?{x:ca(e-g)<Na?t:f,y:g}:null),i.site,null)),++c)}function or(n,t){return t.angle-n.angle}function ar(){yr(this),this.x=this.y=this.arc=this.site=this.cy=null}function cr(n){var t=n.P,e=n.N;if(t&&e){var r=t.site,u=n.site,i=e.site;if(r!==i){var o=u.x,a=u.y,c=r.x-o,s=r.y-a,l=i.x-o,f=i.y-a,h=2*(c*f-s*l);if(!(h>=-La)){var g=c*c+s*s,p=l*l+f*f,v=(f*g-s*p)/h,d=(c*p-l*g)/h,f=d+a,m=Kc.pop()||new ar;m.arc=n,m.site=u,m.x=v+o,m.y=f+Math.sqrt(v*v+d*d),m.cy=f,n.circle=m;for(var y=null,x=Jc._;x;)if(m.y<x.y||m.y===x.y&&m.x<=x.x){if(!x.L){y=x.P;break}x=x.L}else{if(!x.R){y=x;break}x=x.R}Jc.insert(y,m),y||(Wc=m)}}}}function sr(n){var t=n.circle;t&&(t.P||(Wc=t.N),Jc.remove(t),Kc.push(t),yr(t),n.circle=null)}function lr(n){for(var t,e=Xc,r=ue(n[0][0],n[0][1],n[1][0],n[1][1]),u=e.length;u--;)t=e[u],(!fr(t,n)||!r(t)||ca(t.a.x-t.b.x)<Na&&ca(t.a.y-t.b.y)<Na)&&(t.a=t.b=null,e.splice(u,1))}function fr(n,t){var e=n.b;if(e)return!0;var r,u,i=n.a,o=t[0][0],a=t[1][0],c=t[0][1],s=t[1][1],l=n.l,f=n.r,h=l.x,g=l.y,p=f.x,v=f.y,d=(h+p)/2,m=(g+v)/2; +if(v===g){if(o>d||d>=a)return;if(h>p){if(i){if(i.y>=s)return}else i={x:d,y:c};e={x:d,y:s}}else{if(i){if(i.y<c)return}else i={x:d,y:s};e={x:d,y:c}}}else if(r=(h-p)/(v-g),u=m-r*d,-1>r||r>1)if(h>p){if(i){if(i.y>=s)return}else i={x:(c-u)/r,y:c};e={x:(s-u)/r,y:s}}else{if(i){if(i.y<c)return}else i={x:(s-u)/r,y:s};e={x:(c-u)/r,y:c}}else if(v>g){if(i){if(i.x>=a)return}else i={x:o,y:r*o+u};e={x:a,y:r*a+u}}else{if(i){if(i.x<o)return}else i={x:a,y:r*a+u};e={x:o,y:r*o+u}}return n.a=i,n.b=e,!0}function hr(n,t){this.l=n,this.r=t,this.a=this.b=null}function gr(n,t,e,r){var u=new hr(n,t);return Xc.push(u),e&&vr(u,n,t,e),r&&vr(u,t,n,r),$c[n.i].edges.push(new dr(u,n,t)),$c[t.i].edges.push(new dr(u,t,n)),u}function pr(n,t,e){var r=new hr(n,null);return r.a=t,r.b=e,Xc.push(r),r}function vr(n,t,e,r){n.a||n.b?n.l===e?n.b=r:n.a=r:(n.a=r,n.l=t,n.r=e)}function dr(n,t,e){var r=n.a,u=n.b;this.edge=n,this.site=t,this.angle=e?Math.atan2(e.y-t.y,e.x-t.x):n.l===t?Math.atan2(u.x-r.x,r.y-u.y):Math.atan2(r.x-u.x,u.y-r.y)}function mr(){this._=null}function yr(n){n.U=n.C=n.L=n.R=n.P=n.N=null}function xr(n,t){var e=t,r=t.R,u=e.U;u?u.L===e?u.L=r:u.R=r:n._=r,r.U=u,e.U=r,e.R=r.L,e.R&&(e.R.U=e),r.L=e}function Mr(n,t){var e=t,r=t.L,u=e.U;u?u.L===e?u.L=r:u.R=r:n._=r,r.U=u,e.U=r,e.L=r.R,e.L&&(e.L.U=e),r.R=e}function _r(n){for(;n.L;)n=n.L;return n}function br(n,t){var e,r,u,i=n.sort(wr).pop();for(Xc=[],$c=new Array(n.length),Bc=new mr,Jc=new mr;;)if(u=Wc,i&&(!u||i.y<u.y||i.y===u.y&&i.x<u.x))(i.x!==e||i.y!==r)&&($c[i.i]=new ur(i),tr(i),e=i.x,r=i.y),i=n.pop();else{if(!u)break;nr(u.arc)}t&&(lr(t),ir(t));var o={cells:$c,edges:Xc};return Bc=Jc=Xc=$c=null,o}function wr(n,t){return t.y-n.y||t.x-n.x}function Sr(n,t,e){return(n.x-e.x)*(t.y-n.y)-(n.x-t.x)*(e.y-n.y)}function kr(n){return n.x}function Er(n){return n.y}function Ar(){return{leaf:!0,nodes:[],point:null,x:null,y:null}}function Cr(n,t,e,r,u,i){if(!n(t,e,r,u,i)){var o=.5*(e+u),a=.5*(r+i),c=t.nodes;c[0]&&Cr(n,c[0],e,r,o,a),c[1]&&Cr(n,c[1],o,r,u,a),c[2]&&Cr(n,c[2],e,a,o,i),c[3]&&Cr(n,c[3],o,a,u,i)}}function Nr(n,t){n=Bo.rgb(n),t=Bo.rgb(t);var e=n.r,r=n.g,u=n.b,i=t.r-e,o=t.g-r,a=t.b-u;return function(n){return"#"+st(Math.round(e+i*n))+st(Math.round(r+o*n))+st(Math.round(u+a*n))}}function Lr(n,t){var e,r={},u={};for(e in n)e in t?r[e]=zr(n[e],t[e]):u[e]=n[e];for(e in t)e in n||(u[e]=t[e]);return function(n){for(e in r)u[e]=r[e](n);return u}}function Tr(n,t){return t-=n=+n,function(e){return n+t*e}}function qr(n,t){var e,r,u,i,o,a=0,c=0,s=[],l=[];for(n+="",t+="",ns.lastIndex=0,r=0;e=ns.exec(t);++r)e.index&&s.push(t.substring(a,c=e.index)),l.push({i:s.length,x:e[0]}),s.push(null),a=ns.lastIndex;for(a<t.length&&s.push(t.substring(a)),r=0,i=l.length;(e=ns.exec(n))&&i>r;++r)if(o=l[r],o.x==e[0]){if(o.i)if(null==s[o.i+1])for(s[o.i-1]+=o.x,s.splice(o.i,1),u=r+1;i>u;++u)l[u].i--;else for(s[o.i-1]+=o.x+s[o.i+1],s.splice(o.i,2),u=r+1;i>u;++u)l[u].i-=2;else if(null==s[o.i+1])s[o.i]=o.x;else for(s[o.i]=o.x+s[o.i+1],s.splice(o.i+1,1),u=r+1;i>u;++u)l[u].i--;l.splice(r,1),i--,r--}else o.x=Tr(parseFloat(e[0]),parseFloat(o.x));for(;i>r;)o=l.pop(),null==s[o.i+1]?s[o.i]=o.x:(s[o.i]=o.x+s[o.i+1],s.splice(o.i+1,1)),i--;return 1===s.length?null==s[0]?(o=l[0].x,function(n){return o(n)+""}):function(){return t}:function(n){for(r=0;i>r;++r)s[(o=l[r]).i]=o.x(n);return s.join("")}}function zr(n,t){for(var e,r=Bo.interpolators.length;--r>=0&&!(e=Bo.interpolators[r](n,t)););return e}function Rr(n,t){var e,r=[],u=[],i=n.length,o=t.length,a=Math.min(n.length,t.length);for(e=0;a>e;++e)r.push(zr(n[e],t[e]));for(;i>e;++e)u[e]=n[e];for(;o>e;++e)u[e]=t[e];return function(n){for(e=0;a>e;++e)u[e]=r[e](n);return u}}function Dr(n){return function(t){return 0>=t?0:t>=1?1:n(t)}}function Pr(n){return function(t){return 1-n(1-t)}}function Ur(n){return function(t){return.5*(.5>t?n(2*t):2-n(2-2*t))}}function jr(n){return n*n}function Hr(n){return n*n*n}function Fr(n){if(0>=n)return 0;if(n>=1)return 1;var t=n*n,e=t*n;return 4*(.5>n?e:3*(n-t)+e-.75)}function Or(n){return function(t){return Math.pow(t,n)}}function Yr(n){return 1-Math.cos(n*Ca)}function Ir(n){return Math.pow(2,10*(n-1))}function Zr(n){return 1-Math.sqrt(1-n*n)}function Vr(n,t){var e;return arguments.length<2&&(t=.45),arguments.length?e=t/Aa*Math.asin(1/n):(n=1,e=t/4),function(r){return 1+n*Math.pow(2,-10*r)*Math.sin((r-e)*Aa/t)}}function Xr(n){return n||(n=1.70158),function(t){return t*t*((n+1)*t-n)}}function $r(n){return 1/2.75>n?7.5625*n*n:2/2.75>n?7.5625*(n-=1.5/2.75)*n+.75:2.5/2.75>n?7.5625*(n-=2.25/2.75)*n+.9375:7.5625*(n-=2.625/2.75)*n+.984375}function Br(n,t){n=Bo.hcl(n),t=Bo.hcl(t);var e=n.h,r=n.c,u=n.l,i=t.h-e,o=t.c-r,a=t.l-u;return isNaN(o)&&(o=0,r=isNaN(r)?t.c:r),isNaN(i)?(i=0,e=isNaN(e)?t.h:e):i>180?i-=360:-180>i&&(i+=360),function(n){return G(e+i*n,r+o*n,u+a*n)+""}}function Wr(n,t){n=Bo.hsl(n),t=Bo.hsl(t);var e=n.h,r=n.s,u=n.l,i=t.h-e,o=t.s-r,a=t.l-u;return isNaN(o)&&(o=0,r=isNaN(r)?t.s:r),isNaN(i)?(i=0,e=isNaN(e)?t.h:e):i>180?i-=360:-180>i&&(i+=360),function(n){return B(e+i*n,r+o*n,u+a*n)+""}}function Jr(n,t){n=Bo.lab(n),t=Bo.lab(t);var e=n.l,r=n.a,u=n.b,i=t.l-e,o=t.a-r,a=t.b-u;return function(n){return nt(e+i*n,r+o*n,u+a*n)+""}}function Gr(n,t){return t-=n,function(e){return Math.round(n+t*e)}}function Kr(n){var t=[n.a,n.b],e=[n.c,n.d],r=nu(t),u=Qr(t,e),i=nu(tu(e,t,-u))||0;t[0]*e[1]<e[0]*t[1]&&(t[0]*=-1,t[1]*=-1,r*=-1,u*=-1),this.rotate=(r?Math.atan2(t[1],t[0]):Math.atan2(-e[0],e[1]))*qa,this.translate=[n.e,n.f],this.scale=[r,i],this.skew=i?Math.atan2(u,i)*qa:0}function Qr(n,t){return n[0]*t[0]+n[1]*t[1]}function nu(n){var t=Math.sqrt(Qr(n,n));return t&&(n[0]/=t,n[1]/=t),t}function tu(n,t,e){return n[0]+=e*t[0],n[1]+=e*t[1],n}function eu(n,t){var e,r=[],u=[],i=Bo.transform(n),o=Bo.transform(t),a=i.translate,c=o.translate,s=i.rotate,l=o.rotate,f=i.skew,h=o.skew,g=i.scale,p=o.scale;return a[0]!=c[0]||a[1]!=c[1]?(r.push("translate(",null,",",null,")"),u.push({i:1,x:Tr(a[0],c[0])},{i:3,x:Tr(a[1],c[1])})):c[0]||c[1]?r.push("translate("+c+")"):r.push(""),s!=l?(s-l>180?l+=360:l-s>180&&(s+=360),u.push({i:r.push(r.pop()+"rotate(",null,")")-2,x:Tr(s,l)})):l&&r.push(r.pop()+"rotate("+l+")"),f!=h?u.push({i:r.push(r.pop()+"skewX(",null,")")-2,x:Tr(f,h)}):h&&r.push(r.pop()+"skewX("+h+")"),g[0]!=p[0]||g[1]!=p[1]?(e=r.push(r.pop()+"scale(",null,",",null,")"),u.push({i:e-4,x:Tr(g[0],p[0])},{i:e-2,x:Tr(g[1],p[1])})):(1!=p[0]||1!=p[1])&&r.push(r.pop()+"scale("+p+")"),e=u.length,function(n){for(var t,i=-1;++i<e;)r[(t=u[i]).i]=t.x(n);return r.join("")}}function ru(n,t){return t=t-(n=+n)?1/(t-n):0,function(e){return(e-n)*t}}function uu(n,t){return t=t-(n=+n)?1/(t-n):0,function(e){return Math.max(0,Math.min(1,(e-n)*t))}}function iu(n){for(var t=n.source,e=n.target,r=au(t,e),u=[t];t!==r;)t=t.parent,u.push(t);for(var i=u.length;e!==r;)u.splice(i,0,e),e=e.parent;return u}function ou(n){for(var t=[],e=n.parent;null!=e;)t.push(n),n=e,e=e.parent;return t.push(n),t}function au(n,t){if(n===t)return n;for(var e=ou(n),r=ou(t),u=e.pop(),i=r.pop(),o=null;u===i;)o=u,u=e.pop(),i=r.pop();return o}function cu(n){n.fixed|=2}function su(n){n.fixed&=-7}function lu(n){n.fixed|=4,n.px=n.x,n.py=n.y}function fu(n){n.fixed&=-5}function hu(n,t,e){var r=0,u=0;if(n.charge=0,!n.leaf)for(var i,o=n.nodes,a=o.length,c=-1;++c<a;)i=o[c],null!=i&&(hu(i,t,e),n.charge+=i.charge,r+=i.charge*i.cx,u+=i.charge*i.cy);if(n.point){n.leaf||(n.point.x+=Math.random()-.5,n.point.y+=Math.random()-.5);var s=t*e[n.point.index];n.charge+=n.pointCharge=s,r+=s*n.point.x,u+=s*n.point.y}n.cx=r/n.charge,n.cy=u/n.charge}function gu(n,t){return Bo.rebind(n,t,"sort","children","value"),n.nodes=n,n.links=mu,n}function pu(n){return n.children}function vu(n){return n.value}function du(n,t){return t.value-n.value}function mu(n){return Bo.merge(n.map(function(n){return(n.children||[]).map(function(t){return{source:n,target:t}})}))}function yu(n){return n.x}function xu(n){return n.y}function Mu(n,t,e){n.y0=t,n.y=e}function _u(n){return Bo.range(n.length)}function bu(n){for(var t=-1,e=n[0].length,r=[];++t<e;)r[t]=0;return r}function wu(n){for(var t,e=1,r=0,u=n[0][1],i=n.length;i>e;++e)(t=n[e][1])>u&&(r=e,u=t);return r}function Su(n){return n.reduce(ku,0)}function ku(n,t){return n+t[1]}function Eu(n,t){return Au(n,Math.ceil(Math.log(t.length)/Math.LN2+1))}function Au(n,t){for(var e=-1,r=+n[0],u=(n[1]-r)/t,i=[];++e<=t;)i[e]=u*e+r;return i}function Cu(n){return[Bo.min(n),Bo.max(n)]}function Nu(n,t){return n.parent==t.parent?1:2}function Lu(n){var t=n.children;return t&&t.length?t[0]:n._tree.thread}function Tu(n){var t,e=n.children;return e&&(t=e.length)?e[t-1]:n._tree.thread}function qu(n,t){var e=n.children;if(e&&(u=e.length))for(var r,u,i=-1;++i<u;)t(r=qu(e[i],t),n)>0&&(n=r);return n}function zu(n,t){return n.x-t.x}function Ru(n,t){return t.x-n.x}function Du(n,t){return n.depth-t.depth}function Pu(n,t){function e(n,r){var u=n.children;if(u&&(o=u.length))for(var i,o,a=null,c=-1;++c<o;)i=u[c],e(i,a),a=i;t(n,r)}e(n,null)}function Uu(n){for(var t,e=0,r=0,u=n.children,i=u.length;--i>=0;)t=u[i]._tree,t.prelim+=e,t.mod+=e,e+=t.shift+(r+=t.change)}function ju(n,t,e){n=n._tree,t=t._tree;var r=e/(t.number-n.number);n.change+=r,t.change-=r,t.shift+=e,t.prelim+=e,t.mod+=e}function Hu(n,t,e){return n._tree.ancestor.parent==t.parent?n._tree.ancestor:e}function Fu(n,t){return n.value-t.value}function Ou(n,t){var e=n._pack_next;n._pack_next=t,t._pack_prev=n,t._pack_next=e,e._pack_prev=t}function Yu(n,t){n._pack_next=t,t._pack_prev=n}function Iu(n,t){var e=t.x-n.x,r=t.y-n.y,u=n.r+t.r;return.999*u*u>e*e+r*r}function Zu(n){function t(n){l=Math.min(n.x-n.r,l),f=Math.max(n.x+n.r,f),h=Math.min(n.y-n.r,h),g=Math.max(n.y+n.r,g)}if((e=n.children)&&(s=e.length)){var e,r,u,i,o,a,c,s,l=1/0,f=-1/0,h=1/0,g=-1/0;if(e.forEach(Vu),r=e[0],r.x=-r.r,r.y=0,t(r),s>1&&(u=e[1],u.x=u.r,u.y=0,t(u),s>2))for(i=e[2],Bu(r,u,i),t(i),Ou(r,i),r._pack_prev=i,Ou(i,u),u=r._pack_next,o=3;s>o;o++){Bu(r,u,i=e[o]);var p=0,v=1,d=1;for(a=u._pack_next;a!==u;a=a._pack_next,v++)if(Iu(a,i)){p=1;break}if(1==p)for(c=r._pack_prev;c!==a._pack_prev&&!Iu(c,i);c=c._pack_prev,d++);p?(d>v||v==d&&u.r<r.r?Yu(r,u=a):Yu(r=c,u),o--):(Ou(r,i),u=i,t(i))}var m=(l+f)/2,y=(h+g)/2,x=0;for(o=0;s>o;o++)i=e[o],i.x-=m,i.y-=y,x=Math.max(x,i.r+Math.sqrt(i.x*i.x+i.y*i.y));n.r=x,e.forEach(Xu)}}function Vu(n){n._pack_next=n._pack_prev=n}function Xu(n){delete n._pack_next,delete n._pack_prev}function $u(n,t,e,r){var u=n.children;if(n.x=t+=r*n.x,n.y=e+=r*n.y,n.r*=r,u)for(var i=-1,o=u.length;++i<o;)$u(u[i],t,e,r)}function Bu(n,t,e){var r=n.r+e.r,u=t.x-n.x,i=t.y-n.y;if(r&&(u||i)){var o=t.r+e.r,a=u*u+i*i;o*=o,r*=r;var c=.5+(r-o)/(2*a),s=Math.sqrt(Math.max(0,2*o*(r+a)-(r-=a)*r-o*o))/(2*a);e.x=n.x+c*u+s*i,e.y=n.y+c*i-s*u}else e.x=n.x+r,e.y=n.y}function Wu(n){return 1+Bo.max(n,function(n){return n.y})}function Ju(n){return n.reduce(function(n,t){return n+t.x},0)/n.length}function Gu(n){var t=n.children;return t&&t.length?Gu(t[0]):n}function Ku(n){var t,e=n.children;return e&&(t=e.length)?Ku(e[t-1]):n}function Qu(n){return{x:n.x,y:n.y,dx:n.dx,dy:n.dy}}function ni(n,t){var e=n.x+t[3],r=n.y+t[0],u=n.dx-t[1]-t[3],i=n.dy-t[0]-t[2];return 0>u&&(e+=u/2,u=0),0>i&&(r+=i/2,i=0),{x:e,y:r,dx:u,dy:i}}function ti(n){var t=n[0],e=n[n.length-1];return e>t?[t,e]:[e,t]}function ei(n){return n.rangeExtent?n.rangeExtent():ti(n.range())}function ri(n,t,e,r){var u=e(n[0],n[1]),i=r(t[0],t[1]);return function(n){return i(u(n))}}function ui(n,t){var e,r=0,u=n.length-1,i=n[r],o=n[u];return i>o&&(e=r,r=u,u=e,e=i,i=o,o=e),n[r]=t.floor(i),n[u]=t.ceil(o),n}function ii(n){return n?{floor:function(t){return Math.floor(t/n)*n},ceil:function(t){return Math.ceil(t/n)*n}}:ls}function oi(n,t,e,r){var u=[],i=[],o=0,a=Math.min(n.length,t.length)-1;for(n[a]<n[0]&&(n=n.slice().reverse(),t=t.slice().reverse());++o<=a;)u.push(e(n[o-1],n[o])),i.push(r(t[o-1],t[o]));return function(t){var e=Bo.bisect(n,t,1,a)-1;return i[e](u[e](t))}}function ai(n,t,e,r){function u(){var u=Math.min(n.length,t.length)>2?oi:ri,c=r?uu:ru;return o=u(n,t,c,e),a=u(t,n,c,zr),i}function i(n){return o(n)}var o,a;return i.invert=function(n){return a(n)},i.domain=function(t){return arguments.length?(n=t.map(Number),u()):n},i.range=function(n){return arguments.length?(t=n,u()):t},i.rangeRound=function(n){return i.range(n).interpolate(Gr)},i.clamp=function(n){return arguments.length?(r=n,u()):r},i.interpolate=function(n){return arguments.length?(e=n,u()):e},i.ticks=function(t){return fi(n,t)},i.tickFormat=function(t,e){return hi(n,t,e)},i.nice=function(t){return si(n,t),u()},i.copy=function(){return ai(n,t,e,r)},u()}function ci(n,t){return Bo.rebind(n,t,"range","rangeRound","interpolate","clamp")}function si(n,t){return ui(n,ii(li(n,t)[2]))}function li(n,t){null==t&&(t=10);var e=ti(n),r=e[1]-e[0],u=Math.pow(10,Math.floor(Math.log(r/t)/Math.LN10)),i=t/r*u;return.15>=i?u*=10:.35>=i?u*=5:.75>=i&&(u*=2),e[0]=Math.ceil(e[0]/u)*u,e[1]=Math.floor(e[1]/u)*u+.5*u,e[2]=u,e}function fi(n,t){return Bo.range.apply(Bo,li(n,t))}function hi(n,t,e){var r=li(n,t);return Bo.format(e?e.replace(ic,function(n,t,e,u,i,o,a,c,s,l){return[t,e,u,i,o,a,c,s||"."+pi(l,r),l].join("")}):",."+gi(r[2])+"f")}function gi(n){return-Math.floor(Math.log(n)/Math.LN10+.01)}function pi(n,t){var e=gi(t[2]);return n in fs?Math.abs(e-gi(Math.max(Math.abs(t[0]),Math.abs(t[1]))))+ +("e"!==n):e-2*("%"===n)}function vi(n,t,e,r){function u(n){return(e?Math.log(0>n?0:n):-Math.log(n>0?0:-n))/Math.log(t)}function i(n){return e?Math.pow(t,n):-Math.pow(t,-n)}function o(t){return n(u(t))}return o.invert=function(t){return i(n.invert(t))},o.domain=function(t){return arguments.length?(e=t[0]>=0,n.domain((r=t.map(Number)).map(u)),o):r},o.base=function(e){return arguments.length?(t=+e,n.domain(r.map(u)),o):t},o.nice=function(){var t=ui(r.map(u),e?Math:gs);return n.domain(t),r=t.map(i),o},o.ticks=function(){var n=ti(r),o=[],a=n[0],c=n[1],s=Math.floor(u(a)),l=Math.ceil(u(c)),f=t%1?2:t;if(isFinite(l-s)){if(e){for(;l>s;s++)for(var h=1;f>h;h++)o.push(i(s)*h);o.push(i(s))}else for(o.push(i(s));s++<l;)for(var h=f-1;h>0;h--)o.push(i(s)*h);for(s=0;o[s]<a;s++);for(l=o.length;o[l-1]>c;l--);o=o.slice(s,l)}return o},o.tickFormat=function(n,t){if(!arguments.length)return hs;arguments.length<2?t=hs:"function"!=typeof t&&(t=Bo.format(t));var r,a=Math.max(.1,n/o.ticks().length),c=e?(r=1e-12,Math.ceil):(r=-1e-12,Math.floor);return function(n){return n/i(c(u(n)+r))<=a?t(n):""}},o.copy=function(){return vi(n.copy(),t,e,r)},ci(o,n)}function di(n,t,e){function r(t){return n(u(t))}var u=mi(t),i=mi(1/t);return r.invert=function(t){return i(n.invert(t))},r.domain=function(t){return arguments.length?(n.domain((e=t.map(Number)).map(u)),r):e},r.ticks=function(n){return fi(e,n)},r.tickFormat=function(n,t){return hi(e,n,t)},r.nice=function(n){return r.domain(si(e,n))},r.exponent=function(o){return arguments.length?(u=mi(t=o),i=mi(1/t),n.domain(e.map(u)),r):t},r.copy=function(){return di(n.copy(),t,e)},ci(r,n)}function mi(n){return function(t){return 0>t?-Math.pow(-t,n):Math.pow(t,n)}}function yi(n,t){function e(e){return o[((i.get(e)||"range"===t.t&&i.set(e,n.push(e)))-1)%o.length]}function r(t,e){return Bo.range(n.length).map(function(n){return t+e*n})}var i,o,a;return e.domain=function(r){if(!arguments.length)return n;n=[],i=new u;for(var o,a=-1,c=r.length;++a<c;)i.has(o=r[a])||i.set(o,n.push(o));return e[t.t].apply(e,t.a)},e.range=function(n){return arguments.length?(o=n,a=0,t={t:"range",a:arguments},e):o},e.rangePoints=function(u,i){arguments.length<2&&(i=0);var c=u[0],s=u[1],l=(s-c)/(Math.max(1,n.length-1)+i);return o=r(n.length<2?(c+s)/2:c+l*i/2,l),a=0,t={t:"rangePoints",a:arguments},e},e.rangeBands=function(u,i,c){arguments.length<2&&(i=0),arguments.length<3&&(c=i);var s=u[1]<u[0],l=u[s-0],f=u[1-s],h=(f-l)/(n.length-i+2*c);return o=r(l+h*c,h),s&&o.reverse(),a=h*(1-i),t={t:"rangeBands",a:arguments},e},e.rangeRoundBands=function(u,i,c){arguments.length<2&&(i=0),arguments.length<3&&(c=i);var s=u[1]<u[0],l=u[s-0],f=u[1-s],h=Math.floor((f-l)/(n.length-i+2*c)),g=f-l-(n.length-i)*h;return o=r(l+Math.round(g/2),h),s&&o.reverse(),a=Math.round(h*(1-i)),t={t:"rangeRoundBands",a:arguments},e},e.rangeBand=function(){return a},e.rangeExtent=function(){return ti(t.a[0])},e.copy=function(){return yi(n,t)},e.domain(n)}function xi(n,t){function e(){var e=0,i=t.length;for(u=[];++e<i;)u[e-1]=Bo.quantile(n,e/i);return r}function r(n){return isNaN(n=+n)?void 0:t[Bo.bisect(u,n)]}var u;return r.domain=function(t){return arguments.length?(n=t.filter(function(n){return!isNaN(n)}).sort(Bo.ascending),e()):n},r.range=function(n){return arguments.length?(t=n,e()):t},r.quantiles=function(){return u},r.invertExtent=function(e){return e=t.indexOf(e),0>e?[0/0,0/0]:[e>0?u[e-1]:n[0],e<u.length?u[e]:n[n.length-1]]},r.copy=function(){return xi(n,t)},e()}function Mi(n,t,e){function r(t){return e[Math.max(0,Math.min(o,Math.floor(i*(t-n))))]}function u(){return i=e.length/(t-n),o=e.length-1,r}var i,o;return r.domain=function(e){return arguments.length?(n=+e[0],t=+e[e.length-1],u()):[n,t]},r.range=function(n){return arguments.length?(e=n,u()):e},r.invertExtent=function(t){return t=e.indexOf(t),t=0>t?0/0:t/i+n,[t,t+1/i]},r.copy=function(){return Mi(n,t,e)},u()}function _i(n,t){function e(e){return e>=e?t[Bo.bisect(n,e)]:void 0}return e.domain=function(t){return arguments.length?(n=t,e):n},e.range=function(n){return arguments.length?(t=n,e):t},e.invertExtent=function(e){return e=t.indexOf(e),[n[e-1],n[e]]},e.copy=function(){return _i(n,t)},e}function bi(n){function t(n){return+n}return t.invert=t,t.domain=t.range=function(e){return arguments.length?(n=e.map(t),t):n},t.ticks=function(t){return fi(n,t)},t.tickFormat=function(t,e){return hi(n,t,e)},t.copy=function(){return bi(n)},t}function wi(n){return n.innerRadius}function Si(n){return n.outerRadius}function ki(n){return n.startAngle}function Ei(n){return n.endAngle}function Ai(n){function t(t){function o(){s.push("M",i(n(l),a))}for(var c,s=[],l=[],f=-1,h=t.length,g=vt(e),p=vt(r);++f<h;)u.call(this,c=t[f],f)?l.push([+g.call(this,c,f),+p.call(this,c,f)]):l.length&&(o(),l=[]);return l.length&&o(),s.length?s.join(""):null}var e=Ve,r=Xe,u=Vt,i=Ci,o=i.key,a=.7;return t.x=function(n){return arguments.length?(e=n,t):e},t.y=function(n){return arguments.length?(r=n,t):r},t.defined=function(n){return arguments.length?(u=n,t):u},t.interpolate=function(n){return arguments.length?(o="function"==typeof n?i=n:(i=Ms.get(n)||Ci).key,t):o},t.tension=function(n){return arguments.length?(a=n,t):a},t}function Ci(n){return n.join("L")}function Ni(n){return Ci(n)+"Z"}function Li(n){for(var t=0,e=n.length,r=n[0],u=[r[0],",",r[1]];++t<e;)u.push("H",(r[0]+(r=n[t])[0])/2,"V",r[1]);return e>1&&u.push("H",r[0]),u.join("")}function Ti(n){for(var t=0,e=n.length,r=n[0],u=[r[0],",",r[1]];++t<e;)u.push("V",(r=n[t])[1],"H",r[0]);return u.join("")}function qi(n){for(var t=0,e=n.length,r=n[0],u=[r[0],",",r[1]];++t<e;)u.push("H",(r=n[t])[0],"V",r[1]);return u.join("")}function zi(n,t){return n.length<4?Ci(n):n[1]+Pi(n.slice(1,n.length-1),Ui(n,t))}function Ri(n,t){return n.length<3?Ci(n):n[0]+Pi((n.push(n[0]),n),Ui([n[n.length-2]].concat(n,[n[1]]),t))}function Di(n,t){return n.length<3?Ci(n):n[0]+Pi(n,Ui(n,t))}function Pi(n,t){if(t.length<1||n.length!=t.length&&n.length!=t.length+2)return Ci(n);var e=n.length!=t.length,r="",u=n[0],i=n[1],o=t[0],a=o,c=1;if(e&&(r+="Q"+(i[0]-2*o[0]/3)+","+(i[1]-2*o[1]/3)+","+i[0]+","+i[1],u=n[1],c=2),t.length>1){a=t[1],i=n[c],c++,r+="C"+(u[0]+o[0])+","+(u[1]+o[1])+","+(i[0]-a[0])+","+(i[1]-a[1])+","+i[0]+","+i[1];for(var s=2;s<t.length;s++,c++)i=n[c],a=t[s],r+="S"+(i[0]-a[0])+","+(i[1]-a[1])+","+i[0]+","+i[1]}if(e){var l=n[c];r+="Q"+(i[0]+2*a[0]/3)+","+(i[1]+2*a[1]/3)+","+l[0]+","+l[1]}return r}function Ui(n,t){for(var e,r=[],u=(1-t)/2,i=n[0],o=n[1],a=1,c=n.length;++a<c;)e=i,i=o,o=n[a],r.push([u*(o[0]-e[0]),u*(o[1]-e[1])]);return r}function ji(n){if(n.length<3)return Ci(n);var t=1,e=n.length,r=n[0],u=r[0],i=r[1],o=[u,u,u,(r=n[1])[0]],a=[i,i,i,r[1]],c=[u,",",i,"L",Yi(ws,o),",",Yi(ws,a)];for(n.push(n[e-1]);++t<=e;)r=n[t],o.shift(),o.push(r[0]),a.shift(),a.push(r[1]),Ii(c,o,a);return n.pop(),c.push("L",r),c.join("")}function Hi(n){if(n.length<4)return Ci(n);for(var t,e=[],r=-1,u=n.length,i=[0],o=[0];++r<3;)t=n[r],i.push(t[0]),o.push(t[1]);for(e.push(Yi(ws,i)+","+Yi(ws,o)),--r;++r<u;)t=n[r],i.shift(),i.push(t[0]),o.shift(),o.push(t[1]),Ii(e,i,o);return e.join("")}function Fi(n){for(var t,e,r=-1,u=n.length,i=u+4,o=[],a=[];++r<4;)e=n[r%u],o.push(e[0]),a.push(e[1]);for(t=[Yi(ws,o),",",Yi(ws,a)],--r;++r<i;)e=n[r%u],o.shift(),o.push(e[0]),a.shift(),a.push(e[1]),Ii(t,o,a);return t.join("")}function Oi(n,t){var e=n.length-1;if(e)for(var r,u,i=n[0][0],o=n[0][1],a=n[e][0]-i,c=n[e][1]-o,s=-1;++s<=e;)r=n[s],u=s/e,r[0]=t*r[0]+(1-t)*(i+u*a),r[1]=t*r[1]+(1-t)*(o+u*c);return ji(n)}function Yi(n,t){return n[0]*t[0]+n[1]*t[1]+n[2]*t[2]+n[3]*t[3]}function Ii(n,t,e){n.push("C",Yi(_s,t),",",Yi(_s,e),",",Yi(bs,t),",",Yi(bs,e),",",Yi(ws,t),",",Yi(ws,e))}function Zi(n,t){return(t[1]-n[1])/(t[0]-n[0])}function Vi(n){for(var t=0,e=n.length-1,r=[],u=n[0],i=n[1],o=r[0]=Zi(u,i);++t<e;)r[t]=(o+(o=Zi(u=i,i=n[t+1])))/2;return r[t]=o,r}function Xi(n){for(var t,e,r,u,i=[],o=Vi(n),a=-1,c=n.length-1;++a<c;)t=Zi(n[a],n[a+1]),ca(t)<Na?o[a]=o[a+1]=0:(e=o[a]/t,r=o[a+1]/t,u=e*e+r*r,u>9&&(u=3*t/Math.sqrt(u),o[a]=u*e,o[a+1]=u*r));for(a=-1;++a<=c;)u=(n[Math.min(c,a+1)][0]-n[Math.max(0,a-1)][0])/(6*(1+o[a]*o[a])),i.push([u||0,o[a]*u||0]);return i}function $i(n){return n.length<3?Ci(n):n[0]+Pi(n,Xi(n))}function Bi(n){for(var t,e,r,u=-1,i=n.length;++u<i;)t=n[u],e=t[0],r=t[1]+ys,t[0]=e*Math.cos(r),t[1]=e*Math.sin(r);return n}function Wi(n){function t(t){function c(){v.push("M",a(n(m),f),l,s(n(d.reverse()),f),"Z")}for(var h,g,p,v=[],d=[],m=[],y=-1,x=t.length,M=vt(e),_=vt(u),b=e===r?function(){return g}:vt(r),w=u===i?function(){return p}:vt(i);++y<x;)o.call(this,h=t[y],y)?(d.push([g=+M.call(this,h,y),p=+_.call(this,h,y)]),m.push([+b.call(this,h,y),+w.call(this,h,y)])):d.length&&(c(),d=[],m=[]);return d.length&&c(),v.length?v.join(""):null}var e=Ve,r=Ve,u=0,i=Xe,o=Vt,a=Ci,c=a.key,s=a,l="L",f=.7;return t.x=function(n){return arguments.length?(e=r=n,t):r},t.x0=function(n){return arguments.length?(e=n,t):e},t.x1=function(n){return arguments.length?(r=n,t):r},t.y=function(n){return arguments.length?(u=i=n,t):i},t.y0=function(n){return arguments.length?(u=n,t):u},t.y1=function(n){return arguments.length?(i=n,t):i},t.defined=function(n){return arguments.length?(o=n,t):o},t.interpolate=function(n){return arguments.length?(c="function"==typeof n?a=n:(a=Ms.get(n)||Ci).key,s=a.reverse||a,l=a.closed?"M":"L",t):c},t.tension=function(n){return arguments.length?(f=n,t):f},t}function Ji(n){return n.radius}function Gi(n){return[n.x,n.y]}function Ki(n){return function(){var t=n.apply(this,arguments),e=t[0],r=t[1]+ys;return[e*Math.cos(r),e*Math.sin(r)]}}function Qi(){return 64}function no(){return"circle"}function to(n){var t=Math.sqrt(n/Ea);return"M0,"+t+"A"+t+","+t+" 0 1,1 0,"+-t+"A"+t+","+t+" 0 1,1 0,"+t+"Z"}function eo(n,t){return ga(n,Ns),n.id=t,n}function ro(n,t,e,r){var u=n.id;return N(n,"function"==typeof e?function(n,i,o){n.__transition__[u].tween.set(t,r(e.call(n,n.__data__,i,o)))}:(e=r(e),function(n){n.__transition__[u].tween.set(t,e)}))}function uo(n){return null==n&&(n=""),function(){this.textContent=n}}function io(n,t,e,r){var i=n.__transition__||(n.__transition__={active:0,count:0}),o=i[e];if(!o){var a=r.time;o=i[e]={tween:new u,time:a,ease:r.ease,delay:r.delay,duration:r.duration},++i.count,Bo.timer(function(r){function u(r){return i.active>e?s():(i.active=e,o.event&&o.event.start.call(n,l,t),o.tween.forEach(function(e,r){(r=r.call(n,l,t))&&v.push(r)}),Bo.timer(function(){return p.c=c(r||1)?Vt:c,1},0,a),void 0)}function c(r){if(i.active!==e)return s();for(var u=r/g,a=f(u),c=v.length;c>0;)v[--c].call(n,a);return u>=1?(o.event&&o.event.end.call(n,l,t),s()):void 0}function s(){return--i.count?delete i[e]:delete n.__transition__,1}var l=n.__data__,f=o.ease,h=o.delay,g=o.duration,p=Ka,v=[];return p.t=h+a,r>=h?u(r-h):(p.c=u,void 0)},0,a)}}function oo(n,t){n.attr("transform",function(n){return"translate("+t(n)+",0)"})}function ao(n,t){n.attr("transform",function(n){return"translate(0,"+t(n)+")"})}function co(){this._=new Date(arguments.length>1?Date.UTC.apply(this,arguments):arguments[0])}function so(n,t,e){function r(t){var e=n(t),r=i(e,1);return r-t>t-e?e:r}function u(e){return t(e=n(new Ps(e-1)),1),e}function i(n,e){return t(n=new Ps(+n),e),n}function o(n,r,i){var o=u(n),a=[];if(i>1)for(;r>o;)e(o)%i||a.push(new Date(+o)),t(o,1);else for(;r>o;)a.push(new Date(+o)),t(o,1);return a}function a(n,t,e){try{Ps=co;var r=new co;return r._=n,o(r,t,e)}finally{Ps=Date}}n.floor=n,n.round=r,n.ceil=u,n.offset=i,n.range=o;var c=n.utc=lo(n);return c.floor=c,c.round=lo(r),c.ceil=lo(u),c.offset=lo(i),c.range=a,n}function lo(n){return function(t,e){try{Ps=co;var r=new co;return r._=t,n(r,e)._}finally{Ps=Date}}}function fo(n){function t(t){for(var r,u,i,o=[],a=-1,c=0;++a<e;)37===n.charCodeAt(a)&&(o.push(n.substring(c,a)),null!=(u=tl[r=n.charAt(++a)])&&(r=n.charAt(++a)),(i=el[r])&&(r=i(t,null==u?"e"===r?" ":"0":u)),o.push(r),c=a+1);return o.push(n.substring(c,a)),o.join("")}var e=n.length;return t.parse=function(t){var e={y:1900,m:0,d:1,H:0,M:0,S:0,L:0,Z:null},r=ho(e,n,t,0);if(r!=t.length)return null;"p"in e&&(e.H=e.H%12+12*e.p);var u=null!=e.Z&&Ps!==co,i=new(u?co:Ps);return"j"in e?i.setFullYear(e.y,0,e.j):"w"in e&&("W"in e||"U"in e)?(i.setFullYear(e.y,0,1),i.setFullYear(e.y,0,"W"in e?(e.w+6)%7+7*e.W-(i.getDay()+5)%7:e.w+7*e.U-(i.getDay()+6)%7)):i.setFullYear(e.y,e.m,e.d),i.setHours(e.H+Math.floor(e.Z/100),e.M+e.Z%100,e.S,e.L),u?i._:i},t.toString=function(){return n},t}function ho(n,t,e,r){for(var u,i,o,a=0,c=t.length,s=e.length;c>a;){if(r>=s)return-1;if(u=t.charCodeAt(a++),37===u){if(o=t.charAt(a++),i=rl[o in tl?t.charAt(a++):o],!i||(r=i(n,e,r))<0)return-1}else if(u!=e.charCodeAt(r++))return-1}return r}function go(n){return new RegExp("^(?:"+n.map(Bo.requote).join("|")+")","i")}function po(n){for(var t=new u,e=-1,r=n.length;++e<r;)t.set(n[e].toLowerCase(),e);return t}function vo(n,t,e){var r=0>n?"-":"",u=(r?-n:n)+"",i=u.length;return r+(e>i?new Array(e-i+1).join(t)+u:u)}function mo(n,t,e){Bs.lastIndex=0;var r=Bs.exec(t.substring(e));return r?(n.w=Ws.get(r[0].toLowerCase()),e+r[0].length):-1}function yo(n,t,e){Xs.lastIndex=0;var r=Xs.exec(t.substring(e));return r?(n.w=$s.get(r[0].toLowerCase()),e+r[0].length):-1}function xo(n,t,e){ul.lastIndex=0;var r=ul.exec(t.substring(e,e+1));return r?(n.w=+r[0],e+r[0].length):-1}function Mo(n,t,e){ul.lastIndex=0;var r=ul.exec(t.substring(e));return r?(n.U=+r[0],e+r[0].length):-1}function _o(n,t,e){ul.lastIndex=0;var r=ul.exec(t.substring(e));return r?(n.W=+r[0],e+r[0].length):-1}function bo(n,t,e){Ks.lastIndex=0;var r=Ks.exec(t.substring(e));return r?(n.m=Qs.get(r[0].toLowerCase()),e+r[0].length):-1}function wo(n,t,e){Js.lastIndex=0;var r=Js.exec(t.substring(e));return r?(n.m=Gs.get(r[0].toLowerCase()),e+r[0].length):-1}function So(n,t,e){return ho(n,el.c.toString(),t,e)}function ko(n,t,e){return ho(n,el.x.toString(),t,e)}function Eo(n,t,e){return ho(n,el.X.toString(),t,e)}function Ao(n,t,e){ul.lastIndex=0;var r=ul.exec(t.substring(e,e+4));return r?(n.y=+r[0],e+r[0].length):-1}function Co(n,t,e){ul.lastIndex=0;var r=ul.exec(t.substring(e,e+2));return r?(n.y=Lo(+r[0]),e+r[0].length):-1}function No(n,t,e){return/^[+-]\d{4}$/.test(t=t.substring(e,e+5))?(n.Z=+t,e+5):-1}function Lo(n){return n+(n>68?1900:2e3)}function To(n,t,e){ul.lastIndex=0;var r=ul.exec(t.substring(e,e+2));return r?(n.m=r[0]-1,e+r[0].length):-1}function qo(n,t,e){ul.lastIndex=0;var r=ul.exec(t.substring(e,e+2));return r?(n.d=+r[0],e+r[0].length):-1}function zo(n,t,e){ul.lastIndex=0;var r=ul.exec(t.substring(e,e+3));return r?(n.j=+r[0],e+r[0].length):-1}function Ro(n,t,e){ul.lastIndex=0;var r=ul.exec(t.substring(e,e+2));return r?(n.H=+r[0],e+r[0].length):-1}function Do(n,t,e){ul.lastIndex=0;var r=ul.exec(t.substring(e,e+2));return r?(n.M=+r[0],e+r[0].length):-1}function Po(n,t,e){ul.lastIndex=0;var r=ul.exec(t.substring(e,e+2));return r?(n.S=+r[0],e+r[0].length):-1}function Uo(n,t,e){ul.lastIndex=0;var r=ul.exec(t.substring(e,e+3));return r?(n.L=+r[0],e+r[0].length):-1}function jo(n,t,e){var r=il.get(t.substring(e,e+=2).toLowerCase());return null==r?-1:(n.p=r,e)}function Ho(n){var t=n.getTimezoneOffset(),e=t>0?"-":"+",r=~~(ca(t)/60),u=ca(t)%60;return e+vo(r,"0",2)+vo(u,"0",2)}function Fo(n,t,e){nl.lastIndex=0;var r=nl.exec(t.substring(e,e+1));return r?e+r[0].length:-1}function Oo(n){function t(n){try{Ps=co;var t=new Ps;return t._=n,e(t)}finally{Ps=Date}}var e=fo(n);return t.parse=function(n){try{Ps=co;var t=e.parse(n);return t&&t._}finally{Ps=Date}},t.toString=e.toString,t}function Yo(n){return n.toISOString()}function Io(n,t,e){function r(t){return n(t)}function u(n,e){var r=n[1]-n[0],u=r/e,i=Bo.bisect(al,u);return i==al.length?[t.year,li(n.map(function(n){return n/31536e6}),e)[2]]:i?t[u/al[i-1]<al[i]/u?i-1:i]:[fl,li(n,e)[2]]}return r.invert=function(t){return Zo(n.invert(t))},r.domain=function(t){return arguments.length?(n.domain(t),r):n.domain().map(Zo)},r.nice=function(n,t){function e(e){return!isNaN(e)&&!n.range(e,Zo(+e+1),t).length}var i=r.domain(),o=ti(i),a=null==n?u(o,10):"number"==typeof n&&u(o,n);return a&&(n=a[0],t=a[1]),r.domain(ui(i,t>1?{floor:function(t){for(;e(t=n.floor(t));)t=Zo(t-1);return t},ceil:function(t){for(;e(t=n.ceil(t));)t=Zo(+t+1);return t}}:n))},r.ticks=function(n,t){var e=ti(r.domain()),i=null==n?u(e,10):"number"==typeof n?u(e,n):!n.range&&[{range:n},t];return i&&(n=i[0],t=i[1]),n.range(e[0],Zo(+e[1]+1),1>t?1:t)},r.tickFormat=function(){return e},r.copy=function(){return Io(n.copy(),t,e)},ci(r,n)}function Zo(n){return new Date(n)}function Vo(n){return function(t){for(var e=n.length-1,r=n[e];!r[1](t);)r=n[--e];return r[0](t)}}function Xo(n){return JSON.parse(n.responseText)}function $o(n){var t=Go.createRange();return t.selectNode(Go.body),t.createContextualFragment(n.responseText)}var Bo={version:"3.3.13"};Date.now||(Date.now=function(){return+new Date});var Wo=[].slice,Jo=function(n){return Wo.call(n)},Go=document,Ko=Go.documentElement,Qo=window;try{Jo(Ko.childNodes)[0].nodeType}catch(na){Jo=function(n){for(var t=n.length,e=new Array(t);t--;)e[t]=n[t];return e}}try{Go.createElement("div").style.setProperty("opacity",0,"")}catch(ta){var ea=Qo.Element.prototype,ra=ea.setAttribute,ua=ea.setAttributeNS,ia=Qo.CSSStyleDeclaration.prototype,oa=ia.setProperty;ea.setAttribute=function(n,t){ra.call(this,n,t+"")},ea.setAttributeNS=function(n,t,e){ua.call(this,n,t,e+"")},ia.setProperty=function(n,t,e){oa.call(this,n,t+"",e)}}Bo.ascending=function(n,t){return t>n?-1:n>t?1:n>=t?0:0/0},Bo.descending=function(n,t){return n>t?-1:t>n?1:t>=n?0:0/0},Bo.min=function(n,t){var e,r,u=-1,i=n.length;if(1===arguments.length){for(;++u<i&&!(null!=(e=n[u])&&e>=e);)e=void 0;for(;++u<i;)null!=(r=n[u])&&e>r&&(e=r)}else{for(;++u<i&&!(null!=(e=t.call(n,n[u],u))&&e>=e);)e=void 0;for(;++u<i;)null!=(r=t.call(n,n[u],u))&&e>r&&(e=r)}return e},Bo.max=function(n,t){var e,r,u=-1,i=n.length;if(1===arguments.length){for(;++u<i&&!(null!=(e=n[u])&&e>=e);)e=void 0;for(;++u<i;)null!=(r=n[u])&&r>e&&(e=r)}else{for(;++u<i&&!(null!=(e=t.call(n,n[u],u))&&e>=e);)e=void 0;for(;++u<i;)null!=(r=t.call(n,n[u],u))&&r>e&&(e=r)}return e},Bo.extent=function(n,t){var e,r,u,i=-1,o=n.length;if(1===arguments.length){for(;++i<o&&!(null!=(e=u=n[i])&&e>=e);)e=u=void 0;for(;++i<o;)null!=(r=n[i])&&(e>r&&(e=r),r>u&&(u=r))}else{for(;++i<o&&!(null!=(e=u=t.call(n,n[i],i))&&e>=e);)e=void 0;for(;++i<o;)null!=(r=t.call(n,n[i],i))&&(e>r&&(e=r),r>u&&(u=r))}return[e,u]},Bo.sum=function(n,t){var e,r=0,u=n.length,i=-1;if(1===arguments.length)for(;++i<u;)isNaN(e=+n[i])||(r+=e);else for(;++i<u;)isNaN(e=+t.call(n,n[i],i))||(r+=e);return r},Bo.mean=function(t,e){var r,u=t.length,i=0,o=-1,a=0;if(1===arguments.length)for(;++o<u;)n(r=t[o])&&(i+=(r-i)/++a);else for(;++o<u;)n(r=e.call(t,t[o],o))&&(i+=(r-i)/++a);return a?i:void 0},Bo.quantile=function(n,t){var e=(n.length-1)*t+1,r=Math.floor(e),u=+n[r-1],i=e-r; +return i?u+i*(n[r]-u):u},Bo.median=function(t,e){return arguments.length>1&&(t=t.map(e)),t=t.filter(n),t.length?Bo.quantile(t.sort(Bo.ascending),.5):void 0},Bo.bisector=function(n){return{left:function(t,e,r,u){for(arguments.length<3&&(r=0),arguments.length<4&&(u=t.length);u>r;){var i=r+u>>>1;n.call(t,t[i],i)<e?r=i+1:u=i}return r},right:function(t,e,r,u){for(arguments.length<3&&(r=0),arguments.length<4&&(u=t.length);u>r;){var i=r+u>>>1;e<n.call(t,t[i],i)?u=i:r=i+1}return r}}};var aa=Bo.bisector(function(n){return n});Bo.bisectLeft=aa.left,Bo.bisect=Bo.bisectRight=aa.right,Bo.shuffle=function(n){for(var t,e,r=n.length;r;)e=0|Math.random()*r--,t=n[r],n[r]=n[e],n[e]=t;return n},Bo.permute=function(n,t){for(var e=t.length,r=new Array(e);e--;)r[e]=n[t[e]];return r},Bo.pairs=function(n){for(var t,e=0,r=n.length-1,u=n[0],i=new Array(0>r?0:r);r>e;)i[e]=[t=u,u=n[++e]];return i},Bo.zip=function(){if(!(u=arguments.length))return[];for(var n=-1,e=Bo.min(arguments,t),r=new Array(e);++n<e;)for(var u,i=-1,o=r[n]=new Array(u);++i<u;)o[i]=arguments[i][n];return r},Bo.transpose=function(n){return Bo.zip.apply(Bo,n)},Bo.keys=function(n){var t=[];for(var e in n)t.push(e);return t},Bo.values=function(n){var t=[];for(var e in n)t.push(n[e]);return t},Bo.entries=function(n){var t=[];for(var e in n)t.push({key:e,value:n[e]});return t},Bo.merge=function(n){for(var t,e,r,u=n.length,i=-1,o=0;++i<u;)o+=n[i].length;for(e=new Array(o);--u>=0;)for(r=n[u],t=r.length;--t>=0;)e[--o]=r[t];return e};var ca=Math.abs;Bo.range=function(n,t,r){if(arguments.length<3&&(r=1,arguments.length<2&&(t=n,n=0)),1/0===(t-n)/r)throw new Error("infinite range");var u,i=[],o=e(ca(r)),a=-1;if(n*=o,t*=o,r*=o,0>r)for(;(u=n+r*++a)>t;)i.push(u/o);else for(;(u=n+r*++a)<t;)i.push(u/o);return i},Bo.map=function(n){var t=new u;if(n instanceof u)n.forEach(function(n,e){t.set(n,e)});else for(var e in n)t.set(e,n[e]);return t},r(u,{has:function(n){return sa+n in this},get:function(n){return this[sa+n]},set:function(n,t){return this[sa+n]=t},remove:function(n){return n=sa+n,n in this&&delete this[n]},keys:function(){var n=[];return this.forEach(function(t){n.push(t)}),n},values:function(){var n=[];return this.forEach(function(t,e){n.push(e)}),n},entries:function(){var n=[];return this.forEach(function(t,e){n.push({key:t,value:e})}),n},forEach:function(n){for(var t in this)t.charCodeAt(0)===la&&n.call(this,t.substring(1),this[t])}});var sa="\x00",la=sa.charCodeAt(0);Bo.nest=function(){function n(t,a,c){if(c>=o.length)return r?r.call(i,a):e?a.sort(e):a;for(var s,l,f,h,g=-1,p=a.length,v=o[c++],d=new u;++g<p;)(h=d.get(s=v(l=a[g])))?h.push(l):d.set(s,[l]);return t?(l=t(),f=function(e,r){l.set(e,n(t,r,c))}):(l={},f=function(e,r){l[e]=n(t,r,c)}),d.forEach(f),l}function t(n,e){if(e>=o.length)return n;var r=[],u=a[e++];return n.forEach(function(n,u){r.push({key:n,values:t(u,e)})}),u?r.sort(function(n,t){return u(n.key,t.key)}):r}var e,r,i={},o=[],a=[];return i.map=function(t,e){return n(e,t,0)},i.entries=function(e){return t(n(Bo.map,e,0),0)},i.key=function(n){return o.push(n),i},i.sortKeys=function(n){return a[o.length-1]=n,i},i.sortValues=function(n){return e=n,i},i.rollup=function(n){return r=n,i},i},Bo.set=function(n){var t=new i;if(n)for(var e=0,r=n.length;r>e;++e)t.add(n[e]);return t},r(i,{has:function(n){return sa+n in this},add:function(n){return this[sa+n]=!0,n},remove:function(n){return n=sa+n,n in this&&delete this[n]},values:function(){var n=[];return this.forEach(function(t){n.push(t)}),n},forEach:function(n){for(var t in this)t.charCodeAt(0)===la&&n.call(this,t.substring(1))}}),Bo.behavior={},Bo.rebind=function(n,t){for(var e,r=1,u=arguments.length;++r<u;)n[e=arguments[r]]=o(n,t,t[e]);return n};var fa=["webkit","ms","moz","Moz","o","O"];Bo.dispatch=function(){for(var n=new s,t=-1,e=arguments.length;++t<e;)n[arguments[t]]=l(n);return n},s.prototype.on=function(n,t){var e=n.indexOf("."),r="";if(e>=0&&(r=n.substring(e+1),n=n.substring(0,e)),n)return arguments.length<2?this[n].on(r):this[n].on(r,t);if(2===arguments.length){if(null==t)for(n in this)this.hasOwnProperty(n)&&this[n].on(r,null);return this}},Bo.event=null,Bo.requote=function(n){return n.replace(ha,"\\$&")};var ha=/[\\\^\$\*\+\?\|\[\]\(\)\.\{\}]/g,ga={}.__proto__?function(n,t){n.__proto__=t}:function(n,t){for(var e in t)n[e]=t[e]},pa=function(n,t){return t.querySelector(n)},va=function(n,t){return t.querySelectorAll(n)},da=Ko[a(Ko,"matchesSelector")],ma=function(n,t){return da.call(n,t)};"function"==typeof Sizzle&&(pa=function(n,t){return Sizzle(n,t)[0]||null},va=function(n,t){return Sizzle.uniqueSort(Sizzle(n,t))},ma=Sizzle.matchesSelector),Bo.selection=function(){return _a};var ya=Bo.selection.prototype=[];ya.select=function(n){var t,e,r,u,i=[];n=v(n);for(var o=-1,a=this.length;++o<a;){i.push(t=[]),t.parentNode=(r=this[o]).parentNode;for(var c=-1,s=r.length;++c<s;)(u=r[c])?(t.push(e=n.call(u,u.__data__,c,o)),e&&"__data__"in u&&(e.__data__=u.__data__)):t.push(null)}return p(i)},ya.selectAll=function(n){var t,e,r=[];n=d(n);for(var u=-1,i=this.length;++u<i;)for(var o=this[u],a=-1,c=o.length;++a<c;)(e=o[a])&&(r.push(t=Jo(n.call(e,e.__data__,a,u))),t.parentNode=e);return p(r)};var xa={svg:"http://www.w3.org/2000/svg",xhtml:"http://www.w3.org/1999/xhtml",xlink:"http://www.w3.org/1999/xlink",xml:"http://www.w3.org/XML/1998/namespace",xmlns:"http://www.w3.org/2000/xmlns/"};Bo.ns={prefix:xa,qualify:function(n){var t=n.indexOf(":"),e=n;return t>=0&&(e=n.substring(0,t),n=n.substring(t+1)),xa.hasOwnProperty(e)?{space:xa[e],local:n}:n}},ya.attr=function(n,t){if(arguments.length<2){if("string"==typeof n){var e=this.node();return n=Bo.ns.qualify(n),n.local?e.getAttributeNS(n.space,n.local):e.getAttribute(n)}for(t in n)this.each(m(t,n[t]));return this}return this.each(m(n,t))},ya.classed=function(n,t){if(arguments.length<2){if("string"==typeof n){var e=this.node(),r=(n=M(n)).length,u=-1;if(t=e.classList){for(;++u<r;)if(!t.contains(n[u]))return!1}else for(t=e.getAttribute("class");++u<r;)if(!x(n[u]).test(t))return!1;return!0}for(t in n)this.each(_(t,n[t]));return this}return this.each(_(n,t))},ya.style=function(n,t,e){var r=arguments.length;if(3>r){if("string"!=typeof n){2>r&&(t="");for(e in n)this.each(w(e,n[e],t));return this}if(2>r)return Qo.getComputedStyle(this.node(),null).getPropertyValue(n);e=""}return this.each(w(n,t,e))},ya.property=function(n,t){if(arguments.length<2){if("string"==typeof n)return this.node()[n];for(t in n)this.each(S(t,n[t]));return this}return this.each(S(n,t))},ya.text=function(n){return arguments.length?this.each("function"==typeof n?function(){var t=n.apply(this,arguments);this.textContent=null==t?"":t}:null==n?function(){this.textContent=""}:function(){this.textContent=n}):this.node().textContent},ya.html=function(n){return arguments.length?this.each("function"==typeof n?function(){var t=n.apply(this,arguments);this.innerHTML=null==t?"":t}:null==n?function(){this.innerHTML=""}:function(){this.innerHTML=n}):this.node().innerHTML},ya.append=function(n){return n=k(n),this.select(function(){return this.appendChild(n.apply(this,arguments))})},ya.insert=function(n,t){return n=k(n),t=v(t),this.select(function(){return this.insertBefore(n.apply(this,arguments),t.apply(this,arguments)||null)})},ya.remove=function(){return this.each(function(){var n=this.parentNode;n&&n.removeChild(this)})},ya.data=function(n,t){function e(n,e){var r,i,o,a=n.length,f=e.length,h=Math.min(a,f),g=new Array(f),p=new Array(f),v=new Array(a);if(t){var d,m=new u,y=new u,x=[];for(r=-1;++r<a;)d=t.call(i=n[r],i.__data__,r),m.has(d)?v[r]=i:m.set(d,i),x.push(d);for(r=-1;++r<f;)d=t.call(e,o=e[r],r),(i=m.get(d))?(g[r]=i,i.__data__=o):y.has(d)||(p[r]=E(o)),y.set(d,o),m.remove(d);for(r=-1;++r<a;)m.has(x[r])&&(v[r]=n[r])}else{for(r=-1;++r<h;)i=n[r],o=e[r],i?(i.__data__=o,g[r]=i):p[r]=E(o);for(;f>r;++r)p[r]=E(e[r]);for(;a>r;++r)v[r]=n[r]}p.update=g,p.parentNode=g.parentNode=v.parentNode=n.parentNode,c.push(p),s.push(g),l.push(v)}var r,i,o=-1,a=this.length;if(!arguments.length){for(n=new Array(a=(r=this[0]).length);++o<a;)(i=r[o])&&(n[o]=i.__data__);return n}var c=L([]),s=p([]),l=p([]);if("function"==typeof n)for(;++o<a;)e(r=this[o],n.call(r,r.parentNode.__data__,o));else for(;++o<a;)e(r=this[o],n);return s.enter=function(){return c},s.exit=function(){return l},s},ya.datum=function(n){return arguments.length?this.property("__data__",n):this.property("__data__")},ya.filter=function(n){var t,e,r,u=[];"function"!=typeof n&&(n=A(n));for(var i=0,o=this.length;o>i;i++){u.push(t=[]),t.parentNode=(e=this[i]).parentNode;for(var a=0,c=e.length;c>a;a++)(r=e[a])&&n.call(r,r.__data__,a,i)&&t.push(r)}return p(u)},ya.order=function(){for(var n=-1,t=this.length;++n<t;)for(var e,r=this[n],u=r.length-1,i=r[u];--u>=0;)(e=r[u])&&(i&&i!==e.nextSibling&&i.parentNode.insertBefore(e,i),i=e);return this},ya.sort=function(n){n=C.apply(this,arguments);for(var t=-1,e=this.length;++t<e;)this[t].sort(n);return this.order()},ya.each=function(n){return N(this,function(t,e,r){n.call(t,t.__data__,e,r)})},ya.call=function(n){var t=Jo(arguments);return n.apply(t[0]=this,t),this},ya.empty=function(){return!this.node()},ya.node=function(){for(var n=0,t=this.length;t>n;n++)for(var e=this[n],r=0,u=e.length;u>r;r++){var i=e[r];if(i)return i}return null},ya.size=function(){var n=0;return this.each(function(){++n}),n};var Ma=[];Bo.selection.enter=L,Bo.selection.enter.prototype=Ma,Ma.append=ya.append,Ma.empty=ya.empty,Ma.node=ya.node,Ma.call=ya.call,Ma.size=ya.size,Ma.select=function(n){for(var t,e,r,u,i,o=[],a=-1,c=this.length;++a<c;){r=(u=this[a]).update,o.push(t=[]),t.parentNode=u.parentNode;for(var s=-1,l=u.length;++s<l;)(i=u[s])?(t.push(r[s]=e=n.call(u.parentNode,i.__data__,s,a)),e.__data__=i.__data__):t.push(null)}return p(o)},Ma.insert=function(n,t){return arguments.length<2&&(t=T(this)),ya.insert.call(this,n,t)},ya.transition=function(){for(var n,t,e=ks||++Ls,r=[],u=Es||{time:Date.now(),ease:Fr,delay:0,duration:250},i=-1,o=this.length;++i<o;){r.push(n=[]);for(var a=this[i],c=-1,s=a.length;++c<s;)(t=a[c])&&io(t,c,e,u),n.push(t)}return eo(r,e)},ya.interrupt=function(){return this.each(q)},Bo.select=function(n){var t=["string"==typeof n?pa(n,Go):n];return t.parentNode=Ko,p([t])},Bo.selectAll=function(n){var t=Jo("string"==typeof n?va(n,Go):n);return t.parentNode=Ko,p([t])};var _a=Bo.select(Ko);ya.on=function(n,t,e){var r=arguments.length;if(3>r){if("string"!=typeof n){2>r&&(t=!1);for(e in n)this.each(z(e,n[e],t));return this}if(2>r)return(r=this.node()["__on"+n])&&r._;e=!1}return this.each(z(n,t,e))};var ba=Bo.map({mouseenter:"mouseover",mouseleave:"mouseout"});ba.forEach(function(n){"on"+n in Go&&ba.remove(n)});var wa="onselectstart"in Go?null:a(Ko.style,"userSelect"),Sa=0;Bo.mouse=function(n){return U(n,h())};var ka=/WebKit/.test(Qo.navigator.userAgent)?-1:0;Bo.touches=function(n,t){return arguments.length<2&&(t=h().touches),t?Jo(t).map(function(t){var e=U(n,t);return e.identifier=t.identifier,e}):[]},Bo.behavior.drag=function(){function n(){this.on("mousedown.drag",o).on("touchstart.drag",a)}function t(){return Bo.event.changedTouches[0].identifier}function e(n,t){return Bo.touches(n).filter(function(n){return n.identifier===t})[0]}function r(n,t,e,r){return function(){function o(){var n=t(l,g),e=n[0]-v[0],r=n[1]-v[1];d|=e|r,v=n,f({type:"drag",x:n[0]+c[0],y:n[1]+c[1],dx:e,dy:r})}function a(){m.on(e+"."+p,null).on(r+"."+p,null),y(d&&Bo.event.target===h),f({type:"dragend"})}var c,s=this,l=s.parentNode,f=u.of(s,arguments),h=Bo.event.target,g=n(),p=null==g?"drag":"drag-"+g,v=t(l,g),d=0,m=Bo.select(Qo).on(e+"."+p,o).on(r+"."+p,a),y=P();i?(c=i.apply(s,arguments),c=[c.x-v[0],c.y-v[1]]):c=[0,0],f({type:"dragstart"})}}var u=g(n,"drag","dragstart","dragend"),i=null,o=r(c,Bo.mouse,"mousemove","mouseup"),a=r(t,e,"touchmove","touchend");return n.origin=function(t){return arguments.length?(i=t,n):i},Bo.rebind(n,u,"on")};var Ea=Math.PI,Aa=2*Ea,Ca=Ea/2,Na=1e-6,La=Na*Na,Ta=Ea/180,qa=180/Ea,za=Math.SQRT2,Ra=2,Da=4;Bo.interpolateZoom=function(n,t){function e(n){var t=n*y;if(m){var e=Y(v),o=i/(Ra*h)*(e*I(za*t+v)-O(v));return[r+o*s,u+o*l,i*e/Y(za*t+v)]}return[r+n*s,u+n*l,i*Math.exp(za*t)]}var r=n[0],u=n[1],i=n[2],o=t[0],a=t[1],c=t[2],s=o-r,l=a-u,f=s*s+l*l,h=Math.sqrt(f),g=(c*c-i*i+Da*f)/(2*i*Ra*h),p=(c*c-i*i-Da*f)/(2*c*Ra*h),v=Math.log(Math.sqrt(g*g+1)-g),d=Math.log(Math.sqrt(p*p+1)-p),m=d-v,y=(m||Math.log(c/i))/za;return e.duration=1e3*y,e},Bo.behavior.zoom=function(){function n(n){n.on(A,s).on(ja+".zoom",h).on(C,p).on("dblclick.zoom",v).on(L,l)}function t(n){return[(n[0]-S.x)/S.k,(n[1]-S.y)/S.k]}function e(n){return[n[0]*S.k+S.x,n[1]*S.k+S.y]}function r(n){S.k=Math.max(E[0],Math.min(E[1],n))}function u(n,t){t=e(t),S.x+=n[0]-t[0],S.y+=n[1]-t[1]}function i(){_&&_.domain(M.range().map(function(n){return(n-S.x)/S.k}).map(M.invert)),w&&w.domain(b.range().map(function(n){return(n-S.y)/S.k}).map(b.invert))}function o(n){n({type:"zoomstart"})}function a(n){i(),n({type:"zoom",scale:S.k,translate:[S.x,S.y]})}function c(n){n({type:"zoomend"})}function s(){function n(){l=1,u(Bo.mouse(r),h),a(i)}function e(){f.on(C,Qo===r?p:null).on(N,null),g(l&&Bo.event.target===s),c(i)}var r=this,i=T.of(r,arguments),s=Bo.event.target,l=0,f=Bo.select(Qo).on(C,n).on(N,e),h=t(Bo.mouse(r)),g=P();q.call(r),o(i)}function l(){function n(){var n=Bo.touches(p);return g=S.k,n.forEach(function(n){n.identifier in d&&(d[n.identifier]=t(n))}),n}function e(){for(var t=Bo.event.changedTouches,e=0,i=t.length;i>e;++e)d[t[e].identifier]=null;var o=n(),c=Date.now();if(1===o.length){if(500>c-x){var s=o[0],l=d[s.identifier];r(2*S.k),u(s,l),f(),a(v)}x=c}else if(o.length>1){var s=o[0],h=o[1],g=s[0]-h[0],p=s[1]-h[1];m=g*g+p*p}}function i(){for(var n,t,e,i,o=Bo.touches(p),c=0,s=o.length;s>c;++c,i=null)if(e=o[c],i=d[e.identifier]){if(t)break;n=e,t=i}if(i){var l=(l=e[0]-n[0])*l+(l=e[1]-n[1])*l,f=m&&Math.sqrt(l/m);n=[(n[0]+e[0])/2,(n[1]+e[1])/2],t=[(t[0]+i[0])/2,(t[1]+i[1])/2],r(f*g)}x=null,u(n,t),a(v)}function h(){if(Bo.event.touches.length){for(var t=Bo.event.changedTouches,e=0,r=t.length;r>e;++e)delete d[t[e].identifier];for(var u in d)return void n()}b.on(M,null).on(_,null),w.on(A,s).on(L,l),k(),c(v)}var g,p=this,v=T.of(p,arguments),d={},m=0,y=Bo.event.changedTouches[0].identifier,M="touchmove.zoom-"+y,_="touchend.zoom-"+y,b=Bo.select(Qo).on(M,i).on(_,h),w=Bo.select(p).on(A,null).on(L,e),k=P();q.call(p),e(),o(v)}function h(){var n=T.of(this,arguments);y?clearTimeout(y):(q.call(this),o(n)),y=setTimeout(function(){y=null,c(n)},50),f();var e=m||Bo.mouse(this);d||(d=t(e)),r(Math.pow(2,.002*Pa())*S.k),u(e,d),a(n)}function p(){d=null}function v(){var n=T.of(this,arguments),e=Bo.mouse(this),i=t(e),s=Math.log(S.k)/Math.LN2;o(n),r(Math.pow(2,Bo.event.shiftKey?Math.ceil(s)-1:Math.floor(s)+1)),u(e,i),a(n),c(n)}var d,m,y,x,M,_,b,w,S={x:0,y:0,k:1},k=[960,500],E=Ua,A="mousedown.zoom",C="mousemove.zoom",N="mouseup.zoom",L="touchstart.zoom",T=g(n,"zoomstart","zoom","zoomend");return n.event=function(n){n.each(function(){var n=T.of(this,arguments),t=S;ks?Bo.select(this).transition().each("start.zoom",function(){S=this.__chart__||{x:0,y:0,k:1},o(n)}).tween("zoom:zoom",function(){var e=k[0],r=k[1],u=e/2,i=r/2,o=Bo.interpolateZoom([(u-S.x)/S.k,(i-S.y)/S.k,e/S.k],[(u-t.x)/t.k,(i-t.y)/t.k,e/t.k]);return function(t){var r=o(t),c=e/r[2];this.__chart__=S={x:u-r[0]*c,y:i-r[1]*c,k:c},a(n)}}).each("end.zoom",function(){c(n)}):(this.__chart__=S,o(n),a(n),c(n))})},n.translate=function(t){return arguments.length?(S={x:+t[0],y:+t[1],k:S.k},i(),n):[S.x,S.y]},n.scale=function(t){return arguments.length?(S={x:S.x,y:S.y,k:+t},i(),n):S.k},n.scaleExtent=function(t){return arguments.length?(E=null==t?Ua:[+t[0],+t[1]],n):E},n.center=function(t){return arguments.length?(m=t&&[+t[0],+t[1]],n):m},n.size=function(t){return arguments.length?(k=t&&[+t[0],+t[1]],n):k},n.x=function(t){return arguments.length?(_=t,M=t.copy(),S={x:0,y:0,k:1},n):_},n.y=function(t){return arguments.length?(w=t,b=t.copy(),S={x:0,y:0,k:1},n):w},Bo.rebind(n,T,"on")};var Pa,Ua=[0,1/0],ja="onwheel"in Go?(Pa=function(){return-Bo.event.deltaY*(Bo.event.deltaMode?120:1)},"wheel"):"onmousewheel"in Go?(Pa=function(){return Bo.event.wheelDelta},"mousewheel"):(Pa=function(){return-Bo.event.detail},"MozMousePixelScroll");V.prototype.toString=function(){return this.rgb()+""},Bo.hsl=function(n,t,e){return 1===arguments.length?n instanceof $?X(n.h,n.s,n.l):lt(""+n,ft,X):X(+n,+t,+e)};var Ha=$.prototype=new V;Ha.brighter=function(n){return n=Math.pow(.7,arguments.length?n:1),X(this.h,this.s,this.l/n)},Ha.darker=function(n){return n=Math.pow(.7,arguments.length?n:1),X(this.h,this.s,n*this.l)},Ha.rgb=function(){return B(this.h,this.s,this.l)},Bo.hcl=function(n,t,e){return 1===arguments.length?n instanceof J?W(n.h,n.c,n.l):n instanceof Q?tt(n.l,n.a,n.b):tt((n=ht((n=Bo.rgb(n)).r,n.g,n.b)).l,n.a,n.b):W(+n,+t,+e)};var Fa=J.prototype=new V;Fa.brighter=function(n){return W(this.h,this.c,Math.min(100,this.l+Oa*(arguments.length?n:1)))},Fa.darker=function(n){return W(this.h,this.c,Math.max(0,this.l-Oa*(arguments.length?n:1)))},Fa.rgb=function(){return G(this.h,this.c,this.l).rgb()},Bo.lab=function(n,t,e){return 1===arguments.length?n instanceof Q?K(n.l,n.a,n.b):n instanceof J?G(n.l,n.c,n.h):ht((n=Bo.rgb(n)).r,n.g,n.b):K(+n,+t,+e)};var Oa=18,Ya=.95047,Ia=1,Za=1.08883,Va=Q.prototype=new V;Va.brighter=function(n){return K(Math.min(100,this.l+Oa*(arguments.length?n:1)),this.a,this.b)},Va.darker=function(n){return K(Math.max(0,this.l-Oa*(arguments.length?n:1)),this.a,this.b)},Va.rgb=function(){return nt(this.l,this.a,this.b)},Bo.rgb=function(n,t,e){return 1===arguments.length?n instanceof ct?at(n.r,n.g,n.b):lt(""+n,at,B):at(~~n,~~t,~~e)};var Xa=ct.prototype=new V;Xa.brighter=function(n){n=Math.pow(.7,arguments.length?n:1);var t=this.r,e=this.g,r=this.b,u=30;return t||e||r?(t&&u>t&&(t=u),e&&u>e&&(e=u),r&&u>r&&(r=u),at(Math.min(255,~~(t/n)),Math.min(255,~~(e/n)),Math.min(255,~~(r/n)))):at(u,u,u)},Xa.darker=function(n){return n=Math.pow(.7,arguments.length?n:1),at(~~(n*this.r),~~(n*this.g),~~(n*this.b))},Xa.hsl=function(){return ft(this.r,this.g,this.b)},Xa.toString=function(){return"#"+st(this.r)+st(this.g)+st(this.b)};var $a=Bo.map({aliceblue:15792383,antiquewhite:16444375,aqua:65535,aquamarine:8388564,azure:15794175,beige:16119260,bisque:16770244,black:0,blanchedalmond:16772045,blue:255,blueviolet:9055202,brown:10824234,burlywood:14596231,cadetblue:6266528,chartreuse:8388352,chocolate:13789470,coral:16744272,cornflowerblue:6591981,cornsilk:16775388,crimson:14423100,cyan:65535,darkblue:139,darkcyan:35723,darkgoldenrod:12092939,darkgray:11119017,darkgreen:25600,darkgrey:11119017,darkkhaki:12433259,darkmagenta:9109643,darkolivegreen:5597999,darkorange:16747520,darkorchid:10040012,darkred:9109504,darksalmon:15308410,darkseagreen:9419919,darkslateblue:4734347,darkslategray:3100495,darkslategrey:3100495,darkturquoise:52945,darkviolet:9699539,deeppink:16716947,deepskyblue:49151,dimgray:6908265,dimgrey:6908265,dodgerblue:2003199,firebrick:11674146,floralwhite:16775920,forestgreen:2263842,fuchsia:16711935,gainsboro:14474460,ghostwhite:16316671,gold:16766720,goldenrod:14329120,gray:8421504,green:32768,greenyellow:11403055,grey:8421504,honeydew:15794160,hotpink:16738740,indianred:13458524,indigo:4915330,ivory:16777200,khaki:15787660,lavender:15132410,lavenderblush:16773365,lawngreen:8190976,lemonchiffon:16775885,lightblue:11393254,lightcoral:15761536,lightcyan:14745599,lightgoldenrodyellow:16448210,lightgray:13882323,lightgreen:9498256,lightgrey:13882323,lightpink:16758465,lightsalmon:16752762,lightseagreen:2142890,lightskyblue:8900346,lightslategray:7833753,lightslategrey:7833753,lightsteelblue:11584734,lightyellow:16777184,lime:65280,limegreen:3329330,linen:16445670,magenta:16711935,maroon:8388608,mediumaquamarine:6737322,mediumblue:205,mediumorchid:12211667,mediumpurple:9662683,mediumseagreen:3978097,mediumslateblue:8087790,mediumspringgreen:64154,mediumturquoise:4772300,mediumvioletred:13047173,midnightblue:1644912,mintcream:16121850,mistyrose:16770273,moccasin:16770229,navajowhite:16768685,navy:128,oldlace:16643558,olive:8421376,olivedrab:7048739,orange:16753920,orangered:16729344,orchid:14315734,palegoldenrod:15657130,palegreen:10025880,paleturquoise:11529966,palevioletred:14381203,papayawhip:16773077,peachpuff:16767673,peru:13468991,pink:16761035,plum:14524637,powderblue:11591910,purple:8388736,red:16711680,rosybrown:12357519,royalblue:4286945,saddlebrown:9127187,salmon:16416882,sandybrown:16032864,seagreen:3050327,seashell:16774638,sienna:10506797,silver:12632256,skyblue:8900331,slateblue:6970061,slategray:7372944,slategrey:7372944,snow:16775930,springgreen:65407,steelblue:4620980,tan:13808780,teal:32896,thistle:14204888,tomato:16737095,turquoise:4251856,violet:15631086,wheat:16113331,white:16777215,whitesmoke:16119285,yellow:16776960,yellowgreen:10145074});$a.forEach(function(n,t){$a.set(n,it(t))}),Bo.functor=vt,Bo.xhr=mt(dt),Bo.dsv=function(n,t){function e(n,e,i){arguments.length<3&&(i=e,e=null);var o=yt(n,t,null==e?r:u(e),i);return o.row=function(n){return arguments.length?o.response(null==(e=n)?r:u(n)):e},o}function r(n){return e.parse(n.responseText)}function u(n){return function(t){return e.parse(t.responseText,n)}}function o(t){return t.map(a).join(n)}function a(n){return c.test(n)?'"'+n.replace(/\"/g,'""')+'"':n}var c=new RegExp('["'+n+"\n]"),s=n.charCodeAt(0);return e.parse=function(n,t){var r;return e.parseRows(n,function(n,e){if(r)return r(n,e-1);var u=new Function("d","return {"+n.map(function(n,t){return JSON.stringify(n)+": d["+t+"]"}).join(",")+"}");r=t?function(n,e){return t(u(n),e)}:u})},e.parseRows=function(n,t){function e(){if(l>=c)return o;if(u)return u=!1,i;var t=l;if(34===n.charCodeAt(t)){for(var e=t;e++<c;)if(34===n.charCodeAt(e)){if(34!==n.charCodeAt(e+1))break;++e}l=e+2;var r=n.charCodeAt(e+1);return 13===r?(u=!0,10===n.charCodeAt(e+2)&&++l):10===r&&(u=!0),n.substring(t+1,e).replace(/""/g,'"')}for(;c>l;){var r=n.charCodeAt(l++),a=1;if(10===r)u=!0;else if(13===r)u=!0,10===n.charCodeAt(l)&&(++l,++a);else if(r!==s)continue;return n.substring(t,l-a)}return n.substring(t)}for(var r,u,i={},o={},a=[],c=n.length,l=0,f=0;(r=e())!==o;){for(var h=[];r!==i&&r!==o;)h.push(r),r=e();(!t||(h=t(h,f++)))&&a.push(h)}return a},e.format=function(t){if(Array.isArray(t[0]))return e.formatRows(t);var r=new i,u=[];return t.forEach(function(n){for(var t in n)r.has(t)||u.push(r.add(t))}),[u.map(a).join(n)].concat(t.map(function(t){return u.map(function(n){return a(t[n])}).join(n)})).join("\n")},e.formatRows=function(n){return n.map(o).join("\n")},e},Bo.csv=Bo.dsv(",","text/csv"),Bo.tsv=Bo.dsv(" ","text/tab-separated-values");var Ba,Wa,Ja,Ga,Ka,Qa=Qo[a(Qo,"requestAnimationFrame")]||function(n){setTimeout(n,17)};Bo.timer=function(n,t,e){var r=arguments.length;2>r&&(t=0),3>r&&(e=Date.now());var u=e+t,i={c:n,t:u,f:!1,n:null};Wa?Wa.n=i:Ba=i,Wa=i,Ja||(Ga=clearTimeout(Ga),Ja=1,Qa(Mt))},Bo.timer.flush=function(){_t(),bt()};var nc=".",tc=",",ec=[3,3],rc="$",uc=["y","z","a","f","p","n","\xb5","m","","k","M","G","T","P","E","Z","Y"].map(wt);Bo.formatPrefix=function(n,t){var e=0;return n&&(0>n&&(n*=-1),t&&(n=Bo.round(n,St(n,t))),e=1+Math.floor(1e-12+Math.log(n)/Math.LN10),e=Math.max(-24,Math.min(24,3*Math.floor((0>=e?e+1:e-1)/3)))),uc[8+e/3]},Bo.round=function(n,t){return t?Math.round(n*(t=Math.pow(10,t)))/t:Math.round(n)},Bo.format=function(n){var t=ic.exec(n),e=t[1]||" ",r=t[2]||">",u=t[3]||"",i=t[4]||"",o=t[5],a=+t[6],c=t[7],s=t[8],l=t[9],f=1,h="",g=!1;switch(s&&(s=+s.substring(1)),(o||"0"===e&&"="===r)&&(o=e="0",r="=",c&&(a-=Math.floor((a-1)/4))),l){case"n":c=!0,l="g";break;case"%":f=100,h="%",l="f";break;case"p":f=100,h="%",l="r";break;case"b":case"o":case"x":case"X":"#"===i&&(i="0"+l.toLowerCase());case"c":case"d":g=!0,s=0;break;case"s":f=-1,l="r"}"#"===i?i="":"$"===i&&(i=rc),"r"!=l||s||(l="g"),null!=s&&("g"==l?s=Math.max(1,Math.min(21,s)):("e"==l||"f"==l)&&(s=Math.max(0,Math.min(20,s)))),l=oc.get(l)||kt;var p=o&&c;return function(n){if(g&&n%1)return"";var t=0>n||0===n&&0>1/n?(n=-n,"-"):u;if(0>f){var v=Bo.formatPrefix(n,s);n=v.scale(n),h=v.symbol}else n*=f;n=l(n,s);var d=n.lastIndexOf("."),m=0>d?n:n.substring(0,d),y=0>d?"":nc+n.substring(d+1);!o&&c&&(m=ac(m));var x=i.length+m.length+y.length+(p?0:t.length),M=a>x?new Array(x=a-x+1).join(e):"";return p&&(m=ac(M+m)),t+=i,n=m+y,("<"===r?t+n+M:">"===r?M+t+n:"^"===r?M.substring(0,x>>=1)+t+n+M.substring(x):t+(p?n:M+n))+h}};var ic=/(?:([^{])?([<>=^]))?([+\- ])?([$#])?(0)?(\d+)?(,)?(\.-?\d+)?([a-z%])?/i,oc=Bo.map({b:function(n){return n.toString(2)},c:function(n){return String.fromCharCode(n)},o:function(n){return n.toString(8)},x:function(n){return n.toString(16)},X:function(n){return n.toString(16).toUpperCase()},g:function(n,t){return n.toPrecision(t)},e:function(n,t){return n.toExponential(t)},f:function(n,t){return n.toFixed(t)},r:function(n,t){return(n=Bo.round(n,St(n,t))).toFixed(Math.max(0,Math.min(20,St(n*(1+1e-15),t))))}}),ac=dt;if(ec){var cc=ec.length;ac=function(n){for(var t=n.length,e=[],r=0,u=ec[0];t>0&&u>0;)e.push(n.substring(t-=u,t+u)),u=ec[r=(r+1)%cc];return e.reverse().join(tc)}}Bo.geo={},Et.prototype={s:0,t:0,add:function(n){At(n,this.t,sc),At(sc.s,this.s,this),this.s?this.t+=sc.t:this.s=sc.t},reset:function(){this.s=this.t=0},valueOf:function(){return this.s}};var sc=new Et;Bo.geo.stream=function(n,t){n&&lc.hasOwnProperty(n.type)?lc[n.type](n,t):Ct(n,t)};var lc={Feature:function(n,t){Ct(n.geometry,t)},FeatureCollection:function(n,t){for(var e=n.features,r=-1,u=e.length;++r<u;)Ct(e[r].geometry,t)}},fc={Sphere:function(n,t){t.sphere()},Point:function(n,t){n=n.coordinates,t.point(n[0],n[1],n[2])},MultiPoint:function(n,t){for(var e=n.coordinates,r=-1,u=e.length;++r<u;)n=e[r],t.point(n[0],n[1],n[2])},LineString:function(n,t){Nt(n.coordinates,t,0)},MultiLineString:function(n,t){for(var e=n.coordinates,r=-1,u=e.length;++r<u;)Nt(e[r],t,0)},Polygon:function(n,t){Lt(n.coordinates,t)},MultiPolygon:function(n,t){for(var e=n.coordinates,r=-1,u=e.length;++r<u;)Lt(e[r],t)},GeometryCollection:function(n,t){for(var e=n.geometries,r=-1,u=e.length;++r<u;)Ct(e[r],t)}};Bo.geo.area=function(n){return hc=0,Bo.geo.stream(n,pc),hc};var hc,gc=new Et,pc={sphere:function(){hc+=4*Ea},point:c,lineStart:c,lineEnd:c,polygonStart:function(){gc.reset(),pc.lineStart=Tt},polygonEnd:function(){var n=2*gc;hc+=0>n?4*Ea+n:n,pc.lineStart=pc.lineEnd=pc.point=c}};Bo.geo.bounds=function(){function n(n,t){x.push(M=[l=n,h=n]),f>t&&(f=t),t>g&&(g=t)}function t(t,e){var r=qt([t*Ta,e*Ta]);if(m){var u=Rt(m,r),i=[u[1],-u[0],0],o=Rt(i,u);Ut(o),o=jt(o);var c=t-p,s=c>0?1:-1,v=o[0]*qa*s,d=ca(c)>180;if(d^(v>s*p&&s*t>v)){var y=o[1]*qa;y>g&&(g=y)}else if(v=(v+360)%360-180,d^(v>s*p&&s*t>v)){var y=-o[1]*qa;f>y&&(f=y)}else f>e&&(f=e),e>g&&(g=e);d?p>t?a(l,t)>a(l,h)&&(h=t):a(t,h)>a(l,h)&&(l=t):h>=l?(l>t&&(l=t),t>h&&(h=t)):t>p?a(l,t)>a(l,h)&&(h=t):a(t,h)>a(l,h)&&(l=t)}else n(t,e);m=r,p=t}function e(){_.point=t}function r(){M[0]=l,M[1]=h,_.point=n,m=null}function u(n,e){if(m){var r=n-p;y+=ca(r)>180?r+(r>0?360:-360):r}else v=n,d=e;pc.point(n,e),t(n,e)}function i(){pc.lineStart()}function o(){u(v,d),pc.lineEnd(),ca(y)>Na&&(l=-(h=180)),M[0]=l,M[1]=h,m=null}function a(n,t){return(t-=n)<0?t+360:t}function c(n,t){return n[0]-t[0]}function s(n,t){return t[0]<=t[1]?t[0]<=n&&n<=t[1]:n<t[0]||t[1]<n}var l,f,h,g,p,v,d,m,y,x,M,_={point:n,lineStart:e,lineEnd:r,polygonStart:function(){_.point=u,_.lineStart=i,_.lineEnd=o,y=0,pc.polygonStart()},polygonEnd:function(){pc.polygonEnd(),_.point=n,_.lineStart=e,_.lineEnd=r,0>gc?(l=-(h=180),f=-(g=90)):y>Na?g=90:-Na>y&&(f=-90),M[0]=l,M[1]=h}};return function(n){g=h=-(l=f=1/0),x=[],Bo.geo.stream(n,_);var t=x.length;if(t){x.sort(c);for(var e,r=1,u=x[0],i=[u];t>r;++r)e=x[r],s(e[0],u)||s(e[1],u)?(a(u[0],e[1])>a(u[0],u[1])&&(u[1]=e[1]),a(e[0],u[1])>a(u[0],u[1])&&(u[0]=e[0])):i.push(u=e);for(var o,e,p=-1/0,t=i.length-1,r=0,u=i[t];t>=r;u=e,++r)e=i[r],(o=a(u[1],e[0]))>p&&(p=o,l=e[0],h=u[1])}return x=M=null,1/0===l||1/0===f?[[0/0,0/0],[0/0,0/0]]:[[l,f],[h,g]]}}(),Bo.geo.centroid=function(n){vc=dc=mc=yc=xc=Mc=_c=bc=wc=Sc=kc=0,Bo.geo.stream(n,Ec);var t=wc,e=Sc,r=kc,u=t*t+e*e+r*r;return La>u&&(t=Mc,e=_c,r=bc,Na>dc&&(t=mc,e=yc,r=xc),u=t*t+e*e+r*r,La>u)?[0/0,0/0]:[Math.atan2(e,t)*qa,F(r/Math.sqrt(u))*qa]};var vc,dc,mc,yc,xc,Mc,_c,bc,wc,Sc,kc,Ec={sphere:c,point:Ft,lineStart:Yt,lineEnd:It,polygonStart:function(){Ec.lineStart=Zt},polygonEnd:function(){Ec.lineStart=Yt}},Ac=Wt(Vt,ne,ee,[-Ea,-Ea/2]),Cc=1e9;Bo.geo.clipExtent=function(){var n,t,e,r,u,i,o={stream:function(n){return u&&(u.valid=!1),u=i(n),u.valid=!0,u},extent:function(a){return arguments.length?(i=ie(n=+a[0][0],t=+a[0][1],e=+a[1][0],r=+a[1][1]),u&&(u.valid=!1,u=null),o):[[n,t],[e,r]]}};return o.extent([[0,0],[960,500]])},(Bo.geo.conicEqualArea=function(){return ae(ce)}).raw=ce,Bo.geo.albers=function(){return Bo.geo.conicEqualArea().rotate([96,0]).center([-.6,38.7]).parallels([29.5,45.5]).scale(1070)},Bo.geo.albersUsa=function(){function n(n){var i=n[0],o=n[1];return t=null,e(i,o),t||(r(i,o),t)||u(i,o),t}var t,e,r,u,i=Bo.geo.albers(),o=Bo.geo.conicEqualArea().rotate([154,0]).center([-2,58.5]).parallels([55,65]),a=Bo.geo.conicEqualArea().rotate([157,0]).center([-3,19.9]).parallels([8,18]),c={point:function(n,e){t=[n,e]}};return n.invert=function(n){var t=i.scale(),e=i.translate(),r=(n[0]-e[0])/t,u=(n[1]-e[1])/t;return(u>=.12&&.234>u&&r>=-.425&&-.214>r?o:u>=.166&&.234>u&&r>=-.214&&-.115>r?a:i).invert(n)},n.stream=function(n){var t=i.stream(n),e=o.stream(n),r=a.stream(n);return{point:function(n,u){t.point(n,u),e.point(n,u),r.point(n,u)},sphere:function(){t.sphere(),e.sphere(),r.sphere()},lineStart:function(){t.lineStart(),e.lineStart(),r.lineStart()},lineEnd:function(){t.lineEnd(),e.lineEnd(),r.lineEnd()},polygonStart:function(){t.polygonStart(),e.polygonStart(),r.polygonStart()},polygonEnd:function(){t.polygonEnd(),e.polygonEnd(),r.polygonEnd()}}},n.precision=function(t){return arguments.length?(i.precision(t),o.precision(t),a.precision(t),n):i.precision()},n.scale=function(t){return arguments.length?(i.scale(t),o.scale(.35*t),a.scale(t),n.translate(i.translate())):i.scale()},n.translate=function(t){if(!arguments.length)return i.translate();var s=i.scale(),l=+t[0],f=+t[1];return e=i.translate(t).clipExtent([[l-.455*s,f-.238*s],[l+.455*s,f+.238*s]]).stream(c).point,r=o.translate([l-.307*s,f+.201*s]).clipExtent([[l-.425*s+Na,f+.12*s+Na],[l-.214*s-Na,f+.234*s-Na]]).stream(c).point,u=a.translate([l-.205*s,f+.212*s]).clipExtent([[l-.214*s+Na,f+.166*s+Na],[l-.115*s-Na,f+.234*s-Na]]).stream(c).point,n},n.scale(1070)};var Nc,Lc,Tc,qc,zc,Rc,Dc={point:c,lineStart:c,lineEnd:c,polygonStart:function(){Lc=0,Dc.lineStart=se},polygonEnd:function(){Dc.lineStart=Dc.lineEnd=Dc.point=c,Nc+=ca(Lc/2)}},Pc={point:le,lineStart:c,lineEnd:c,polygonStart:c,polygonEnd:c},Uc={point:ge,lineStart:pe,lineEnd:ve,polygonStart:function(){Uc.lineStart=de},polygonEnd:function(){Uc.point=ge,Uc.lineStart=pe,Uc.lineEnd=ve}};Bo.geo.path=function(){function n(n){return n&&("function"==typeof a&&i.pointRadius(+a.apply(this,arguments)),o&&o.valid||(o=u(i)),Bo.geo.stream(n,o)),i.result()}function t(){return o=null,n}var e,r,u,i,o,a=4.5;return n.area=function(n){return Nc=0,Bo.geo.stream(n,u(Dc)),Nc},n.centroid=function(n){return mc=yc=xc=Mc=_c=bc=wc=Sc=kc=0,Bo.geo.stream(n,u(Uc)),kc?[wc/kc,Sc/kc]:bc?[Mc/bc,_c/bc]:xc?[mc/xc,yc/xc]:[0/0,0/0]},n.bounds=function(n){return zc=Rc=-(Tc=qc=1/0),Bo.geo.stream(n,u(Pc)),[[Tc,qc],[zc,Rc]]},n.projection=function(n){return arguments.length?(u=(e=n)?n.stream||xe(n):dt,t()):e},n.context=function(n){return arguments.length?(i=null==(r=n)?new fe:new me(n),"function"!=typeof a&&i.pointRadius(a),t()):r},n.pointRadius=function(t){return arguments.length?(a="function"==typeof t?t:(i.pointRadius(+t),+t),n):a},n.projection(Bo.geo.albersUsa()).context(null)},Bo.geo.transform=function(n){return{stream:function(t){var e=new Me(t);for(var r in n)e[r]=n[r];return e}}},Me.prototype={point:function(n,t){this.stream.point(n,t)},sphere:function(){this.stream.sphere()},lineStart:function(){this.stream.lineStart() +},lineEnd:function(){this.stream.lineEnd()},polygonStart:function(){this.stream.polygonStart()},polygonEnd:function(){this.stream.polygonEnd()}},Bo.geo.projection=be,Bo.geo.projectionMutator=we,(Bo.geo.equirectangular=function(){return be(ke)}).raw=ke.invert=ke,Bo.geo.rotation=function(n){function t(t){return t=n(t[0]*Ta,t[1]*Ta),t[0]*=qa,t[1]*=qa,t}return n=Ae(n[0]%360*Ta,n[1]*Ta,n.length>2?n[2]*Ta:0),t.invert=function(t){return t=n.invert(t[0]*Ta,t[1]*Ta),t[0]*=qa,t[1]*=qa,t},t},Ee.invert=ke,Bo.geo.circle=function(){function n(){var n="function"==typeof r?r.apply(this,arguments):r,t=Ae(-n[0]*Ta,-n[1]*Ta,0).invert,u=[];return e(null,null,1,{point:function(n,e){u.push(n=t(n,e)),n[0]*=qa,n[1]*=qa}}),{type:"Polygon",coordinates:[u]}}var t,e,r=[0,0],u=6;return n.origin=function(t){return arguments.length?(r=t,n):r},n.angle=function(r){return arguments.length?(e=Te((t=+r)*Ta,u*Ta),n):t},n.precision=function(r){return arguments.length?(e=Te(t*Ta,(u=+r)*Ta),n):u},n.angle(90)},Bo.geo.distance=function(n,t){var e,r=(t[0]-n[0])*Ta,u=n[1]*Ta,i=t[1]*Ta,o=Math.sin(r),a=Math.cos(r),c=Math.sin(u),s=Math.cos(u),l=Math.sin(i),f=Math.cos(i);return Math.atan2(Math.sqrt((e=f*o)*e+(e=s*l-c*f*a)*e),c*l+s*f*a)},Bo.geo.graticule=function(){function n(){return{type:"MultiLineString",coordinates:t()}}function t(){return Bo.range(Math.ceil(i/d)*d,u,d).map(h).concat(Bo.range(Math.ceil(s/m)*m,c,m).map(g)).concat(Bo.range(Math.ceil(r/p)*p,e,p).filter(function(n){return ca(n%d)>Na}).map(l)).concat(Bo.range(Math.ceil(a/v)*v,o,v).filter(function(n){return ca(n%m)>Na}).map(f))}var e,r,u,i,o,a,c,s,l,f,h,g,p=10,v=p,d=90,m=360,y=2.5;return n.lines=function(){return t().map(function(n){return{type:"LineString",coordinates:n}})},n.outline=function(){return{type:"Polygon",coordinates:[h(i).concat(g(c).slice(1),h(u).reverse().slice(1),g(s).reverse().slice(1))]}},n.extent=function(t){return arguments.length?n.majorExtent(t).minorExtent(t):n.minorExtent()},n.majorExtent=function(t){return arguments.length?(i=+t[0][0],u=+t[1][0],s=+t[0][1],c=+t[1][1],i>u&&(t=i,i=u,u=t),s>c&&(t=s,s=c,c=t),n.precision(y)):[[i,s],[u,c]]},n.minorExtent=function(t){return arguments.length?(r=+t[0][0],e=+t[1][0],a=+t[0][1],o=+t[1][1],r>e&&(t=r,r=e,e=t),a>o&&(t=a,a=o,o=t),n.precision(y)):[[r,a],[e,o]]},n.step=function(t){return arguments.length?n.majorStep(t).minorStep(t):n.minorStep()},n.majorStep=function(t){return arguments.length?(d=+t[0],m=+t[1],n):[d,m]},n.minorStep=function(t){return arguments.length?(p=+t[0],v=+t[1],n):[p,v]},n.precision=function(t){return arguments.length?(y=+t,l=ze(a,o,90),f=Re(r,e,y),h=ze(s,c,90),g=Re(i,u,y),n):y},n.majorExtent([[-180,-90+Na],[180,90-Na]]).minorExtent([[-180,-80-Na],[180,80+Na]])},Bo.geo.greatArc=function(){function n(){return{type:"LineString",coordinates:[t||r.apply(this,arguments),e||u.apply(this,arguments)]}}var t,e,r=De,u=Pe;return n.distance=function(){return Bo.geo.distance(t||r.apply(this,arguments),e||u.apply(this,arguments))},n.source=function(e){return arguments.length?(r=e,t="function"==typeof e?null:e,n):r},n.target=function(t){return arguments.length?(u=t,e="function"==typeof t?null:t,n):u},n.precision=function(){return arguments.length?n:0},n},Bo.geo.interpolate=function(n,t){return Ue(n[0]*Ta,n[1]*Ta,t[0]*Ta,t[1]*Ta)},Bo.geo.length=function(n){return jc=0,Bo.geo.stream(n,Hc),jc};var jc,Hc={sphere:c,point:c,lineStart:je,lineEnd:c,polygonStart:c,polygonEnd:c},Fc=He(function(n){return Math.sqrt(2/(1+n))},function(n){return 2*Math.asin(n/2)});(Bo.geo.azimuthalEqualArea=function(){return be(Fc)}).raw=Fc;var Oc=He(function(n){var t=Math.acos(n);return t&&t/Math.sin(t)},dt);(Bo.geo.azimuthalEquidistant=function(){return be(Oc)}).raw=Oc,(Bo.geo.conicConformal=function(){return ae(Fe)}).raw=Fe,(Bo.geo.conicEquidistant=function(){return ae(Oe)}).raw=Oe;var Yc=He(function(n){return 1/n},Math.atan);(Bo.geo.gnomonic=function(){return be(Yc)}).raw=Yc,Ye.invert=function(n,t){return[n,2*Math.atan(Math.exp(t))-Ca]},(Bo.geo.mercator=function(){return Ie(Ye)}).raw=Ye;var Ic=He(function(){return 1},Math.asin);(Bo.geo.orthographic=function(){return be(Ic)}).raw=Ic;var Zc=He(function(n){return 1/(1+n)},function(n){return 2*Math.atan(n)});(Bo.geo.stereographic=function(){return be(Zc)}).raw=Zc,Ze.invert=function(n,t){return[-t,2*Math.atan(Math.exp(n))-Ca]},(Bo.geo.transverseMercator=function(){var n=Ie(Ze),t=n.center,e=n.rotate;return n.center=function(n){return n?t([-n[1],n[0]]):(n=t(),[-n[1],n[0]])},n.rotate=function(n){return n?e([n[0],n[1],n.length>2?n[2]+90:90]):(n=e(),[n[0],n[1],n[2]-90])},n.rotate([0,0])}).raw=Ze,Bo.geom={},Bo.geom.hull=function(n){function t(n){if(n.length<3)return[];var t,u,i,o,a,c,s,l,f,h,g,p,v=vt(e),d=vt(r),m=n.length,y=m-1,x=[],M=[],_=0;if(v===Ve&&r===Xe)t=n;else for(i=0,t=[];m>i;++i)t.push([+v.call(this,u=n[i],i),+d.call(this,u,i)]);for(i=1;m>i;++i)(t[i][1]<t[_][1]||t[i][1]==t[_][1]&&t[i][0]<t[_][0])&&(_=i);for(i=0;m>i;++i)i!==_&&(c=t[i][1]-t[_][1],a=t[i][0]-t[_][0],x.push({angle:Math.atan2(c,a),index:i}));for(x.sort(function(n,t){return n.angle-t.angle}),g=x[0].angle,h=x[0].index,f=0,i=1;y>i;++i){if(o=x[i].index,g==x[i].angle){if(a=t[h][0]-t[_][0],c=t[h][1]-t[_][1],s=t[o][0]-t[_][0],l=t[o][1]-t[_][1],a*a+c*c>=s*s+l*l){x[i].index=-1;continue}x[f].index=-1}g=x[i].angle,f=i,h=o}for(M.push(_),i=0,o=0;2>i;++o)x[o].index>-1&&(M.push(x[o].index),i++);for(p=M.length;y>o;++o)if(!(x[o].index<0)){for(;!$e(M[p-2],M[p-1],x[o].index,t);)--p;M[p++]=x[o].index}var b=[];for(i=p-1;i>=0;--i)b.push(n[M[i]]);return b}var e=Ve,r=Xe;return arguments.length?t(n):(t.x=function(n){return arguments.length?(e=n,t):e},t.y=function(n){return arguments.length?(r=n,t):r},t)},Bo.geom.polygon=function(n){return ga(n,Vc),n};var Vc=Bo.geom.polygon.prototype=[];Vc.area=function(){for(var n,t=-1,e=this.length,r=this[e-1],u=0;++t<e;)n=r,r=this[t],u+=n[1]*r[0]-n[0]*r[1];return.5*u},Vc.centroid=function(n){var t,e,r=-1,u=this.length,i=0,o=0,a=this[u-1];for(arguments.length||(n=-1/(6*this.area()));++r<u;)t=a,a=this[r],e=t[0]*a[1]-a[0]*t[1],i+=(t[0]+a[0])*e,o+=(t[1]+a[1])*e;return[i*n,o*n]},Vc.clip=function(n){for(var t,e,r,u,i,o,a=Je(n),c=-1,s=this.length-Je(this),l=this[s-1];++c<s;){for(t=n.slice(),n.length=0,u=this[c],i=t[(r=t.length-a)-1],e=-1;++e<r;)o=t[e],Be(o,l,u)?(Be(i,l,u)||n.push(We(i,o,l,u)),n.push(o)):Be(i,l,u)&&n.push(We(i,o,l,u)),i=o;a&&n.push(n[0]),l=u}return n};var Xc,$c,Bc,Wc,Jc,Gc=[],Kc=[];ur.prototype.prepare=function(){for(var n,t=this.edges,e=t.length;e--;)n=t[e].edge,n.b&&n.a||t.splice(e,1);return t.sort(or),t.length},dr.prototype={start:function(){return this.edge.l===this.site?this.edge.a:this.edge.b},end:function(){return this.edge.l===this.site?this.edge.b:this.edge.a}},mr.prototype={insert:function(n,t){var e,r,u;if(n){if(t.P=n,t.N=n.N,n.N&&(n.N.P=t),n.N=t,n.R){for(n=n.R;n.L;)n=n.L;n.L=t}else n.R=t;e=n}else this._?(n=_r(this._),t.P=null,t.N=n,n.P=n.L=t,e=n):(t.P=t.N=null,this._=t,e=null);for(t.L=t.R=null,t.U=e,t.C=!0,n=t;e&&e.C;)r=e.U,e===r.L?(u=r.R,u&&u.C?(e.C=u.C=!1,r.C=!0,n=r):(n===e.R&&(xr(this,e),n=e,e=n.U),e.C=!1,r.C=!0,Mr(this,r))):(u=r.L,u&&u.C?(e.C=u.C=!1,r.C=!0,n=r):(n===e.L&&(Mr(this,e),n=e,e=n.U),e.C=!1,r.C=!0,xr(this,r))),e=n.U;this._.C=!1},remove:function(n){n.N&&(n.N.P=n.P),n.P&&(n.P.N=n.N),n.N=n.P=null;var t,e,r,u=n.U,i=n.L,o=n.R;if(e=i?o?_r(o):i:o,u?u.L===n?u.L=e:u.R=e:this._=e,i&&o?(r=e.C,e.C=n.C,e.L=i,i.U=e,e!==o?(u=e.U,e.U=n.U,n=e.R,u.L=n,e.R=o,o.U=e):(e.U=u,u=e,n=e.R)):(r=n.C,n=e),n&&(n.U=u),!r){if(n&&n.C)return n.C=!1,void 0;do{if(n===this._)break;if(n===u.L){if(t=u.R,t.C&&(t.C=!1,u.C=!0,xr(this,u),t=u.R),t.L&&t.L.C||t.R&&t.R.C){t.R&&t.R.C||(t.L.C=!1,t.C=!0,Mr(this,t),t=u.R),t.C=u.C,u.C=t.R.C=!1,xr(this,u),n=this._;break}}else if(t=u.L,t.C&&(t.C=!1,u.C=!0,Mr(this,u),t=u.L),t.L&&t.L.C||t.R&&t.R.C){t.L&&t.L.C||(t.R.C=!1,t.C=!0,xr(this,t),t=u.L),t.C=u.C,u.C=t.L.C=!1,Mr(this,u),n=this._;break}t.C=!0,n=u,u=u.U}while(!n.C);n&&(n.C=!1)}}},Bo.geom.voronoi=function(n){function t(n){var t=new Array(n.length),r=a[0][0],u=a[0][1],i=a[1][0],o=a[1][1];return br(e(n),a).cells.forEach(function(e,a){var c=e.edges,s=e.site,l=t[a]=c.length?c.map(function(n){var t=n.start();return[t.x,t.y]}):s.x>=r&&s.x<=i&&s.y>=u&&s.y<=o?[[r,o],[i,o],[i,u],[r,u]]:[];l.point=n[a]}),t}function e(n){return n.map(function(n,t){return{x:Math.round(i(n,t)/Na)*Na,y:Math.round(o(n,t)/Na)*Na,i:t}})}var r=Ve,u=Xe,i=r,o=u,a=Qc;return n?t(n):(t.links=function(n){return br(e(n)).edges.filter(function(n){return n.l&&n.r}).map(function(t){return{source:n[t.l.i],target:n[t.r.i]}})},t.triangles=function(n){var t=[];return br(e(n)).cells.forEach(function(e,r){for(var u,i,o=e.site,a=e.edges.sort(or),c=-1,s=a.length,l=a[s-1].edge,f=l.l===o?l.r:l.l;++c<s;)u=l,i=f,l=a[c].edge,f=l.l===o?l.r:l.l,r<i.i&&r<f.i&&Sr(o,i,f)<0&&t.push([n[r],n[i.i],n[f.i]])}),t},t.x=function(n){return arguments.length?(i=vt(r=n),t):r},t.y=function(n){return arguments.length?(o=vt(u=n),t):u},t.clipExtent=function(n){return arguments.length?(a=null==n?Qc:n,t):a===Qc?null:a},t.size=function(n){return arguments.length?t.clipExtent(n&&[[0,0],n]):a===Qc?null:a&&a[1]},t)};var Qc=[[-1e6,-1e6],[1e6,1e6]];Bo.geom.delaunay=function(n){return Bo.geom.voronoi().triangles(n)},Bo.geom.quadtree=function(n,t,e,r,u){function i(n){function i(n,t,e,r,u,i,o,a){if(!isNaN(e)&&!isNaN(r))if(n.leaf){var c=n.x,l=n.y;if(null!=c)if(ca(c-e)+ca(l-r)<.01)s(n,t,e,r,u,i,o,a);else{var f=n.point;n.x=n.y=n.point=null,s(n,f,c,l,u,i,o,a),s(n,t,e,r,u,i,o,a)}else n.x=e,n.y=r,n.point=t}else s(n,t,e,r,u,i,o,a)}function s(n,t,e,r,u,o,a,c){var s=.5*(u+a),l=.5*(o+c),f=e>=s,h=r>=l,g=(h<<1)+f;n.leaf=!1,n=n.nodes[g]||(n.nodes[g]=Ar()),f?u=s:a=s,h?o=l:c=l,i(n,t,e,r,u,o,a,c)}var l,f,h,g,p,v,d,m,y,x=vt(a),M=vt(c);if(null!=t)v=t,d=e,m=r,y=u;else if(m=y=-(v=d=1/0),f=[],h=[],p=n.length,o)for(g=0;p>g;++g)l=n[g],l.x<v&&(v=l.x),l.y<d&&(d=l.y),l.x>m&&(m=l.x),l.y>y&&(y=l.y),f.push(l.x),h.push(l.y);else for(g=0;p>g;++g){var _=+x(l=n[g],g),b=+M(l,g);v>_&&(v=_),d>b&&(d=b),_>m&&(m=_),b>y&&(y=b),f.push(_),h.push(b)}var w=m-v,S=y-d;w>S?y=d+w:m=v+S;var k=Ar();if(k.add=function(n){i(k,n,+x(n,++g),+M(n,g),v,d,m,y)},k.visit=function(n){Cr(n,k,v,d,m,y)},g=-1,null==t){for(;++g<p;)i(k,n[g],f[g],h[g],v,d,m,y);--g}else n.forEach(k.add);return f=h=n=l=null,k}var o,a=Ve,c=Xe;return(o=arguments.length)?(a=kr,c=Er,3===o&&(u=e,r=t,e=t=0),i(n)):(i.x=function(n){return arguments.length?(a=n,i):a},i.y=function(n){return arguments.length?(c=n,i):c},i.extent=function(n){return arguments.length?(null==n?t=e=r=u=null:(t=+n[0][0],e=+n[0][1],r=+n[1][0],u=+n[1][1]),i):null==t?null:[[t,e],[r,u]]},i.size=function(n){return arguments.length?(null==n?t=e=r=u=null:(t=e=0,r=+n[0],u=+n[1]),i):null==t?null:[r-t,u-e]},i)},Bo.interpolateRgb=Nr,Bo.interpolateObject=Lr,Bo.interpolateNumber=Tr,Bo.interpolateString=qr;var ns=/[-+]?(?:\d+\.?\d*|\.?\d+)(?:[eE][-+]?\d+)?/g;Bo.interpolate=zr,Bo.interpolators=[function(n,t){var e=typeof t;return("string"===e?$a.has(t)||/^(#|rgb\(|hsl\()/.test(t)?Nr:qr:t instanceof V?Nr:"object"===e?Array.isArray(t)?Rr:Lr:Tr)(n,t)}],Bo.interpolateArray=Rr;var ts=function(){return dt},es=Bo.map({linear:ts,poly:Or,quad:function(){return jr},cubic:function(){return Hr},sin:function(){return Yr},exp:function(){return Ir},circle:function(){return Zr},elastic:Vr,back:Xr,bounce:function(){return $r}}),rs=Bo.map({"in":dt,out:Pr,"in-out":Ur,"out-in":function(n){return Ur(Pr(n))}});Bo.ease=function(n){var t=n.indexOf("-"),e=t>=0?n.substring(0,t):n,r=t>=0?n.substring(t+1):"in";return e=es.get(e)||ts,r=rs.get(r)||dt,Dr(r(e.apply(null,Wo.call(arguments,1))))},Bo.interpolateHcl=Br,Bo.interpolateHsl=Wr,Bo.interpolateLab=Jr,Bo.interpolateRound=Gr,Bo.transform=function(n){var t=Go.createElementNS(Bo.ns.prefix.svg,"g");return(Bo.transform=function(n){if(null!=n){t.setAttribute("transform",n);var e=t.transform.baseVal.consolidate()}return new Kr(e?e.matrix:us)})(n)},Kr.prototype.toString=function(){return"translate("+this.translate+")rotate("+this.rotate+")skewX("+this.skew+")scale("+this.scale+")"};var us={a:1,b:0,c:0,d:1,e:0,f:0};Bo.interpolateTransform=eu,Bo.layout={},Bo.layout.bundle=function(){return function(n){for(var t=[],e=-1,r=n.length;++e<r;)t.push(iu(n[e]));return t}},Bo.layout.chord=function(){function n(){var n,s,f,h,g,p={},v=[],d=Bo.range(i),m=[];for(e=[],r=[],n=0,h=-1;++h<i;){for(s=0,g=-1;++g<i;)s+=u[h][g];v.push(s),m.push(Bo.range(i)),n+=s}for(o&&d.sort(function(n,t){return o(v[n],v[t])}),a&&m.forEach(function(n,t){n.sort(function(n,e){return a(u[t][n],u[t][e])})}),n=(Aa-l*i)/n,s=0,h=-1;++h<i;){for(f=s,g=-1;++g<i;){var y=d[h],x=m[y][g],M=u[y][x],_=s,b=s+=M*n;p[y+"-"+x]={index:y,subindex:x,startAngle:_,endAngle:b,value:M}}r[y]={index:y,startAngle:f,endAngle:s,value:(s-f)/n},s+=l}for(h=-1;++h<i;)for(g=h-1;++g<i;){var w=p[h+"-"+g],S=p[g+"-"+h];(w.value||S.value)&&e.push(w.value<S.value?{source:S,target:w}:{source:w,target:S})}c&&t()}function t(){e.sort(function(n,t){return c((n.source.value+n.target.value)/2,(t.source.value+t.target.value)/2)})}var e,r,u,i,o,a,c,s={},l=0;return s.matrix=function(n){return arguments.length?(i=(u=n)&&u.length,e=r=null,s):u},s.padding=function(n){return arguments.length?(l=n,e=r=null,s):l},s.sortGroups=function(n){return arguments.length?(o=n,e=r=null,s):o},s.sortSubgroups=function(n){return arguments.length?(a=n,e=null,s):a},s.sortChords=function(n){return arguments.length?(c=n,e&&t(),s):c},s.chords=function(){return e||n(),e},s.groups=function(){return r||n(),r},s},Bo.layout.force=function(){function n(n){return function(t,e,r,u){if(t.point!==n){var i=t.cx-n.x,o=t.cy-n.y,a=1/Math.sqrt(i*i+o*o);if(v>(u-e)*a){var c=t.charge*a*a;return n.px-=i*c,n.py-=o*c,!0}if(t.point&&isFinite(a)){var c=t.pointCharge*a*a;n.px-=i*c,n.py-=o*c}}return!t.charge}}function t(n){n.px=Bo.event.x,n.py=Bo.event.y,a.resume()}var e,r,u,i,o,a={},c=Bo.dispatch("start","tick","end"),s=[1,1],l=.9,f=is,h=os,g=-30,p=.1,v=.8,d=[],m=[];return a.tick=function(){if((r*=.99)<.005)return c.end({type:"end",alpha:r=0}),!0;var t,e,a,f,h,v,y,x,M,_=d.length,b=m.length;for(e=0;b>e;++e)a=m[e],f=a.source,h=a.target,x=h.x-f.x,M=h.y-f.y,(v=x*x+M*M)&&(v=r*i[e]*((v=Math.sqrt(v))-u[e])/v,x*=v,M*=v,h.x-=x*(y=f.weight/(h.weight+f.weight)),h.y-=M*y,f.x+=x*(y=1-y),f.y+=M*y);if((y=r*p)&&(x=s[0]/2,M=s[1]/2,e=-1,y))for(;++e<_;)a=d[e],a.x+=(x-a.x)*y,a.y+=(M-a.y)*y;if(g)for(hu(t=Bo.geom.quadtree(d),r,o),e=-1;++e<_;)(a=d[e]).fixed||t.visit(n(a));for(e=-1;++e<_;)a=d[e],a.fixed?(a.x=a.px,a.y=a.py):(a.x-=(a.px-(a.px=a.x))*l,a.y-=(a.py-(a.py=a.y))*l);c.tick({type:"tick",alpha:r})},a.nodes=function(n){return arguments.length?(d=n,a):d},a.links=function(n){return arguments.length?(m=n,a):m},a.size=function(n){return arguments.length?(s=n,a):s},a.linkDistance=function(n){return arguments.length?(f="function"==typeof n?n:+n,a):f},a.distance=a.linkDistance,a.linkStrength=function(n){return arguments.length?(h="function"==typeof n?n:+n,a):h},a.friction=function(n){return arguments.length?(l=+n,a):l},a.charge=function(n){return arguments.length?(g="function"==typeof n?n:+n,a):g},a.gravity=function(n){return arguments.length?(p=+n,a):p},a.theta=function(n){return arguments.length?(v=+n,a):v},a.alpha=function(n){return arguments.length?(n=+n,r?r=n>0?n:0:n>0&&(c.start({type:"start",alpha:r=n}),Bo.timer(a.tick)),a):r},a.start=function(){function n(n,r){if(!e){for(e=new Array(c),a=0;c>a;++a)e[a]=[];for(a=0;s>a;++a){var u=m[a];e[u.source.index].push(u.target),e[u.target.index].push(u.source)}}for(var i,o=e[t],a=-1,s=o.length;++a<s;)if(!isNaN(i=o[a][n]))return i;return Math.random()*r}var t,e,r,c=d.length,l=m.length,p=s[0],v=s[1];for(t=0;c>t;++t)(r=d[t]).index=t,r.weight=0;for(t=0;l>t;++t)r=m[t],"number"==typeof r.source&&(r.source=d[r.source]),"number"==typeof r.target&&(r.target=d[r.target]),++r.source.weight,++r.target.weight;for(t=0;c>t;++t)r=d[t],isNaN(r.x)&&(r.x=n("x",p)),isNaN(r.y)&&(r.y=n("y",v)),isNaN(r.px)&&(r.px=r.x),isNaN(r.py)&&(r.py=r.y);if(u=[],"function"==typeof f)for(t=0;l>t;++t)u[t]=+f.call(this,m[t],t);else for(t=0;l>t;++t)u[t]=f;if(i=[],"function"==typeof h)for(t=0;l>t;++t)i[t]=+h.call(this,m[t],t);else for(t=0;l>t;++t)i[t]=h;if(o=[],"function"==typeof g)for(t=0;c>t;++t)o[t]=+g.call(this,d[t],t);else for(t=0;c>t;++t)o[t]=g;return a.resume()},a.resume=function(){return a.alpha(.1)},a.stop=function(){return a.alpha(0)},a.drag=function(){return e||(e=Bo.behavior.drag().origin(dt).on("dragstart.force",cu).on("drag.force",t).on("dragend.force",su)),arguments.length?(this.on("mouseover.force",lu).on("mouseout.force",fu).call(e),void 0):e},Bo.rebind(a,c,"on")};var is=20,os=1;Bo.layout.hierarchy=function(){function n(t,o,a){var c=u.call(e,t,o);if(t.depth=o,a.push(t),c&&(s=c.length)){for(var s,l,f=-1,h=t.children=new Array(s),g=0,p=o+1;++f<s;)l=h[f]=n(c[f],p,a),l.parent=t,g+=l.value;r&&h.sort(r),i&&(t.value=g)}else delete t.children,i&&(t.value=+i.call(e,t,o)||0);return t}function t(n,r){var u=n.children,o=0;if(u&&(a=u.length))for(var a,c=-1,s=r+1;++c<a;)o+=t(u[c],s);else i&&(o=+i.call(e,n,r)||0);return i&&(n.value=o),o}function e(t){var e=[];return n(t,0,e),e}var r=du,u=pu,i=vu;return e.sort=function(n){return arguments.length?(r=n,e):r},e.children=function(n){return arguments.length?(u=n,e):u},e.value=function(n){return arguments.length?(i=n,e):i},e.revalue=function(n){return t(n,0),n},e},Bo.layout.partition=function(){function n(t,e,r,u){var i=t.children;if(t.x=e,t.y=t.depth*u,t.dx=r,t.dy=u,i&&(o=i.length)){var o,a,c,s=-1;for(r=t.value?r/t.value:0;++s<o;)n(a=i[s],e,c=a.value*r,u),e+=c}}function t(n){var e=n.children,r=0;if(e&&(u=e.length))for(var u,i=-1;++i<u;)r=Math.max(r,t(e[i]));return 1+r}function e(e,i){var o=r.call(this,e,i);return n(o[0],0,u[0],u[1]/t(o[0])),o}var r=Bo.layout.hierarchy(),u=[1,1];return e.size=function(n){return arguments.length?(u=n,e):u},gu(e,r)},Bo.layout.pie=function(){function n(i){var o=i.map(function(e,r){return+t.call(n,e,r)}),a=+("function"==typeof r?r.apply(this,arguments):r),c=(("function"==typeof u?u.apply(this,arguments):u)-a)/Bo.sum(o),s=Bo.range(i.length);null!=e&&s.sort(e===as?function(n,t){return o[t]-o[n]}:function(n,t){return e(i[n],i[t])});var l=[];return s.forEach(function(n){var t;l[n]={data:i[n],value:t=o[n],startAngle:a,endAngle:a+=t*c}}),l}var t=Number,e=as,r=0,u=Aa;return n.value=function(e){return arguments.length?(t=e,n):t},n.sort=function(t){return arguments.length?(e=t,n):e},n.startAngle=function(t){return arguments.length?(r=t,n):r},n.endAngle=function(t){return arguments.length?(u=t,n):u},n};var as={};Bo.layout.stack=function(){function n(a,c){var s=a.map(function(e,r){return t.call(n,e,r)}),l=s.map(function(t){return t.map(function(t,e){return[i.call(n,t,e),o.call(n,t,e)]})}),f=e.call(n,l,c);s=Bo.permute(s,f),l=Bo.permute(l,f);var h,g,p,v=r.call(n,l,c),d=s.length,m=s[0].length;for(g=0;m>g;++g)for(u.call(n,s[0][g],p=v[g],l[0][g][1]),h=1;d>h;++h)u.call(n,s[h][g],p+=l[h-1][g][1],l[h][g][1]);return a}var t=dt,e=_u,r=bu,u=Mu,i=yu,o=xu;return n.values=function(e){return arguments.length?(t=e,n):t},n.order=function(t){return arguments.length?(e="function"==typeof t?t:cs.get(t)||_u,n):e},n.offset=function(t){return arguments.length?(r="function"==typeof t?t:ss.get(t)||bu,n):r},n.x=function(t){return arguments.length?(i=t,n):i},n.y=function(t){return arguments.length?(o=t,n):o},n.out=function(t){return arguments.length?(u=t,n):u},n};var cs=Bo.map({"inside-out":function(n){var t,e,r=n.length,u=n.map(wu),i=n.map(Su),o=Bo.range(r).sort(function(n,t){return u[n]-u[t]}),a=0,c=0,s=[],l=[];for(t=0;r>t;++t)e=o[t],c>a?(a+=i[e],s.push(e)):(c+=i[e],l.push(e));return l.reverse().concat(s)},reverse:function(n){return Bo.range(n.length).reverse()},"default":_u}),ss=Bo.map({silhouette:function(n){var t,e,r,u=n.length,i=n[0].length,o=[],a=0,c=[];for(e=0;i>e;++e){for(t=0,r=0;u>t;t++)r+=n[t][e][1];r>a&&(a=r),o.push(r)}for(e=0;i>e;++e)c[e]=(a-o[e])/2;return c},wiggle:function(n){var t,e,r,u,i,o,a,c,s,l=n.length,f=n[0],h=f.length,g=[];for(g[0]=c=s=0,e=1;h>e;++e){for(t=0,u=0;l>t;++t)u+=n[t][e][1];for(t=0,i=0,a=f[e][0]-f[e-1][0];l>t;++t){for(r=0,o=(n[t][e][1]-n[t][e-1][1])/(2*a);t>r;++r)o+=(n[r][e][1]-n[r][e-1][1])/a;i+=o*n[t][e][1]}g[e]=c-=u?i/u*a:0,s>c&&(s=c)}for(e=0;h>e;++e)g[e]-=s;return g},expand:function(n){var t,e,r,u=n.length,i=n[0].length,o=1/u,a=[];for(e=0;i>e;++e){for(t=0,r=0;u>t;t++)r+=n[t][e][1];if(r)for(t=0;u>t;t++)n[t][e][1]/=r;else for(t=0;u>t;t++)n[t][e][1]=o}for(e=0;i>e;++e)a[e]=0;return a},zero:bu});Bo.layout.histogram=function(){function n(n,i){for(var o,a,c=[],s=n.map(e,this),l=r.call(this,s,i),f=u.call(this,l,s,i),i=-1,h=s.length,g=f.length-1,p=t?1:1/h;++i<g;)o=c[i]=[],o.dx=f[i+1]-(o.x=f[i]),o.y=0;if(g>0)for(i=-1;++i<h;)a=s[i],a>=l[0]&&a<=l[1]&&(o=c[Bo.bisect(f,a,1,g)-1],o.y+=p,o.push(n[i]));return c}var t=!0,e=Number,r=Cu,u=Eu;return n.value=function(t){return arguments.length?(e=t,n):e},n.range=function(t){return arguments.length?(r=vt(t),n):r},n.bins=function(t){return arguments.length?(u="number"==typeof t?function(n){return Au(n,t)}:vt(t),n):u},n.frequency=function(e){return arguments.length?(t=!!e,n):t},n},Bo.layout.tree=function(){function n(n,i){function o(n,t){var r=n.children,u=n._tree;if(r&&(i=r.length)){for(var i,a,s,l=r[0],f=l,h=-1;++h<i;)s=r[h],o(s,a),f=c(s,a,f),a=s;Uu(n);var g=.5*(l._tree.prelim+s._tree.prelim);t?(u.prelim=t._tree.prelim+e(n,t),u.mod=u.prelim-g):u.prelim=g}else t&&(u.prelim=t._tree.prelim+e(n,t))}function a(n,t){n.x=n._tree.prelim+t;var e=n.children;if(e&&(r=e.length)){var r,u=-1;for(t+=n._tree.mod;++u<r;)a(e[u],t)}}function c(n,t,r){if(t){for(var u,i=n,o=n,a=t,c=n.parent.children[0],s=i._tree.mod,l=o._tree.mod,f=a._tree.mod,h=c._tree.mod;a=Tu(a),i=Lu(i),a&&i;)c=Lu(c),o=Tu(o),o._tree.ancestor=n,u=a._tree.prelim+f-i._tree.prelim-s+e(a,i),u>0&&(ju(Hu(a,n,r),n,u),s+=u,l+=u),f+=a._tree.mod,s+=i._tree.mod,h+=c._tree.mod,l+=o._tree.mod;a&&!Tu(o)&&(o._tree.thread=a,o._tree.mod+=f-l),i&&!Lu(c)&&(c._tree.thread=i,c._tree.mod+=s-h,r=n)}return r}var s=t.call(this,n,i),l=s[0];Pu(l,function(n,t){n._tree={ancestor:n,prelim:0,mod:0,change:0,shift:0,number:t?t._tree.number+1:0}}),o(l),a(l,-l._tree.prelim);var f=qu(l,Ru),h=qu(l,zu),g=qu(l,Du),p=f.x-e(f,h)/2,v=h.x+e(h,f)/2,d=g.depth||1;return Pu(l,u?function(n){n.x*=r[0],n.y=n.depth*r[1],delete n._tree}:function(n){n.x=(n.x-p)/(v-p)*r[0],n.y=n.depth/d*r[1],delete n._tree}),s}var t=Bo.layout.hierarchy().sort(null).value(null),e=Nu,r=[1,1],u=!1;return n.separation=function(t){return arguments.length?(e=t,n):e},n.size=function(t){return arguments.length?(u=null==(r=t),n):u?null:r},n.nodeSize=function(t){return arguments.length?(u=null!=(r=t),n):u?r:null},gu(n,t)},Bo.layout.pack=function(){function n(n,i){var o=e.call(this,n,i),a=o[0],c=u[0],s=u[1],l=null==t?Math.sqrt:"function"==typeof t?t:function(){return t};if(a.x=a.y=0,Pu(a,function(n){n.r=+l(n.value)}),Pu(a,Zu),r){var f=r*(t?1:Math.max(2*a.r/c,2*a.r/s))/2;Pu(a,function(n){n.r+=f}),Pu(a,Zu),Pu(a,function(n){n.r-=f})}return $u(a,c/2,s/2,t?1:1/Math.max(2*a.r/c,2*a.r/s)),o}var t,e=Bo.layout.hierarchy().sort(Fu),r=0,u=[1,1];return n.size=function(t){return arguments.length?(u=t,n):u},n.radius=function(e){return arguments.length?(t=null==e||"function"==typeof e?e:+e,n):t},n.padding=function(t){return arguments.length?(r=+t,n):r},gu(n,e)},Bo.layout.cluster=function(){function n(n,i){var o,a=t.call(this,n,i),c=a[0],s=0;Pu(c,function(n){var t=n.children;t&&t.length?(n.x=Ju(t),n.y=Wu(t)):(n.x=o?s+=e(n,o):0,n.y=0,o=n)});var l=Gu(c),f=Ku(c),h=l.x-e(l,f)/2,g=f.x+e(f,l)/2;return Pu(c,u?function(n){n.x=(n.x-c.x)*r[0],n.y=(c.y-n.y)*r[1]}:function(n){n.x=(n.x-h)/(g-h)*r[0],n.y=(1-(c.y?n.y/c.y:1))*r[1]}),a}var t=Bo.layout.hierarchy().sort(null).value(null),e=Nu,r=[1,1],u=!1;return n.separation=function(t){return arguments.length?(e=t,n):e},n.size=function(t){return arguments.length?(u=null==(r=t),n):u?null:r},n.nodeSize=function(t){return arguments.length?(u=null!=(r=t),n):u?r:null},gu(n,t)},Bo.layout.treemap=function(){function n(n,t){for(var e,r,u=-1,i=n.length;++u<i;)r=(e=n[u]).value*(0>t?0:t),e.area=isNaN(r)||0>=r?0:r}function t(e){var i=e.children;if(i&&i.length){var o,a,c,s=f(e),l=[],h=i.slice(),p=1/0,v="slice"===g?s.dx:"dice"===g?s.dy:"slice-dice"===g?1&e.depth?s.dy:s.dx:Math.min(s.dx,s.dy);for(n(h,s.dx*s.dy/e.value),l.area=0;(c=h.length)>0;)l.push(o=h[c-1]),l.area+=o.area,"squarify"!==g||(a=r(l,v))<=p?(h.pop(),p=a):(l.area-=l.pop().area,u(l,v,s,!1),v=Math.min(s.dx,s.dy),l.length=l.area=0,p=1/0);l.length&&(u(l,v,s,!0),l.length=l.area=0),i.forEach(t)}}function e(t){var r=t.children;if(r&&r.length){var i,o=f(t),a=r.slice(),c=[];for(n(a,o.dx*o.dy/t.value),c.area=0;i=a.pop();)c.push(i),c.area+=i.area,null!=i.z&&(u(c,i.z?o.dx:o.dy,o,!a.length),c.length=c.area=0);r.forEach(e)}}function r(n,t){for(var e,r=n.area,u=0,i=1/0,o=-1,a=n.length;++o<a;)(e=n[o].area)&&(i>e&&(i=e),e>u&&(u=e));return r*=r,t*=t,r?Math.max(t*u*p/r,r/(t*i*p)):1/0}function u(n,t,e,r){var u,i=-1,o=n.length,a=e.x,s=e.y,l=t?c(n.area/t):0;if(t==e.dx){for((r||l>e.dy)&&(l=e.dy);++i<o;)u=n[i],u.x=a,u.y=s,u.dy=l,a+=u.dx=Math.min(e.x+e.dx-a,l?c(u.area/l):0);u.z=!0,u.dx+=e.x+e.dx-a,e.y+=l,e.dy-=l}else{for((r||l>e.dx)&&(l=e.dx);++i<o;)u=n[i],u.x=a,u.y=s,u.dx=l,s+=u.dy=Math.min(e.y+e.dy-s,l?c(u.area/l):0);u.z=!1,u.dy+=e.y+e.dy-s,e.x+=l,e.dx-=l}}function i(r){var u=o||a(r),i=u[0];return i.x=0,i.y=0,i.dx=s[0],i.dy=s[1],o&&a.revalue(i),n([i],i.dx*i.dy/i.value),(o?e:t)(i),h&&(o=u),u}var o,a=Bo.layout.hierarchy(),c=Math.round,s=[1,1],l=null,f=Qu,h=!1,g="squarify",p=.5*(1+Math.sqrt(5));return i.size=function(n){return arguments.length?(s=n,i):s},i.padding=function(n){function t(t){var e=n.call(i,t,t.depth);return null==e?Qu(t):ni(t,"number"==typeof e?[e,e,e,e]:e)}function e(t){return ni(t,n)}if(!arguments.length)return l;var r;return f=null==(l=n)?Qu:"function"==(r=typeof n)?t:"number"===r?(n=[n,n,n,n],e):e,i},i.round=function(n){return arguments.length?(c=n?Math.round:Number,i):c!=Number},i.sticky=function(n){return arguments.length?(h=n,o=null,i):h},i.ratio=function(n){return arguments.length?(p=n,i):p},i.mode=function(n){return arguments.length?(g=n+"",i):g},gu(i,a)},Bo.random={normal:function(n,t){var e=arguments.length;return 2>e&&(t=1),1>e&&(n=0),function(){var e,r,u;do e=2*Math.random()-1,r=2*Math.random()-1,u=e*e+r*r;while(!u||u>1);return n+t*e*Math.sqrt(-2*Math.log(u)/u)}},logNormal:function(){var n=Bo.random.normal.apply(Bo,arguments);return function(){return Math.exp(n())}},bates:function(n){var t=Bo.random.irwinHall(n);return function(){return t()/n}},irwinHall:function(n){return function(){for(var t=0,e=0;n>e;e++)t+=Math.random();return t}}},Bo.scale={};var ls={floor:dt,ceil:dt};Bo.scale.linear=function(){return ai([0,1],[0,1],zr,!1)};var fs={s:1,g:1,p:1,r:1,e:1};Bo.scale.log=function(){return vi(Bo.scale.linear().domain([0,1]),10,!0,[1,10])};var hs=Bo.format(".0e"),gs={floor:function(n){return-Math.ceil(-n)},ceil:function(n){return-Math.floor(-n)}};Bo.scale.pow=function(){return di(Bo.scale.linear(),1,[0,1])},Bo.scale.sqrt=function(){return Bo.scale.pow().exponent(.5)},Bo.scale.ordinal=function(){return yi([],{t:"range",a:[[]]})},Bo.scale.category10=function(){return Bo.scale.ordinal().range(ps)},Bo.scale.category20=function(){return Bo.scale.ordinal().range(vs)},Bo.scale.category20b=function(){return Bo.scale.ordinal().range(ds)},Bo.scale.category20c=function(){return Bo.scale.ordinal().range(ms)};var ps=[2062260,16744206,2924588,14034728,9725885,9197131,14907330,8355711,12369186,1556175].map(ot),vs=[2062260,11454440,16744206,16759672,2924588,10018698,14034728,16750742,9725885,12955861,9197131,12885140,14907330,16234194,8355711,13092807,12369186,14408589,1556175,10410725].map(ot),ds=[3750777,5395619,7040719,10264286,6519097,9216594,11915115,13556636,9202993,12426809,15186514,15190932,8666169,11356490,14049643,15177372,8077683,10834324,13528509,14589654].map(ot),ms=[3244733,7057110,10406625,13032431,15095053,16616764,16625259,16634018,3253076,7652470,10607003,13101504,7695281,10394312,12369372,14342891,6513507,9868950,12434877,14277081].map(ot);Bo.scale.quantile=function(){return xi([],[])},Bo.scale.quantize=function(){return Mi(0,1,[0,1])},Bo.scale.threshold=function(){return _i([.5],[0,1])},Bo.scale.identity=function(){return bi([0,1])},Bo.svg={},Bo.svg.arc=function(){function n(){var n=t.apply(this,arguments),i=e.apply(this,arguments),o=r.apply(this,arguments)+ys,a=u.apply(this,arguments)+ys,c=(o>a&&(c=o,o=a,a=c),a-o),s=Ea>c?"0":"1",l=Math.cos(o),f=Math.sin(o),h=Math.cos(a),g=Math.sin(a);return c>=xs?n?"M0,"+i+"A"+i+","+i+" 0 1,1 0,"+-i+"A"+i+","+i+" 0 1,1 0,"+i+"M0,"+n+"A"+n+","+n+" 0 1,0 0,"+-n+"A"+n+","+n+" 0 1,0 0,"+n+"Z":"M0,"+i+"A"+i+","+i+" 0 1,1 0,"+-i+"A"+i+","+i+" 0 1,1 0,"+i+"Z":n?"M"+i*l+","+i*f+"A"+i+","+i+" 0 "+s+",1 "+i*h+","+i*g+"L"+n*h+","+n*g+"A"+n+","+n+" 0 "+s+",0 "+n*l+","+n*f+"Z":"M"+i*l+","+i*f+"A"+i+","+i+" 0 "+s+",1 "+i*h+","+i*g+"L0,0"+"Z"}var t=wi,e=Si,r=ki,u=Ei;return n.innerRadius=function(e){return arguments.length?(t=vt(e),n):t},n.outerRadius=function(t){return arguments.length?(e=vt(t),n):e},n.startAngle=function(t){return arguments.length?(r=vt(t),n):r},n.endAngle=function(t){return arguments.length?(u=vt(t),n):u},n.centroid=function(){var n=(t.apply(this,arguments)+e.apply(this,arguments))/2,i=(r.apply(this,arguments)+u.apply(this,arguments))/2+ys;return[Math.cos(i)*n,Math.sin(i)*n]},n};var ys=-Ca,xs=Aa-Na;Bo.svg.line=function(){return Ai(dt)};var Ms=Bo.map({linear:Ci,"linear-closed":Ni,step:Li,"step-before":Ti,"step-after":qi,basis:ji,"basis-open":Hi,"basis-closed":Fi,bundle:Oi,cardinal:Di,"cardinal-open":zi,"cardinal-closed":Ri,monotone:$i});Ms.forEach(function(n,t){t.key=n,t.closed=/-closed$/.test(n)});var _s=[0,2/3,1/3,0],bs=[0,1/3,2/3,0],ws=[0,1/6,2/3,1/6];Bo.svg.line.radial=function(){var n=Ai(Bi);return n.radius=n.x,delete n.x,n.angle=n.y,delete n.y,n},Ti.reverse=qi,qi.reverse=Ti,Bo.svg.area=function(){return Wi(dt)},Bo.svg.area.radial=function(){var n=Wi(Bi);return n.radius=n.x,delete n.x,n.innerRadius=n.x0,delete n.x0,n.outerRadius=n.x1,delete n.x1,n.angle=n.y,delete n.y,n.startAngle=n.y0,delete n.y0,n.endAngle=n.y1,delete n.y1,n},Bo.svg.chord=function(){function n(n,a){var c=t(this,i,n,a),s=t(this,o,n,a);return"M"+c.p0+r(c.r,c.p1,c.a1-c.a0)+(e(c,s)?u(c.r,c.p1,c.r,c.p0):u(c.r,c.p1,s.r,s.p0)+r(s.r,s.p1,s.a1-s.a0)+u(s.r,s.p1,c.r,c.p0))+"Z"}function t(n,t,e,r){var u=t.call(n,e,r),i=a.call(n,u,r),o=c.call(n,u,r)+ys,l=s.call(n,u,r)+ys;return{r:i,a0:o,a1:l,p0:[i*Math.cos(o),i*Math.sin(o)],p1:[i*Math.cos(l),i*Math.sin(l)]}}function e(n,t){return n.a0==t.a0&&n.a1==t.a1}function r(n,t,e){return"A"+n+","+n+" 0 "+ +(e>Ea)+",1 "+t}function u(n,t,e,r){return"Q 0,0 "+r}var i=De,o=Pe,a=Ji,c=ki,s=Ei;return n.radius=function(t){return arguments.length?(a=vt(t),n):a},n.source=function(t){return arguments.length?(i=vt(t),n):i},n.target=function(t){return arguments.length?(o=vt(t),n):o},n.startAngle=function(t){return arguments.length?(c=vt(t),n):c},n.endAngle=function(t){return arguments.length?(s=vt(t),n):s},n},Bo.svg.diagonal=function(){function n(n,u){var i=t.call(this,n,u),o=e.call(this,n,u),a=(i.y+o.y)/2,c=[i,{x:i.x,y:a},{x:o.x,y:a},o];return c=c.map(r),"M"+c[0]+"C"+c[1]+" "+c[2]+" "+c[3]}var t=De,e=Pe,r=Gi;return n.source=function(e){return arguments.length?(t=vt(e),n):t},n.target=function(t){return arguments.length?(e=vt(t),n):e},n.projection=function(t){return arguments.length?(r=t,n):r},n},Bo.svg.diagonal.radial=function(){var n=Bo.svg.diagonal(),t=Gi,e=n.projection;return n.projection=function(n){return arguments.length?e(Ki(t=n)):t},n},Bo.svg.symbol=function(){function n(n,r){return(Ss.get(t.call(this,n,r))||to)(e.call(this,n,r))}var t=no,e=Qi;return n.type=function(e){return arguments.length?(t=vt(e),n):t},n.size=function(t){return arguments.length?(e=vt(t),n):e},n};var Ss=Bo.map({circle:to,cross:function(n){var t=Math.sqrt(n/5)/2;return"M"+-3*t+","+-t+"H"+-t+"V"+-3*t+"H"+t+"V"+-t+"H"+3*t+"V"+t+"H"+t+"V"+3*t+"H"+-t+"V"+t+"H"+-3*t+"Z"},diamond:function(n){var t=Math.sqrt(n/(2*Cs)),e=t*Cs;return"M0,"+-t+"L"+e+",0"+" 0,"+t+" "+-e+",0"+"Z"},square:function(n){var t=Math.sqrt(n)/2;return"M"+-t+","+-t+"L"+t+","+-t+" "+t+","+t+" "+-t+","+t+"Z" +},"triangle-down":function(n){var t=Math.sqrt(n/As),e=t*As/2;return"M0,"+e+"L"+t+","+-e+" "+-t+","+-e+"Z"},"triangle-up":function(n){var t=Math.sqrt(n/As),e=t*As/2;return"M0,"+-e+"L"+t+","+e+" "+-t+","+e+"Z"}});Bo.svg.symbolTypes=Ss.keys();var ks,Es,As=Math.sqrt(3),Cs=Math.tan(30*Ta),Ns=[],Ls=0;Ns.call=ya.call,Ns.empty=ya.empty,Ns.node=ya.node,Ns.size=ya.size,Bo.transition=function(n){return arguments.length?ks?n.transition():n:_a.transition()},Bo.transition.prototype=Ns,Ns.select=function(n){var t,e,r,u=this.id,i=[];n=v(n);for(var o=-1,a=this.length;++o<a;){i.push(t=[]);for(var c=this[o],s=-1,l=c.length;++s<l;)(r=c[s])&&(e=n.call(r,r.__data__,s,o))?("__data__"in r&&(e.__data__=r.__data__),io(e,s,u,r.__transition__[u]),t.push(e)):t.push(null)}return eo(i,u)},Ns.selectAll=function(n){var t,e,r,u,i,o=this.id,a=[];n=d(n);for(var c=-1,s=this.length;++c<s;)for(var l=this[c],f=-1,h=l.length;++f<h;)if(r=l[f]){i=r.__transition__[o],e=n.call(r,r.__data__,f,c),a.push(t=[]);for(var g=-1,p=e.length;++g<p;)(u=e[g])&&io(u,g,o,i),t.push(u)}return eo(a,o)},Ns.filter=function(n){var t,e,r,u=[];"function"!=typeof n&&(n=A(n));for(var i=0,o=this.length;o>i;i++){u.push(t=[]);for(var e=this[i],a=0,c=e.length;c>a;a++)(r=e[a])&&n.call(r,r.__data__,a,i)&&t.push(r)}return eo(u,this.id)},Ns.tween=function(n,t){var e=this.id;return arguments.length<2?this.node().__transition__[e].tween.get(n):N(this,null==t?function(t){t.__transition__[e].tween.remove(n)}:function(r){r.__transition__[e].tween.set(n,t)})},Ns.attr=function(n,t){function e(){this.removeAttribute(a)}function r(){this.removeAttributeNS(a.space,a.local)}function u(n){return null==n?e:(n+="",function(){var t,e=this.getAttribute(a);return e!==n&&(t=o(e,n),function(n){this.setAttribute(a,t(n))})})}function i(n){return null==n?r:(n+="",function(){var t,e=this.getAttributeNS(a.space,a.local);return e!==n&&(t=o(e,n),function(n){this.setAttributeNS(a.space,a.local,t(n))})})}if(arguments.length<2){for(t in n)this.attr(t,n[t]);return this}var o="transform"==n?eu:zr,a=Bo.ns.qualify(n);return ro(this,"attr."+n,t,a.local?i:u)},Ns.attrTween=function(n,t){function e(n,e){var r=t.call(this,n,e,this.getAttribute(u));return r&&function(n){this.setAttribute(u,r(n))}}function r(n,e){var r=t.call(this,n,e,this.getAttributeNS(u.space,u.local));return r&&function(n){this.setAttributeNS(u.space,u.local,r(n))}}var u=Bo.ns.qualify(n);return this.tween("attr."+n,u.local?r:e)},Ns.style=function(n,t,e){function r(){this.style.removeProperty(n)}function u(t){return null==t?r:(t+="",function(){var r,u=Qo.getComputedStyle(this,null).getPropertyValue(n);return u!==t&&(r=zr(u,t),function(t){this.style.setProperty(n,r(t),e)})})}var i=arguments.length;if(3>i){if("string"!=typeof n){2>i&&(t="");for(e in n)this.style(e,n[e],t);return this}e=""}return ro(this,"style."+n,t,u)},Ns.styleTween=function(n,t,e){function r(r,u){var i=t.call(this,r,u,Qo.getComputedStyle(this,null).getPropertyValue(n));return i&&function(t){this.style.setProperty(n,i(t),e)}}return arguments.length<3&&(e=""),this.tween("style."+n,r)},Ns.text=function(n){return ro(this,"text",n,uo)},Ns.remove=function(){return this.each("end.transition",function(){var n;this.__transition__.count<2&&(n=this.parentNode)&&n.removeChild(this)})},Ns.ease=function(n){var t=this.id;return arguments.length<1?this.node().__transition__[t].ease:("function"!=typeof n&&(n=Bo.ease.apply(Bo,arguments)),N(this,function(e){e.__transition__[t].ease=n}))},Ns.delay=function(n){var t=this.id;return N(this,"function"==typeof n?function(e,r,u){e.__transition__[t].delay=+n.call(e,e.__data__,r,u)}:(n=+n,function(e){e.__transition__[t].delay=n}))},Ns.duration=function(n){var t=this.id;return N(this,"function"==typeof n?function(e,r,u){e.__transition__[t].duration=Math.max(1,n.call(e,e.__data__,r,u))}:(n=Math.max(1,n),function(e){e.__transition__[t].duration=n}))},Ns.each=function(n,t){var e=this.id;if(arguments.length<2){var r=Es,u=ks;ks=e,N(this,function(t,r,u){Es=t.__transition__[e],n.call(t,t.__data__,r,u)}),Es=r,ks=u}else N(this,function(r){var u=r.__transition__[e];(u.event||(u.event=Bo.dispatch("start","end"))).on(n,t)});return this},Ns.transition=function(){for(var n,t,e,r,u=this.id,i=++Ls,o=[],a=0,c=this.length;c>a;a++){o.push(n=[]);for(var t=this[a],s=0,l=t.length;l>s;s++)(e=t[s])&&(r=Object.create(e.__transition__[u]),r.delay+=r.duration,io(e,s,i,r)),n.push(e)}return eo(o,i)},Bo.svg.axis=function(){function n(n){n.each(function(){var n,s=Bo.select(this),l=this.__chart__||e,f=this.__chart__=e.copy(),h=null==c?f.ticks?f.ticks.apply(f,a):f.domain():c,g=null==t?f.tickFormat?f.tickFormat.apply(f,a):dt:t,p=s.selectAll(".tick").data(h,f),v=p.enter().insert("g",".domain").attr("class","tick").style("opacity",Na),d=Bo.transition(p.exit()).style("opacity",Na).remove(),m=Bo.transition(p).style("opacity",1),y=ei(f),x=s.selectAll(".domain").data([0]),M=(x.enter().append("path").attr("class","domain"),Bo.transition(x));v.append("line"),v.append("text");var _=v.select("line"),b=m.select("line"),w=p.select("text").text(g),S=v.select("text"),k=m.select("text");switch(r){case"bottom":n=oo,_.attr("y2",u),S.attr("y",Math.max(u,0)+o),b.attr("x2",0).attr("y2",u),k.attr("x",0).attr("y",Math.max(u,0)+o),w.attr("dy",".71em").style("text-anchor","middle"),M.attr("d","M"+y[0]+","+i+"V0H"+y[1]+"V"+i);break;case"top":n=oo,_.attr("y2",-u),S.attr("y",-(Math.max(u,0)+o)),b.attr("x2",0).attr("y2",-u),k.attr("x",0).attr("y",-(Math.max(u,0)+o)),w.attr("dy","0em").style("text-anchor","middle"),M.attr("d","M"+y[0]+","+-i+"V0H"+y[1]+"V"+-i);break;case"left":n=ao,_.attr("x2",-u),S.attr("x",-(Math.max(u,0)+o)),b.attr("x2",-u).attr("y2",0),k.attr("x",-(Math.max(u,0)+o)).attr("y",0),w.attr("dy",".32em").style("text-anchor","end"),M.attr("d","M"+-i+","+y[0]+"H0V"+y[1]+"H"+-i);break;case"right":n=ao,_.attr("x2",u),S.attr("x",Math.max(u,0)+o),b.attr("x2",u).attr("y2",0),k.attr("x",Math.max(u,0)+o).attr("y",0),w.attr("dy",".32em").style("text-anchor","start"),M.attr("d","M"+i+","+y[0]+"H0V"+y[1]+"H"+i)}if(f.rangeBand){var E=f,A=E.rangeBand()/2;l=f=function(n){return E(n)+A}}else l.rangeBand?l=f:d.call(n,f);v.call(n,l),m.call(n,f)})}var t,e=Bo.scale.linear(),r=Ts,u=6,i=6,o=3,a=[10],c=null;return n.scale=function(t){return arguments.length?(e=t,n):e},n.orient=function(t){return arguments.length?(r=t in qs?t+"":Ts,n):r},n.ticks=function(){return arguments.length?(a=arguments,n):a},n.tickValues=function(t){return arguments.length?(c=t,n):c},n.tickFormat=function(e){return arguments.length?(t=e,n):t},n.tickSize=function(t){var e=arguments.length;return e?(u=+t,i=+arguments[e-1],n):u},n.innerTickSize=function(t){return arguments.length?(u=+t,n):u},n.outerTickSize=function(t){return arguments.length?(i=+t,n):i},n.tickPadding=function(t){return arguments.length?(o=+t,n):o},n.tickSubdivide=function(){return arguments.length&&n},n};var Ts="bottom",qs={top:1,right:1,bottom:1,left:1};Bo.svg.brush=function(){function n(i){i.each(function(){var i=Bo.select(this).style("pointer-events","all").style("-webkit-tap-highlight-color","rgba(0,0,0,0)").on("mousedown.brush",u).on("touchstart.brush",u),o=i.selectAll(".background").data([0]);o.enter().append("rect").attr("class","background").style("visibility","hidden").style("cursor","crosshair"),i.selectAll(".extent").data([0]).enter().append("rect").attr("class","extent").style("cursor","move");var a=i.selectAll(".resize").data(d,dt);a.exit().remove(),a.enter().append("g").attr("class",function(n){return"resize "+n}).style("cursor",function(n){return zs[n]}).append("rect").attr("x",function(n){return/[ew]$/.test(n)?-3:null}).attr("y",function(n){return/^[ns]/.test(n)?-3:null}).attr("width",6).attr("height",6).style("visibility","hidden"),a.style("display",n.empty()?"none":null);var l,f=Bo.transition(i),h=Bo.transition(o);c&&(l=ei(c),h.attr("x",l[0]).attr("width",l[1]-l[0]),e(f)),s&&(l=ei(s),h.attr("y",l[0]).attr("height",l[1]-l[0]),r(f)),t(f)})}function t(n){n.selectAll(".resize").attr("transform",function(n){return"translate("+l[+/e$/.test(n)]+","+h[+/^s/.test(n)]+")"})}function e(n){n.select(".extent").attr("x",l[0]),n.selectAll(".extent,.n>rect,.s>rect").attr("width",l[1]-l[0])}function r(n){n.select(".extent").attr("y",h[0]),n.selectAll(".extent,.e>rect,.w>rect").attr("height",h[1]-h[0])}function u(){function u(){32==Bo.event.keyCode&&(C||(x=null,L[0]-=l[1],L[1]-=h[1],C=2),f())}function g(){32==Bo.event.keyCode&&2==C&&(L[0]+=l[1],L[1]+=h[1],C=0,f())}function d(){var n=Bo.mouse(_),u=!1;M&&(n[0]+=M[0],n[1]+=M[1]),C||(Bo.event.altKey?(x||(x=[(l[0]+l[1])/2,(h[0]+h[1])/2]),L[0]=l[+(n[0]<x[0])],L[1]=h[+(n[1]<x[1])]):x=null),E&&m(n,c,0)&&(e(S),u=!0),A&&m(n,s,1)&&(r(S),u=!0),u&&(t(S),w({type:"brush",mode:C?"move":"resize"}))}function m(n,t,e){var r,u,a=ei(t),c=a[0],s=a[1],f=L[e],g=e?h:l,d=g[1]-g[0];return C&&(c-=f,s-=d+f),r=(e?v:p)?Math.max(c,Math.min(s,n[e])):n[e],C?u=(r+=f)+d:(x&&(f=Math.max(c,Math.min(s,2*x[e]-r))),r>f?(u=r,r=f):u=f),g[0]!=r||g[1]!=u?(e?o=null:i=null,g[0]=r,g[1]=u,!0):void 0}function y(){d(),S.style("pointer-events","all").selectAll(".resize").style("display",n.empty()?"none":null),Bo.select("body").style("cursor",null),T.on("mousemove.brush",null).on("mouseup.brush",null).on("touchmove.brush",null).on("touchend.brush",null).on("keydown.brush",null).on("keyup.brush",null),N(),w({type:"brushend"})}var x,M,_=this,b=Bo.select(Bo.event.target),w=a.of(_,arguments),S=Bo.select(_),k=b.datum(),E=!/^(n|s)$/.test(k)&&c,A=!/^(e|w)$/.test(k)&&s,C=b.classed("extent"),N=P(),L=Bo.mouse(_),T=Bo.select(Qo).on("keydown.brush",u).on("keyup.brush",g);if(Bo.event.changedTouches?T.on("touchmove.brush",d).on("touchend.brush",y):T.on("mousemove.brush",d).on("mouseup.brush",y),S.interrupt().selectAll("*").interrupt(),C)L[0]=l[0]-L[0],L[1]=h[0]-L[1];else if(k){var q=+/w$/.test(k),z=+/^n/.test(k);M=[l[1-q]-L[0],h[1-z]-L[1]],L[0]=l[q],L[1]=h[z]}else Bo.event.altKey&&(x=L.slice());S.style("pointer-events","none").selectAll(".resize").style("display",null),Bo.select("body").style("cursor",b.style("cursor")),w({type:"brushstart"}),d()}var i,o,a=g(n,"brushstart","brush","brushend"),c=null,s=null,l=[0,0],h=[0,0],p=!0,v=!0,d=Rs[0];return n.event=function(n){n.each(function(){var n=a.of(this,arguments),t={x:l,y:h,i:i,j:o},e=this.__chart__||t;this.__chart__=t,ks?Bo.select(this).transition().each("start.brush",function(){i=e.i,o=e.j,l=e.x,h=e.y,n({type:"brushstart"})}).tween("brush:brush",function(){var e=Rr(l,t.x),r=Rr(h,t.y);return i=o=null,function(u){l=t.x=e(u),h=t.y=r(u),n({type:"brush",mode:"resize"})}}).each("end.brush",function(){i=t.i,o=t.j,n({type:"brush",mode:"resize"}),n({type:"brushend"})}):(n({type:"brushstart"}),n({type:"brush",mode:"resize"}),n({type:"brushend"}))})},n.x=function(t){return arguments.length?(c=t,d=Rs[!c<<1|!s],n):c},n.y=function(t){return arguments.length?(s=t,d=Rs[!c<<1|!s],n):s},n.clamp=function(t){return arguments.length?(c&&s?(p=!!t[0],v=!!t[1]):c?p=!!t:s&&(v=!!t),n):c&&s?[p,v]:c?p:s?v:null},n.extent=function(t){var e,r,u,a,f;return arguments.length?(c&&(e=t[0],r=t[1],s&&(e=e[0],r=r[0]),i=[e,r],c.invert&&(e=c(e),r=c(r)),e>r&&(f=e,e=r,r=f),(e!=l[0]||r!=l[1])&&(l=[e,r])),s&&(u=t[0],a=t[1],c&&(u=u[1],a=a[1]),o=[u,a],s.invert&&(u=s(u),a=s(a)),u>a&&(f=u,u=a,a=f),(u!=h[0]||a!=h[1])&&(h=[u,a])),n):(c&&(i?(e=i[0],r=i[1]):(e=l[0],r=l[1],c.invert&&(e=c.invert(e),r=c.invert(r)),e>r&&(f=e,e=r,r=f))),s&&(o?(u=o[0],a=o[1]):(u=h[0],a=h[1],s.invert&&(u=s.invert(u),a=s.invert(a)),u>a&&(f=u,u=a,a=f))),c&&s?[[e,u],[r,a]]:c?[e,r]:s&&[u,a])},n.clear=function(){return n.empty()||(l=[0,0],h=[0,0],i=o=null),n},n.empty=function(){return!!c&&l[0]==l[1]||!!s&&h[0]==h[1]},Bo.rebind(n,a,"on")};var zs={n:"ns-resize",e:"ew-resize",s:"ns-resize",w:"ew-resize",nw:"nwse-resize",ne:"nesw-resize",se:"nwse-resize",sw:"nesw-resize"},Rs=[["n","e","s","w","nw","ne","se","sw"],["e","w"],["n","s"],[]],Ds=Bo.time={},Ps=Date,Us=["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"];co.prototype={getDate:function(){return this._.getUTCDate()},getDay:function(){return this._.getUTCDay()},getFullYear:function(){return this._.getUTCFullYear()},getHours:function(){return this._.getUTCHours()},getMilliseconds:function(){return this._.getUTCMilliseconds()},getMinutes:function(){return this._.getUTCMinutes()},getMonth:function(){return this._.getUTCMonth()},getSeconds:function(){return this._.getUTCSeconds()},getTime:function(){return this._.getTime()},getTimezoneOffset:function(){return 0},valueOf:function(){return this._.valueOf()},setDate:function(){js.setUTCDate.apply(this._,arguments)},setDay:function(){js.setUTCDay.apply(this._,arguments)},setFullYear:function(){js.setUTCFullYear.apply(this._,arguments)},setHours:function(){js.setUTCHours.apply(this._,arguments)},setMilliseconds:function(){js.setUTCMilliseconds.apply(this._,arguments)},setMinutes:function(){js.setUTCMinutes.apply(this._,arguments)},setMonth:function(){js.setUTCMonth.apply(this._,arguments)},setSeconds:function(){js.setUTCSeconds.apply(this._,arguments)},setTime:function(){js.setTime.apply(this._,arguments)}};var js=Date.prototype,Hs="%a %b %e %X %Y",Fs="%m/%d/%Y",Os="%H:%M:%S",Ys=["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],Is=["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],Zs=["January","February","March","April","May","June","July","August","September","October","November","December"],Vs=["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"];Ds.year=so(function(n){return n=Ds.day(n),n.setMonth(0,1),n},function(n,t){n.setFullYear(n.getFullYear()+t)},function(n){return n.getFullYear()}),Ds.years=Ds.year.range,Ds.years.utc=Ds.year.utc.range,Ds.day=so(function(n){var t=new Ps(2e3,0);return t.setFullYear(n.getFullYear(),n.getMonth(),n.getDate()),t},function(n,t){n.setDate(n.getDate()+t)},function(n){return n.getDate()-1}),Ds.days=Ds.day.range,Ds.days.utc=Ds.day.utc.range,Ds.dayOfYear=function(n){var t=Ds.year(n);return Math.floor((n-t-6e4*(n.getTimezoneOffset()-t.getTimezoneOffset()))/864e5)},Us.forEach(function(n,t){n=n.toLowerCase(),t=7-t;var e=Ds[n]=so(function(n){return(n=Ds.day(n)).setDate(n.getDate()-(n.getDay()+t)%7),n},function(n,t){n.setDate(n.getDate()+7*Math.floor(t))},function(n){var e=Ds.year(n).getDay();return Math.floor((Ds.dayOfYear(n)+(e+t)%7)/7)-(e!==t)});Ds[n+"s"]=e.range,Ds[n+"s"].utc=e.utc.range,Ds[n+"OfYear"]=function(n){var e=Ds.year(n).getDay();return Math.floor((Ds.dayOfYear(n)+(e+t)%7)/7)}}),Ds.week=Ds.sunday,Ds.weeks=Ds.sunday.range,Ds.weeks.utc=Ds.sunday.utc.range,Ds.weekOfYear=Ds.sundayOfYear,Ds.format=fo;var Xs=go(Ys),$s=po(Ys),Bs=go(Is),Ws=po(Is),Js=go(Zs),Gs=po(Zs),Ks=go(Vs),Qs=po(Vs),nl=/^%/,tl={"-":"",_:" ",0:"0"},el={a:function(n){return Is[n.getDay()]},A:function(n){return Ys[n.getDay()]},b:function(n){return Vs[n.getMonth()]},B:function(n){return Zs[n.getMonth()]},c:fo(Hs),d:function(n,t){return vo(n.getDate(),t,2)},e:function(n,t){return vo(n.getDate(),t,2)},H:function(n,t){return vo(n.getHours(),t,2)},I:function(n,t){return vo(n.getHours()%12||12,t,2)},j:function(n,t){return vo(1+Ds.dayOfYear(n),t,3)},L:function(n,t){return vo(n.getMilliseconds(),t,3)},m:function(n,t){return vo(n.getMonth()+1,t,2)},M:function(n,t){return vo(n.getMinutes(),t,2)},p:function(n){return n.getHours()>=12?"PM":"AM"},S:function(n,t){return vo(n.getSeconds(),t,2)},U:function(n,t){return vo(Ds.sundayOfYear(n),t,2)},w:function(n){return n.getDay()},W:function(n,t){return vo(Ds.mondayOfYear(n),t,2)},x:fo(Fs),X:fo(Os),y:function(n,t){return vo(n.getFullYear()%100,t,2)},Y:function(n,t){return vo(n.getFullYear()%1e4,t,4)},Z:Ho,"%":function(){return"%"}},rl={a:mo,A:yo,b:bo,B:wo,c:So,d:qo,e:qo,H:Ro,I:Ro,j:zo,L:Uo,m:To,M:Do,p:jo,S:Po,U:Mo,w:xo,W:_o,x:ko,X:Eo,y:Co,Y:Ao,Z:No,"%":Fo},ul=/^\s*\d+/,il=Bo.map({am:0,pm:1});fo.utc=Oo;var ol=Oo("%Y-%m-%dT%H:%M:%S.%LZ");fo.iso=Date.prototype.toISOString&&+new Date("2000-01-01T00:00:00.000Z")?Yo:ol,Yo.parse=function(n){var t=new Date(n);return isNaN(t)?null:t},Yo.toString=ol.toString,Ds.second=so(function(n){return new Ps(1e3*Math.floor(n/1e3))},function(n,t){n.setTime(n.getTime()+1e3*Math.floor(t))},function(n){return n.getSeconds()}),Ds.seconds=Ds.second.range,Ds.seconds.utc=Ds.second.utc.range,Ds.minute=so(function(n){return new Ps(6e4*Math.floor(n/6e4))},function(n,t){n.setTime(n.getTime()+6e4*Math.floor(t))},function(n){return n.getMinutes()}),Ds.minutes=Ds.minute.range,Ds.minutes.utc=Ds.minute.utc.range,Ds.hour=so(function(n){var t=n.getTimezoneOffset()/60;return new Ps(36e5*(Math.floor(n/36e5-t)+t))},function(n,t){n.setTime(n.getTime()+36e5*Math.floor(t))},function(n){return n.getHours()}),Ds.hours=Ds.hour.range,Ds.hours.utc=Ds.hour.utc.range,Ds.month=so(function(n){return n=Ds.day(n),n.setDate(1),n},function(n,t){n.setMonth(n.getMonth()+t)},function(n){return n.getMonth()}),Ds.months=Ds.month.range,Ds.months.utc=Ds.month.utc.range;var al=[1e3,5e3,15e3,3e4,6e4,3e5,9e5,18e5,36e5,108e5,216e5,432e5,864e5,1728e5,6048e5,2592e6,7776e6,31536e6],cl=[[Ds.second,1],[Ds.second,5],[Ds.second,15],[Ds.second,30],[Ds.minute,1],[Ds.minute,5],[Ds.minute,15],[Ds.minute,30],[Ds.hour,1],[Ds.hour,3],[Ds.hour,6],[Ds.hour,12],[Ds.day,1],[Ds.day,2],[Ds.week,1],[Ds.month,1],[Ds.month,3],[Ds.year,1]],sl=[[fo("%Y"),Vt],[fo("%B"),function(n){return n.getMonth()}],[fo("%b %d"),function(n){return 1!=n.getDate()}],[fo("%a %d"),function(n){return n.getDay()&&1!=n.getDate()}],[fo("%I %p"),function(n){return n.getHours()}],[fo("%I:%M"),function(n){return n.getMinutes()}],[fo(":%S"),function(n){return n.getSeconds()}],[fo(".%L"),function(n){return n.getMilliseconds()}]],ll=Vo(sl);cl.year=Ds.year,Ds.scale=function(){return Io(Bo.scale.linear(),cl,ll)};var fl={range:function(n,t,e){return Bo.range(+n,+t,e).map(Zo)},floor:dt,ceil:dt},hl=cl.map(function(n){return[n[0].utc,n[1]]}),gl=[[Oo("%Y"),Vt],[Oo("%B"),function(n){return n.getUTCMonth()}],[Oo("%b %d"),function(n){return 1!=n.getUTCDate()}],[Oo("%a %d"),function(n){return n.getUTCDay()&&1!=n.getUTCDate()}],[Oo("%I %p"),function(n){return n.getUTCHours()}],[Oo("%I:%M"),function(n){return n.getUTCMinutes()}],[Oo(":%S"),function(n){return n.getUTCSeconds()}],[Oo(".%L"),function(n){return n.getUTCMilliseconds()}]],pl=Vo(gl);return hl.year=Ds.year.utc,Ds.scale.utc=function(){return Io(Bo.scale.linear(),hl,pl)},Bo.text=mt(function(n){return n.responseText}),Bo.json=function(n,t){return yt(n,"application/json",Xo,t)},Bo.html=function(n,t){return yt(n,"text/html",$o,t)},Bo.xml=mt(function(n){return n.responseXML}),Bo}(); \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/popoto_dev/js/jquery-2.1.0.min.js Fri Oct 02 01:08:46 2015 -0400 @@ -0,0 +1,4 @@ +/*! jQuery v2.1.0 | (c) 2005, 2014 jQuery Foundation, Inc. | jquery.org/license */ +!function(a,b){"object"==typeof module&&"object"==typeof module.exports?module.exports=a.document?b(a,!0):function(a){if(!a.document)throw new Error("jQuery requires a window with a document");return b(a)}:b(a)}("undefined"!=typeof window?window:this,function(a,b){var c=[],d=c.slice,e=c.concat,f=c.push,g=c.indexOf,h={},i=h.toString,j=h.hasOwnProperty,k="".trim,l={},m=a.document,n="2.1.0",o=function(a,b){return new o.fn.init(a,b)},p=/^-ms-/,q=/-([\da-z])/gi,r=function(a,b){return b.toUpperCase()};o.fn=o.prototype={jquery:n,constructor:o,selector:"",length:0,toArray:function(){return d.call(this)},get:function(a){return null!=a?0>a?this[a+this.length]:this[a]:d.call(this)},pushStack:function(a){var b=o.merge(this.constructor(),a);return b.prevObject=this,b.context=this.context,b},each:function(a,b){return o.each(this,a,b)},map:function(a){return this.pushStack(o.map(this,function(b,c){return a.call(b,c,b)}))},slice:function(){return this.pushStack(d.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(a){var b=this.length,c=+a+(0>a?b:0);return this.pushStack(c>=0&&b>c?[this[c]]:[])},end:function(){return this.prevObject||this.constructor(null)},push:f,sort:c.sort,splice:c.splice},o.extend=o.fn.extend=function(){var a,b,c,d,e,f,g=arguments[0]||{},h=1,i=arguments.length,j=!1;for("boolean"==typeof g&&(j=g,g=arguments[h]||{},h++),"object"==typeof g||o.isFunction(g)||(g={}),h===i&&(g=this,h--);i>h;h++)if(null!=(a=arguments[h]))for(b in a)c=g[b],d=a[b],g!==d&&(j&&d&&(o.isPlainObject(d)||(e=o.isArray(d)))?(e?(e=!1,f=c&&o.isArray(c)?c:[]):f=c&&o.isPlainObject(c)?c:{},g[b]=o.extend(j,f,d)):void 0!==d&&(g[b]=d));return g},o.extend({expando:"jQuery"+(n+Math.random()).replace(/\D/g,""),isReady:!0,error:function(a){throw new Error(a)},noop:function(){},isFunction:function(a){return"function"===o.type(a)},isArray:Array.isArray,isWindow:function(a){return null!=a&&a===a.window},isNumeric:function(a){return a-parseFloat(a)>=0},isPlainObject:function(a){if("object"!==o.type(a)||a.nodeType||o.isWindow(a))return!1;try{if(a.constructor&&!j.call(a.constructor.prototype,"isPrototypeOf"))return!1}catch(b){return!1}return!0},isEmptyObject:function(a){var b;for(b in a)return!1;return!0},type:function(a){return null==a?a+"":"object"==typeof a||"function"==typeof a?h[i.call(a)]||"object":typeof a},globalEval:function(a){var b,c=eval;a=o.trim(a),a&&(1===a.indexOf("use strict")?(b=m.createElement("script"),b.text=a,m.head.appendChild(b).parentNode.removeChild(b)):c(a))},camelCase:function(a){return a.replace(p,"ms-").replace(q,r)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toLowerCase()===b.toLowerCase()},each:function(a,b,c){var d,e=0,f=a.length,g=s(a);if(c){if(g){for(;f>e;e++)if(d=b.apply(a[e],c),d===!1)break}else for(e in a)if(d=b.apply(a[e],c),d===!1)break}else if(g){for(;f>e;e++)if(d=b.call(a[e],e,a[e]),d===!1)break}else for(e in a)if(d=b.call(a[e],e,a[e]),d===!1)break;return a},trim:function(a){return null==a?"":k.call(a)},makeArray:function(a,b){var c=b||[];return null!=a&&(s(Object(a))?o.merge(c,"string"==typeof a?[a]:a):f.call(c,a)),c},inArray:function(a,b,c){return null==b?-1:g.call(b,a,c)},merge:function(a,b){for(var c=+b.length,d=0,e=a.length;c>d;d++)a[e++]=b[d];return a.length=e,a},grep:function(a,b,c){for(var d,e=[],f=0,g=a.length,h=!c;g>f;f++)d=!b(a[f],f),d!==h&&e.push(a[f]);return e},map:function(a,b,c){var d,f=0,g=a.length,h=s(a),i=[];if(h)for(;g>f;f++)d=b(a[f],f,c),null!=d&&i.push(d);else for(f in a)d=b(a[f],f,c),null!=d&&i.push(d);return e.apply([],i)},guid:1,proxy:function(a,b){var c,e,f;return"string"==typeof b&&(c=a[b],b=a,a=c),o.isFunction(a)?(e=d.call(arguments,2),f=function(){return a.apply(b||this,e.concat(d.call(arguments)))},f.guid=a.guid=a.guid||o.guid++,f):void 0},now:Date.now,support:l}),o.each("Boolean Number String Function Array Date RegExp Object Error".split(" "),function(a,b){h["[object "+b+"]"]=b.toLowerCase()});function s(a){var b=a.length,c=o.type(a);return"function"===c||o.isWindow(a)?!1:1===a.nodeType&&b?!0:"array"===c||0===b||"number"==typeof b&&b>0&&b-1 in a}var t=function(a){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s="sizzle"+-new Date,t=a.document,u=0,v=0,w=eb(),x=eb(),y=eb(),z=function(a,b){return a===b&&(j=!0),0},A="undefined",B=1<<31,C={}.hasOwnProperty,D=[],E=D.pop,F=D.push,G=D.push,H=D.slice,I=D.indexOf||function(a){for(var b=0,c=this.length;c>b;b++)if(this[b]===a)return b;return-1},J="checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",K="[\\x20\\t\\r\\n\\f]",L="(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",M=L.replace("w","w#"),N="\\["+K+"*("+L+")"+K+"*(?:([*^$|!~]?=)"+K+"*(?:(['\"])((?:\\\\.|[^\\\\])*?)\\3|("+M+")|)|)"+K+"*\\]",O=":("+L+")(?:\\(((['\"])((?:\\\\.|[^\\\\])*?)\\3|((?:\\\\.|[^\\\\()[\\]]|"+N.replace(3,8)+")*)|.*)\\)|)",P=new RegExp("^"+K+"+|((?:^|[^\\\\])(?:\\\\.)*)"+K+"+$","g"),Q=new RegExp("^"+K+"*,"+K+"*"),R=new RegExp("^"+K+"*([>+~]|"+K+")"+K+"*"),S=new RegExp("="+K+"*([^\\]'\"]*?)"+K+"*\\]","g"),T=new RegExp(O),U=new RegExp("^"+M+"$"),V={ID:new RegExp("^#("+L+")"),CLASS:new RegExp("^\\.("+L+")"),TAG:new RegExp("^("+L.replace("w","w*")+")"),ATTR:new RegExp("^"+N),PSEUDO:new RegExp("^"+O),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+K+"*(even|odd|(([+-]|)(\\d*)n|)"+K+"*(?:([+-]|)"+K+"*(\\d+)|))"+K+"*\\)|)","i"),bool:new RegExp("^(?:"+J+")$","i"),needsContext:new RegExp("^"+K+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+K+"*((?:-\\d)?\\d*)"+K+"*\\)|)(?=[^-]|$)","i")},W=/^(?:input|select|textarea|button)$/i,X=/^h\d$/i,Y=/^[^{]+\{\s*\[native \w/,Z=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,$=/[+~]/,_=/'|\\/g,ab=new RegExp("\\\\([\\da-f]{1,6}"+K+"?|("+K+")|.)","ig"),bb=function(a,b,c){var d="0x"+b-65536;return d!==d||c?b:0>d?String.fromCharCode(d+65536):String.fromCharCode(d>>10|55296,1023&d|56320)};try{G.apply(D=H.call(t.childNodes),t.childNodes),D[t.childNodes.length].nodeType}catch(cb){G={apply:D.length?function(a,b){F.apply(a,H.call(b))}:function(a,b){var c=a.length,d=0;while(a[c++]=b[d++]);a.length=c-1}}}function db(a,b,d,e){var f,g,h,i,j,m,p,q,u,v;if((b?b.ownerDocument||b:t)!==l&&k(b),b=b||l,d=d||[],!a||"string"!=typeof a)return d;if(1!==(i=b.nodeType)&&9!==i)return[];if(n&&!e){if(f=Z.exec(a))if(h=f[1]){if(9===i){if(g=b.getElementById(h),!g||!g.parentNode)return d;if(g.id===h)return d.push(g),d}else if(b.ownerDocument&&(g=b.ownerDocument.getElementById(h))&&r(b,g)&&g.id===h)return d.push(g),d}else{if(f[2])return G.apply(d,b.getElementsByTagName(a)),d;if((h=f[3])&&c.getElementsByClassName&&b.getElementsByClassName)return G.apply(d,b.getElementsByClassName(h)),d}if(c.qsa&&(!o||!o.test(a))){if(q=p=s,u=b,v=9===i&&a,1===i&&"object"!==b.nodeName.toLowerCase()){m=ob(a),(p=b.getAttribute("id"))?q=p.replace(_,"\\$&"):b.setAttribute("id",q),q="[id='"+q+"'] ",j=m.length;while(j--)m[j]=q+pb(m[j]);u=$.test(a)&&mb(b.parentNode)||b,v=m.join(",")}if(v)try{return G.apply(d,u.querySelectorAll(v)),d}catch(w){}finally{p||b.removeAttribute("id")}}}return xb(a.replace(P,"$1"),b,d,e)}function eb(){var a=[];function b(c,e){return a.push(c+" ")>d.cacheLength&&delete b[a.shift()],b[c+" "]=e}return b}function fb(a){return a[s]=!0,a}function gb(a){var b=l.createElement("div");try{return!!a(b)}catch(c){return!1}finally{b.parentNode&&b.parentNode.removeChild(b),b=null}}function hb(a,b){var c=a.split("|"),e=a.length;while(e--)d.attrHandle[c[e]]=b}function ib(a,b){var c=b&&a,d=c&&1===a.nodeType&&1===b.nodeType&&(~b.sourceIndex||B)-(~a.sourceIndex||B);if(d)return d;if(c)while(c=c.nextSibling)if(c===b)return-1;return a?1:-1}function jb(a){return function(b){var c=b.nodeName.toLowerCase();return"input"===c&&b.type===a}}function kb(a){return function(b){var c=b.nodeName.toLowerCase();return("input"===c||"button"===c)&&b.type===a}}function lb(a){return fb(function(b){return b=+b,fb(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 mb(a){return a&&typeof a.getElementsByTagName!==A&&a}c=db.support={},f=db.isXML=function(a){var b=a&&(a.ownerDocument||a).documentElement;return b?"HTML"!==b.nodeName:!1},k=db.setDocument=function(a){var b,e=a?a.ownerDocument||a:t,g=e.defaultView;return e!==l&&9===e.nodeType&&e.documentElement?(l=e,m=e.documentElement,n=!f(e),g&&g!==g.top&&(g.addEventListener?g.addEventListener("unload",function(){k()},!1):g.attachEvent&&g.attachEvent("onunload",function(){k()})),c.attributes=gb(function(a){return a.className="i",!a.getAttribute("className")}),c.getElementsByTagName=gb(function(a){return a.appendChild(e.createComment("")),!a.getElementsByTagName("*").length}),c.getElementsByClassName=Y.test(e.getElementsByClassName)&&gb(function(a){return a.innerHTML="<div class='a'></div><div class='a i'></div>",a.firstChild.className="i",2===a.getElementsByClassName("i").length}),c.getById=gb(function(a){return m.appendChild(a).id=s,!e.getElementsByName||!e.getElementsByName(s).length}),c.getById?(d.find.ID=function(a,b){if(typeof b.getElementById!==A&&n){var c=b.getElementById(a);return c&&c.parentNode?[c]:[]}},d.filter.ID=function(a){var b=a.replace(ab,bb);return function(a){return a.getAttribute("id")===b}}):(delete d.find.ID,d.filter.ID=function(a){var b=a.replace(ab,bb);return function(a){var c=typeof a.getAttributeNode!==A&&a.getAttributeNode("id");return c&&c.value===b}}),d.find.TAG=c.getElementsByTagName?function(a,b){return typeof b.getElementsByTagName!==A?b.getElementsByTagName(a):void 0}:function(a,b){var c,d=[],e=0,f=b.getElementsByTagName(a);if("*"===a){while(c=f[e++])1===c.nodeType&&d.push(c);return d}return f},d.find.CLASS=c.getElementsByClassName&&function(a,b){return typeof b.getElementsByClassName!==A&&n?b.getElementsByClassName(a):void 0},p=[],o=[],(c.qsa=Y.test(e.querySelectorAll))&&(gb(function(a){a.innerHTML="<select t=''><option selected=''></option></select>",a.querySelectorAll("[t^='']").length&&o.push("[*^$]="+K+"*(?:''|\"\")"),a.querySelectorAll("[selected]").length||o.push("\\["+K+"*(?:value|"+J+")"),a.querySelectorAll(":checked").length||o.push(":checked")}),gb(function(a){var b=e.createElement("input");b.setAttribute("type","hidden"),a.appendChild(b).setAttribute("name","D"),a.querySelectorAll("[name=d]").length&&o.push("name"+K+"*[*^$|!~]?="),a.querySelectorAll(":enabled").length||o.push(":enabled",":disabled"),a.querySelectorAll("*,:x"),o.push(",.*:")})),(c.matchesSelector=Y.test(q=m.webkitMatchesSelector||m.mozMatchesSelector||m.oMatchesSelector||m.msMatchesSelector))&&gb(function(a){c.disconnectedMatch=q.call(a,"div"),q.call(a,"[s!='']:x"),p.push("!=",O)}),o=o.length&&new RegExp(o.join("|")),p=p.length&&new RegExp(p.join("|")),b=Y.test(m.compareDocumentPosition),r=b||Y.test(m.contains)?function(a,b){var c=9===a.nodeType?a.documentElement:a,d=b&&b.parentNode;return a===d||!(!d||1!==d.nodeType||!(c.contains?c.contains(d):a.compareDocumentPosition&&16&a.compareDocumentPosition(d)))}:function(a,b){if(b)while(b=b.parentNode)if(b===a)return!0;return!1},z=b?function(a,b){if(a===b)return j=!0,0;var d=!a.compareDocumentPosition-!b.compareDocumentPosition;return d?d:(d=(a.ownerDocument||a)===(b.ownerDocument||b)?a.compareDocumentPosition(b):1,1&d||!c.sortDetached&&b.compareDocumentPosition(a)===d?a===e||a.ownerDocument===t&&r(t,a)?-1:b===e||b.ownerDocument===t&&r(t,b)?1:i?I.call(i,a)-I.call(i,b):0:4&d?-1:1)}:function(a,b){if(a===b)return j=!0,0;var c,d=0,f=a.parentNode,g=b.parentNode,h=[a],k=[b];if(!f||!g)return a===e?-1:b===e?1:f?-1:g?1:i?I.call(i,a)-I.call(i,b):0;if(f===g)return ib(a,b);c=a;while(c=c.parentNode)h.unshift(c);c=b;while(c=c.parentNode)k.unshift(c);while(h[d]===k[d])d++;return d?ib(h[d],k[d]):h[d]===t?-1:k[d]===t?1:0},e):l},db.matches=function(a,b){return db(a,null,null,b)},db.matchesSelector=function(a,b){if((a.ownerDocument||a)!==l&&k(a),b=b.replace(S,"='$1']"),!(!c.matchesSelector||!n||p&&p.test(b)||o&&o.test(b)))try{var d=q.call(a,b);if(d||c.disconnectedMatch||a.document&&11!==a.document.nodeType)return d}catch(e){}return db(b,l,null,[a]).length>0},db.contains=function(a,b){return(a.ownerDocument||a)!==l&&k(a),r(a,b)},db.attr=function(a,b){(a.ownerDocument||a)!==l&&k(a);var e=d.attrHandle[b.toLowerCase()],f=e&&C.call(d.attrHandle,b.toLowerCase())?e(a,b,!n):void 0;return void 0!==f?f:c.attributes||!n?a.getAttribute(b):(f=a.getAttributeNode(b))&&f.specified?f.value:null},db.error=function(a){throw new Error("Syntax error, unrecognized expression: "+a)},db.uniqueSort=function(a){var b,d=[],e=0,f=0;if(j=!c.detectDuplicates,i=!c.sortStable&&a.slice(0),a.sort(z),j){while(b=a[f++])b===a[f]&&(e=d.push(f));while(e--)a.splice(d[e],1)}return i=null,a},e=db.getText=function(a){var b,c="",d=0,f=a.nodeType;if(f){if(1===f||9===f||11===f){if("string"==typeof a.textContent)return a.textContent;for(a=a.firstChild;a;a=a.nextSibling)c+=e(a)}else if(3===f||4===f)return a.nodeValue}else while(b=a[d++])c+=e(b);return c},d=db.selectors={cacheLength:50,createPseudo:fb,match:V,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(a){return a[1]=a[1].replace(ab,bb),a[3]=(a[4]||a[5]||"").replace(ab,bb),"~="===a[2]&&(a[3]=" "+a[3]+" "),a.slice(0,4)},CHILD:function(a){return a[1]=a[1].toLowerCase(),"nth"===a[1].slice(0,3)?(a[3]||db.error(a[0]),a[4]=+(a[4]?a[5]+(a[6]||1):2*("even"===a[3]||"odd"===a[3])),a[5]=+(a[7]+a[8]||"odd"===a[3])):a[3]&&db.error(a[0]),a},PSEUDO:function(a){var b,c=!a[5]&&a[2];return V.CHILD.test(a[0])?null:(a[3]&&void 0!==a[4]?a[2]=a[4]:c&&T.test(c)&&(b=ob(c,!0))&&(b=c.indexOf(")",c.length-b)-c.length)&&(a[0]=a[0].slice(0,b),a[2]=c.slice(0,b)),a.slice(0,3))}},filter:{TAG:function(a){var b=a.replace(ab,bb).toLowerCase();return"*"===a?function(){return!0}:function(a){return a.nodeName&&a.nodeName.toLowerCase()===b}},CLASS:function(a){var b=w[a+" "];return b||(b=new RegExp("(^|"+K+")"+a+"("+K+"|$)"))&&w(a,function(a){return b.test("string"==typeof a.className&&a.className||typeof a.getAttribute!==A&&a.getAttribute("class")||"")})},ATTR:function(a,b,c){return function(d){var e=db.attr(d,a);return null==e?"!="===b:b?(e+="","="===b?e===c:"!="===b?e!==c:"^="===b?c&&0===e.indexOf(c):"*="===b?c&&e.indexOf(c)>-1:"$="===b?c&&e.slice(-c.length)===c:"~="===b?(" "+e+" ").indexOf(c)>-1:"|="===b?e===c||e.slice(0,c.length+1)===c+"-":!1):!0}},CHILD:function(a,b,c,d,e){var f="nth"!==a.slice(0,3),g="last"!==a.slice(-4),h="of-type"===b;return 1===d&&0===e?function(a){return!!a.parentNode}:function(b,c,i){var j,k,l,m,n,o,p=f!==g?"nextSibling":"previousSibling",q=b.parentNode,r=h&&b.nodeName.toLowerCase(),t=!i&&!h;if(q){if(f){while(p){l=b;while(l=l[p])if(h?l.nodeName.toLowerCase()===r:1===l.nodeType)return!1;o=p="only"===a&&!o&&"nextSibling"}return!0}if(o=[g?q.firstChild:q.lastChild],g&&t){k=q[s]||(q[s]={}),j=k[a]||[],n=j[0]===u&&j[1],m=j[0]===u&&j[2],l=n&&q.childNodes[n];while(l=++n&&l&&l[p]||(m=n=0)||o.pop())if(1===l.nodeType&&++m&&l===b){k[a]=[u,n,m];break}}else if(t&&(j=(b[s]||(b[s]={}))[a])&&j[0]===u)m=j[1];else while(l=++n&&l&&l[p]||(m=n=0)||o.pop())if((h?l.nodeName.toLowerCase()===r:1===l.nodeType)&&++m&&(t&&((l[s]||(l[s]={}))[a]=[u,m]),l===b))break;return m-=e,m===d||m%d===0&&m/d>=0}}},PSEUDO:function(a,b){var c,e=d.pseudos[a]||d.setFilters[a.toLowerCase()]||db.error("unsupported pseudo: "+a);return e[s]?e(b):e.length>1?(c=[a,a,"",b],d.setFilters.hasOwnProperty(a.toLowerCase())?fb(function(a,c){var d,f=e(a,b),g=f.length;while(g--)d=I.call(a,f[g]),a[d]=!(c[d]=f[g])}):function(a){return e(a,0,c)}):e}},pseudos:{not:fb(function(a){var b=[],c=[],d=g(a.replace(P,"$1"));return d[s]?fb(function(a,b,c,e){var f,g=d(a,null,e,[]),h=a.length;while(h--)(f=g[h])&&(a[h]=!(b[h]=f))}):function(a,e,f){return b[0]=a,d(b,null,f,c),!c.pop()}}),has:fb(function(a){return function(b){return db(a,b).length>0}}),contains:fb(function(a){return function(b){return(b.textContent||b.innerText||e(b)).indexOf(a)>-1}}),lang:fb(function(a){return U.test(a||"")||db.error("unsupported lang: "+a),a=a.replace(ab,bb).toLowerCase(),function(b){var c;do if(c=n?b.lang:b.getAttribute("xml:lang")||b.getAttribute("lang"))return c=c.toLowerCase(),c===a||0===c.indexOf(a+"-");while((b=b.parentNode)&&1===b.nodeType);return!1}}),target:function(b){var c=a.location&&a.location.hash;return c&&c.slice(1)===b.id},root:function(a){return a===m},focus:function(a){return a===l.activeElement&&(!l.hasFocus||l.hasFocus())&&!!(a.type||a.href||~a.tabIndex)},enabled:function(a){return a.disabled===!1},disabled:function(a){return a.disabled===!0},checked:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&!!a.checked||"option"===b&&!!a.selected},selected:function(a){return a.parentNode&&a.parentNode.selectedIndex,a.selected===!0},empty:function(a){for(a=a.firstChild;a;a=a.nextSibling)if(a.nodeType<6)return!1;return!0},parent:function(a){return!d.pseudos.empty(a)},header:function(a){return X.test(a.nodeName)},input:function(a){return W.test(a.nodeName)},button:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&"button"===a.type||"button"===b},text:function(a){var b;return"input"===a.nodeName.toLowerCase()&&"text"===a.type&&(null==(b=a.getAttribute("type"))||"text"===b.toLowerCase())},first:lb(function(){return[0]}),last:lb(function(a,b){return[b-1]}),eq:lb(function(a,b,c){return[0>c?c+b:c]}),even:lb(function(a,b){for(var c=0;b>c;c+=2)a.push(c);return a}),odd:lb(function(a,b){for(var c=1;b>c;c+=2)a.push(c);return a}),lt:lb(function(a,b,c){for(var d=0>c?c+b:c;--d>=0;)a.push(d);return a}),gt:lb(function(a,b,c){for(var d=0>c?c+b:c;++d<b;)a.push(d);return a})}},d.pseudos.nth=d.pseudos.eq;for(b in{radio:!0,checkbox:!0,file:!0,password:!0,image:!0})d.pseudos[b]=jb(b);for(b in{submit:!0,reset:!0})d.pseudos[b]=kb(b);function nb(){}nb.prototype=d.filters=d.pseudos,d.setFilters=new nb;function ob(a,b){var c,e,f,g,h,i,j,k=x[a+" "];if(k)return b?0:k.slice(0);h=a,i=[],j=d.preFilter;while(h){(!c||(e=Q.exec(h)))&&(e&&(h=h.slice(e[0].length)||h),i.push(f=[])),c=!1,(e=R.exec(h))&&(c=e.shift(),f.push({value:c,type:e[0].replace(P," ")}),h=h.slice(c.length));for(g in d.filter)!(e=V[g].exec(h))||j[g]&&!(e=j[g](e))||(c=e.shift(),f.push({value:c,type:g,matches:e}),h=h.slice(c.length));if(!c)break}return b?h.length:h?db.error(a):x(a,i).slice(0)}function pb(a){for(var b=0,c=a.length,d="";c>b;b++)d+=a[b].value;return d}function qb(a,b,c){var d=b.dir,e=c&&"parentNode"===d,f=v++;return b.first?function(b,c,f){while(b=b[d])if(1===b.nodeType||e)return a(b,c,f)}:function(b,c,g){var h,i,j=[u,f];if(g){while(b=b[d])if((1===b.nodeType||e)&&a(b,c,g))return!0}else while(b=b[d])if(1===b.nodeType||e){if(i=b[s]||(b[s]={}),(h=i[d])&&h[0]===u&&h[1]===f)return j[2]=h[2];if(i[d]=j,j[2]=a(b,c,g))return!0}}}function rb(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 sb(a,b,c,d,e){for(var f,g=[],h=0,i=a.length,j=null!=b;i>h;h++)(f=a[h])&&(!c||c(f,d,e))&&(g.push(f),j&&b.push(h));return g}function tb(a,b,c,d,e,f){return d&&!d[s]&&(d=tb(d)),e&&!e[s]&&(e=tb(e,f)),fb(function(f,g,h,i){var j,k,l,m=[],n=[],o=g.length,p=f||wb(b||"*",h.nodeType?[h]:h,[]),q=!a||!f&&b?p:sb(p,m,a,h,i),r=c?e||(f?a:o||d)?[]:g:q;if(c&&c(q,r,h,i),d){j=sb(r,n),d(j,[],h,i),k=j.length;while(k--)(l=j[k])&&(r[n[k]]=!(q[n[k]]=l))}if(f){if(e||a){if(e){j=[],k=r.length;while(k--)(l=r[k])&&j.push(q[k]=l);e(null,r=[],j,i)}k=r.length;while(k--)(l=r[k])&&(j=e?I.call(f,l):m[k])>-1&&(f[j]=!(g[j]=l))}}else r=sb(r===g?r.splice(o,r.length):r),e?e(null,g,r,i):G.apply(g,r)})}function ub(a){for(var b,c,e,f=a.length,g=d.relative[a[0].type],i=g||d.relative[" "],j=g?1:0,k=qb(function(a){return a===b},i,!0),l=qb(function(a){return I.call(b,a)>-1},i,!0),m=[function(a,c,d){return!g&&(d||c!==h)||((b=c).nodeType?k(a,c,d):l(a,c,d))}];f>j;j++)if(c=d.relative[a[j].type])m=[qb(rb(m),c)];else{if(c=d.filter[a[j].type].apply(null,a[j].matches),c[s]){for(e=++j;f>e;e++)if(d.relative[a[e].type])break;return tb(j>1&&rb(m),j>1&&pb(a.slice(0,j-1).concat({value:" "===a[j-2].type?"*":""})).replace(P,"$1"),c,e>j&&ub(a.slice(j,e)),f>e&&ub(a=a.slice(e)),f>e&&pb(a))}m.push(c)}return rb(m)}function vb(a,b){var c=b.length>0,e=a.length>0,f=function(f,g,i,j,k){var m,n,o,p=0,q="0",r=f&&[],s=[],t=h,v=f||e&&d.find.TAG("*",k),w=u+=null==t?1:Math.random()||.1,x=v.length;for(k&&(h=g!==l&&g);q!==x&&null!=(m=v[q]);q++){if(e&&m){n=0;while(o=a[n++])if(o(m,g,i)){j.push(m);break}k&&(u=w)}c&&((m=!o&&m)&&p--,f&&r.push(m))}if(p+=q,c&&q!==p){n=0;while(o=b[n++])o(r,s,g,i);if(f){if(p>0)while(q--)r[q]||s[q]||(s[q]=E.call(j));s=sb(s)}G.apply(j,s),k&&!f&&s.length>0&&p+b.length>1&&db.uniqueSort(j)}return k&&(u=w,h=t),r};return c?fb(f):f}g=db.compile=function(a,b){var c,d=[],e=[],f=y[a+" "];if(!f){b||(b=ob(a)),c=b.length;while(c--)f=ub(b[c]),f[s]?d.push(f):e.push(f);f=y(a,vb(e,d))}return f};function wb(a,b,c){for(var d=0,e=b.length;e>d;d++)db(a,b[d],c);return c}function xb(a,b,e,f){var h,i,j,k,l,m=ob(a);if(!f&&1===m.length){if(i=m[0]=m[0].slice(0),i.length>2&&"ID"===(j=i[0]).type&&c.getById&&9===b.nodeType&&n&&d.relative[i[1].type]){if(b=(d.find.ID(j.matches[0].replace(ab,bb),b)||[])[0],!b)return e;a=a.slice(i.shift().value.length)}h=V.needsContext.test(a)?0:i.length;while(h--){if(j=i[h],d.relative[k=j.type])break;if((l=d.find[k])&&(f=l(j.matches[0].replace(ab,bb),$.test(i[0].type)&&mb(b.parentNode)||b))){if(i.splice(h,1),a=f.length&&pb(i),!a)return G.apply(e,f),e;break}}}return g(a,m)(f,b,!n,e,$.test(a)&&mb(b.parentNode)||b),e}return c.sortStable=s.split("").sort(z).join("")===s,c.detectDuplicates=!!j,k(),c.sortDetached=gb(function(a){return 1&a.compareDocumentPosition(l.createElement("div"))}),gb(function(a){return a.innerHTML="<a href='#'></a>","#"===a.firstChild.getAttribute("href")})||hb("type|href|height|width",function(a,b,c){return c?void 0:a.getAttribute(b,"type"===b.toLowerCase()?1:2)}),c.attributes&&gb(function(a){return a.innerHTML="<input/>",a.firstChild.setAttribute("value",""),""===a.firstChild.getAttribute("value")})||hb("value",function(a,b,c){return c||"input"!==a.nodeName.toLowerCase()?void 0:a.defaultValue}),gb(function(a){return null==a.getAttribute("disabled")})||hb(J,function(a,b,c){var d;return c?void 0:a[b]===!0?b.toLowerCase():(d=a.getAttributeNode(b))&&d.specified?d.value:null}),db}(a);o.find=t,o.expr=t.selectors,o.expr[":"]=o.expr.pseudos,o.unique=t.uniqueSort,o.text=t.getText,o.isXMLDoc=t.isXML,o.contains=t.contains;var u=o.expr.match.needsContext,v=/^<(\w+)\s*\/?>(?:<\/\1>|)$/,w=/^.[^:#\[\.,]*$/;function x(a,b,c){if(o.isFunction(b))return o.grep(a,function(a,d){return!!b.call(a,d,a)!==c});if(b.nodeType)return o.grep(a,function(a){return a===b!==c});if("string"==typeof b){if(w.test(b))return o.filter(b,a,c);b=o.filter(b,a)}return o.grep(a,function(a){return g.call(b,a)>=0!==c})}o.filter=function(a,b,c){var d=b[0];return c&&(a=":not("+a+")"),1===b.length&&1===d.nodeType?o.find.matchesSelector(d,a)?[d]:[]:o.find.matches(a,o.grep(b,function(a){return 1===a.nodeType}))},o.fn.extend({find:function(a){var b,c=this.length,d=[],e=this;if("string"!=typeof a)return this.pushStack(o(a).filter(function(){for(b=0;c>b;b++)if(o.contains(e[b],this))return!0}));for(b=0;c>b;b++)o.find(a,e[b],d);return d=this.pushStack(c>1?o.unique(d):d),d.selector=this.selector?this.selector+" "+a:a,d},filter:function(a){return this.pushStack(x(this,a||[],!1))},not:function(a){return this.pushStack(x(this,a||[],!0))},is:function(a){return!!x(this,"string"==typeof a&&u.test(a)?o(a):a||[],!1).length}});var y,z=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,A=o.fn.init=function(a,b){var c,d;if(!a)return this;if("string"==typeof a){if(c="<"===a[0]&&">"===a[a.length-1]&&a.length>=3?[null,a,null]:z.exec(a),!c||!c[1]&&b)return!b||b.jquery?(b||y).find(a):this.constructor(b).find(a);if(c[1]){if(b=b instanceof o?b[0]:b,o.merge(this,o.parseHTML(c[1],b&&b.nodeType?b.ownerDocument||b:m,!0)),v.test(c[1])&&o.isPlainObject(b))for(c in b)o.isFunction(this[c])?this[c](b[c]):this.attr(c,b[c]);return this}return d=m.getElementById(c[2]),d&&d.parentNode&&(this.length=1,this[0]=d),this.context=m,this.selector=a,this}return a.nodeType?(this.context=this[0]=a,this.length=1,this):o.isFunction(a)?"undefined"!=typeof y.ready?y.ready(a):a(o):(void 0!==a.selector&&(this.selector=a.selector,this.context=a.context),o.makeArray(a,this))};A.prototype=o.fn,y=o(m);var B=/^(?:parents|prev(?:Until|All))/,C={children:!0,contents:!0,next:!0,prev:!0};o.extend({dir:function(a,b,c){var d=[],e=void 0!==c;while((a=a[b])&&9!==a.nodeType)if(1===a.nodeType){if(e&&o(a).is(c))break;d.push(a)}return d},sibling:function(a,b){for(var c=[];a;a=a.nextSibling)1===a.nodeType&&a!==b&&c.push(a);return c}}),o.fn.extend({has:function(a){var b=o(a,this),c=b.length;return this.filter(function(){for(var a=0;c>a;a++)if(o.contains(this,b[a]))return!0})},closest:function(a,b){for(var c,d=0,e=this.length,f=[],g=u.test(a)||"string"!=typeof a?o(a,b||this.context):0;e>d;d++)for(c=this[d];c&&c!==b;c=c.parentNode)if(c.nodeType<11&&(g?g.index(c)>-1:1===c.nodeType&&o.find.matchesSelector(c,a))){f.push(c);break}return this.pushStack(f.length>1?o.unique(f):f)},index:function(a){return a?"string"==typeof a?g.call(o(a),this[0]):g.call(this,a.jquery?a[0]:a):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(a,b){return this.pushStack(o.unique(o.merge(this.get(),o(a,b))))},addBack:function(a){return this.add(null==a?this.prevObject:this.prevObject.filter(a))}});function D(a,b){while((a=a[b])&&1!==a.nodeType);return a}o.each({parent:function(a){var b=a.parentNode;return b&&11!==b.nodeType?b:null},parents:function(a){return o.dir(a,"parentNode")},parentsUntil:function(a,b,c){return o.dir(a,"parentNode",c)},next:function(a){return D(a,"nextSibling")},prev:function(a){return D(a,"previousSibling")},nextAll:function(a){return o.dir(a,"nextSibling")},prevAll:function(a){return o.dir(a,"previousSibling")},nextUntil:function(a,b,c){return o.dir(a,"nextSibling",c)},prevUntil:function(a,b,c){return o.dir(a,"previousSibling",c)},siblings:function(a){return o.sibling((a.parentNode||{}).firstChild,a)},children:function(a){return o.sibling(a.firstChild)},contents:function(a){return a.contentDocument||o.merge([],a.childNodes)}},function(a,b){o.fn[a]=function(c,d){var e=o.map(this,b,c);return"Until"!==a.slice(-5)&&(d=c),d&&"string"==typeof d&&(e=o.filter(d,e)),this.length>1&&(C[a]||o.unique(e),B.test(a)&&e.reverse()),this.pushStack(e)}});var E=/\S+/g,F={};function G(a){var b=F[a]={};return o.each(a.match(E)||[],function(a,c){b[c]=!0}),b}o.Callbacks=function(a){a="string"==typeof a?F[a]||G(a):o.extend({},a);var b,c,d,e,f,g,h=[],i=!a.once&&[],j=function(l){for(b=a.memory&&l,c=!0,g=e||0,e=0,f=h.length,d=!0;h&&f>g;g++)if(h[g].apply(l[0],l[1])===!1&&a.stopOnFalse){b=!1;break}d=!1,h&&(i?i.length&&j(i.shift()):b?h=[]:k.disable())},k={add:function(){if(h){var c=h.length;!function g(b){o.each(b,function(b,c){var d=o.type(c);"function"===d?a.unique&&k.has(c)||h.push(c):c&&c.length&&"string"!==d&&g(c)})}(arguments),d?f=h.length:b&&(e=c,j(b))}return this},remove:function(){return h&&o.each(arguments,function(a,b){var c;while((c=o.inArray(b,h,c))>-1)h.splice(c,1),d&&(f>=c&&f--,g>=c&&g--)}),this},has:function(a){return a?o.inArray(a,h)>-1:!(!h||!h.length)},empty:function(){return h=[],f=0,this},disable:function(){return h=i=b=void 0,this},disabled:function(){return!h},lock:function(){return i=void 0,b||k.disable(),this},locked:function(){return!i},fireWith:function(a,b){return!h||c&&!i||(b=b||[],b=[a,b.slice?b.slice():b],d?i.push(b):j(b)),this},fire:function(){return k.fireWith(this,arguments),this},fired:function(){return!!c}};return k},o.extend({Deferred:function(a){var b=[["resolve","done",o.Callbacks("once memory"),"resolved"],["reject","fail",o.Callbacks("once memory"),"rejected"],["notify","progress",o.Callbacks("memory")]],c="pending",d={state:function(){return c},always:function(){return e.done(arguments).fail(arguments),this},then:function(){var a=arguments;return o.Deferred(function(c){o.each(b,function(b,f){var g=o.isFunction(a[b])&&a[b];e[f[1]](function(){var a=g&&g.apply(this,arguments);a&&o.isFunction(a.promise)?a.promise().done(c.resolve).fail(c.reject).progress(c.notify):c[f[0]+"With"](this===d?c.promise():this,g?[a]:arguments)})}),a=null}).promise()},promise:function(a){return null!=a?o.extend(a,d):d}},e={};return d.pipe=d.then,o.each(b,function(a,f){var g=f[2],h=f[3];d[f[1]]=g.add,h&&g.add(function(){c=h},b[1^a][2].disable,b[2][2].lock),e[f[0]]=function(){return e[f[0]+"With"](this===e?d:this,arguments),this},e[f[0]+"With"]=g.fireWith}),d.promise(e),a&&a.call(e,e),e},when:function(a){var b=0,c=d.call(arguments),e=c.length,f=1!==e||a&&o.isFunction(a.promise)?e:0,g=1===f?a:o.Deferred(),h=function(a,b,c){return function(e){b[a]=this,c[a]=arguments.length>1?d.call(arguments):e,c===i?g.notifyWith(b,c):--f||g.resolveWith(b,c)}},i,j,k;if(e>1)for(i=new Array(e),j=new Array(e),k=new Array(e);e>b;b++)c[b]&&o.isFunction(c[b].promise)?c[b].promise().done(h(b,k,c)).fail(g.reject).progress(h(b,j,i)):--f;return f||g.resolveWith(k,c),g.promise()}});var H;o.fn.ready=function(a){return o.ready.promise().done(a),this},o.extend({isReady:!1,readyWait:1,holdReady:function(a){a?o.readyWait++:o.ready(!0)},ready:function(a){(a===!0?--o.readyWait:o.isReady)||(o.isReady=!0,a!==!0&&--o.readyWait>0||(H.resolveWith(m,[o]),o.fn.trigger&&o(m).trigger("ready").off("ready")))}});function I(){m.removeEventListener("DOMContentLoaded",I,!1),a.removeEventListener("load",I,!1),o.ready()}o.ready.promise=function(b){return H||(H=o.Deferred(),"complete"===m.readyState?setTimeout(o.ready):(m.addEventListener("DOMContentLoaded",I,!1),a.addEventListener("load",I,!1))),H.promise(b)},o.ready.promise();var J=o.access=function(a,b,c,d,e,f,g){var h=0,i=a.length,j=null==c;if("object"===o.type(c)){e=!0;for(h in c)o.access(a,b,h,c[h],!0,f,g)}else if(void 0!==d&&(e=!0,o.isFunction(d)||(g=!0),j&&(g?(b.call(a,d),b=null):(j=b,b=function(a,b,c){return j.call(o(a),c)})),b))for(;i>h;h++)b(a[h],c,g?d:d.call(a[h],h,b(a[h],c)));return e?a:j?b.call(a):i?b(a[0],c):f};o.acceptData=function(a){return 1===a.nodeType||9===a.nodeType||!+a.nodeType};function K(){Object.defineProperty(this.cache={},0,{get:function(){return{}}}),this.expando=o.expando+Math.random()}K.uid=1,K.accepts=o.acceptData,K.prototype={key:function(a){if(!K.accepts(a))return 0;var b={},c=a[this.expando];if(!c){c=K.uid++;try{b[this.expando]={value:c},Object.defineProperties(a,b)}catch(d){b[this.expando]=c,o.extend(a,b)}}return this.cache[c]||(this.cache[c]={}),c},set:function(a,b,c){var d,e=this.key(a),f=this.cache[e];if("string"==typeof b)f[b]=c;else if(o.isEmptyObject(f))o.extend(this.cache[e],b);else for(d in b)f[d]=b[d];return f},get:function(a,b){var c=this.cache[this.key(a)];return void 0===b?c:c[b]},access:function(a,b,c){var d;return void 0===b||b&&"string"==typeof b&&void 0===c?(d=this.get(a,b),void 0!==d?d:this.get(a,o.camelCase(b))):(this.set(a,b,c),void 0!==c?c:b)},remove:function(a,b){var c,d,e,f=this.key(a),g=this.cache[f];if(void 0===b)this.cache[f]={};else{o.isArray(b)?d=b.concat(b.map(o.camelCase)):(e=o.camelCase(b),b in g?d=[b,e]:(d=e,d=d in g?[d]:d.match(E)||[])),c=d.length;while(c--)delete g[d[c]]}},hasData:function(a){return!o.isEmptyObject(this.cache[a[this.expando]]||{})},discard:function(a){a[this.expando]&&delete this.cache[a[this.expando]]}};var L=new K,M=new K,N=/^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,O=/([A-Z])/g;function P(a,b,c){var d;if(void 0===c&&1===a.nodeType)if(d="data-"+b.replace(O,"-$1").toLowerCase(),c=a.getAttribute(d),"string"==typeof c){try{c="true"===c?!0:"false"===c?!1:"null"===c?null:+c+""===c?+c:N.test(c)?o.parseJSON(c):c}catch(e){}M.set(a,b,c)}else c=void 0;return c}o.extend({hasData:function(a){return M.hasData(a)||L.hasData(a)},data:function(a,b,c){return M.access(a,b,c)},removeData:function(a,b){M.remove(a,b)},_data:function(a,b,c){return L.access(a,b,c)},_removeData:function(a,b){L.remove(a,b)}}),o.fn.extend({data:function(a,b){var c,d,e,f=this[0],g=f&&f.attributes;if(void 0===a){if(this.length&&(e=M.get(f),1===f.nodeType&&!L.get(f,"hasDataAttrs"))){c=g.length; +while(c--)d=g[c].name,0===d.indexOf("data-")&&(d=o.camelCase(d.slice(5)),P(f,d,e[d]));L.set(f,"hasDataAttrs",!0)}return e}return"object"==typeof a?this.each(function(){M.set(this,a)}):J(this,function(b){var c,d=o.camelCase(a);if(f&&void 0===b){if(c=M.get(f,a),void 0!==c)return c;if(c=M.get(f,d),void 0!==c)return c;if(c=P(f,d,void 0),void 0!==c)return c}else this.each(function(){var c=M.get(this,d);M.set(this,d,b),-1!==a.indexOf("-")&&void 0!==c&&M.set(this,a,b)})},null,b,arguments.length>1,null,!0)},removeData:function(a){return this.each(function(){M.remove(this,a)})}}),o.extend({queue:function(a,b,c){var d;return a?(b=(b||"fx")+"queue",d=L.get(a,b),c&&(!d||o.isArray(c)?d=L.access(a,b,o.makeArray(c)):d.push(c)),d||[]):void 0},dequeue:function(a,b){b=b||"fx";var c=o.queue(a,b),d=c.length,e=c.shift(),f=o._queueHooks(a,b),g=function(){o.dequeue(a,b)};"inprogress"===e&&(e=c.shift(),d--),e&&("fx"===b&&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 L.get(a,c)||L.access(a,c,{empty:o.Callbacks("once memory").add(function(){L.remove(a,[b+"queue",c])})})}}),o.fn.extend({queue:function(a,b){var c=2;return"string"!=typeof a&&(b=a,a="fx",c--),arguments.length<c?o.queue(this[0],a):void 0===b?this:this.each(function(){var c=o.queue(this,a,b);o._queueHooks(this,a),"fx"===a&&"inprogress"!==c[0]&&o.dequeue(this,a)})},dequeue:function(a){return this.each(function(){o.dequeue(this,a)})},clearQueue:function(a){return this.queue(a||"fx",[])},promise:function(a,b){var c,d=1,e=o.Deferred(),f=this,g=this.length,h=function(){--d||e.resolveWith(f,[f])};"string"!=typeof a&&(b=a,a=void 0),a=a||"fx";while(g--)c=L.get(f[g],a+"queueHooks"),c&&c.empty&&(d++,c.empty.add(h));return h(),e.promise(b)}});var Q=/[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source,R=["Top","Right","Bottom","Left"],S=function(a,b){return a=b||a,"none"===o.css(a,"display")||!o.contains(a.ownerDocument,a)},T=/^(?:checkbox|radio)$/i;!function(){var a=m.createDocumentFragment(),b=a.appendChild(m.createElement("div"));b.innerHTML="<input type='radio' checked='checked' name='t'/>",l.checkClone=b.cloneNode(!0).cloneNode(!0).lastChild.checked,b.innerHTML="<textarea>x</textarea>",l.noCloneChecked=!!b.cloneNode(!0).lastChild.defaultValue}();var U="undefined";l.focusinBubbles="onfocusin"in a;var V=/^key/,W=/^(?:mouse|contextmenu)|click/,X=/^(?:focusinfocus|focusoutblur)$/,Y=/^([^.]*)(?:\.(.+)|)$/;function Z(){return!0}function $(){return!1}function _(){try{return m.activeElement}catch(a){}}o.event={global:{},add:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,n,p,q,r=L.get(a);if(r){c.handler&&(f=c,c=f.handler,e=f.selector),c.guid||(c.guid=o.guid++),(i=r.events)||(i=r.events={}),(g=r.handle)||(g=r.handle=function(b){return typeof o!==U&&o.event.triggered!==b.type?o.event.dispatch.apply(a,arguments):void 0}),b=(b||"").match(E)||[""],j=b.length;while(j--)h=Y.exec(b[j])||[],n=q=h[1],p=(h[2]||"").split(".").sort(),n&&(l=o.event.special[n]||{},n=(e?l.delegateType:l.bindType)||n,l=o.event.special[n]||{},k=o.extend({type:n,origType:q,data:d,handler:c,guid:c.guid,selector:e,needsContext:e&&o.expr.match.needsContext.test(e),namespace:p.join(".")},f),(m=i[n])||(m=i[n]=[],m.delegateCount=0,l.setup&&l.setup.call(a,d,p,g)!==!1||a.addEventListener&&a.addEventListener(n,g,!1)),l.add&&(l.add.call(a,k),k.handler.guid||(k.handler.guid=c.guid)),e?m.splice(m.delegateCount++,0,k):m.push(k),o.event.global[n]=!0)}},remove:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,n,p,q,r=L.hasData(a)&&L.get(a);if(r&&(i=r.events)){b=(b||"").match(E)||[""],j=b.length;while(j--)if(h=Y.exec(b[j])||[],n=q=h[1],p=(h[2]||"").split(".").sort(),n){l=o.event.special[n]||{},n=(d?l.delegateType:l.bindType)||n,m=i[n]||[],h=h[2]&&new RegExp("(^|\\.)"+p.join("\\.(?:.*\\.|)")+"(\\.|$)"),g=f=m.length;while(f--)k=m[f],!e&&q!==k.origType||c&&c.guid!==k.guid||h&&!h.test(k.namespace)||d&&d!==k.selector&&("**"!==d||!k.selector)||(m.splice(f,1),k.selector&&m.delegateCount--,l.remove&&l.remove.call(a,k));g&&!m.length&&(l.teardown&&l.teardown.call(a,p,r.handle)!==!1||o.removeEvent(a,n,r.handle),delete i[n])}else for(n in i)o.event.remove(a,n+b[j],c,d,!0);o.isEmptyObject(i)&&(delete r.handle,L.remove(a,"events"))}},trigger:function(b,c,d,e){var f,g,h,i,k,l,n,p=[d||m],q=j.call(b,"type")?b.type:b,r=j.call(b,"namespace")?b.namespace.split("."):[];if(g=h=d=d||m,3!==d.nodeType&&8!==d.nodeType&&!X.test(q+o.event.triggered)&&(q.indexOf(".")>=0&&(r=q.split("."),q=r.shift(),r.sort()),k=q.indexOf(":")<0&&"on"+q,b=b[o.expando]?b:new o.Event(q,"object"==typeof b&&b),b.isTrigger=e?2:3,b.namespace=r.join("."),b.namespace_re=b.namespace?new RegExp("(^|\\.)"+r.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,b.result=void 0,b.target||(b.target=d),c=null==c?[b]:o.makeArray(c,[b]),n=o.event.special[q]||{},e||!n.trigger||n.trigger.apply(d,c)!==!1)){if(!e&&!n.noBubble&&!o.isWindow(d)){for(i=n.delegateType||q,X.test(i+q)||(g=g.parentNode);g;g=g.parentNode)p.push(g),h=g;h===(d.ownerDocument||m)&&p.push(h.defaultView||h.parentWindow||a)}f=0;while((g=p[f++])&&!b.isPropagationStopped())b.type=f>1?i:n.bindType||q,l=(L.get(g,"events")||{})[b.type]&&L.get(g,"handle"),l&&l.apply(g,c),l=k&&g[k],l&&l.apply&&o.acceptData(g)&&(b.result=l.apply(g,c),b.result===!1&&b.preventDefault());return b.type=q,e||b.isDefaultPrevented()||n._default&&n._default.apply(p.pop(),c)!==!1||!o.acceptData(d)||k&&o.isFunction(d[q])&&!o.isWindow(d)&&(h=d[k],h&&(d[k]=null),o.event.triggered=q,d[q](),o.event.triggered=void 0,h&&(d[k]=h)),b.result}},dispatch:function(a){a=o.event.fix(a);var b,c,e,f,g,h=[],i=d.call(arguments),j=(L.get(this,"events")||{})[a.type]||[],k=o.event.special[a.type]||{};if(i[0]=a,a.delegateTarget=this,!k.preDispatch||k.preDispatch.call(this,a)!==!1){h=o.event.handlers.call(this,a,j),b=0;while((f=h[b++])&&!a.isPropagationStopped()){a.currentTarget=f.elem,c=0;while((g=f.handlers[c++])&&!a.isImmediatePropagationStopped())(!a.namespace_re||a.namespace_re.test(g.namespace))&&(a.handleObj=g,a.data=g.data,e=((o.event.special[g.origType]||{}).handle||g.handler).apply(f.elem,i),void 0!==e&&(a.result=e)===!1&&(a.preventDefault(),a.stopPropagation()))}return k.postDispatch&&k.postDispatch.call(this,a),a.result}},handlers:function(a,b){var c,d,e,f,g=[],h=b.delegateCount,i=a.target;if(h&&i.nodeType&&(!a.button||"click"!==a.type))for(;i!==this;i=i.parentNode||this)if(i.disabled!==!0||"click"!==a.type){for(d=[],c=0;h>c;c++)f=b[c],e=f.selector+" ",void 0===d[e]&&(d[e]=f.needsContext?o(e,this).index(i)>=0:o.find(e,this,null,[i]).length),d[e]&&d.push(f);d.length&&g.push({elem:i,handlers:d})}return h<b.length&&g.push({elem:this,handlers:b.slice(h)}),g},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(a,b){return null==a.which&&(a.which=null!=b.charCode?b.charCode:b.keyCode),a}},mouseHooks:{props:"button buttons clientX clientY offsetX offsetY pageX pageY screenX screenY toElement".split(" "),filter:function(a,b){var c,d,e,f=b.button;return null==a.pageX&&null!=b.clientX&&(c=a.target.ownerDocument||m,d=c.documentElement,e=c.body,a.pageX=b.clientX+(d&&d.scrollLeft||e&&e.scrollLeft||0)-(d&&d.clientLeft||e&&e.clientLeft||0),a.pageY=b.clientY+(d&&d.scrollTop||e&&e.scrollTop||0)-(d&&d.clientTop||e&&e.clientTop||0)),a.which||void 0===f||(a.which=1&f?1:2&f?3:4&f?2:0),a}},fix:function(a){if(a[o.expando])return a;var b,c,d,e=a.type,f=a,g=this.fixHooks[e];g||(this.fixHooks[e]=g=W.test(e)?this.mouseHooks:V.test(e)?this.keyHooks:{}),d=g.props?this.props.concat(g.props):this.props,a=new o.Event(f),b=d.length;while(b--)c=d[b],a[c]=f[c];return a.target||(a.target=m),3===a.target.nodeType&&(a.target=a.target.parentNode),g.filter?g.filter(a,f):a},special:{load:{noBubble:!0},focus:{trigger:function(){return this!==_()&&this.focus?(this.focus(),!1):void 0},delegateType:"focusin"},blur:{trigger:function(){return this===_()&&this.blur?(this.blur(),!1):void 0},delegateType:"focusout"},click:{trigger:function(){return"checkbox"===this.type&&this.click&&o.nodeName(this,"input")?(this.click(),!1):void 0},_default:function(a){return o.nodeName(a.target,"a")}},beforeunload:{postDispatch:function(a){void 0!==a.result&&(a.originalEvent.returnValue=a.result)}}},simulate:function(a,b,c,d){var e=o.extend(new o.Event,c,{type:a,isSimulated:!0,originalEvent:{}});d?o.event.trigger(e,null,b):o.event.dispatch.call(b,e),e.isDefaultPrevented()&&c.preventDefault()}},o.removeEvent=function(a,b,c){a.removeEventListener&&a.removeEventListener(b,c,!1)},o.Event=function(a,b){return this instanceof o.Event?(a&&a.type?(this.originalEvent=a,this.type=a.type,this.isDefaultPrevented=a.defaultPrevented||void 0===a.defaultPrevented&&a.getPreventDefault&&a.getPreventDefault()?Z:$):this.type=a,b&&o.extend(this,b),this.timeStamp=a&&a.timeStamp||o.now(),void(this[o.expando]=!0)):new o.Event(a,b)},o.Event.prototype={isDefaultPrevented:$,isPropagationStopped:$,isImmediatePropagationStopped:$,preventDefault:function(){var a=this.originalEvent;this.isDefaultPrevented=Z,a&&a.preventDefault&&a.preventDefault()},stopPropagation:function(){var a=this.originalEvent;this.isPropagationStopped=Z,a&&a.stopPropagation&&a.stopPropagation()},stopImmediatePropagation:function(){this.isImmediatePropagationStopped=Z,this.stopPropagation()}},o.each({mouseenter:"mouseover",mouseleave:"mouseout"},function(a,b){o.event.special[a]={delegateType:b,bindType:b,handle:function(a){var c,d=this,e=a.relatedTarget,f=a.handleObj;return(!e||e!==d&&!o.contains(d,e))&&(a.type=f.origType,c=f.handler.apply(this,arguments),a.type=b),c}}}),l.focusinBubbles||o.each({focus:"focusin",blur:"focusout"},function(a,b){var c=function(a){o.event.simulate(b,a.target,o.event.fix(a),!0)};o.event.special[b]={setup:function(){var d=this.ownerDocument||this,e=L.access(d,b);e||d.addEventListener(a,c,!0),L.access(d,b,(e||0)+1)},teardown:function(){var d=this.ownerDocument||this,e=L.access(d,b)-1;e?L.access(d,b,e):(d.removeEventListener(a,c,!0),L.remove(d,b))}}}),o.fn.extend({on:function(a,b,c,d,e){var f,g;if("object"==typeof a){"string"!=typeof b&&(c=c||b,b=void 0);for(g in a)this.on(g,b,c,a[g],e);return this}if(null==c&&null==d?(d=b,c=b=void 0):null==d&&("string"==typeof b?(d=c,c=void 0):(d=c,c=b,b=void 0)),d===!1)d=$;else if(!d)return this;return 1===e&&(f=d,d=function(a){return o().off(a),f.apply(this,arguments)},d.guid=f.guid||(f.guid=o.guid++)),this.each(function(){o.event.add(this,a,d,c,b)})},one:function(a,b,c,d){return this.on(a,b,c,d,1)},off:function(a,b,c){var d,e;if(a&&a.preventDefault&&a.handleObj)return d=a.handleObj,o(a.delegateTarget).off(d.namespace?d.origType+"."+d.namespace:d.origType,d.selector,d.handler),this;if("object"==typeof a){for(e in a)this.off(e,b,a[e]);return this}return(b===!1||"function"==typeof b)&&(c=b,b=void 0),c===!1&&(c=$),this.each(function(){o.event.remove(this,a,c,b)})},trigger:function(a,b){return this.each(function(){o.event.trigger(a,b,this)})},triggerHandler:function(a,b){var c=this[0];return c?o.event.trigger(a,b,c,!0):void 0}});var ab=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi,bb=/<([\w:]+)/,cb=/<|&#?\w+;/,db=/<(?:script|style|link)/i,eb=/checked\s*(?:[^=]|=\s*.checked.)/i,fb=/^$|\/(?:java|ecma)script/i,gb=/^true\/(.*)/,hb=/^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g,ib={option:[1,"<select multiple='multiple'>","</select>"],thead:[1,"<table>","</table>"],col:[2,"<table><colgroup>","</colgroup></table>"],tr:[2,"<table><tbody>","</tbody></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],_default:[0,"",""]};ib.optgroup=ib.option,ib.tbody=ib.tfoot=ib.colgroup=ib.caption=ib.thead,ib.th=ib.td;function jb(a,b){return o.nodeName(a,"table")&&o.nodeName(11!==b.nodeType?b:b.firstChild,"tr")?a.getElementsByTagName("tbody")[0]||a.appendChild(a.ownerDocument.createElement("tbody")):a}function kb(a){return a.type=(null!==a.getAttribute("type"))+"/"+a.type,a}function lb(a){var b=gb.exec(a.type);return b?a.type=b[1]:a.removeAttribute("type"),a}function mb(a,b){for(var c=0,d=a.length;d>c;c++)L.set(a[c],"globalEval",!b||L.get(b[c],"globalEval"))}function nb(a,b){var c,d,e,f,g,h,i,j;if(1===b.nodeType){if(L.hasData(a)&&(f=L.access(a),g=L.set(b,f),j=f.events)){delete g.handle,g.events={};for(e in j)for(c=0,d=j[e].length;d>c;c++)o.event.add(b,e,j[e][c])}M.hasData(a)&&(h=M.access(a),i=o.extend({},h),M.set(b,i))}}function ob(a,b){var c=a.getElementsByTagName?a.getElementsByTagName(b||"*"):a.querySelectorAll?a.querySelectorAll(b||"*"):[];return void 0===b||b&&o.nodeName(a,b)?o.merge([a],c):c}function pb(a,b){var c=b.nodeName.toLowerCase();"input"===c&&T.test(a.type)?b.checked=a.checked:("input"===c||"textarea"===c)&&(b.defaultValue=a.defaultValue)}o.extend({clone:function(a,b,c){var d,e,f,g,h=a.cloneNode(!0),i=o.contains(a.ownerDocument,a);if(!(l.noCloneChecked||1!==a.nodeType&&11!==a.nodeType||o.isXMLDoc(a)))for(g=ob(h),f=ob(a),d=0,e=f.length;e>d;d++)pb(f[d],g[d]);if(b)if(c)for(f=f||ob(a),g=g||ob(h),d=0,e=f.length;e>d;d++)nb(f[d],g[d]);else nb(a,h);return g=ob(h,"script"),g.length>0&&mb(g,!i&&ob(a,"script")),h},buildFragment:function(a,b,c,d){for(var e,f,g,h,i,j,k=b.createDocumentFragment(),l=[],m=0,n=a.length;n>m;m++)if(e=a[m],e||0===e)if("object"===o.type(e))o.merge(l,e.nodeType?[e]:e);else if(cb.test(e)){f=f||k.appendChild(b.createElement("div")),g=(bb.exec(e)||["",""])[1].toLowerCase(),h=ib[g]||ib._default,f.innerHTML=h[1]+e.replace(ab,"<$1></$2>")+h[2],j=h[0];while(j--)f=f.lastChild;o.merge(l,f.childNodes),f=k.firstChild,f.textContent=""}else l.push(b.createTextNode(e));k.textContent="",m=0;while(e=l[m++])if((!d||-1===o.inArray(e,d))&&(i=o.contains(e.ownerDocument,e),f=ob(k.appendChild(e),"script"),i&&mb(f),c)){j=0;while(e=f[j++])fb.test(e.type||"")&&c.push(e)}return k},cleanData:function(a){for(var b,c,d,e,f,g,h=o.event.special,i=0;void 0!==(c=a[i]);i++){if(o.acceptData(c)&&(f=c[L.expando],f&&(b=L.cache[f]))){if(d=Object.keys(b.events||{}),d.length)for(g=0;void 0!==(e=d[g]);g++)h[e]?o.event.remove(c,e):o.removeEvent(c,e,b.handle);L.cache[f]&&delete L.cache[f]}delete M.cache[c[M.expando]]}}}),o.fn.extend({text:function(a){return J(this,function(a){return void 0===a?o.text(this):this.empty().each(function(){(1===this.nodeType||11===this.nodeType||9===this.nodeType)&&(this.textContent=a)})},null,a,arguments.length)},append:function(){return this.domManip(arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=jb(this,a);b.appendChild(a)}})},prepend:function(){return this.domManip(arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=jb(this,a);b.insertBefore(a,b.firstChild)}})},before:function(){return this.domManip(arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this)})},after:function(){return this.domManip(arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this.nextSibling)})},remove:function(a,b){for(var c,d=a?o.filter(a,this):this,e=0;null!=(c=d[e]);e++)b||1!==c.nodeType||o.cleanData(ob(c)),c.parentNode&&(b&&o.contains(c.ownerDocument,c)&&mb(ob(c,"script")),c.parentNode.removeChild(c));return this},empty:function(){for(var a,b=0;null!=(a=this[b]);b++)1===a.nodeType&&(o.cleanData(ob(a,!1)),a.textContent="");return this},clone:function(a,b){return a=null==a?!1:a,b=null==b?a:b,this.map(function(){return o.clone(this,a,b)})},html:function(a){return J(this,function(a){var b=this[0]||{},c=0,d=this.length;if(void 0===a&&1===b.nodeType)return b.innerHTML;if("string"==typeof a&&!db.test(a)&&!ib[(bb.exec(a)||["",""])[1].toLowerCase()]){a=a.replace(ab,"<$1></$2>");try{for(;d>c;c++)b=this[c]||{},1===b.nodeType&&(o.cleanData(ob(b,!1)),b.innerHTML=a);b=0}catch(e){}}b&&this.empty().append(a)},null,a,arguments.length)},replaceWith:function(){var a=arguments[0];return this.domManip(arguments,function(b){a=this.parentNode,o.cleanData(ob(this)),a&&a.replaceChild(b,this)}),a&&(a.length||a.nodeType)?this:this.remove()},detach:function(a){return this.remove(a,!0)},domManip:function(a,b){a=e.apply([],a);var c,d,f,g,h,i,j=0,k=this.length,m=this,n=k-1,p=a[0],q=o.isFunction(p);if(q||k>1&&"string"==typeof p&&!l.checkClone&&eb.test(p))return this.each(function(c){var d=m.eq(c);q&&(a[0]=p.call(this,c,d.html())),d.domManip(a,b)});if(k&&(c=o.buildFragment(a,this[0].ownerDocument,!1,this),d=c.firstChild,1===c.childNodes.length&&(c=d),d)){for(f=o.map(ob(c,"script"),kb),g=f.length;k>j;j++)h=c,j!==n&&(h=o.clone(h,!0,!0),g&&o.merge(f,ob(h,"script"))),b.call(this[j],h,j);if(g)for(i=f[f.length-1].ownerDocument,o.map(f,lb),j=0;g>j;j++)h=f[j],fb.test(h.type||"")&&!L.access(h,"globalEval")&&o.contains(i,h)&&(h.src?o._evalUrl&&o._evalUrl(h.src):o.globalEval(h.textContent.replace(hb,"")))}return this}}),o.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){o.fn[a]=function(a){for(var c,d=[],e=o(a),g=e.length-1,h=0;g>=h;h++)c=h===g?this:this.clone(!0),o(e[h])[b](c),f.apply(d,c.get());return this.pushStack(d)}});var qb,rb={};function sb(b,c){var d=o(c.createElement(b)).appendTo(c.body),e=a.getDefaultComputedStyle?a.getDefaultComputedStyle(d[0]).display:o.css(d[0],"display");return d.detach(),e}function tb(a){var b=m,c=rb[a];return c||(c=sb(a,b),"none"!==c&&c||(qb=(qb||o("<iframe frameborder='0' width='0' height='0'/>")).appendTo(b.documentElement),b=qb[0].contentDocument,b.write(),b.close(),c=sb(a,b),qb.detach()),rb[a]=c),c}var ub=/^margin/,vb=new RegExp("^("+Q+")(?!px)[a-z%]+$","i"),wb=function(a){return a.ownerDocument.defaultView.getComputedStyle(a,null)};function xb(a,b,c){var d,e,f,g,h=a.style;return c=c||wb(a),c&&(g=c.getPropertyValue(b)||c[b]),c&&(""!==g||o.contains(a.ownerDocument,a)||(g=o.style(a,b)),vb.test(g)&&ub.test(b)&&(d=h.width,e=h.minWidth,f=h.maxWidth,h.minWidth=h.maxWidth=h.width=g,g=c.width,h.width=d,h.minWidth=e,h.maxWidth=f)),void 0!==g?g+"":g}function yb(a,b){return{get:function(){return a()?void delete this.get:(this.get=b).apply(this,arguments)}}}!function(){var b,c,d="padding:0;margin:0;border:0;display:block;-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box",e=m.documentElement,f=m.createElement("div"),g=m.createElement("div");g.style.backgroundClip="content-box",g.cloneNode(!0).style.backgroundClip="",l.clearCloneStyle="content-box"===g.style.backgroundClip,f.style.cssText="border:0;width:0;height:0;position:absolute;top:0;left:-9999px;margin-top:1px",f.appendChild(g);function h(){g.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%",e.appendChild(f);var d=a.getComputedStyle(g,null);b="1%"!==d.top,c="4px"===d.width,e.removeChild(f)}a.getComputedStyle&&o.extend(l,{pixelPosition:function(){return h(),b},boxSizingReliable:function(){return null==c&&h(),c},reliableMarginRight:function(){var b,c=g.appendChild(m.createElement("div"));return c.style.cssText=g.style.cssText=d,c.style.marginRight=c.style.width="0",g.style.width="1px",e.appendChild(f),b=!parseFloat(a.getComputedStyle(c,null).marginRight),e.removeChild(f),g.innerHTML="",b}})}(),o.swap=function(a,b,c,d){var e,f,g={};for(f in b)g[f]=a.style[f],a.style[f]=b[f];e=c.apply(a,d||[]);for(f in b)a.style[f]=g[f];return e};var zb=/^(none|table(?!-c[ea]).+)/,Ab=new RegExp("^("+Q+")(.*)$","i"),Bb=new RegExp("^([+-])=("+Q+")","i"),Cb={position:"absolute",visibility:"hidden",display:"block"},Db={letterSpacing:0,fontWeight:400},Eb=["Webkit","O","Moz","ms"];function Fb(a,b){if(b in a)return b;var c=b[0].toUpperCase()+b.slice(1),d=b,e=Eb.length;while(e--)if(b=Eb[e]+c,b in a)return b;return d}function Gb(a,b,c){var d=Ab.exec(b);return d?Math.max(0,d[1]-(c||0))+(d[2]||"px"):b}function Hb(a,b,c,d,e){for(var f=c===(d?"border":"content")?4:"width"===b?1:0,g=0;4>f;f+=2)"margin"===c&&(g+=o.css(a,c+R[f],!0,e)),d?("content"===c&&(g-=o.css(a,"padding"+R[f],!0,e)),"margin"!==c&&(g-=o.css(a,"border"+R[f]+"Width",!0,e))):(g+=o.css(a,"padding"+R[f],!0,e),"padding"!==c&&(g+=o.css(a,"border"+R[f]+"Width",!0,e)));return g}function Ib(a,b,c){var d=!0,e="width"===b?a.offsetWidth:a.offsetHeight,f=wb(a),g="border-box"===o.css(a,"boxSizing",!1,f);if(0>=e||null==e){if(e=xb(a,b,f),(0>e||null==e)&&(e=a.style[b]),vb.test(e))return e;d=g&&(l.boxSizingReliable()||e===a.style[b]),e=parseFloat(e)||0}return e+Hb(a,b,c||(g?"border":"content"),d,f)+"px"}function Jb(a,b){for(var c,d,e,f=[],g=0,h=a.length;h>g;g++)d=a[g],d.style&&(f[g]=L.get(d,"olddisplay"),c=d.style.display,b?(f[g]||"none"!==c||(d.style.display=""),""===d.style.display&&S(d)&&(f[g]=L.access(d,"olddisplay",tb(d.nodeName)))):f[g]||(e=S(d),(c&&"none"!==c||!e)&&L.set(d,"olddisplay",e?c:o.css(d,"display"))));for(g=0;h>g;g++)d=a[g],d.style&&(b&&"none"!==d.style.display&&""!==d.style.display||(d.style.display=b?f[g]||"":"none"));return a}o.extend({cssHooks:{opacity:{get:function(a,b){if(b){var c=xb(a,"opacity");return""===c?"1":c}}}},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(a,b,c,d){if(a&&3!==a.nodeType&&8!==a.nodeType&&a.style){var e,f,g,h=o.camelCase(b),i=a.style;return b=o.cssProps[h]||(o.cssProps[h]=Fb(i,h)),g=o.cssHooks[b]||o.cssHooks[h],void 0===c?g&&"get"in g&&void 0!==(e=g.get(a,!1,d))?e:i[b]:(f=typeof c,"string"===f&&(e=Bb.exec(c))&&(c=(e[1]+1)*e[2]+parseFloat(o.css(a,b)),f="number"),null!=c&&c===c&&("number"!==f||o.cssNumber[h]||(c+="px"),l.clearCloneStyle||""!==c||0!==b.indexOf("background")||(i[b]="inherit"),g&&"set"in g&&void 0===(c=g.set(a,c,d))||(i[b]="",i[b]=c)),void 0)}},css:function(a,b,c,d){var e,f,g,h=o.camelCase(b);return b=o.cssProps[h]||(o.cssProps[h]=Fb(a.style,h)),g=o.cssHooks[b]||o.cssHooks[h],g&&"get"in g&&(e=g.get(a,!0,c)),void 0===e&&(e=xb(a,b,d)),"normal"===e&&b in Db&&(e=Db[b]),""===c||c?(f=parseFloat(e),c===!0||o.isNumeric(f)?f||0:e):e}}),o.each(["height","width"],function(a,b){o.cssHooks[b]={get:function(a,c,d){return c?0===a.offsetWidth&&zb.test(o.css(a,"display"))?o.swap(a,Cb,function(){return Ib(a,b,d)}):Ib(a,b,d):void 0},set:function(a,c,d){var e=d&&wb(a);return Gb(a,c,d?Hb(a,b,d,"border-box"===o.css(a,"boxSizing",!1,e),e):0)}}}),o.cssHooks.marginRight=yb(l.reliableMarginRight,function(a,b){return b?o.swap(a,{display:"inline-block"},xb,[a,"marginRight"]):void 0}),o.each({margin:"",padding:"",border:"Width"},function(a,b){o.cssHooks[a+b]={expand:function(c){for(var d=0,e={},f="string"==typeof c?c.split(" "):[c];4>d;d++)e[a+R[d]+b]=f[d]||f[d-2]||f[0];return e}},ub.test(a)||(o.cssHooks[a+b].set=Gb)}),o.fn.extend({css:function(a,b){return J(this,function(a,b,c){var d,e,f={},g=0;if(o.isArray(b)){for(d=wb(a),e=b.length;e>g;g++)f[b[g]]=o.css(a,b[g],!1,d);return f}return void 0!==c?o.style(a,b,c):o.css(a,b)},a,b,arguments.length>1)},show:function(){return Jb(this,!0)},hide:function(){return Jb(this)},toggle:function(a){return"boolean"==typeof a?a?this.show():this.hide():this.each(function(){S(this)?o(this).show():o(this).hide()})}});function Kb(a,b,c,d,e){return new Kb.prototype.init(a,b,c,d,e)}o.Tween=Kb,Kb.prototype={constructor:Kb,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||(o.cssNumber[c]?"":"px")},cur:function(){var a=Kb.propHooks[this.prop];return a&&a.get?a.get(this):Kb.propHooks._default.get(this)},run:function(a){var b,c=Kb.propHooks[this.prop];return this.pos=b=this.options.duration?o.easing[this.easing](a,this.options.duration*a,0,1,this.options.duration):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):Kb.propHooks._default.set(this),this}},Kb.prototype.init.prototype=Kb.prototype,Kb.propHooks={_default:{get:function(a){var b;return null==a.elem[a.prop]||a.elem.style&&null!=a.elem.style[a.prop]?(b=o.css(a.elem,a.prop,""),b&&"auto"!==b?b:0):a.elem[a.prop]},set:function(a){o.fx.step[a.prop]?o.fx.step[a.prop](a):a.elem.style&&(null!=a.elem.style[o.cssProps[a.prop]]||o.cssHooks[a.prop])?o.style(a.elem,a.prop,a.now+a.unit):a.elem[a.prop]=a.now}}},Kb.propHooks.scrollTop=Kb.propHooks.scrollLeft={set:function(a){a.elem.nodeType&&a.elem.parentNode&&(a.elem[a.prop]=a.now)}},o.easing={linear:function(a){return a},swing:function(a){return.5-Math.cos(a*Math.PI)/2}},o.fx=Kb.prototype.init,o.fx.step={};var Lb,Mb,Nb=/^(?:toggle|show|hide)$/,Ob=new RegExp("^(?:([+-])=|)("+Q+")([a-z%]*)$","i"),Pb=/queueHooks$/,Qb=[Vb],Rb={"*":[function(a,b){var c=this.createTween(a,b),d=c.cur(),e=Ob.exec(b),f=e&&e[3]||(o.cssNumber[a]?"":"px"),g=(o.cssNumber[a]||"px"!==f&&+d)&&Ob.exec(o.css(c.elem,a)),h=1,i=20;if(g&&g[3]!==f){f=f||g[3],e=e||[],g=+d||1;do h=h||".5",g/=h,o.style(c.elem,a,g+f);while(h!==(h=c.cur()/d)&&1!==h&&--i)}return e&&(g=c.start=+g||+d||0,c.unit=f,c.end=e[1]?g+(e[1]+1)*e[2]:+e[2]),c}]};function Sb(){return setTimeout(function(){Lb=void 0}),Lb=o.now()}function Tb(a,b){var c,d=0,e={height:a};for(b=b?1:0;4>d;d+=2-b)c=R[d],e["margin"+c]=e["padding"+c]=a;return b&&(e.opacity=e.width=a),e}function Ub(a,b,c){for(var d,e=(Rb[b]||[]).concat(Rb["*"]),f=0,g=e.length;g>f;f++)if(d=e[f].call(c,b,a))return d}function Vb(a,b,c){var d,e,f,g,h,i,j,k=this,l={},m=a.style,n=a.nodeType&&S(a),p=L.get(a,"fxshow");c.queue||(h=o._queueHooks(a,"fx"),null==h.unqueued&&(h.unqueued=0,i=h.empty.fire,h.empty.fire=function(){h.unqueued||i()}),h.unqueued++,k.always(function(){k.always(function(){h.unqueued--,o.queue(a,"fx").length||h.empty.fire()})})),1===a.nodeType&&("height"in b||"width"in b)&&(c.overflow=[m.overflow,m.overflowX,m.overflowY],j=o.css(a,"display"),"none"===j&&(j=tb(a.nodeName)),"inline"===j&&"none"===o.css(a,"float")&&(m.display="inline-block")),c.overflow&&(m.overflow="hidden",k.always(function(){m.overflow=c.overflow[0],m.overflowX=c.overflow[1],m.overflowY=c.overflow[2]}));for(d in b)if(e=b[d],Nb.exec(e)){if(delete b[d],f=f||"toggle"===e,e===(n?"hide":"show")){if("show"!==e||!p||void 0===p[d])continue;n=!0}l[d]=p&&p[d]||o.style(a,d)}if(!o.isEmptyObject(l)){p?"hidden"in p&&(n=p.hidden):p=L.access(a,"fxshow",{}),f&&(p.hidden=!n),n?o(a).show():k.done(function(){o(a).hide()}),k.done(function(){var b;L.remove(a,"fxshow");for(b in l)o.style(a,b,l[b])});for(d in l)g=Ub(n?p[d]:0,d,k),d in p||(p[d]=g.start,n&&(g.end=g.start,g.start="width"===d||"height"===d?1:0))}}function Wb(a,b){var c,d,e,f,g;for(c in a)if(d=o.camelCase(c),e=b[d],f=a[c],o.isArray(f)&&(e=f[1],f=a[c]=f[0]),c!==d&&(a[d]=f,delete a[c]),g=o.cssHooks[d],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 Xb(a,b,c){var d,e,f=0,g=Qb.length,h=o.Deferred().always(function(){delete i.elem}),i=function(){if(e)return!1;for(var b=Lb||Sb(),c=Math.max(0,j.startTime+j.duration-b),d=c/j.duration||0,f=1-d,g=0,i=j.tweens.length;i>g;g++)j.tweens[g].run(f);return h.notifyWith(a,[j,f,c]),1>f&&i?c:(h.resolveWith(a,[j]),!1)},j=h.promise({elem:a,props:o.extend({},b),opts:o.extend(!0,{specialEasing:{}},c),originalProperties:b,originalOptions:c,startTime:Lb||Sb(),duration:c.duration,tweens:[],createTween:function(b,c){var d=o.Tween(a,j.opts,b,c,j.opts.specialEasing[b]||j.opts.easing);return j.tweens.push(d),d},stop:function(b){var c=0,d=b?j.tweens.length:0;if(e)return this;for(e=!0;d>c;c++)j.tweens[c].run(1);return b?h.resolveWith(a,[j,b]):h.rejectWith(a,[j,b]),this}}),k=j.props;for(Wb(k,j.opts.specialEasing);g>f;f++)if(d=Qb[f].call(j,a,k,j.opts))return d;return o.map(k,Ub,j),o.isFunction(j.opts.start)&&j.opts.start.call(a,j),o.fx.timer(o.extend(i,{elem:a,anim:j,queue:j.opts.queue})),j.progress(j.opts.progress).done(j.opts.done,j.opts.complete).fail(j.opts.fail).always(j.opts.always)}o.Animation=o.extend(Xb,{tweener:function(a,b){o.isFunction(a)?(b=a,a=["*"]):a=a.split(" ");for(var c,d=0,e=a.length;e>d;d++)c=a[d],Rb[c]=Rb[c]||[],Rb[c].unshift(b)},prefilter:function(a,b){b?Qb.unshift(a):Qb.push(a)}}),o.speed=function(a,b,c){var d=a&&"object"==typeof a?o.extend({},a):{complete:c||!c&&b||o.isFunction(a)&&a,duration:a,easing:c&&b||b&&!o.isFunction(b)&&b};return d.duration=o.fx.off?0:"number"==typeof d.duration?d.duration:d.duration in o.fx.speeds?o.fx.speeds[d.duration]:o.fx.speeds._default,(null==d.queue||d.queue===!0)&&(d.queue="fx"),d.old=d.complete,d.complete=function(){o.isFunction(d.old)&&d.old.call(this),d.queue&&o.dequeue(this,d.queue)},d},o.fn.extend({fadeTo:function(a,b,c,d){return this.filter(S).css("opacity",0).show().end().animate({opacity:b},a,c,d)},animate:function(a,b,c,d){var e=o.isEmptyObject(a),f=o.speed(b,c,d),g=function(){var b=Xb(this,o.extend({},a),f);(e||L.get(this,"finish"))&&b.stop(!0)};return g.finish=g,e||f.queue===!1?this.each(g):this.queue(f.queue,g)},stop:function(a,b,c){var d=function(a){var b=a.stop;delete a.stop,b(c)};return"string"!=typeof a&&(c=b,b=a,a=void 0),b&&a!==!1&&this.queue(a||"fx",[]),this.each(function(){var b=!0,e=null!=a&&a+"queueHooks",f=o.timers,g=L.get(this);if(e)g[e]&&g[e].stop&&d(g[e]);else for(e in g)g[e]&&g[e].stop&&Pb.test(e)&&d(g[e]);for(e=f.length;e--;)f[e].elem!==this||null!=a&&f[e].queue!==a||(f[e].anim.stop(c),b=!1,f.splice(e,1));(b||!c)&&o.dequeue(this,a)})},finish:function(a){return a!==!1&&(a=a||"fx"),this.each(function(){var b,c=L.get(this),d=c[a+"queue"],e=c[a+"queueHooks"],f=o.timers,g=d?d.length:0;for(c.finish=!0,o.queue(this,a,[]),e&&e.stop&&e.stop.call(this,!0),b=f.length;b--;)f[b].elem===this&&f[b].queue===a&&(f[b].anim.stop(!0),f.splice(b,1));for(b=0;g>b;b++)d[b]&&d[b].finish&&d[b].finish.call(this);delete c.finish})}}),o.each(["toggle","show","hide"],function(a,b){var c=o.fn[b];o.fn[b]=function(a,d,e){return null==a||"boolean"==typeof a?c.apply(this,arguments):this.animate(Tb(b,!0),a,d,e)}}),o.each({slideDown:Tb("show"),slideUp:Tb("hide"),slideToggle:Tb("toggle"),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"},fadeToggle:{opacity:"toggle"}},function(a,b){o.fn[a]=function(a,c,d){return this.animate(b,a,c,d)}}),o.timers=[],o.fx.tick=function(){var a,b=0,c=o.timers;for(Lb=o.now();b<c.length;b++)a=c[b],a()||c[b]!==a||c.splice(b--,1);c.length||o.fx.stop(),Lb=void 0},o.fx.timer=function(a){o.timers.push(a),a()?o.fx.start():o.timers.pop()},o.fx.interval=13,o.fx.start=function(){Mb||(Mb=setInterval(o.fx.tick,o.fx.interval))},o.fx.stop=function(){clearInterval(Mb),Mb=null},o.fx.speeds={slow:600,fast:200,_default:400},o.fn.delay=function(a,b){return a=o.fx?o.fx.speeds[a]||a:a,b=b||"fx",this.queue(b,function(b,c){var d=setTimeout(b,a);c.stop=function(){clearTimeout(d)}})},function(){var a=m.createElement("input"),b=m.createElement("select"),c=b.appendChild(m.createElement("option"));a.type="checkbox",l.checkOn=""!==a.value,l.optSelected=c.selected,b.disabled=!0,l.optDisabled=!c.disabled,a=m.createElement("input"),a.value="t",a.type="radio",l.radioValue="t"===a.value}();var Yb,Zb,$b=o.expr.attrHandle;o.fn.extend({attr:function(a,b){return J(this,o.attr,a,b,arguments.length>1)},removeAttr:function(a){return this.each(function(){o.removeAttr(this,a)})}}),o.extend({attr:function(a,b,c){var d,e,f=a.nodeType;if(a&&3!==f&&8!==f&&2!==f)return typeof a.getAttribute===U?o.prop(a,b,c):(1===f&&o.isXMLDoc(a)||(b=b.toLowerCase(),d=o.attrHooks[b]||(o.expr.match.bool.test(b)?Zb:Yb)),void 0===c?d&&"get"in d&&null!==(e=d.get(a,b))?e:(e=o.find.attr(a,b),null==e?void 0:e):null!==c?d&&"set"in d&&void 0!==(e=d.set(a,c,b))?e:(a.setAttribute(b,c+""),c):void o.removeAttr(a,b))},removeAttr:function(a,b){var c,d,e=0,f=b&&b.match(E);if(f&&1===a.nodeType)while(c=f[e++])d=o.propFix[c]||c,o.expr.match.bool.test(c)&&(a[d]=!1),a.removeAttribute(c)},attrHooks:{type:{set:function(a,b){if(!l.radioValue&&"radio"===b&&o.nodeName(a,"input")){var c=a.value;return a.setAttribute("type",b),c&&(a.value=c),b}}}}}),Zb={set:function(a,b,c){return b===!1?o.removeAttr(a,c):a.setAttribute(c,c),c}},o.each(o.expr.match.bool.source.match(/\w+/g),function(a,b){var c=$b[b]||o.find.attr;$b[b]=function(a,b,d){var e,f; +return d||(f=$b[b],$b[b]=e,e=null!=c(a,b,d)?b.toLowerCase():null,$b[b]=f),e}});var _b=/^(?:input|select|textarea|button)$/i;o.fn.extend({prop:function(a,b){return J(this,o.prop,a,b,arguments.length>1)},removeProp:function(a){return this.each(function(){delete this[o.propFix[a]||a]})}}),o.extend({propFix:{"for":"htmlFor","class":"className"},prop:function(a,b,c){var d,e,f,g=a.nodeType;if(a&&3!==g&&8!==g&&2!==g)return f=1!==g||!o.isXMLDoc(a),f&&(b=o.propFix[b]||b,e=o.propHooks[b]),void 0!==c?e&&"set"in e&&void 0!==(d=e.set(a,c,b))?d:a[b]=c:e&&"get"in e&&null!==(d=e.get(a,b))?d:a[b]},propHooks:{tabIndex:{get:function(a){return a.hasAttribute("tabindex")||_b.test(a.nodeName)||a.href?a.tabIndex:-1}}}}),l.optSelected||(o.propHooks.selected={get:function(a){var b=a.parentNode;return b&&b.parentNode&&b.parentNode.selectedIndex,null}}),o.each(["tabIndex","readOnly","maxLength","cellSpacing","cellPadding","rowSpan","colSpan","useMap","frameBorder","contentEditable"],function(){o.propFix[this.toLowerCase()]=this});var ac=/[\t\r\n\f]/g;o.fn.extend({addClass:function(a){var b,c,d,e,f,g,h="string"==typeof a&&a,i=0,j=this.length;if(o.isFunction(a))return this.each(function(b){o(this).addClass(a.call(this,b,this.className))});if(h)for(b=(a||"").match(E)||[];j>i;i++)if(c=this[i],d=1===c.nodeType&&(c.className?(" "+c.className+" ").replace(ac," "):" ")){f=0;while(e=b[f++])d.indexOf(" "+e+" ")<0&&(d+=e+" ");g=o.trim(d),c.className!==g&&(c.className=g)}return this},removeClass:function(a){var b,c,d,e,f,g,h=0===arguments.length||"string"==typeof a&&a,i=0,j=this.length;if(o.isFunction(a))return this.each(function(b){o(this).removeClass(a.call(this,b,this.className))});if(h)for(b=(a||"").match(E)||[];j>i;i++)if(c=this[i],d=1===c.nodeType&&(c.className?(" "+c.className+" ").replace(ac," "):"")){f=0;while(e=b[f++])while(d.indexOf(" "+e+" ")>=0)d=d.replace(" "+e+" "," ");g=a?o.trim(d):"",c.className!==g&&(c.className=g)}return this},toggleClass:function(a,b){var c=typeof a;return"boolean"==typeof b&&"string"===c?b?this.addClass(a):this.removeClass(a):this.each(o.isFunction(a)?function(c){o(this).toggleClass(a.call(this,c,this.className,b),b)}:function(){if("string"===c){var b,d=0,e=o(this),f=a.match(E)||[];while(b=f[d++])e.hasClass(b)?e.removeClass(b):e.addClass(b)}else(c===U||"boolean"===c)&&(this.className&&L.set(this,"__className__",this.className),this.className=this.className||a===!1?"":L.get(this,"__className__")||"")})},hasClass:function(a){for(var b=" "+a+" ",c=0,d=this.length;d>c;c++)if(1===this[c].nodeType&&(" "+this[c].className+" ").replace(ac," ").indexOf(b)>=0)return!0;return!1}});var bc=/\r/g;o.fn.extend({val:function(a){var b,c,d,e=this[0];{if(arguments.length)return d=o.isFunction(a),this.each(function(c){var e;1===this.nodeType&&(e=d?a.call(this,c,o(this).val()):a,null==e?e="":"number"==typeof e?e+="":o.isArray(e)&&(e=o.map(e,function(a){return null==a?"":a+""})),b=o.valHooks[this.type]||o.valHooks[this.nodeName.toLowerCase()],b&&"set"in b&&void 0!==b.set(this,e,"value")||(this.value=e))});if(e)return b=o.valHooks[e.type]||o.valHooks[e.nodeName.toLowerCase()],b&&"get"in b&&void 0!==(c=b.get(e,"value"))?c:(c=e.value,"string"==typeof c?c.replace(bc,""):null==c?"":c)}}}),o.extend({valHooks:{select:{get:function(a){for(var b,c,d=a.options,e=a.selectedIndex,f="select-one"===a.type||0>e,g=f?null:[],h=f?e+1:d.length,i=0>e?h:f?e:0;h>i;i++)if(c=d[i],!(!c.selected&&i!==e||(l.optDisabled?c.disabled:null!==c.getAttribute("disabled"))||c.parentNode.disabled&&o.nodeName(c.parentNode,"optgroup"))){if(b=o(c).val(),f)return b;g.push(b)}return g},set:function(a,b){var c,d,e=a.options,f=o.makeArray(b),g=e.length;while(g--)d=e[g],(d.selected=o.inArray(o(d).val(),f)>=0)&&(c=!0);return c||(a.selectedIndex=-1),f}}}}),o.each(["radio","checkbox"],function(){o.valHooks[this]={set:function(a,b){return o.isArray(b)?a.checked=o.inArray(o(a).val(),b)>=0:void 0}},l.checkOn||(o.valHooks[this].get=function(a){return null===a.getAttribute("value")?"on":a.value})}),o.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){o.fn[b]=function(a,c){return arguments.length>0?this.on(b,null,a,c):this.trigger(b)}}),o.fn.extend({hover:function(a,b){return this.mouseenter(a).mouseleave(b||a)},bind:function(a,b,c){return this.on(a,null,b,c)},unbind:function(a,b){return this.off(a,null,b)},delegate:function(a,b,c,d){return this.on(b,a,c,d)},undelegate:function(a,b,c){return 1===arguments.length?this.off(a,"**"):this.off(b,a||"**",c)}});var cc=o.now(),dc=/\?/;o.parseJSON=function(a){return JSON.parse(a+"")},o.parseXML=function(a){var b,c;if(!a||"string"!=typeof a)return null;try{c=new DOMParser,b=c.parseFromString(a,"text/xml")}catch(d){b=void 0}return(!b||b.getElementsByTagName("parsererror").length)&&o.error("Invalid XML: "+a),b};var ec,fc,gc=/#.*$/,hc=/([?&])_=[^&]*/,ic=/^(.*?):[ \t]*([^\r\n]*)$/gm,jc=/^(?:about|app|app-storage|.+-extension|file|res|widget):$/,kc=/^(?:GET|HEAD)$/,lc=/^\/\//,mc=/^([\w.+-]+:)(?:\/\/(?:[^\/?#]*@|)([^\/?#:]*)(?::(\d+)|)|)/,nc={},oc={},pc="*/".concat("*");try{fc=location.href}catch(qc){fc=m.createElement("a"),fc.href="",fc=fc.href}ec=mc.exec(fc.toLowerCase())||[];function rc(a){return function(b,c){"string"!=typeof b&&(c=b,b="*");var d,e=0,f=b.toLowerCase().match(E)||[];if(o.isFunction(c))while(d=f[e++])"+"===d[0]?(d=d.slice(1)||"*",(a[d]=a[d]||[]).unshift(c)):(a[d]=a[d]||[]).push(c)}}function sc(a,b,c,d){var e={},f=a===oc;function g(h){var i;return e[h]=!0,o.each(a[h]||[],function(a,h){var j=h(b,c,d);return"string"!=typeof j||f||e[j]?f?!(i=j):void 0:(b.dataTypes.unshift(j),g(j),!1)}),i}return g(b.dataTypes[0])||!e["*"]&&g("*")}function tc(a,b){var c,d,e=o.ajaxSettings.flatOptions||{};for(c in b)void 0!==b[c]&&((e[c]?a:d||(d={}))[c]=b[c]);return d&&o.extend(!0,a,d),a}function uc(a,b,c){var d,e,f,g,h=a.contents,i=a.dataTypes;while("*"===i[0])i.shift(),void 0===d&&(d=a.mimeType||b.getResponseHeader("Content-Type"));if(d)for(e in h)if(h[e]&&h[e].test(d)){i.unshift(e);break}if(i[0]in c)f=i[0];else{for(e in c){if(!i[0]||a.converters[e+" "+i[0]]){f=e;break}g||(g=e)}f=f||g}return f?(f!==i[0]&&i.unshift(f),c[f]):void 0}function vc(a,b,c,d){var e,f,g,h,i,j={},k=a.dataTypes.slice();if(k[1])for(g in a.converters)j[g.toLowerCase()]=a.converters[g];f=k.shift();while(f)if(a.responseFields[f]&&(c[a.responseFields[f]]=b),!i&&d&&a.dataFilter&&(b=a.dataFilter(b,a.dataType)),i=f,f=k.shift())if("*"===f)f=i;else if("*"!==i&&i!==f){if(g=j[i+" "+f]||j["* "+f],!g)for(e in j)if(h=e.split(" "),h[1]===f&&(g=j[i+" "+h[0]]||j["* "+h[0]])){g===!0?g=j[e]:j[e]!==!0&&(f=h[0],k.unshift(h[1]));break}if(g!==!0)if(g&&a["throws"])b=g(b);else try{b=g(b)}catch(l){return{state:"parsererror",error:g?l:"No conversion from "+i+" to "+f}}}return{state:"success",data:b}}o.extend({active:0,lastModified:{},etag:{},ajaxSettings:{url:fc,type:"GET",isLocal:jc.test(ec[1]),global:!0,processData:!0,async:!0,contentType:"application/x-www-form-urlencoded; charset=UTF-8",accepts:{"*":pc,text:"text/plain",html:"text/html",xml:"application/xml, text/xml",json:"application/json, text/javascript"},contents:{xml:/xml/,html:/html/,json:/json/},responseFields:{xml:"responseXML",text:"responseText",json:"responseJSON"},converters:{"* text":String,"text html":!0,"text json":o.parseJSON,"text xml":o.parseXML},flatOptions:{url:!0,context:!0}},ajaxSetup:function(a,b){return b?tc(tc(a,o.ajaxSettings),b):tc(o.ajaxSettings,a)},ajaxPrefilter:rc(nc),ajaxTransport:rc(oc),ajax:function(a,b){"object"==typeof a&&(b=a,a=void 0),b=b||{};var c,d,e,f,g,h,i,j,k=o.ajaxSetup({},b),l=k.context||k,m=k.context&&(l.nodeType||l.jquery)?o(l):o.event,n=o.Deferred(),p=o.Callbacks("once memory"),q=k.statusCode||{},r={},s={},t=0,u="canceled",v={readyState:0,getResponseHeader:function(a){var b;if(2===t){if(!f){f={};while(b=ic.exec(e))f[b[1].toLowerCase()]=b[2]}b=f[a.toLowerCase()]}return null==b?null:b},getAllResponseHeaders:function(){return 2===t?e:null},setRequestHeader:function(a,b){var c=a.toLowerCase();return t||(a=s[c]=s[c]||a,r[a]=b),this},overrideMimeType:function(a){return t||(k.mimeType=a),this},statusCode:function(a){var b;if(a)if(2>t)for(b in a)q[b]=[q[b],a[b]];else v.always(a[v.status]);return this},abort:function(a){var b=a||u;return c&&c.abort(b),x(0,b),this}};if(n.promise(v).complete=p.add,v.success=v.done,v.error=v.fail,k.url=((a||k.url||fc)+"").replace(gc,"").replace(lc,ec[1]+"//"),k.type=b.method||b.type||k.method||k.type,k.dataTypes=o.trim(k.dataType||"*").toLowerCase().match(E)||[""],null==k.crossDomain&&(h=mc.exec(k.url.toLowerCase()),k.crossDomain=!(!h||h[1]===ec[1]&&h[2]===ec[2]&&(h[3]||("http:"===h[1]?"80":"443"))===(ec[3]||("http:"===ec[1]?"80":"443")))),k.data&&k.processData&&"string"!=typeof k.data&&(k.data=o.param(k.data,k.traditional)),sc(nc,k,b,v),2===t)return v;i=k.global,i&&0===o.active++&&o.event.trigger("ajaxStart"),k.type=k.type.toUpperCase(),k.hasContent=!kc.test(k.type),d=k.url,k.hasContent||(k.data&&(d=k.url+=(dc.test(d)?"&":"?")+k.data,delete k.data),k.cache===!1&&(k.url=hc.test(d)?d.replace(hc,"$1_="+cc++):d+(dc.test(d)?"&":"?")+"_="+cc++)),k.ifModified&&(o.lastModified[d]&&v.setRequestHeader("If-Modified-Since",o.lastModified[d]),o.etag[d]&&v.setRequestHeader("If-None-Match",o.etag[d])),(k.data&&k.hasContent&&k.contentType!==!1||b.contentType)&&v.setRequestHeader("Content-Type",k.contentType),v.setRequestHeader("Accept",k.dataTypes[0]&&k.accepts[k.dataTypes[0]]?k.accepts[k.dataTypes[0]]+("*"!==k.dataTypes[0]?", "+pc+"; q=0.01":""):k.accepts["*"]);for(j in k.headers)v.setRequestHeader(j,k.headers[j]);if(k.beforeSend&&(k.beforeSend.call(l,v,k)===!1||2===t))return v.abort();u="abort";for(j in{success:1,error:1,complete:1})v[j](k[j]);if(c=sc(oc,k,b,v)){v.readyState=1,i&&m.trigger("ajaxSend",[v,k]),k.async&&k.timeout>0&&(g=setTimeout(function(){v.abort("timeout")},k.timeout));try{t=1,c.send(r,x)}catch(w){if(!(2>t))throw w;x(-1,w)}}else x(-1,"No Transport");function x(a,b,f,h){var j,r,s,u,w,x=b;2!==t&&(t=2,g&&clearTimeout(g),c=void 0,e=h||"",v.readyState=a>0?4:0,j=a>=200&&300>a||304===a,f&&(u=uc(k,v,f)),u=vc(k,u,v,j),j?(k.ifModified&&(w=v.getResponseHeader("Last-Modified"),w&&(o.lastModified[d]=w),w=v.getResponseHeader("etag"),w&&(o.etag[d]=w)),204===a||"HEAD"===k.type?x="nocontent":304===a?x="notmodified":(x=u.state,r=u.data,s=u.error,j=!s)):(s=x,(a||!x)&&(x="error",0>a&&(a=0))),v.status=a,v.statusText=(b||x)+"",j?n.resolveWith(l,[r,x,v]):n.rejectWith(l,[v,x,s]),v.statusCode(q),q=void 0,i&&m.trigger(j?"ajaxSuccess":"ajaxError",[v,k,j?r:s]),p.fireWith(l,[v,x]),i&&(m.trigger("ajaxComplete",[v,k]),--o.active||o.event.trigger("ajaxStop")))}return v},getJSON:function(a,b,c){return o.get(a,b,c,"json")},getScript:function(a,b){return o.get(a,void 0,b,"script")}}),o.each(["get","post"],function(a,b){o[b]=function(a,c,d,e){return o.isFunction(c)&&(e=e||d,d=c,c=void 0),o.ajax({url:a,type:b,dataType:e,data:c,success:d})}}),o.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(a,b){o.fn[b]=function(a){return this.on(b,a)}}),o._evalUrl=function(a){return o.ajax({url:a,type:"GET",dataType:"script",async:!1,global:!1,"throws":!0})},o.fn.extend({wrapAll:function(a){var b;return o.isFunction(a)?this.each(function(b){o(this).wrapAll(a.call(this,b))}):(this[0]&&(b=o(a,this[0].ownerDocument).eq(0).clone(!0),this[0].parentNode&&b.insertBefore(this[0]),b.map(function(){var a=this;while(a.firstElementChild)a=a.firstElementChild;return a}).append(this)),this)},wrapInner:function(a){return this.each(o.isFunction(a)?function(b){o(this).wrapInner(a.call(this,b))}:function(){var b=o(this),c=b.contents();c.length?c.wrapAll(a):b.append(a)})},wrap:function(a){var b=o.isFunction(a);return this.each(function(c){o(this).wrapAll(b?a.call(this,c):a)})},unwrap:function(){return this.parent().each(function(){o.nodeName(this,"body")||o(this).replaceWith(this.childNodes)}).end()}}),o.expr.filters.hidden=function(a){return a.offsetWidth<=0&&a.offsetHeight<=0},o.expr.filters.visible=function(a){return!o.expr.filters.hidden(a)};var wc=/%20/g,xc=/\[\]$/,yc=/\r?\n/g,zc=/^(?:submit|button|image|reset|file)$/i,Ac=/^(?:input|select|textarea|keygen)/i;function Bc(a,b,c,d){var e;if(o.isArray(b))o.each(b,function(b,e){c||xc.test(a)?d(a,e):Bc(a+"["+("object"==typeof e?b:"")+"]",e,c,d)});else if(c||"object"!==o.type(b))d(a,b);else for(e in b)Bc(a+"["+e+"]",b[e],c,d)}o.param=function(a,b){var c,d=[],e=function(a,b){b=o.isFunction(b)?b():null==b?"":b,d[d.length]=encodeURIComponent(a)+"="+encodeURIComponent(b)};if(void 0===b&&(b=o.ajaxSettings&&o.ajaxSettings.traditional),o.isArray(a)||a.jquery&&!o.isPlainObject(a))o.each(a,function(){e(this.name,this.value)});else for(c in a)Bc(c,a[c],b,e);return d.join("&").replace(wc,"+")},o.fn.extend({serialize:function(){return o.param(this.serializeArray())},serializeArray:function(){return this.map(function(){var a=o.prop(this,"elements");return a?o.makeArray(a):this}).filter(function(){var a=this.type;return this.name&&!o(this).is(":disabled")&&Ac.test(this.nodeName)&&!zc.test(a)&&(this.checked||!T.test(a))}).map(function(a,b){var c=o(this).val();return null==c?null:o.isArray(c)?o.map(c,function(a){return{name:b.name,value:a.replace(yc,"\r\n")}}):{name:b.name,value:c.replace(yc,"\r\n")}}).get()}}),o.ajaxSettings.xhr=function(){try{return new XMLHttpRequest}catch(a){}};var Cc=0,Dc={},Ec={0:200,1223:204},Fc=o.ajaxSettings.xhr();a.ActiveXObject&&o(a).on("unload",function(){for(var a in Dc)Dc[a]()}),l.cors=!!Fc&&"withCredentials"in Fc,l.ajax=Fc=!!Fc,o.ajaxTransport(function(a){var b;return l.cors||Fc&&!a.crossDomain?{send:function(c,d){var e,f=a.xhr(),g=++Cc;if(f.open(a.type,a.url,a.async,a.username,a.password),a.xhrFields)for(e in a.xhrFields)f[e]=a.xhrFields[e];a.mimeType&&f.overrideMimeType&&f.overrideMimeType(a.mimeType),a.crossDomain||c["X-Requested-With"]||(c["X-Requested-With"]="XMLHttpRequest");for(e in c)f.setRequestHeader(e,c[e]);b=function(a){return function(){b&&(delete Dc[g],b=f.onload=f.onerror=null,"abort"===a?f.abort():"error"===a?d(f.status,f.statusText):d(Ec[f.status]||f.status,f.statusText,"string"==typeof f.responseText?{text:f.responseText}:void 0,f.getAllResponseHeaders()))}},f.onload=b(),f.onerror=b("error"),b=Dc[g]=b("abort"),f.send(a.hasContent&&a.data||null)},abort:function(){b&&b()}}:void 0}),o.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/(?:java|ecma)script/},converters:{"text script":function(a){return o.globalEval(a),a}}}),o.ajaxPrefilter("script",function(a){void 0===a.cache&&(a.cache=!1),a.crossDomain&&(a.type="GET")}),o.ajaxTransport("script",function(a){if(a.crossDomain){var b,c;return{send:function(d,e){b=o("<script>").prop({async:!0,charset:a.scriptCharset,src:a.url}).on("load error",c=function(a){b.remove(),c=null,a&&e("error"===a.type?404:200,a.type)}),m.head.appendChild(b[0])},abort:function(){c&&c()}}}});var Gc=[],Hc=/(=)\?(?=&|$)|\?\?/;o.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var a=Gc.pop()||o.expando+"_"+cc++;return this[a]=!0,a}}),o.ajaxPrefilter("json jsonp",function(b,c,d){var e,f,g,h=b.jsonp!==!1&&(Hc.test(b.url)?"url":"string"==typeof b.data&&!(b.contentType||"").indexOf("application/x-www-form-urlencoded")&&Hc.test(b.data)&&"data");return h||"jsonp"===b.dataTypes[0]?(e=b.jsonpCallback=o.isFunction(b.jsonpCallback)?b.jsonpCallback():b.jsonpCallback,h?b[h]=b[h].replace(Hc,"$1"+e):b.jsonp!==!1&&(b.url+=(dc.test(b.url)?"&":"?")+b.jsonp+"="+e),b.converters["script json"]=function(){return g||o.error(e+" was not called"),g[0]},b.dataTypes[0]="json",f=a[e],a[e]=function(){g=arguments},d.always(function(){a[e]=f,b[e]&&(b.jsonpCallback=c.jsonpCallback,Gc.push(e)),g&&o.isFunction(f)&&f(g[0]),g=f=void 0}),"script"):void 0}),o.parseHTML=function(a,b,c){if(!a||"string"!=typeof a)return null;"boolean"==typeof b&&(c=b,b=!1),b=b||m;var d=v.exec(a),e=!c&&[];return d?[b.createElement(d[1])]:(d=o.buildFragment([a],b,e),e&&e.length&&o(e).remove(),o.merge([],d.childNodes))};var Ic=o.fn.load;o.fn.load=function(a,b,c){if("string"!=typeof a&&Ic)return Ic.apply(this,arguments);var d,e,f,g=this,h=a.indexOf(" ");return h>=0&&(d=a.slice(h),a=a.slice(0,h)),o.isFunction(b)?(c=b,b=void 0):b&&"object"==typeof b&&(e="POST"),g.length>0&&o.ajax({url:a,type:e,dataType:"html",data:b}).done(function(a){f=arguments,g.html(d?o("<div>").append(o.parseHTML(a)).find(d):a)}).complete(c&&function(a,b){g.each(c,f||[a.responseText,b,a])}),this},o.expr.filters.animated=function(a){return o.grep(o.timers,function(b){return a===b.elem}).length};var Jc=a.document.documentElement;function Kc(a){return o.isWindow(a)?a:9===a.nodeType&&a.defaultView}o.offset={setOffset:function(a,b,c){var d,e,f,g,h,i,j,k=o.css(a,"position"),l=o(a),m={};"static"===k&&(a.style.position="relative"),h=l.offset(),f=o.css(a,"top"),i=o.css(a,"left"),j=("absolute"===k||"fixed"===k)&&(f+i).indexOf("auto")>-1,j?(d=l.position(),g=d.top,e=d.left):(g=parseFloat(f)||0,e=parseFloat(i)||0),o.isFunction(b)&&(b=b.call(a,c,h)),null!=b.top&&(m.top=b.top-h.top+g),null!=b.left&&(m.left=b.left-h.left+e),"using"in b?b.using.call(a,m):l.css(m)}},o.fn.extend({offset:function(a){if(arguments.length)return void 0===a?this:this.each(function(b){o.offset.setOffset(this,a,b)});var b,c,d=this[0],e={top:0,left:0},f=d&&d.ownerDocument;if(f)return b=f.documentElement,o.contains(b,d)?(typeof d.getBoundingClientRect!==U&&(e=d.getBoundingClientRect()),c=Kc(f),{top:e.top+c.pageYOffset-b.clientTop,left:e.left+c.pageXOffset-b.clientLeft}):e},position:function(){if(this[0]){var a,b,c=this[0],d={top:0,left:0};return"fixed"===o.css(c,"position")?b=c.getBoundingClientRect():(a=this.offsetParent(),b=this.offset(),o.nodeName(a[0],"html")||(d=a.offset()),d.top+=o.css(a[0],"borderTopWidth",!0),d.left+=o.css(a[0],"borderLeftWidth",!0)),{top:b.top-d.top-o.css(c,"marginTop",!0),left:b.left-d.left-o.css(c,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var a=this.offsetParent||Jc;while(a&&!o.nodeName(a,"html")&&"static"===o.css(a,"position"))a=a.offsetParent;return a||Jc})}}),o.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(b,c){var d="pageYOffset"===c;o.fn[b]=function(e){return J(this,function(b,e,f){var g=Kc(b);return void 0===f?g?g[c]:b[e]:void(g?g.scrollTo(d?a.pageXOffset:f,d?f:a.pageYOffset):b[e]=f)},b,e,arguments.length,null)}}),o.each(["top","left"],function(a,b){o.cssHooks[b]=yb(l.pixelPosition,function(a,c){return c?(c=xb(a,b),vb.test(c)?o(a).position()[b]+"px":c):void 0})}),o.each({Height:"height",Width:"width"},function(a,b){o.each({padding:"inner"+a,content:b,"":"outer"+a},function(c,d){o.fn[d]=function(d,e){var f=arguments.length&&(c||"boolean"!=typeof d),g=c||(d===!0||e===!0?"margin":"border");return J(this,function(b,c,d){var e;return o.isWindow(b)?b.document.documentElement["client"+a]:9===b.nodeType?(e=b.documentElement,Math.max(b.body["scroll"+a],e["scroll"+a],b.body["offset"+a],e["offset"+a],e["client"+a])):void 0===d?o.css(b,c,g):o.style(b,c,d,g)},b,f?d:void 0,f,null)}})}),o.fn.size=function(){return this.length},o.fn.andSelf=o.fn.addBack,"function"==typeof define&&define.amd&&define("jquery",[],function(){return o});var Lc=a.jQuery,Mc=a.$;return o.noConflict=function(b){return a.$===o&&(a.$=Mc),b&&a.jQuery===o&&(a.jQuery=Lc),o},typeof b===U&&(a.jQuery=a.$=o),o});
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/popoto_dev/js/popoto.min.js Fri Oct 02 01:08:46 2015 -0400 @@ -0,0 +1,108 @@ +popoto=function(){var a={version:"0.0-a6",start:function(b){a.logger.info("Popoto "+a.version+" start.");"undefined"==typeof a.rest.CYPHER_URL?a.logger.error("popoto.rest.CYPHER_URL is not set but this property is required."):(a.checkHtmlComponents(),a.taxonomy.isActive&&a.taxonomy.createTaxonomyPanel(),a.graph.isActive&&(a.graph.createGraphArea(),a.graph.createForceLayout(),a.graph.addRootNode(b)),a.queryviewer.isActive&&a.queryviewer.createQueryArea(),a.update())},checkHtmlComponents:function(){var b= +d3.select("#"+a.graph.containerId),c=d3.select("#"+a.taxonomy.containerId),d=d3.select("#"+a.queryviewer.containerId),e=d3.select("#"+a.cypherviewer.containerId),f=d3.select("#"+a.result.containerId);b.empty()?(a.logger.debug("The page doesn't contain a container with ID = \""+a.graph.containerId+'" no graph area will be generated. This ID is defined in popoto.graph.containerId property.'),a.graph.isActive=!1):a.graph.isActive=!0;c.empty()?(a.logger.debug("The page doesn't contain a container with ID = \""+ +a.taxonomy.containerId+'" no taxonomy filter will be generated. This ID is defined in popoto.taxonomy.containerId property.'),a.taxonomy.isActive=!1):a.taxonomy.isActive=!0;d.empty()?(a.logger.debug("The page doesn't contain a container with ID = \""+a.queryviewer.containerId+'" no query viewer will be generated. This ID is defined in popoto.queryviewer.containerId property.'),a.queryviewer.isActive=!1):a.queryviewer.isActive=!0;e.empty()?(a.logger.debug("The page doesn't contain a container with ID = \""+ +a.cypherviewer.containerId+'" no cypher query viewer will be generated. This ID is defined in popoto.cypherviewer.containerId property.'),a.cypherviewer.isActive=!1):a.cypherviewer.isActive=!0;f.empty()?(a.logger.debug("The page doesn't contain a container with ID = \""+a.result.containerId+'" no result area will be generated. This ID is defined in popoto.result.containerId property.'),a.result.isActive=!1):a.result.isActive=!0},update:function(){a.updateGraph();a.queryviewer.isActive&&a.queryviewer.updateQuery(); +(a.result.isActive||0<a.result.resultListeners.length||0<a.result.resultCountListeners.length)&&a.result.updateResults()},updateGraph:function(){a.graph.isActive&&(a.graph.force.start(),a.graph.link.updateLinks(),a.graph.node.updateNodes())},rest:{}};a.rest.CYPHER_URL="http://localhost:7474/db/data/transaction/commit";a.rest.post=function(b){b=JSON.stringify(b);a.logger.info("REST POST:"+b);return $.ajax({type:"POST",beforeSend:function(b){a.rest.AUTHORIZATION&&b.setRequestHeader("Authorization", +a.rest.AUTHORIZATION)},url:a.rest.CYPHER_URL,contentType:"application/json",data:b})};a.logger={};a.logger.LogLevels=Object.freeze({DEBUG:0,INFO:1,WARN:2,ERROR:3,NONE:4});a.logger.LEVEL=a.logger.LogLevels.NONE;a.logger.TRACE=!1;a.logger.log=function(b,c){if(console&&b>=a.logger.LEVEL)switch(a.logger.TRACE&&(c=c+"\n"+Error().stack),b){case a.logger.LogLevels.DEBUG:console.log(c);break;case a.logger.LogLevels.INFO:console.log(c);break;case a.logger.LogLevels.WARN:console.warn(c);break;case a.logger.LogLevels.ERROR:console.error(c)}}; +a.logger.debug=function(b){a.logger.log(a.logger.LogLevels.DEBUG,b)};a.logger.info=function(b){a.logger.log(a.logger.LogLevels.INFO,b)};a.logger.warn=function(b){a.logger.log(a.logger.LogLevels.WARN,b)};a.logger.error=function(b){a.logger.log(a.logger.LogLevels.ERROR,b)};a.taxonomy={};a.taxonomy.containerId="popoto-taxonomy";a.taxonomy.createTaxonomyPanel=function(){var b=d3.select("#"+a.taxonomy.containerId).append("ul"),c=a.taxonomy.generateTaxonomiesData(),b=b.selectAll(".taxo").data(c).enter().append("li").attr("id", +function(a){return a.id}).attr("value",function(a){return a.label});b.append("img").attr("src","css/image/category.png").attr("width","24").attr("height","24");b.append("span").attr("class","ppt-label").text(function(b){return a.provider.getTaxonomyTextValue(b.label)});b.append("span").attr("class","ppt-count");b.on("click",a.taxonomy.onClick);a.taxonomy.addTaxonomyChildren(b);var d=[];c.forEach(function(b){d.push(b);b.children&&a.taxonomy.flattenChildren(b,d)});a.taxonomy.updateCount(d)};a.taxonomy.flattenChildren= +function(b,c){b.children.forEach(function(b){c.push(b);b.children&&c.concat(a.taxonomy.flattenChildren(b,c))})};a.taxonomy.updateCount=function(b){var c=[];b.forEach(function(b){c.push({statement:a.query.generateTaxonomyCountQuery(b.label)})});(function(b){a.logger.info("Count taxonomies ==> ");a.rest.post({statements:c}).done(function(a){for(var c=0;c<b.length;c++){var l=a.results[c].data[0].row[0];d3.select("#"+b[c].id).select(".ppt-count").text(" ("+l+")")}}).fail(function(b,c,d){a.logger.error(c+ +': error while accessing Neo4j server on URL:"'+a.rest.CYPHER_URL+'" defined in "popoto.rest.CYPHER_URL" property: '+d);d3.select("#popoto-taxonomy").selectAll(".ppt-count").text(" (0)")})})(b)};a.taxonomy.addTaxonomyChildren=function(b){b.each(function(b){var d=d3.select(this),e=b.children;b.children&&(b=d.append("ul").selectAll("li").data(e).enter().append("li").attr("id",function(a){return a.id}).attr("value",function(a){return a.label}),b.append("img").attr("src","css/image/category.png").attr("width", +"24").attr("height","24"),b.append("span").attr("class","ppt-label").text(function(b){return a.provider.getTaxonomyTextValue(b.label)}),b.append("span").attr("class","ppt-count"),b.on("click",a.taxonomy.onClick),a.taxonomy.addTaxonomyChildren(b))})};a.taxonomy.onClick=function(){d3.event.stopPropagation();if(void 0!==a.graph.getRootNode().count){for(var b=this.attributes.value.value;0<a.graph.force.nodes().length;)a.graph.force.nodes().pop();for(;0<a.graph.force.links().length;)a.graph.force.links().pop(); +a.graph.node.internalLabels={};a.update();a.graph.addRootNode(b);a.graph.hasGraphChanged=!0;a.result.hasChanged=!0;a.update();a.tools.center()}};a.taxonomy.generateTaxonomiesData=function(){var b=0,c=[],d;for(d in a.provider.nodeProviders)a.provider.nodeProviders.hasOwnProperty(d)&&a.provider.getProperty(d,"isSearchable")&&!a.provider.nodeProviders[d].parent&&c.push({label:d,id:"popoto-lbl-"+b++});c.forEach(function(c){a.provider.getProvider(c.label).hasOwnProperty("children")&&(b=a.taxonomy.addChildrenData(c, +b))});return c};a.taxonomy.addChildrenData=function(b,c){b.children=[];a.provider.getProvider(b.label).children.forEach(function(d){var e=a.provider.getProvider(d),f={label:d,id:"popoto-lbl-"+c++};e.hasOwnProperty("children")&&(c=a.taxonomy.addChildrenData(f,c));a.provider.getProperty(d,"isSearchable")&&b.children.push(f)});return c};a.tools={};a.tools.CENTER_GRAPH=!0;a.tools.RESET_GRAPH=!0;a.tools.TOGGLE_TAXONOMY=!0;a.tools.TOGGLE_FULL_SCREEN=!0;a.tools.reset=function(){for(var b=a.graph.getRootNode().label;0< +a.graph.force.nodes().length;)a.graph.force.nodes().pop();for(;0<a.graph.force.links().length;)a.graph.force.links().pop();a.graph.node.internalLabels={};a.update();a.graph.addRootNode(b);a.graph.hasGraphChanged=!0;a.result.hasChanged=!0;a.update();a.tools.center()};a.tools.center=function(){a.graph.zoom.translate([0,0]).scale(1);a.graph.svg.transition().attr("transform","translate("+a.graph.zoom.translate()+") scale("+a.graph.zoom.scale()+")")};a.tools.toggleTaxonomy=function(){var b=d3.select("#"+ +a.taxonomy.containerId);b.filter(".disabled").empty()?b.classed("disabled",!0):b.classed("disabled",!1)};a.tools.toggleFullScreen=function(){var b=document.getElementById(a.graph.containerId);document.fullscreenElement||document.mozFullScreenElement||document.webkitFullscreenElement||document.msFullscreenElement?document.exitFullscreen?document.exitFullscreen():document.msExitFullscreen?document.msExitFullscreen():document.mozCancelFullScreen?document.mozCancelFullScreen():document.webkitExitFullscreen&& +document.webkitExitFullscreen():b.requestFullscreen?b.requestFullscreen():b.msRequestFullscreen?b.msRequestFullscreen():b.mozRequestFullScreen?b.mozRequestFullScreen():b.webkitRequestFullscreen&&b.webkitRequestFullscreen(Element.ALLOW_KEYBOARD_INPUT)};a.graph={};a.graph.containerId="popoto-graph";a.graph.hasGraphChanged=!0;a.graph.zoom=d3.behavior.zoom().scaleExtent([.1,10]);a.graph.WHEEL_ZOOM_ENABLED=!0;a.graph.TOOL_TAXONOMY="Show/hide taxonomy panel";a.graph.TOOL_CENTER="Center view";a.graph.TOOL_FULL_SCREEN= +"Full screen";a.graph.TOOL_RESET="Reset graph";a.graph.Events=Object.freeze({NODE_ROOT_ADD:"root.node.add",NODE_EXPAND_RELATIONSHIP:"node.expandRelationship"});a.graph.createGraphArea=function(){var b=d3.select("#"+a.graph.containerId),c=b.append("div").attr("class","ppt-toolbar");if(a.tools.RESET_GRAPH)c.append("span").attr("id","popoto-reset-menu").attr("class","ppt-menu reset").attr("title",a.graph.TOOL_RESET).on("click",a.tools.reset);if(a.taxonomy.isActive&&a.tools.TOGGLE_TAXONOMY)c.append("span").attr("id", +"popoto-taxonomy-menu").attr("class","ppt-menu taxonomy").attr("title",a.graph.TOOL_TAXONOMY).on("click",a.tools.toggleTaxonomy);if(a.tools.CENTER_GRAPH)c.append("span").attr("id","popoto-center-menu").attr("class","ppt-menu center").attr("title",a.graph.TOOL_CENTER).on("click",a.tools.center);if(a.tools.TOGGLE_FULL_SCREEN)c.append("span").attr("id","popoto-fullscreen-menu").attr("class","ppt-menu fullscreen").attr("title",a.graph.TOOL_FULL_SCREEN).on("click",a.tools.toggleFullScreen);b=b.append("svg").call(a.graph.zoom.on("zoom", +a.graph.rescale));b.on("dblclick.zoom",null).attr("class","ppt-svg-graph");if(!a.graph.WHEEL_ZOOM_ENABLED)b.on("wheel.zoom",null).on("mousewheel.zoom",null);a.graph.svg=b.append("svg:g");a.graph.svg.append("g").attr("id",a.graph.link.gID);a.graph.svg.append("g").attr("id",a.graph.node.gID);window.addEventListener("resize",a.graph.centerRootNode)};a.graph.centerRootNode=function(){a.graph.getRootNode().px=a.graph.getSVGWidth()/2;a.graph.getRootNode().py=a.graph.getSVGHeight()/2;a.update()};a.graph.getSVGWidth= +function(){return"undefined"==typeof a.graph.svg||a.graph.svg.empty()?(a.logger.debug("popoto.graph.svg is undefined or empty."),0):document.getElementById(a.graph.containerId).clientWidth};a.graph.getSVGHeight=function(){return"undefined"==typeof a.graph.svg||a.graph.svg.empty()?(a.logger.debug("popoto.graph.svg is undefined or empty."),0):document.getElementById(a.graph.containerId).clientHeight};a.graph.rescale=function(){a.graph.svg.attr("transform","translate("+d3.event.translate+") scale("+ +d3.event.scale+")")};a.graph.LINK_DISTANCE=150;a.graph.LINK_STRENGTH=1;a.graph.FRICTION=.8;a.graph.CHARGE=-1400;a.graph.THETA=.8;a.graph.GRAVITY=0;a.graph.rootNodeAddListeners=[];a.graph.nodeExpandRelationsipListeners=[];a.graph.createForceLayout=function(){a.graph.force=d3.layout.force().size([a.graph.getSVGWidth(),a.graph.getSVGHeight()]).linkDistance(function(b){return b.type===a.graph.link.LinkTypes.RELATION?3*a.graph.LINK_DISTANCE/2:a.graph.LINK_DISTANCE}).linkStrength(function(b){return b.linkStrength? +b.linkStrength:a.graph.LINK_STRENGTH}).friction(a.graph.FRICTION).charge(function(b){return b.charge?b.charge:a.graph.CHARGE}).theta(a.graph.THETA).gravity(a.graph.GRAVITY).on("tick",a.graph.tick);a.graph.force.drag().on("dragstart",function(a){d3.event.sourceEvent.stopPropagation()}).on("dragend",function(a){d3.event.sourceEvent.stopPropagation()})};a.graph.on=function(b,c){b===a.graph.Events.NODE_ROOT_ADD&&a.graph.rootNodeAddListeners.push(c);b===a.graph.Events.NODE_EXPAND_RELATIONSHIP&&a.graph.nodeExpandRelationsipListeners.push(c)}; +a.graph.addRootNode=function(b){0<a.graph.force.nodes().length&&a.logger.debug("popoto.graph.addRootNode is called but the graph is not empty.");a.graph.force.nodes().push({id:"0",type:a.graph.node.NodeTypes.ROOT,x:a.graph.getSVGWidth()/2,y:a.graph.getSVGHeight()/2,label:b,fixed:!0,internalLabel:a.graph.node.generateInternalLabel(b)});a.graph.rootNodeAddListeners.forEach(function(b){b(a.graph.getRootNode())})};a.graph.getRootNode=function(){return a.graph.force.nodes()[0]};a.graph.tick=function(){a.graph.svg.selectAll("#"+ +a.graph.link.gID+" > g").selectAll("path").attr("d",function(b){var c=a.graph.computeParentAngle(b.target),d=b.target.x+a.graph.link.RADIUS*Math.cos(c),e=b.target.y-a.graph.link.RADIUS*Math.sin(c),f=b.source.x-a.graph.link.RADIUS*Math.cos(c),c=b.source.y+a.graph.link.RADIUS*Math.sin(c);return b.source.x<=b.target.x?"M"+f+" "+c+"L"+d+" "+e:"M"+d+" "+e+"L"+f+" "+c});a.graph.svg.selectAll("#"+a.graph.node.gID+" > g").attr("transform",function(a){return"translate("+a.x+","+a.y+")"})};a.graph.link={}; +a.graph.link.RADIUS=25;a.graph.link.gID="popoto-glinks";a.graph.link.LinkTypes=Object.freeze({RELATION:0,VALUE:1});a.graph.link.updateLinks=function(){a.graph.link.svgLinkElements=a.graph.svg.select("#"+a.graph.link.gID).selectAll("g");a.graph.link.updateData();a.graph.link.removeElements();a.graph.link.addNewElements();a.graph.link.updateElements()};a.graph.link.updateData=function(){a.graph.link.svgLinkElements=a.graph.link.svgLinkElements.data(a.graph.force.links(),function(a){return a.id})};a.graph.link.removeElements= +function(){a.graph.link.svgLinkElements.exit().remove()};a.graph.link.addNewElements=function(){var b=a.graph.link.svgLinkElements.enter().append("g").attr("class","ppt-glink").on("mouseover",a.graph.link.mouseOverLink).on("mouseout",a.graph.link.mouseOutLink);b.append("path");b.append("text").attr("text-anchor","middle").attr("dy","-4").append("textPath").attr("class","ppt-textPath").attr("startOffset","50%")};a.graph.link.updateElements=function(){a.graph.link.svgLinkElements.attr("id",function(a){return"ppt-glink_"+ +a.id});a.graph.link.svgLinkElements.selectAll("path").attr("id",function(a){return"ppt-path_"+a.id}).attr("class",function(b){return b.type===a.graph.link.LinkTypes.VALUE?"ppt-link-value":0==b.target.count?"ppt-link-relation disabled":void 0!==b.target.value?"ppt-link-relation value":"ppt-link-relation"});a.graph.link.svgLinkElements.selectAll("text").attr("id",function(a){return"ppt-text_"+a.id}).attr("class",function(b){return b.type===a.graph.link.LinkTypes.VALUE?"ppt-link-text-value":0==b.target.count? +"ppt-link-text-relation disabled":void 0!==b.target.value?"ppt-link-text-relation value":"ppt-link-text-relation"}).selectAll(".ppt-textPath").attr("id",function(a){return"ppt-textpath_"+a.id}).attr("xlink:href",function(a){return"#ppt-path_"+a.id}).text(function(b){return a.provider.getLinkTextValue(b)})};a.graph.link.mouseOverLink=function(){d3.select(this).select("path").classed("ppt-link-hover",!0);d3.select(this).select("text").classed("ppt-link-hover",!0);if(a.queryviewer.isActive){var b=d3.select(this).data()[0]; +a.queryviewer.queryConstraintSpanElements.filter(function(a){return a.ref===b}).classed("hover",!0);a.queryviewer.querySpanElements.filter(function(a){return a.ref===b}).classed("hover",!0)}};a.graph.link.mouseOutLink=function(){d3.select(this).select("path").classed("ppt-link-hover",!1);d3.select(this).select("text").classed("ppt-link-hover",!1);if(a.queryviewer.isActive){var b=d3.select(this).data()[0];a.queryviewer.queryConstraintSpanElements.filter(function(a){return a.ref===b}).classed("hover", +!1);a.queryviewer.querySpanElements.filter(function(a){return a.ref===b}).classed("hover",!1)}};a.graph.node={};a.graph.node.gID="popoto-gnodes";a.graph.node.ELLIPSE_RX=50;a.graph.node.ELLIPSE_RY=25;a.graph.node.TEXT_Y=8;a.graph.node.BACK_CIRCLE_R=70;a.graph.node.NODE_MAX_CHARS=11;a.graph.node.PAGE_SIZE=10;a.graph.node.CountBox={x:16,y:33,w:52,h:19};a.graph.node.chooseWaiting=!1;a.graph.node.NodeTypes=Object.freeze({ROOT:0,CHOOSE:1,VALUE:2,GROUP:3});a.graph.node.idgen=0;a.graph.node.internalLabels= +{};a.graph.node.generateInternalLabel=function(b){b=b.toLowerCase().replace(/ /g,"");if(b in a.graph.node.internalLabels)a.graph.node.internalLabels[b]+=1;else return a.graph.node.internalLabels[b]=0,b;return b+a.graph.node.internalLabels[b]};a.graph.node.updateNodes=function(){a.graph.node.svgNodeElements||(a.graph.node.svgNodeElements=a.graph.svg.select("#"+a.graph.node.gID).selectAll("g"));a.graph.node.updateData();a.graph.node.removeElements();a.graph.node.addNewElements();a.graph.node.updateElements()}; +a.graph.node.updateData=function(){a.graph.node.svgNodeElements=a.graph.node.svgNodeElements.data(a.graph.force.nodes(),function(a){return a.id});a.graph.hasGraphChanged&&(a.graph.node.updateCount(),a.graph.hasGraphChanged=!1)};a.graph.node.updateCount=function(){var b=[],c=a.graph.force.nodes().filter(function(b){return b.type!==a.graph.node.NodeTypes.VALUE&&b.type!==a.graph.node.NodeTypes.GROUP});c.forEach(function(c){c=a.query.generateNodeCountCypherQuery(c);b.push({statement:c})});a.logger.info("Count nodes ==> "); +a.rest.post({statements:b}).done(function(b){b.errors&&0<b.errors.length&&a.logger.error("Cypher query error:"+JSON.stringify(b.errors));if(b.results&&0<b.results.length)for(var e=0;e<c.length;e++)c[e].count=b.results[e].data[0].row[0];else c.forEach(function(a){a.count=0});a.graph.node.updateElements();a.graph.link.updateElements()}).fail(function(b,e,f){a.logger.error(e+': error while accessing Neo4j server on URL:"'+a.rest.CYPHER_URL+'" defined in "popoto.rest.CYPHER_URL" property: '+f);c.forEach(function(a){a.count= +0});a.graph.node.updateElements();a.graph.link.updateElements()})};a.graph.node.removeElements=function(){var b=a.graph.node.svgNodeElements.exit();b.filter(function(a){return!a.parent}).remove();b.filter(function(a){return a.parent}).transition().duration(300).attr("transform",function(a){return"translate("+a.parent.x+","+a.parent.y+")"}).remove()};a.graph.node.addNewElements=function(){var b=a.graph.node.svgNodeElements.enter().append("g").on("click",a.graph.node.nodeClick).on("mouseover",a.graph.node.mouseOverNode).on("mouseout", +a.graph.node.mouseOutNode);b.filter(function(b){return b.type!==a.graph.node.NodeTypes.VALUE}).on("contextmenu",a.graph.node.clearSelection);b.filter(function(b){return b.type===a.graph.node.NodeTypes.VALUE}).on("contextmenu",function(){d3.event.preventDefault()});b.append("title").attr("class","ppt-svg-title");a.graph.node.addBackgroundElements(b);a.graph.node.addMiddlegroundElements(b);a.graph.node.addForegroundElements(b)};a.graph.node.addBackgroundElements=function(b){b.append("g").attr("class", +"ppt-g-node-background").append("circle").attr("class",function(b){var d="ppt-node-background-circle";void 0!==b.value?d+=" selected-value":b.type===a.graph.node.NodeTypes.ROOT?d+=" root":b.type===a.graph.node.NodeTypes.CHOOSE?d+=" choose":b.type===a.graph.node.NodeTypes.VALUE?d+=" value":b.type===a.graph.node.NodeTypes.GROUP&&(d+=" group");return d}).style("fill-opacity",0).attr("r",a.graph.node.BACK_CIRCLE_R)};a.graph.node.addMiddlegroundElements=function(a){a.append("g").attr("class","ppt-g-node-middleground")}; +a.graph.node.addForegroundElements=function(b){b=b.append("g").attr("class","ppt-g-node-foreground");var c=b.filter(function(b){return b.type!==a.graph.node.NodeTypes.VALUE}).append("g").attr("class","ppt-rel-plus-icon");c.append("title").text("Add relationship");c.append("circle").attr("class","ppt-rel-plus-background").attr("cx","32").attr("cy","-43").attr("r","16");c.append("path").attr("class","ppt-rel-plus-path").attr("d","M 40,-45 35,-45 35,-50 30,-50 30,-45 25,-45 25,-40 30,-40 30,-35 35,-35 35,-40 40,-40 z"); +c.on("mouseover",function(){d3.select(this).select(".ppt-rel-plus-background").transition().style("fill-opacity",.5)}).on("mouseout",function(){d3.select(this).select(".ppt-rel-plus-background").transition().style("fill-opacity",0)}).on("click",function(){d3.event.stopPropagation();a.graph.node.expandRelationship.call(this)});c=b.filter(function(b){return b.type!==a.graph.node.NodeTypes.VALUE}).append("g").attr("class","ppt-rel-minus-icon");c.append("title").text("Remove relationship");c.append("circle").attr("class", +"ppt-rel-minus-background").attr("cx","32").attr("cy","-43").attr("r","16");c.append("path").attr("class","ppt-rel-minus-path").attr("d","M 40,-45 25,-45 25,-40 40,-40 z");c.on("mouseover",function(){d3.select(this).select(".ppt-rel-minus-background").transition().style("fill-opacity",.5)}).on("mouseout",function(){d3.select(this).select(".ppt-rel-minus-background").transition().style("fill-opacity",0)}).on("click",function(){d3.event.stopPropagation();a.graph.node.collapseRelationship.call(this)}); +var c=b.filter(function(b){return b.type===a.graph.node.NodeTypes.ROOT||b.type===a.graph.node.NodeTypes.CHOOSE}).append("g").attr("class","ppt-node-foreground-g-arrows"),d=c.append("g");d.append("circle").attr("class","ppt-larrow").attr("cx","-43").attr("cy","-23").attr("r","17");d.append("path").attr("class","ppt-arrow").attr("d","m -44.905361,-23 6.742,-6.742 c 0.81,-0.809 0.81,-2.135 0,-2.944 l -0.737,-0.737 c -0.81,-0.811 -2.135,-0.811 -2.945,0 l -8.835,8.835 c -0.435,0.434 -0.628,1.017 -0.597,1.589 -0.031,0.571 0.162,1.154 0.597,1.588 l 8.835,8.834 c 0.81,0.811 2.135,0.811 2.945,0 l 0.737,-0.737 c 0.81,-0.808 0.81,-2.134 0,-2.943 l -6.742,-6.743 z"); +d.on("click",function(b){d3.event.stopPropagation();1<b.page&&(b.page--,a.graph.node.collapseNode(b),a.graph.node.expandNode(b))});c=c.append("g");c.append("circle").attr("class","ppt-rarrow").attr("cx","43").attr("cy","-23").attr("r","17");c.append("path").attr("class","ppt-arrow").attr("d","m 51.027875,-24.5875 -8.835,-8.835 c -0.811,-0.811 -2.137,-0.811 -2.945,0 l -0.738,0.737 c -0.81,0.81 -0.81,2.136 0,2.944 l 6.742,6.742 -6.742,6.742 c -0.81,0.81 -0.81,2.136 0,2.943 l 0.737,0.737 c 0.81,0.811 2.136,0.811 2.945,0 l 8.835,-8.836 c 0.435,-0.434 0.628,-1.017 0.597,-1.588 0.032,-0.569 -0.161,-1.152 -0.596,-1.586 z"); +c.on("click",function(b){d3.event.stopPropagation();b.page*a.graph.node.PAGE_SIZE<b.count&&(b.page++,a.graph.node.collapseNode(b),a.graph.node.expandNode(b))});b=b.filter(function(b){return b.type!==a.graph.node.NodeTypes.GROUP});b.append("rect").attr("x",a.graph.node.CountBox.x).attr("y",a.graph.node.CountBox.y).attr("width",a.graph.node.CountBox.w).attr("height",a.graph.node.CountBox.h).attr("class","ppt-count-box");b.append("text").attr("x",42).attr("y",48).attr("text-anchor","middle").attr("class", +"ppt-count-text")};a.graph.node.updateElements=function(){a.graph.node.svgNodeElements.attr("id",function(a){return"popoto-gnode_"+a.id});a.graph.node.svgNodeElements.selectAll(".ppt-svg-title").text(function(b){return a.provider.getTextValue(b)});a.graph.node.svgNodeElements.filter(function(b){return b.type!==a.graph.node.NodeTypes.ROOT}).call(a.graph.force.drag);a.graph.node.updateBackgroundElements();a.graph.node.updateMiddlegroundElements();a.graph.node.updateForegroundElements()};a.graph.node.updateBackgroundElements= +function(){a.graph.node.svgNodeElements.selectAll(".ppt-g-node-background").selectAll(".ppt-node-background-circle").attr("class",function(b){var c="ppt-node-background-circle";b.type===a.graph.node.NodeTypes.VALUE?c+=" value":b.type===a.graph.node.NodeTypes.GROUP?c+=" group":void 0!==b.value?b.type===a.graph.node.NodeTypes.ROOT?c+=" selected-root-value":b.type===a.graph.node.NodeTypes.CHOOSE&&(c+=" selected-value"):0==b.count?c+=" disabled":b.type===a.graph.node.NodeTypes.ROOT?c+=" root":b.type=== +a.graph.node.NodeTypes.CHOOSE&&(c+=" choose");return c}).attr("r",a.graph.node.BACK_CIRCLE_R)};a.graph.node.updateMiddlegroundElements=function(){var b=a.graph.node.svgNodeElements.selectAll(".ppt-g-node-middleground");b.selectAll("*").remove();b.filter(function(b){return a.provider.getNodeDisplayType(b)===a.provider.NodeDisplayTypes.IMAGE}).append("image").attr("class","ppt-node-image").attr("width",function(b){return a.provider.getImageWidth(b)}).attr("height",function(b){return a.provider.getImageHeight(b)}).attr("transform", +function(b){return"translate("+-a.provider.getImageWidth(b)/2+","+-a.provider.getImageHeight(b)/2+")"}).attr("xlink:href",function(b){return a.provider.getImagePath(b)});b.filter(function(b){return a.provider.getNodeDisplayType(b)===a.provider.NodeDisplayTypes.TEXT}).append("ellipse").attr("rx",a.graph.node.ELLIPSE_RX).attr("ry",a.graph.node.ELLIPSE_RY).attr("rx",a.graph.node.ELLIPSE_RX).attr("ry",a.graph.node.ELLIPSE_RY).attr("class",function(b){if(b.type===a.graph.node.NodeTypes.ROOT)return b.value? +"ppt-node-ellipse selected-root-value":0==b.count?"ppt-node-ellipse root disabled":"ppt-node-ellipse root";if(b.type===a.graph.node.NodeTypes.CHOOSE)return b.value?"ppt-node-ellipse selected-value":0==b.count?"ppt-node-ellipse choose disabled":"ppt-node-ellipse choose";if(b.type===a.graph.node.NodeTypes.VALUE)return"ppt-node-ellipse value";if(b.type===a.graph.node.NodeTypes.GROUP)return"ppt-node-ellipse group"});var c=b.filter(function(b){return a.provider.getNodeDisplayType(b)===a.provider.NodeDisplayTypes.SVG}).append("g").selectAll("path").data(function(b){return a.provider.getSVGPaths(b)}); +c.exit().remove();c.enter().append("path");b.selectAll("path").attr("d",function(a){return a.d}).attr("class",function(a){return a["class"]});b.filter(function(b){return a.provider.isTextDisplayed(b)}).append("text").attr("x",0).attr("y",a.graph.node.TEXT_Y).attr("text-anchor","middle").attr("y",a.graph.node.TEXT_Y).attr("class",function(b){switch(b.type){case a.graph.node.NodeTypes.CHOOSE:return void 0===b.value?0==b.count?"ppt-node-text-choose disabled":"ppt-node-text-choose":"ppt-node-text-choose selected-value"; +case a.graph.node.NodeTypes.GROUP:return"ppt-node-text-group";case a.graph.node.NodeTypes.ROOT:return void 0===b.value?0==b.count?"ppt-node-text-root disabled":"ppt-node-text-root":"ppt-node-text-root selected-value";case a.graph.node.NodeTypes.VALUE:return"ppt-node-text-value"}}).text(function(b){return a.provider.isTextDisplayed(b)?a.provider.getTextValue(b):""})};a.graph.node.updateForegroundElements=function(){var b=a.graph.node.svgNodeElements.selectAll(".ppt-g-node-foreground").selectAll(".ppt-node-foreground-g-arrows"); +b.classed("active",function(b){return b.valueExpanded&&b.data&&b.data.length>a.graph.node.PAGE_SIZE});b.selectAll(".ppt-larrow").classed("enabled",function(a){return 1<a.page});b.selectAll(".ppt-rarrow").classed("enabled",function(b){return b.data?b.page*a.graph.node.PAGE_SIZE<b.data.length:!1});b=a.graph.node.svgNodeElements.selectAll(".ppt-g-node-foreground");b.selectAll(".ppt-count-box").filter(function(b){return b.type!==a.graph.node.NodeTypes.CHOOSE}).classed("root",!0);b.selectAll(".ppt-count-box").filter(function(b){return b.type=== +a.graph.node.NodeTypes.CHOOSE}).classed("value",!0);b.selectAll(".ppt-count-box").classed("disabled",function(a){return 0==a.count});b.selectAll(".ppt-count-text").text(function(a){return null!=a.count?a.count:"..."}).classed("disabled",function(a){return 0==a.count});b.selectAll(".ppt-rel-plus-icon").classed("disabled",function(a){return a.linkExpanded||0==a.count||0==a.linkCount});b.selectAll(".ppt-rel-minus-icon").classed("disabled",function(a){return!a.linkExpanded||0==a.count||0==a.linkCount})}; +a.graph.node.mouseOverNode=function(){d3.event.preventDefault();d3.select(this).select(".ppt-g-node-background").selectAll("circle").transition().style("fill-opacity",.5);if(a.queryviewer.isActive){var b=d3.select(this).data()[0];a.queryviewer.queryConstraintSpanElements.filter(function(a){return a.ref===b}).classed("hover",!0);a.queryviewer.querySpanElements.filter(function(a){return a.ref===b}).classed("hover",!0)}};a.graph.node.mouseOutNode=function(){d3.event.preventDefault();d3.select(this).select(".ppt-g-node-background").selectAll("circle").transition().style("fill-opacity", +0);if(a.queryviewer.isActive){var b=d3.select(this).data()[0];a.queryviewer.queryConstraintSpanElements.filter(function(a){return a.ref===b}).classed("hover",!1);a.queryviewer.querySpanElements.filter(function(a){return a.ref===b}).classed("hover",!1)}};a.graph.node.nodeClick=function(){var b=d3.select(this).data()[0];a.logger.debug("nodeClick ("+b.label+")");if(b.type===a.graph.node.NodeTypes.VALUE)a.graph.node.valueNodeClick(b);else if(b.type===a.graph.node.NodeTypes.CHOOSE||b.type===a.graph.node.NodeTypes.ROOT)b.valueExpanded? +a.graph.node.collapseNode(b):a.graph.node.chooseNodeClick(b)};a.graph.node.collapseNode=function(b){if(b.valueExpanded){a.logger.debug("collapseNode ("+b.label+")");var c=a.graph.force.links().filter(function(c){return c.source===b&&c.type===a.graph.link.LinkTypes.VALUE});c.forEach(function(b){a.graph.force.nodes().splice(a.graph.force.nodes().indexOf(b.target),1)});for(var d=a.graph.force.links().length-1;0<=d;d--)0<=c.indexOf(a.graph.force.links()[d])&&a.graph.force.links().splice(d,1);b.type!== +a.graph.node.NodeTypes.ROOT&&(b.fixed=!1);b.parent&&b.parent.type!==a.graph.node.NodeTypes.ROOT&&(b.parent.fixed=!1);b.valueExpanded=!1;a.update()}else a.logger.debug("collapseNode called on an unexpanded node")};a.graph.node.valueNodeClick=function(b){a.logger.debug("valueNodeClick ("+b.label+")");b.parent.value=b;a.result.hasChanged=!0;a.graph.hasGraphChanged=!0;a.graph.node.collapseNode(b.parent)};a.graph.node.chooseNodeClick=function(b){a.logger.debug("chooseNodeClick ("+b.label+") with waiting state set to "+ +a.graph.node.chooseWaiting);a.graph.node.chooseWaiting||b.immutable||(a.graph.force.nodes().forEach(function(b){b.type!=a.graph.node.NodeTypes.ROOT&&b.type!=a.graph.node.NodeTypes.CHOOSE||!b.valueExpanded||a.graph.node.collapseNode(b)}),a.graph.node.chooseWaiting=!0,a.logger.info("Values ("+b.label+") ==> "),a.rest.post({statements:[{statement:a.query.generateValueQuery(b)}]}).done(function(c){b.id=++a.graph.node.idgen;b.data=a.graph.node.parseResultData(c);b.page=1;a.graph.node.expandNode(b);a.graph.node.chooseWaiting= +!1}).fail(function(b,d,e){a.graph.node.chooseWaiting=!1;a.logger.error(d+': error while accessing Neo4j server on URL:"'+a.rest.CYPHER_URL+'" defined in "popoto.rest.CYPHER_URL" property: '+e)}))};a.graph.node.parseResultData=function(a){for(var c=[],d=0;d<a.results[0].data.length;d++){for(var e={},f=0;f<a.results[0].columns.length;f++)e[a.results[0].columns[f]]=a.results[0].data[d].row[f];c.push(e)}return c};a.graph.computeParentAngle=function(a){var c=0;if(a.parent){var c=a.parent.x,d=a.parent.y, +e=a.x;a=a.y;var f=100/(Math.sqrt(Math.pow(c-e,2)+Math.pow(d-a,2))-100),c=((e+f*c)/(1+f)-e)/100;-1>c&&(c=-1);1<c&&(c=1);c=Math.acos(c);d>a&&(c=2*Math.PI-c)}return c};a.graph.node.expandNode=function(b){var c=b.page*a.graph.node.PAGE_SIZE,d=b.data.slice(c-a.graph.node.PAGE_SIZE,c),e=a.graph.computeParentAngle(b),f=1;d.forEach(function(c){var g;g=b.parent?360/(d.length+1)*f:360/d.length*f;var h=b.x+100*Math.cos(Math.PI/180*g-e);g=b.y+100*Math.sin(Math.PI/180*g-e);c={id:++a.graph.node.idgen,parent:b, +attributes:c,type:a.graph.node.NodeTypes.VALUE,label:b.label,count:c.count,x:h,y:g,internalID:c[a.query.NEO4J_INTERNAL_ID.queryInternalName]};a.graph.force.nodes().push(c);a.graph.force.links().push({id:"l"+ ++a.graph.node.idgen,source:b,target:c,type:a.graph.link.LinkTypes.VALUE});f++});b.fixed=!0;b.parent&&b.parent.type!==a.graph.node.NodeTypes.ROOT&&(b.parent.fixed=!0);b.valueExpanded=!0;a.update()};a.graph.node.expandRelationship=function(){d3.event.preventDefault();a.graph.nodeExpandRelationsipListeners.forEach(function(a){a(this)}); +var b=d3.select(this).data()[0];b.linkExpanded||a.graph.node.linkWaiting||b.valueExpanded||(a.graph.node.linkWaiting=!0,a.logger.info("Relations ("+b.label+") ==> "),a.rest.post({statements:[{statement:a.query.generateLinkQuery(b)}]}).done(function(c){var d=a.graph.node.parseResultData(c),d=d.filter(function(b){return a.query.filterRelation(b)});if(0>=d.length)b.linkExpanded=!0,b.linkCount=0,a.graph.hasGraphChanged=!0;else{var e=a.graph.computeParentAngle(b),f=1;d.forEach(function(c){var g;g=e?360/ +(d.length+1)*f:360/d.length*f;var h=b.x+100*Math.cos(Math.PI/180*g-e);g=b.y+100*Math.sin(Math.PI/180*g-e);var k=a.provider.getIsGroup(c),h={id:""+ ++a.graph.node.idgen,parent:b,type:k?a.graph.node.NodeTypes.GROUP:a.graph.node.NodeTypes.CHOOSE,label:c.label,fixed:!1,internalLabel:a.graph.node.generateInternalLabel(c.label),x:h,y:g};a.graph.force.nodes().push(h);a.graph.force.links().push({id:"l"+ ++a.graph.node.idgen,source:b,target:h,type:a.graph.link.LinkTypes.RELATION,label:c.relationship});f++}); +a.graph.hasGraphChanged=!0;b.linkExpanded=!0;b.linkCount=d.length}a.update();a.graph.node.linkWaiting=!1}).fail(function(b,d,e){a.logger.error(d+': error while accessing Neo4j server on URL:"'+a.rest.CYPHER_URL+'" defined in "popoto.rest.CYPHER_URL" property: '+e);a.graph.node.linkWaiting=!1}))};a.graph.node.collapseRelationship=function(){d3.event.preventDefault();var b=d3.select(this).data()[0];if(b.linkExpanded&&0<b.linkCount&&!a.graph.node.linkWaiting&&!b.valueExpanded){a.graph.force.nodes().forEach(function(b){b.type!== +a.graph.node.NodeTypes.CHOOSE&&b.type!==a.graph.node.NodeTypes.ROOT||!b.valueExpanded||a.graph.node.collapseNode(b)});var c=a.graph.force.links().filter(function(c){return c.source===b&&c.type===a.graph.link.LinkTypes.RELATION});c.forEach(function(b){a.graph.node.removeNode(b.target)});for(var d=a.graph.force.links().length-1;0<=d;d--)0<=c.indexOf(a.graph.force.links()[d])&&a.graph.force.links().splice(d,1);b.linkExpanded=!1;a.result.hasChanged=!0;a.graph.hasGraphChanged=!0;a.update()}};a.graph.node.removeNode= +function(b){var c=a.graph.force.links().filter(function(a){return a.source===b});c.forEach(function(b){a.graph.node.removeNode(b.target)});for(var d=a.graph.force.links().length-1;0<=d;d--)0<=c.indexOf(a.graph.force.links()[d])&&a.graph.force.links().splice(d,1);a.graph.force.nodes().splice(a.graph.force.nodes().indexOf(b),1)};a.graph.node.clearSelection=function(){d3.event.preventDefault();var b=d3.select(this).data()[0];a.graph.force.nodes().forEach(function(b){b.type!==a.graph.node.NodeTypes.CHOOSE&& +b.type!==a.graph.node.NodeTypes.ROOT||!b.valueExpanded||a.graph.node.collapseNode(b)});null==b.value||b.immutable||(delete b.value,a.result.hasChanged=!0,a.graph.hasGraphChanged=!0,a.update())};a.queryviewer={};a.queryviewer.containerId="popoto-query";a.queryviewer.QUERY_STARTER="I'm looking for";a.queryviewer.CHOOSE_LABEL="choose";a.queryviewer.createQueryArea=function(){var b="#"+a.queryviewer.containerId;a.queryviewer.queryConstraintSpanElements=d3.select(b).append("p").attr("class","ppt-query-constraint-elements").selectAll(".queryConstraintSpan"); +a.queryviewer.querySpanElements=d3.select(b).append("p").attr("class","ppt-query-elements").selectAll(".querySpan")};a.queryviewer.updateQuery=function(){a.queryviewer.queryConstraintSpanElements=a.queryviewer.queryConstraintSpanElements.data([]);a.queryviewer.querySpanElements=a.queryviewer.querySpanElements.data([]);a.queryviewer.queryConstraintSpanElements.exit().remove();a.queryviewer.querySpanElements.exit().remove();a.queryviewer.queryConstraintSpanElements=a.queryviewer.queryConstraintSpanElements.data(a.queryviewer.generateConstraintData(a.graph.force.links(), +a.graph.force.nodes()));a.queryviewer.querySpanElements=a.queryviewer.querySpanElements.data(a.queryviewer.generateData(a.graph.force.links(),a.graph.force.nodes()));a.queryviewer.queryConstraintSpanElements.enter().append("span").on("contextmenu",a.queryviewer.rightClickSpan).on("click",a.queryviewer.clickSpan).on("mouseover",a.queryviewer.mouseOverSpan).on("mouseout",a.queryviewer.mouseOutSpan);a.queryviewer.querySpanElements.enter().append("span").on("contextmenu",a.queryviewer.rightClickSpan).on("click", +a.queryviewer.clickSpan).on("mouseover",a.queryviewer.mouseOverSpan).on("mouseout",a.queryviewer.mouseOutSpan);a.queryviewer.queryConstraintSpanElements.attr("id",function(a){return a.id}).attr("class",function(b){return b.isLink?"ppt-span-link":b.type===a.graph.node.NodeTypes.ROOT?"ppt-span-root":b.type===a.graph.node.NodeTypes.CHOOSE?b.ref.value?"ppt-span-value":"ppt-span-choose":b.type===a.graph.node.NodeTypes.VALUE?"ppt-span-value":b.type===a.graph.node.NodeTypes.GROUP?"ppt-span-group":"ppt-span"}).text(function(a){return a.term+ +" "});a.queryviewer.querySpanElements.attr("id",function(a){return a.id}).attr("class",function(b){return b.isLink?"ppt-span-link":b.type===a.graph.node.NodeTypes.ROOT?"ppt-span-root":b.type===a.graph.node.NodeTypes.CHOOSE?b.ref.value?"ppt-span-value":"ppt-span-choose":b.type===a.graph.node.NodeTypes.VALUE?"ppt-span-value":b.type===a.graph.node.NodeTypes.GROUP?"ppt-span-group":"ppt-span"}).text(function(a){return a.term+" "})};a.queryviewer.generateConstraintData=function(b,c){var d=[],e=0;d.push({id:e++, +term:a.queryviewer.QUERY_STARTER});0<c.length&&d.push({id:e++,type:c[0].type,term:a.provider.getSemanticValue(c[0]),ref:c[0]});b.forEach(function(b){var c=b.source,g=b.target;b.type===a.graph.link.LinkTypes.RELATION&&g.type!==a.graph.node.NodeTypes.GROUP&&g.value&&(c.type===a.graph.node.NodeTypes.GROUP&&d.push({id:e++,type:c.type,term:a.provider.getSemanticValue(c),ref:c}),d.push({id:e++,isLink:!0,term:a.provider.getLinkSemanticValue(b),ref:b}),g.type!==a.graph.node.NodeTypes.GROUP&&(g.value?d.push({id:e++, +type:g.type,term:a.provider.getSemanticValue(g),ref:g}):d.push({id:e++,type:g.type,term:"<"+a.queryviewer.CHOOSE_LABEL+" "+a.provider.getSemanticValue(g)+">",ref:g})))});return d};a.queryviewer.generateData=function(b,c){var d=[],e=[],f=0;b.forEach(function(b){var c=b.source,h=b.target;h.type===a.graph.node.NodeTypes.GROUP&&e.push({id:f++,type:h.type,term:a.provider.getSemanticValue(h),ref:h});b.type!==a.graph.link.LinkTypes.RELATION||h.type===a.graph.node.NodeTypes.GROUP||h.value||(c.type===a.graph.node.NodeTypes.GROUP&& +d.push({id:f++,type:c.type,term:a.provider.getSemanticValue(c),ref:c}),d.push({id:f++,isLink:!0,term:a.provider.getLinkSemanticValue(b),ref:b}),h.type!==a.graph.node.NodeTypes.GROUP&&(h.value?d.push({id:f++,type:h.type,term:a.provider.getSemanticValue(h),ref:h}):d.push({id:f++,type:h.type,term:"<"+a.queryviewer.CHOOSE_LABEL+" "+a.provider.getSemanticValue(h)+">",ref:h})))});return d.concat(e)};a.queryviewer.mouseOverSpan=function(){d3.select(this).classed("hover",function(a){return a.ref});var b= +d3.select(this).data()[0];if(b.ref){var c=a.graph.svg.selectAll("#"+a.graph.link.gID+" > g").filter(function(a){return a===b.ref});c.select("path").classed("ppt-link-hover",!0);c.select("text").classed("ppt-link-hover",!0);a.graph.svg.selectAll("#"+a.graph.node.gID+" > g").filter(function(a){return a===b.ref}).select(".ppt-g-node-background").selectAll("circle").transition().style("fill-opacity",.5)}};a.queryviewer.rightClickSpan=function(){var b=d3.select(this).data()[0];if(!b.isLink&&b.ref){var c= +a.graph.svg.selectAll("#"+a.graph.node.gID+" > g").filter(function(a){return a===b.ref});c.on("contextmenu").call(c.node(),b.ref)}};a.queryviewer.clickSpan=function(){var b=d3.select(this).data()[0];if(!b.isLink&&b.ref){var c=a.graph.svg.selectAll("#"+a.graph.node.gID+" > g").filter(function(a){return a===b.ref});c.on("click").call(c.node(),b.ref)}};a.queryviewer.mouseOutSpan=function(){d3.select(this).classed("hover",!1);var b=d3.select(this).data()[0];if(b.ref){var c=a.graph.svg.selectAll("#"+a.graph.link.gID+ +" > g").filter(function(a){return a===b.ref});c.select("path").classed("ppt-link-hover",!1);c.select("text").classed("ppt-link-hover",!1);a.graph.svg.selectAll("#"+a.graph.node.gID+" > g").filter(function(a){return a===b.ref}).select(".ppt-g-node-background").selectAll("circle").transition().style("fill-opacity",0)}};a.cypherviewer={};a.cypherviewer.containerId="popoto-cypher";a.query={};a.query.RESULTS_PAGE_SIZE=100;a.query.VALUE_QUERY_LIMIT=1E3;a.query.USE_PARENT_RELATION=!1;a.query.USE_RELATION_DIRECTION= +!0;a.query.NEO4J_INTERNAL_ID=Object.freeze({queryInternalName:"NEO4JID"});a.query.filterRelation=function(a){return!0};a.query.generateTaxonomyCountQuery=function(b){var c=a.provider.getConstraintAttribute(b),d=[];a.provider.getPredefinedConstraints(b).forEach(function(a){d.push(a.replace(RegExp("\\$identifier","g"),"n"))});return c===a.query.NEO4J_INTERNAL_ID?"MATCH (n:`"+b+"`)"+(0<d.length?" WHERE "+d.join(" AND "):"")+" RETURN count(DISTINCT ID(n)) as count":"MATCH (n:`"+b+"`)"+(0<d.length?" WHERE "+ +d.join(" AND "):"")+" RETURN count(DISTINCT n."+c+") as count"};a.query.generateQueryElements=function(b,c,d,e){var f=[],l=[],g=a.query.USE_RELATION_DIRECTION?"->":"-";a.provider.getPredefinedConstraints(b.label).forEach(function(a){l.push(a.replace(RegExp("\\$identifier","g"),b.internalLabel))});if(b.value&&(e||b.immutable)){var h=a.provider.getConstraintAttribute(b.label);if(h===a.query.NEO4J_INTERNAL_ID)f.push("("+b.internalLabel+":`"+b.label+"`)"),l.push("ID("+b.internalLabel+") = "+b.value.internalID); +else{var k=b.value.attributes[h];"boolean"===typeof k||"number"===typeof k?f.push("("+b.internalLabel+":`"+b.label+"`{`"+h+"`:"+k+"})"):f.push("("+b.internalLabel+":`"+b.label+"`{`"+h+'`:"'+k+'"})')}}else f.push("("+b.internalLabel+":`"+b.label+"`)");d.forEach(function(d){var h=d.source,k=d.target;a.provider.getPredefinedConstraints(k.label).forEach(function(a){l.push(a.replace(RegExp("\\$identifier","g"),k.internalLabel))});if(k.value&&k!==c&&(e||b.immutable)){var m=a.provider.getConstraintAttribute(k.label), +n=k.value.attributes[m];m===a.query.NEO4J_INTERNAL_ID?(f.push("("+h.internalLabel+":`"+h.label+"`)-[:`"+d.label+"`]"+g+"("+k.internalLabel+":`"+k.label+"`)"),l.push("ID("+k.internalLabel+") = "+k.value.internalID)):"boolean"===typeof n||"number"===typeof n?f.push("("+h.internalLabel+":`"+h.label+"`)-[:`"+d.label+"`]"+g+"("+k.internalLabel+":`"+k.label+"`{`"+m+"`:"+n+"})"):f.push("("+h.internalLabel+":`"+h.label+"`)-[:`"+d.label+"`]"+g+"("+k.internalLabel+":`"+k.label+"`{`"+m+'`:"'+n+'"})')}else f.push("("+ +h.internalLabel+":`"+h.label+"`)-[:`"+d.label+"`]"+g+"("+k.internalLabel+":`"+k.label+"`)")});return{matchElements:f,whereElements:l}};a.query.getRelevantLinks=function(a,c,d){var e=d.slice(),f=[],l=[];e.forEach(function(a){(a.target.value||a.target===c)&&f.push(a)});f.forEach(function(a){e.splice(e.indexOf(a),1)});f.forEach(function(c){var d=c.source;for(c=!0;c;){var f=null;e.forEach(function(a){a.target===d&&(f=a)});null===f?c=!1:f.source===a?(l.push(f),e.splice(e.indexOf(f),1),c=!1):(l.push(f), +e.splice(e.indexOf(f),1),d=f.source)}});return f.concat(l)};a.query.getLinksToRoot=function(b,c){for(var d=[],e=b;e!==a.graph.getRootNode();){for(var f,l=0;l<c.length;l++){var g=c[l];if(g.target===e){f=g;break}}f&&(d.push(f),e=f.source)}return d};a.query.generateLinkQuery=function(b){var c=a.query.getLinksToRoot(b,a.graph.force.links()),d=a.query.generateQueryElements(a.graph.getRootNode(),b,c,!1),c=d.matchElements,e=[],d=d.whereElements,f=[];c.push("("+b.internalLabel+":`"+b.label+"`)-[r]"+(a.query.USE_RELATION_DIRECTION? +"->":"-")+"(x)");e.push("type(r) AS relationship");a.query.USE_PARENT_RELATION?e.push("head(labels(x)) AS label"):e.push("last(labels(x)) AS label");e.push("count(r) AS count");f.push("ORDER BY count(r) DESC");return"MATCH "+c.join(", ")+(0<d.length?" WHERE "+d.join(" AND "):"")+" RETURN "+e.join(", ")+" "+f.join(" ")};a.query.generateResultCypherQuery=function(){var b=a.graph.getRootNode(),c=a.query.generateQueryElements(b,b,a.query.getRelevantLinks(b,b,a.graph.force.links()),!0),d=c.matchElements, +e=[],c=c.whereElements,f=[],l=a.provider.getResultOrderByAttribute(b.label);if(l){var g=a.provider.isResultOrderAscending(b.label)?"ASC":"DESC";f.push("ORDER BY "+l+" "+g)}f.push("LIMIT "+a.query.RESULTS_PAGE_SIZE);for(var l=a.provider.getReturnAttributes(b.label),g=a.provider.getConstraintAttribute(b.label),h=0;h<l.length;h++){var k=l[h];k===a.query.NEO4J_INTERNAL_ID?k==g?e.push("ID("+b.internalLabel+") AS "+a.query.NEO4J_INTERNAL_ID.queryInternalName):e.push("COLLECT(DISTINCT ID("+b.internalLabel+ +")) AS "+a.query.NEO4J_INTERNAL_ID.queryInternalName):k==g?e.push(b.internalLabel+"."+k+" AS "+k):e.push("COLLECT(DISTINCT "+b.internalLabel+"."+k+") AS "+k)}return"MATCH "+d.join(", ")+(0<c.length?" WHERE "+c.join(" AND "):"")+" RETURN DISTINCT "+e.join(", ")+" "+f.join(" ")};a.query.generateResultCypherQueryCount=function(){var b=a.graph.getRootNode(),c=a.query.generateQueryElements(b,b,a.query.getRelevantLinks(b,b,a.graph.force.links()),!0),d=a.provider.getConstraintAttribute(b.label),e=c.matchElements, +f=[],c=c.whereElements,l=[];d===a.query.NEO4J_INTERNAL_ID?f.push("count(DISTINCT ID("+b.internalLabel+")) AS count"):f.push("count(DISTINCT "+b.internalLabel+"."+d+") AS count");return"MATCH "+e.join(", ")+(0<c.length?" WHERE "+c.join(" AND "):"")+" RETURN "+f.join(", ")+(0<l.length?" "+l.join(" "):"")};a.query.generateNodeCountCypherQuery=function(b){var c=a.query.generateQueryElements(a.graph.getRootNode(),b,a.query.getRelevantLinks(a.graph.getRootNode(),b,a.graph.force.links()),!0),d=c.matchElements, +c=c.whereElements,e=[],f=a.provider.getConstraintAttribute(b.label);f===a.query.NEO4J_INTERNAL_ID?e.push("count(DISTINCT ID("+b.internalLabel+")) as count"):e.push("count(DISTINCT "+b.internalLabel+"."+f+") as count");return"MATCH "+d.join(", ")+(0<c.length?" WHERE "+c.join(" AND "):"")+" RETURN "+e.join(", ")};a.query.generateValueQuery=function(b){var c=a.graph.getRootNode(),d=a.query.generateQueryElements(c,b,a.query.getRelevantLinks(c,b,a.graph.force.links()),!0),e=d.matchElements,f=[],d=d.whereElements, +l=[],g=a.provider.getValueOrderByAttribute(b.label);if(g){var h=a.provider.isValueOrderAscending(b.label)?"ASC":"DESC";f.push("ORDER BY "+g+" "+h)}f.push("LIMIT "+a.query.VALUE_QUERY_LIMIT);for(var g=a.provider.getReturnAttributes(b.label),h=a.provider.getConstraintAttribute(b.label),k=0;k<g.length;k++)g[k]===a.query.NEO4J_INTERNAL_ID?g[k]==h?l.push("ID("+b.internalLabel+") AS "+a.query.NEO4J_INTERNAL_ID.queryInternalName):l.push("COLLECT (DISTINCT ID("+b.internalLabel+")) AS "+a.query.NEO4J_INTERNAL_ID.queryInternalName): +g[k]==h?l.push(b.internalLabel+"."+g[k]+" AS "+g[k]):l.push("COLLECT(DISTINCT "+b.internalLabel+"."+g[k]+") AS "+g[k]);b=a.provider.getConstraintAttribute(c.label);b===a.query.NEO4J_INTERNAL_ID?l.push("count(DISTINCT ID("+c.internalLabel+")) AS count"):l.push("count(DISTINCT "+c.internalLabel+"."+b+") AS count");return"MATCH "+e.join(", ")+(0<d.length?" WHERE "+d.join(" AND "):"")+" RETURN DISTINCT "+l.join(", ")+" "+f.join(" ")};a.result={};a.result.containerId="popoto-results";a.result.hasChanged= +!0;a.result.resultCountListeners=[];a.result.resultListeners=[];a.result.onTotalResultCount=function(b){a.result.resultCountListeners.push(b)};a.result.onResultReceived=function(b){a.result.resultListeners.push(b)};a.result.parseResultData=function(b){var c=[];if(b.results&&0<b.results.length)for(var d=0;d<b.results[0].data.length;d++){for(var e={resultIndex:d,label:a.graph.getRootNode().label,attributes:{}},f=0;f<b.results[0].columns.length;f++)e.attributes[b.results[0].columns[f]]=""+b.results[0].data[d].row[f]; +c.push(e)}return c};a.result.updateResults=function(){if(a.result.hasChanged){var b=a.query.generateResultCypherQuery();a.cypherviewer.isActive&&d3.select("#"+a.cypherviewer.containerId).text(b.split("RETURN")[0]+" RETURN "+a.graph.getRootNode().internalLabel);a.logger.info("Results ==> ");a.rest.post({statements:[{statement:b}]}).done(function(b){b.errors&&0<b.errors.length&&a.logger.error("Cypher query error:"+JSON.stringify(b.errors));var d=a.result.parseResultData(b);a.result.resultListeners.forEach(function(a){a(d)}); +a.result.isActive&&(b=d3.select("#"+a.result.containerId).selectAll(".ppt-result").data([]),b.exit().remove(),b=d3.select("#"+a.result.containerId).selectAll(".ppt-result").data(d,function(a){return a.resultIndex}),b.enter().append("p").attr("class","ppt-result").attr("id",function(a){return"popoto-result-"+a.resultIndex}).each(function(b){a.provider.getDisplayResultFunction(b.label)(d3.select(this))}));a.result.hasChanged=!1}).fail(function(b,d,e){a.logger.error(d+': error while accessing Neo4j server on URL:"'+ +a.rest.CYPHER_URL+'" defined in "popoto.rest.CYPHER_URL" property: '+e);a.result.resultListeners.forEach(function(a){a([])})});0<a.result.resultCountListeners.length&&(a.logger.info("Results count ==> "),a.rest.post({statements:[{statement:a.query.generateResultCypherQueryCount()}]}).done(function(b){b.errors&&0<b.errors.length&&a.logger.error("Cypher query error:"+JSON.stringify(b.errors));var d=0;b.results&&0<b.results.length&&(d=b.results[0].data[0].row[0]);a.result.resultCountListeners.forEach(function(a){a(d)})}).fail(function(b, +d,e){a.logger.error(d+': error while accessing Neo4j server on URL:"'+a.rest.CYPHER_URL+'" defined in "popoto.rest.CYPHER_URL" property: '+e);a.result.resultCountListeners.forEach(function(a){a(0)})}))}};a.provider={};a.provider.linkProvider={};a.provider.taxonomyProvider={};a.provider.nodeProviders={};a.provider.getLinkTextValue=function(b){if(a.provider.linkProvider.hasOwnProperty("getLinkTextValue"))return a.provider.linkProvider.getLinkTextValue(b);if(a.provider.DEFAULT_LINK_PROVIDER.hasOwnProperty("getLinkTextValue"))return a.provider.DEFAULT_LINK_PROVIDER.getLinkTextValue(b); +a.logger.error("No provider defined for getLinkTextValue")};a.provider.getLinkSemanticValue=function(b){if(a.provider.linkProvider.hasOwnProperty("getLinkSemanticValue"))return a.provider.linkProvider.getLinkSemanticValue(b);if(a.provider.DEFAULT_LINK_PROVIDER.hasOwnProperty("getLinkSemanticValue"))return a.provider.DEFAULT_LINK_PROVIDER.getLinkSemanticValue(b);a.logger.error("No provider defined for getLinkSemanticValue")};a.provider.DEFAULT_LINK_PROVIDER=Object.freeze({getLinkTextValue:function(b){return b.type=== +a.graph.link.LinkTypes.VALUE?a.provider.isTextDisplayed(b.target)?"":a.provider.getTextValue(b.target):b.label},getLinkSemanticValue:function(b){return a.provider.getLinkTextValue(b)}});a.provider.linkProvider=a.provider.DEFAULT_LINK_PROVIDER;a.provider.getTaxonomyTextValue=function(b){if(a.provider.taxonomyProvider.hasOwnProperty("getTextValue"))return a.provider.taxonomyProvider.getTextValue(b);if(a.provider.DEFAULT_TAXONOMY_PROVIDER.hasOwnProperty("getTextValue"))return a.provider.DEFAULT_TAXONOMY_PROVIDER.getTextValue(b); +a.logger.error("No provider defined for taxonomy getTextValue")};a.provider.DEFAULT_TAXONOMY_PROVIDER=Object.freeze({getTextValue:function(a){return a}});a.provider.taxonomyProvider=a.provider.DEFAULT_TAXONOMY_PROVIDER;a.provider.NodeDisplayTypes=Object.freeze({TEXT:0,IMAGE:1,SVG:2});a.provider.getProvider=function(b){if(void 0===b)a.logger.error("Node label is undefined, no label provider can be found.");else{if(!a.provider.nodeProviders.hasOwnProperty(b)){a.logger.debug("No direct provider found for label "+ +b);for(var c in a.provider.nodeProviders)if(a.provider.nodeProviders.hasOwnProperty(c)){var d=a.provider.nodeProviders[c];if(d.hasOwnProperty("children")&&-1<d.children.indexOf(b)){a.logger.debug("No provider is defined for label ("+b+"), parent ("+c+") will be used");c={parent:c};for(var e in d)d.hasOwnProperty(e)&&"children"!=e&&"parent"!=e&&(c[e]=d[e]);a.provider.nodeProviders[b]=c;return a.provider.nodeProviders[b]}}a.logger.debug("No label provider defined for label ("+b+") default one will be created from popoto.provider.DEFAULT_PROVIDER"); +a.provider.nodeProviders[b]={};for(var f in a.provider.DEFAULT_PROVIDER)a.provider.DEFAULT_PROVIDER.hasOwnProperty(f)&&(a.provider.nodeProviders[b][f]=a.provider.DEFAULT_PROVIDER[f])}return a.provider.nodeProviders[b]}};a.provider.getProperty=function(b,c){var d=a.provider.getProvider(b);if(!d.hasOwnProperty(c)){for(var e=d,f=!1;e.hasOwnProperty("parent")&&!f;)e=a.provider.getProvider(e.parent),e.hasOwnProperty(c)&&(d[c]=e[c],f=!0);f||(a.logger.debug('No "'+c+'" property found for node label provider ('+ +b+"), default value will be used"),a.provider.DEFAULT_PROVIDER.hasOwnProperty(c)?d[c]=a.provider.DEFAULT_PROVIDER[c]:a.logger.error('No default value for "'+c+'" property found for label provider ('+b+")"))}return d[c]};a.provider.getIsSearchable=function(b){return a.provider.getProperty(b,"isSearchable")};a.provider.getReturnAttributes=function(b){var c=a.provider.getProvider(b),d={};if(c.hasOwnProperty("returnAttributes"))for(var e=0;e<c.returnAttributes.length;e++)c.returnAttributes[e]===a.query.NEO4J_INTERNAL_ID? +d[a.query.NEO4J_INTERNAL_ID.queryInternalName]=!0:d[c.returnAttributes[e]]=!0;for(;c.hasOwnProperty("parent");)if(c=a.provider.getProvider(c.parent),c.hasOwnProperty("returnAttributes"))for(e=0;e<c.returnAttributes.length;e++)c.returnAttributes[e]===a.query.NEO4J_INTERNAL_ID?d[a.query.NEO4J_INTERNAL_ID.queryInternalName]=!0:d[c.returnAttributes[e]]=!0;if(a.provider.DEFAULT_PROVIDER.hasOwnProperty("returnAttributes"))for(c=0;c<a.provider.DEFAULT_PROVIDER.returnAttributes.length;c++)a.provider.DEFAULT_PROVIDER.returnAttributes[c]!== +a.query.NEO4J_INTERNAL_ID&&(d[a.provider.DEFAULT_PROVIDER.returnAttributes[c]]=!0);b=a.provider.getConstraintAttribute(b);b===a.query.NEO4J_INTERNAL_ID?d[a.query.NEO4J_INTERNAL_ID.queryInternalName]=!0:d[b]=!0;b=[];for(var f in d)d.hasOwnProperty(f)&&(f==a.query.NEO4J_INTERNAL_ID.queryInternalName?b.push(a.query.NEO4J_INTERNAL_ID):b.push(f));0>=b.length&&b.push(a.query.NEO4J_INTERNAL_ID);return b};a.provider.getConstraintAttribute=function(b){return a.provider.getProperty(b,"constraintAttribute")}; +a.provider.getPredefinedConstraints=function(b){return a.provider.getProperty(b,"getPredefinedConstraints")()};a.provider.getValueOrderByAttribute=function(b){return a.provider.getProperty(b,"valueOrderByAttribute")};a.provider.isValueOrderAscending=function(b){return a.provider.getProperty(b,"isValueOrderAscending")};a.provider.getResultOrderByAttribute=function(b){return a.provider.getProperty(b,"resultOrderByAttribute")};a.provider.isResultOrderAscending=function(b){return a.provider.getProperty(b, +"isResultOrderAscending")};a.provider.getTextValue=function(b){return a.provider.getProperty(b.label,"getTextValue")(b)};a.provider.getTextValue=function(b){return a.provider.getProperty(b.label,"getTextValue")(b)};a.provider.getSemanticValue=function(b){return a.provider.getProperty(b.label,"getSemanticValue")(b)};a.provider.getSVGPaths=function(b){return a.provider.getProperty(b.label,"getSVGPaths")(b)};a.provider.isTextDisplayed=function(b){return a.provider.getProperty(b.label,"getIsTextDisplayed")(b)}; +a.provider.getIsGroup=function(b){return a.provider.getProperty(b.label,"getIsGroup")(b)};a.provider.getNodeDisplayType=function(b){return a.provider.getProperty(b.label,"getDisplayType")(b)};a.provider.getImagePath=function(b){return a.provider.getProperty(b.label,"getImagePath")(b)};a.provider.getImageWidth=function(b){return a.provider.getProperty(b.label,"getImageWidth")(b)};a.provider.getImageHeight=function(b){return a.provider.getProperty(b.label,"getImageHeight")(b)};a.provider.getDisplayResultFunction= +function(b){return a.provider.getProperty(b,"displayResults")};a.provider.DEFAULT_PROVIDER=Object.freeze({isSearchable:!0,returnAttributes:[a.query.NEO4J_INTERNAL_ID],valueOrderByAttribute:"count",isValueOrderAscending:!1,resultOrderByAttribute:null,isResultOrderAscending:!0,constraintAttribute:a.query.NEO4J_INTERNAL_ID,getPredefinedConstraints:function(){return[]},getDisplayType:function(b){return a.provider.NodeDisplayTypes.TEXT},getIsGroup:function(a){return!1},getIsTextDisplayed:function(a){return!0}, +getTextValue:function(b){var c=a.provider.getProperty(b.label,"constraintAttribute");return(b.type===a.graph.node.NodeTypes.VALUE?c===a.query.NEO4J_INTERNAL_ID?""+b.internalID:""+b.attributes[c]:void 0===b.value?b.label:c===a.query.NEO4J_INTERNAL_ID?""+b.value.internalID:""+b.value.attributes[c]).substring(0,a.graph.node.NODE_MAX_CHARS)},getSemanticValue:function(b){var c=a.provider.getProperty(b.label,"constraintAttribute");return b.type===a.graph.node.NodeTypes.VALUE?c===a.query.NEO4J_INTERNAL_ID? +""+b.internalID:""+b.attributes[c]:void 0===b.value?b.label:c===a.query.NEO4J_INTERNAL_ID?""+b.value.internalID:""+b.value.attributes[c]},getImagePath:function(b){if(b.type===a.graph.node.NodeTypes.VALUE)return"css/image/node-yellow.png";if(void 0===b.value){if(b.type===a.graph.node.NodeTypes.ROOT)return"css/image/node-blue.png";if(b.type===a.graph.node.NodeTypes.CHOOSE)return"css/image/node-green.png";if(b.type===a.graph.node.NodeTypes.GROUP)return"css/image/node-black.png"}else return"css/image/node-orange.png"}, +getImageWidth:function(a){return 125},getImageHeight:function(a){return 125},displayResults:function(b){var c=b.data()[0],d=a.provider.getReturnAttributes(c.label),e=b.append("table").attr("class","ppt-result-table");d.forEach(function(a){var b=e.append("tr");b.append("th").text(function(){return a+":"});void 0!==c.attributes[a]&&b.append("td").text(function(b){return b.attributes[a]})})}});return a}();
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/popoto_dev/release-note.txt Fri Oct 02 01:08:46 2015 -0400 @@ -0,0 +1,87 @@ +popoto-0.0.a6 + 2015-06-21 + + - Added support of predefined constraints in node configuration. + + - Added better handling of query execution errors. + +popoto-0.0.a5 + 2015-04-25 + + - Modified default label provider to display all returned attributes with their value by default in the result list instead of constraint attribute only. + + - Added different CSS classes for ellipses when value is selected for root and choose nodes. Also added disabled style on root node if no results are found in the database. + +popoto-0.0.a4 + 2015-04-19 + + - Transition to transactional Cypher HTTP endpoint. Cypher queries are now executed using transactional HTTP endpoint instead of deprecated legacy API. + + - Count query optimization, all count queries are now sent on the same REST call using a list of statements. (better performance on distant databases) + + - Added new CSS styles for nodes and links when count is "0" (disabled node state) + + - Added new property "popoto.graph.WHEEL_ZOOM_ENABLED" to disable zoom with mouse wheel on graph. + + - Added properties to add/disable tool items in graph. + + - Introduced new property "popoto.query.USE_RELATION_DIRECTION" to define whether or not generated Cypher queries will use directed relationship. + + - Added a plus sign icon button on nodes to get relationships instead of right click. Right click is now only used to remove a selection. + + - Added a minus sign icon button on nodes after relation have been expanded. click on this button will remove all the relations from this node. + + - Added reset graph tool option. + + - Added different CSS classes on relation links to be able for example to differentiate links with value ("ppt-link-relation" and "ppt-link-relation value"). + + - Added a new property "popoto.graph.link.RADIUS" to define the radius around the node to start link drawing (nicer on transparent node images). + + - Refactored node svg generation to fully support dynamic type changes (e.g use SVG node type for node label and image for selectable values) + + - Added different CSS classes on node highlight background circle (shown on node hover) to be able to customize it depending on node type. + + - Added listener on root node add event to allow for example to set a specific value on root node when added. + + - Added immutable state on nodes to be able to add unchangeable constraint on graph. Immutable nodes value constraints are used in relations query which will avoid relation on nodes with 0 values. + + - Added configuration to allow filter of relations. This can be used to hide unwanted relation from the graph. + + - Added configuration to define whether the list of relation with same parent label should be grouped or separated using last child label with the property popoto.query.USE_PARENT_RELATION. + The generated Cypher query use head(labels(x)) or last(labels(x)) to get the relation target node label. + +popoto-0.0.a3 + 2015-03-26 + + - Fixed constraint generation in query for root node with non string attributes. (double quotes were always used in Cypher generation on root node constraint even for numeric and boolean values) + + - Added a taxonomy label provider and extracted a few internal labels to fully support localization. + + - Extracted node text y position in variable to be able to customize it + + - Extracted some internal labels to allow localization + + - Extracted popoto.graph.centerRootNode function to allow root node move after HTML component resize for example + + - Added node shadow highlight on node hover + + - Used text value on node title instead of semantic value + +popoto-0.0.a2 + 2015-03-16 + + - Updated AJAX request body to execute Cypher queries on Neo4j REST API with authentication support. + Neo4j 2.2 and GrapheneDB are now supported with this change. + Transition to the new transactional endpoint is not yet ready, legacy Cypher HTTP endpoint is still used in this version. + + - Added sort attribute in configuration for value query. + It is now possible to use the constraint attribute to sort the values displayed on node click instead of count (count is still used by default). + The order can also be specified to be ascending or descending. + + - Removed default returned internal Neo4j id if any other attribute is provided in configuration. + +Popoto.js 0.0.a1 + 2015-02-10 + + - First public release +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/popoto_dev/src/css/popotojs-svg.css Fri Oct 02 01:08:46 2015 -0400 @@ -0,0 +1,287 @@ +/* +* Copyright (C) 2014 Frederic Ciminera +* +* Popoto.js 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. +* +* Popoto.js 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 <http://www.gnu.org/licenses/>. +* +* contact@popotojs.com +*/ + +.ppt-svg-graph { + cursor: move; + min-height: 100px; + width: 100%; + height: 100%; + pointer-events: all; +} + +/******************Node Styles*************************/ +.ppt-node-ellipse { + stroke: #ffffff; + stroke-width: 4px; +} + +.ppt-node-ellipse.root { + fill: #2aa1d3; +} + +.ppt-node-ellipse.root.disabled { + fill: #2e3138; + stroke: #525863; +} + +.ppt-node-ellipse.choose { + fill: #8bb71a; +} + +.ppt-node-ellipse.choose.disabled { + fill: #2e3138; + stroke: #525863; +} + +.ppt-node-ellipse.value { + fill: #f0b017; +} + +.ppt-node-ellipse.selected-value { + fill: #ee4e10; +} + +.ppt-node-ellipse.selected-root-value { + fill: #8F5BCC; +} + +.ppt-node-ellipse.group { + fill: #525863; +} + +.ppt-node-ellipse.disabled { + fill: #2e3138; + stroke: #525863; +} + +/* Node background*/ +.ppt-g-node-background { + cursor: pointer; +} + +.ppt-node-background-circle { + fill-opacity: 0; +} + +.ppt-node-background-circle.root { + fill: #233E7E; +} + +.ppt-node-background-circle.choose { + fill: #628b1a; +} + +.ppt-node-background-circle.value { + fill: #c28a17; +} + +.ppt-node-background-circle.selected-value { + fill: #c24b30; +} + +.ppt-node-background-circle.selected-root-value { + fill: #765ab4; +} + +.ppt-node-background-circle.group { + fill: #3f4450; +} + +.ppt-node-background-circle.disabled { + fill: #3f4450; +} + +/* Node middleground */ +.ppt-g-node-middleground { + cursor: pointer; +} + +/* Node foreground */ +.ppt-g-node-foreground { + cursor: pointer; +} + +.ppt-count-box.value { + fill: #8bb71a; + stroke: #ffffff; + stroke-width: 2px; +} + +.ppt-count-box.root { + fill: #ee4e10; + stroke: #ffffff; + stroke-width: 2px; +} + +.ppt-count-box.root.disabled { + fill: #2e3138; + stroke: #525863; +} + +.ppt-count-box.value.disabled { + fill: #2e3138; + stroke: #525863; +} + +.ppt-count-text { + fill: white; +} + +.ppt-count-text.disabled { + fill: #525863; +} + +.ppt-rel-plus-icon { +} + +.ppt-rel-plus-icon.disabled { + display: none; +} + +.ppt-rel-plus-background { + fill: #f0b017; + fill-opacity: 0; +} + +.ppt-rel-plus-path { + fill: #ff0000; +} + +.ppt-rel-minus-icon { +} + +.ppt-rel-minus-icon.disabled { + display: none; +} + +.ppt-rel-minus-path { + fill: #ff0000; +} + +.ppt-rel-minus-background { + fill: #f0b017; + fill-opacity: 0; +} + +/******************Tool Styles*************************/ +.ppt-node-foreground-g-arrows { + display: none; +} + +.ppt-node-foreground-g-arrows.active { + display: block; +} + +.ppt-arrow { + fill: #ffffff; +} + +.ppt-larrow { + stroke: #ffffff; + stroke-width: 4px; + fill: #525863; +} + +.ppt-rarrow { + stroke: #ffffff; + stroke-width: 4px; + fill: #525863; +} + +.ppt-larrow.enabled { + fill: #2aa1d3; +} + +.ppt-rarrow.enabled { + fill: #2aa1d3; +} + +/******************Link Styles*************************/ + +/* Links */ +.ppt-link-relation { + stroke: #2aa1d3; + stroke-width: 2px; + stroke-dasharray: 9, 5; +} + +.ppt-link-relation.value { + stroke: #ee4e10; +} + +.ppt-link-relation.value.ppt-link-hover { + stroke: #ee4e10; +} + +.ppt-link-relation.disabled { + stroke: #2e3138; + stroke-width: 2px; + stroke-dasharray: 9, 5; +} + +.ppt-link-value { + stroke: #525863; + stroke-width: 2px; + stroke-dasharray: 9, 5; +} + +.ppt-link-hover { + stroke: #ee4e10; +} + +.ppt-link-text-relation { + fill: #ffffff; +} + +.ppt-link-text-relation.value { + fill: #ffffff; +} + +.ppt-link-text-relation.disabled { + fill: #525863; +} + +.ppt-link-text-value { + fill: #525863; +} + +/* text in nodes*/ +.ppt-node-text-root { + fill: #ffffff; +} + +.ppt-node-text-root.disabled { + fill: #525863; +} + +.ppt-node-text-choose { + fill: #ffffff; +} + +.ppt-node-text-choose.disabled { + fill: #525863; +} + +.ppt-node-text-value { + fill: #ffffff; +} + +.ppt-node-text-group { + fill: #ffffff; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/popoto_dev/src/css/popotojs.css Fri Oct 02 01:08:46 2015 -0400 @@ -0,0 +1,354 @@ +/* +* Copyright (C) 2014 Frederic Ciminera +* +* Popoto.js 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. +* +* Popoto.js 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 <http://www.gnu.org/licenses/>. +* +* contact@popotojs.com +*/ + +/***********************************************************/ +/* Asap font*/ +@font-face { + font-family: "Asap"; + src: url("font/asap/Asap-Regular.otf"); +} + +@font-face { + font-family: "Asap"; + src: url("font/asap/Asap-Bold.otf"); + font-weight: bold; +} + +@font-face { + font-family: "Asap"; + src: url("font/asap/Asap-Italic.otf"); + font-style: italic; +} + +@font-face { + font-family: "Asap"; + src: url("font/asap/Asap-BoldItalic.otf"); + font-weight: bold; + font-style: italic; +} + +/**********************************************************************************/ +.ppt-body { + background-color: #2e3138; + margin: 22px; + font-family: Asap, sans-serif; + color: #ffffff; +} + +/* Main HTML container element containing the taxonomy filter and graph */ +.ppt-container-graph { + background-color: #22252a; + height: 750px; + padding: 0 0 0; + border-bottom-right-radius: 5px 5px; + border-bottom-left-radius: 5px 5px; + overflow: hidden; +} + +/**************************/ +/* Taxonomy Filter*/ +.ppt-taxo-nav { + overflow: auto; + padding: 18px 35px 18px 18px; + background-color: #444951; + height: 100%; + float: left; + white-space: nowrap; +} + +.ppt-taxo-nav.disabled { + display: none; +} + +.ppt-taxo-nav ul { + list-style-type: none; + display: block; + vertical-align: top; /* | top | bottom */ + padding: 0 0 0 10px; + margin: 0; +} + +.ppt-taxo-nav li { +} + +.ppt-taxo-nav li img { + vertical-align: middle; /* | top | bottom */ +} + +/**************************/ +/* Div containing SVG element*/ +.ppt-div-graph { + position: relative; + background-color: #22252a; + height: 100%; + padding: 0; + border-bottom-right-radius: 5px 5px; + overflow: hidden; +} + +.ppt-div-graph:-webkit-full-screen { + width: 100%; + height: 100%; +} + +.ppt-div-graph:fullscreen { + width: 100%; + height: 100%; +} + +/**********************************************************************************/ + +.ppt-header { + padding-left: 16px; + padding-right: 16px; + background-color: #525863; + border-radius: 5px 5px; + height: 70px; + min-width: 560px; + line-height: 70px; + font-weight: bold; + font-size: 22px; +} + +.ppt-section-header { + min-width: 560px; + padding-left: 18px; + padding-right: 18px; + background-color: #525863; + height: 68px; + line-height: 67px; + margin-top: 22px; + border-top-right-radius: 5px 5px; + border-top-left-radius: 5px 5px; + font-weight: bold; +} + +.ppt-section-tips { + min-width: 560px; + padding-left: 18px; + padding-right: 18px; + background-color: #525863; + margin-top: 22px; + border-top-left-radius: 5px; + border-top-right-radius: 5px; + font-size: 14px; + line-height: 35px; +} + +.ppt-section-tips a { + color: #8bb71a; +} + +.ppt-section-tips p { + margin-bottom: 0; + margin-top: 0; +} + +.ppt-toolbar { + padding: 12px; + position: absolute; + right: 0; +} + +.ppt-header-span { + color: #8bb71a; +} + +.ppt-section-main { +} + +.ppt-container-query { + text-align: center; + margin-top: 22px; + min-width: 560px; + background-color: #22252a; + border-radius: 5px 5px; + padding: 18px; +} + +.ppt-container-cypher { + text-align: center; + margin-top: 22px; + min-width: 560px; + background-color: #22252a; + border-radius: 5px 5px; + padding: 18px; +} + +.ppt-container-results { + width: 100%; + float: left; + min-width: 300px; + background-color: #22252a; + padding: 0; + border-bottom-right-radius: 5px 5px; + border-bottom-left-radius: 5px 5px; + overflow: auto; +} + +.ppt-footer { + padding-left: 16px; + padding-right: 16px; + background-color: #525863; + border-radius: 5px 5px; + + height: 70px; + min-width: 560px; + line-height: 70px; + + font-weight: bold; + font-size: 22px; +} + +/*****************************/ + +.ppt-menu { + width: 32px; + height: 32px; + display: inline-block; + vertical-align: middle; + cursor: pointer; + margin-left: 12px; + background: url("image/tools.png") no-repeat 0 0; +} + +.ppt-menu.taxonomy { + background-position: 0 0; +} + +.ppt-menu.reset { + background-position: -288px 0; +} + +.ppt-menu.fullscreen { + background-position: -256px 0; +} + +.ppt-menu.center { + background-position: -96px 0; +} + +.ppt-menu.taxonomy:hover { + background-position: 0 -32px; +} + +.ppt-menu.reset:hover { + background-position: -288px -32px; +} + +.ppt-menu.fullscreen:hover { + background-position: -256px -32px; +} + +.ppt-menu.center:hover { + background-position: -96px -32px; +} + +.ppt-count { + cursor: pointer; + color: #2aa1d3; +} + +.ppt-label { + cursor: pointer; +} + +.ppt-label:hover { + color: #f0b017; +} + +.ppt-result { + background-color: #444951; + padding: 9px 18px; + margin: 1px 0 0; +} + +.ppt-result:hover { + background-color: #525863; +} + +.ppt-result-table { +} + +.ppt-result-table th,td { + text-align: left; +} +/****************** Query span Styles *************************/ + +/* P elements containing query constraints */ +.ppt-query-constraint-elements { +} + +/* P elements containing query inactive constraints */ +.ppt-query-elements { +} + +.ppt-span { + color: #ffffff; +} + +.ppt-span-link { + color: #ffffff; +} + +.ppt-span-root { + color: #2aa1d3; + cursor: pointer; +} + +.ppt-span-choose { + color: #8bb71a; + cursor: pointer; +} + +.ppt-span-group { + color: #8e8e8e; + cursor: pointer; +} + +.ppt-span-value { + color: #f0b017; + cursor: pointer; +} + +.ppt-span-link.hover { + color: #ee4e10; + font-weight: bold; +} + +.ppt-span-root.hover { + color: #ee4e10; + font-weight: bold; +} + +.ppt-span-choose.hover { + color: #ee4e10; + font-weight: bold; +} + +.ppt-span-group.hover { + color: #ee4e10; + font-weight: bold; +} + +.ppt-span-value.hover { + color: #ee4e10; + font-weight: bold; +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/popoto_dev/src/js/popoto.js Fri Oct 02 01:08:46 2015 -0400 @@ -0,0 +1,3766 @@ +/** + * Popoto.js is a JavaScript library built with D3.js providing a graph based search interface generated in HTML and SVG usable on any modern browser. + * This library generates an interactive graph query builder into any website or web based application to create dynamic queries on Neo4j databases and display the results. + * + * Copyright (C) 2014-2015 Frederic Ciminera + * + * 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 <http://www.gnu.org/licenses/>. + * + * contact@popotojs.com + */ +popoto = function () { + var popoto = { + version: "0.0-a6" + }; + + /** + * Main function to call to use Popoto.js. + * This function will create all the HTML content based on available IDs in the page. + * popoto.graph.containerId for the graph query builder. + * popoto.queryviewer.containerId for the query viewer. + * + * @param label Root label to use in the graph query builder. + */ + popoto.start = function (label) { + popoto.logger.info("Popoto " + popoto.version + " start."); + + if (typeof popoto.rest.CYPHER_URL == 'undefined') { + popoto.logger.error("popoto.rest.CYPHER_URL is not set but this property is required."); + } else { + // TODO introduce component generator mechanism instead for future plugin extensions + popoto.checkHtmlComponents(); + + if (popoto.taxonomy.isActive) { + popoto.taxonomy.createTaxonomyPanel(); + } + + if (popoto.graph.isActive) { + popoto.graph.createGraphArea(); + popoto.graph.createForceLayout(); + popoto.graph.addRootNode(label); + } + + if (popoto.queryviewer.isActive) { + popoto.queryviewer.createQueryArea(); + } + + popoto.update(); + } + }; + + /** + * Check in the HTML page the components to generate. + */ + popoto.checkHtmlComponents = function () { + var graphHTMLContainer = d3.select("#" + popoto.graph.containerId); + var taxonomyHTMLContainer = d3.select("#" + popoto.taxonomy.containerId); + var queryHTMLContainer = d3.select("#" + popoto.queryviewer.containerId); + var cypherHTMLContainer = d3.select("#" + popoto.cypherviewer.containerId); + var resultsHTMLContainer = d3.select("#" + popoto.result.containerId); + + if (graphHTMLContainer.empty()) { + popoto.logger.debug("The page doesn't contain a container with ID = \"" + popoto.graph.containerId + "\" no graph area will be generated. This ID is defined in popoto.graph.containerId property."); + popoto.graph.isActive = false; + } else { + popoto.graph.isActive = true; + } + + if (taxonomyHTMLContainer.empty()) { + popoto.logger.debug("The page doesn't contain a container with ID = \"" + popoto.taxonomy.containerId + "\" no taxonomy filter will be generated. This ID is defined in popoto.taxonomy.containerId property."); + popoto.taxonomy.isActive = false; + } else { + popoto.taxonomy.isActive = true; + } + + if (queryHTMLContainer.empty()) { + popoto.logger.debug("The page doesn't contain a container with ID = \"" + popoto.queryviewer.containerId + "\" no query viewer will be generated. This ID is defined in popoto.queryviewer.containerId property."); + popoto.queryviewer.isActive = false; + } else { + popoto.queryviewer.isActive = true; + } + + if (cypherHTMLContainer.empty()) { + popoto.logger.debug("The page doesn't contain a container with ID = \"" + popoto.cypherviewer.containerId + "\" no cypher query viewer will be generated. This ID is defined in popoto.cypherviewer.containerId property."); + popoto.cypherviewer.isActive = false; + } else { + popoto.cypherviewer.isActive = true; + } + + if (resultsHTMLContainer.empty()) { + popoto.logger.debug("The page doesn't contain a container with ID = \"" + popoto.result.containerId + "\" no result area will be generated. This ID is defined in popoto.result.containerId property."); + popoto.result.isActive = false; + } else { + popoto.result.isActive = true; + } + }; + + /** + * Function to call to update all the generated elements including svg graph, query viewer and generated results. + */ + popoto.update = function () { + popoto.updateGraph(); + + if (popoto.queryviewer.isActive) { + popoto.queryviewer.updateQuery(); + } + // Results are updated only if needed. + // If id found in html page or if result listeners have been added. + // In this case the query must be executed. + if (popoto.result.isActive || popoto.result.resultListeners.length > 0 || popoto.result.resultCountListeners.length > 0) { + popoto.result.updateResults(); + } + }; + + /** + * Function to call to update the graph only. + */ + popoto.updateGraph = function () { + if (popoto.graph.isActive) { + // Starts the D3.js force simulation. + // This method must be called when the layout is first created, after assigning the nodes and links. + // In addition, it should be called again whenever the nodes or links change. + popoto.graph.force.start(); + popoto.graph.link.updateLinks(); + popoto.graph.node.updateNodes(); + } + }; + + // REST ------------------------------------------------------------------------------------------------------------ + popoto.rest = {}; + + /** + * Default REST URL used to call Neo4j server with cypher queries to execute. + * This property should be updated to access to your own server. + * @type {string} + */ + popoto.rest.CYPHER_URL = "http://localhost:7474/db/data/transaction/commit"; + + /** + * Create JQuery ajax POST request to access Neo4j REST API. + * + * @param data data object containing Cypher query + * @returns {*} the JQuery ajax request object. + */ + popoto.rest.post = function (data) { + var strData = JSON.stringify(data); + popoto.logger.info("REST POST:" + strData); + + return $.ajax({ + type: "POST", + beforeSend: function (request) { + if (popoto.rest.AUTHORIZATION) { + request.setRequestHeader("Authorization", popoto.rest.AUTHORIZATION); + } + }, + url: popoto.rest.CYPHER_URL, + contentType: "application/json", + data: strData + }); + }; + + // LOGGER ----------------------------------------------------------------------------------------------------------- + popoto.logger = {}; + popoto.logger.LogLevels = Object.freeze({DEBUG: 0, INFO: 1, WARN: 2, ERROR: 3, NONE: 4}); + popoto.logger.LEVEL = popoto.logger.LogLevels.NONE; + popoto.logger.TRACE = false; + + /** + * Log a message on console depending on configured log levels. + * Level is define in popoto.logger.LEVEL property. + * If popoto.logger.TRACE is set to true, the stack trace is also added in log. + * @param logLevel Level of the message from popoto.logger.LogLevels. + * @param message Message to log. + */ + popoto.logger.log = function (logLevel, message) { + if (console && logLevel >= popoto.logger.LEVEL) { + if (popoto.logger.TRACE) { + message = message + "\n" + new Error().stack + } + switch (logLevel) { + case popoto.logger.LogLevels.DEBUG: + console.log(message); + break; + case popoto.logger.LogLevels.INFO: + console.log(message); + break; + case popoto.logger.LogLevels.WARN: + console.warn(message); + break; + case popoto.logger.LogLevels.ERROR: + console.error(message); + break; + } + } + }; + + /** + * Log a message in DEBUG level. + * @param message to log. + */ + popoto.logger.debug = function (message) { + popoto.logger.log(popoto.logger.LogLevels.DEBUG, message); + }; + + /** + * Log a message in INFO level. + * @param message to log. + */ + popoto.logger.info = function (message) { + popoto.logger.log(popoto.logger.LogLevels.INFO, message); + }; + + /** + * Log a message in WARN level. + * @param message to log. + */ + popoto.logger.warn = function (message) { + popoto.logger.log(popoto.logger.LogLevels.WARN, message); + }; + + /** + * Log a message in ERROR level. + * @param message to log. + */ + popoto.logger.error = function (message) { + popoto.logger.log(popoto.logger.LogLevels.ERROR, message); + }; + + // TAXONOMIES ----------------------------------------------------------------------------------------------------- + + popoto.taxonomy = {}; + popoto.taxonomy.containerId = "popoto-taxonomy"; + + /** + * Create the taxonomy panel HTML elements. + */ + popoto.taxonomy.createTaxonomyPanel = function () { + var htmlContainer = d3.select("#" + popoto.taxonomy.containerId); + + var taxoUL = htmlContainer.append("ul"); + + var data = popoto.taxonomy.generateTaxonomiesData(); + + var taxos = taxoUL.selectAll(".taxo").data(data); + + var taxoli = taxos.enter().append("li") + .attr("id", function (d) { + return d.id + }) + .attr("value", function (d) { + return d.label; + }); + + taxoli.append("img") + .attr("src", "css/image/category.png") + .attr("width", "24") + .attr("height", "24"); + + taxoli.append("span") + .attr("class", "ppt-label") + .text(function (d) { + return popoto.provider.getTaxonomyTextValue(d.label); + }); + + taxoli.append("span") + .attr("class", "ppt-count"); + + // Add an on click event on the taxonomy to clear the graph and set this label as root + taxoli.on("click", popoto.taxonomy.onClick); + + popoto.taxonomy.addTaxonomyChildren(taxoli); + + // The count is updated for each labels. + var flattenData = []; + data.forEach(function (d) { + flattenData.push(d); + if (d.children) { + popoto.taxonomy.flattenChildren(d, flattenData); + } + }); + + popoto.taxonomy.updateCount(flattenData); + }; + + /** + * Recursive function to flatten data content. + * + */ + popoto.taxonomy.flattenChildren = function (d, vals) { + d.children.forEach(function (c) { + vals.push(c); + if (c.children) { + vals.concat(popoto.taxonomy.flattenChildren(c, vals)); + } + }); + }; + + /** + * Updates the count number on a taxonomy. + * + * @param taxonomyData + */ + popoto.taxonomy.updateCount = function (taxonomyData) { + var statements = []; + + taxonomyData.forEach(function (taxo) { + statements.push( + { + "statement": popoto.query.generateTaxonomyCountQuery(taxo.label) + } + ); + }); + + (function (taxonomies) { + popoto.logger.info("Count taxonomies ==> "); + popoto.rest.post( + { + "statements": statements + }) + .done(function (returnedData) { + for (var i = 0; i < taxonomies.length; i++) { + var count = returnedData.results[i].data[0].row[0]; + d3.select("#" + taxonomies[i].id) + .select(".ppt-count") + .text(" (" + count + ")"); + } + }) + .fail(function (xhr, textStatus, errorThrown) { + popoto.logger.error(textStatus + ": error while accessing Neo4j server on URL:\"" + popoto.rest.CYPHER_URL + "\" defined in \"popoto.rest.CYPHER_URL\" property: " + errorThrown); + d3.select("#popoto-taxonomy") + .selectAll(".ppt-count") + .text(" (0)"); + }); + })(taxonomyData); + }; + + /** + * Recursively generate the taxonomy children elements. + * + * @param selection + */ + popoto.taxonomy.addTaxonomyChildren = function (selection) { + selection.each(function (d) { + var li = d3.select(this); + + var children = d.children; + if (d.children) { + var childLi = li.append("ul") + .selectAll("li") + .data(children) + .enter() + .append("li") + .attr("id", function (d) { + return d.id + }) + .attr("value", function (d) { + return d.label; + }); + + childLi.append("img") + .attr("src", "css/image/category.png") + .attr("width", "24") + .attr("height", "24"); + + childLi.append("span") + .attr("class", "ppt-label") + .text(function (d) { + return popoto.provider.getTaxonomyTextValue(d.label); + }); + + childLi.append("span") + .attr("class", "ppt-count"); + + childLi.on("click", popoto.taxonomy.onClick); + + popoto.taxonomy.addTaxonomyChildren(childLi); + } + + }); + }; + + popoto.taxonomy.onClick = function () { + d3.event.stopPropagation(); + + // Workaround to avoid click on taxonomies if root node has not yet been initialized + // If it contains a count it mean all the initialization has been done + var root = popoto.graph.getRootNode(); + if (root.count === undefined) { + return; + } + + var label = this.attributes.value.value; + + while (popoto.graph.force.nodes().length > 0) { + popoto.graph.force.nodes().pop(); + } + + while (popoto.graph.force.links().length > 0) { + popoto.graph.force.links().pop(); + } + + // Reinitialize internal label generator + popoto.graph.node.internalLabels = {}; + + popoto.update(); + popoto.graph.addRootNode(label); + popoto.graph.hasGraphChanged = true; + popoto.result.hasChanged = true; + popoto.update(); + popoto.tools.center(); + }; + + /** + * Parse the list of label providers and return a list of data object containing only searchable labels. + * @returns {Array} + */ + popoto.taxonomy.generateTaxonomiesData = function () { + var id = 0; + var data = []; + + // Retrieve root providers (searchable and without parent) + for (var label in popoto.provider.nodeProviders) { + if (popoto.provider.nodeProviders.hasOwnProperty(label)) { + if (popoto.provider.getProperty(label, "isSearchable") && !popoto.provider.nodeProviders[label].parent) { + data.push({ + "label": label, + "id": "popoto-lbl-" + id++ + }); + } + } + } + + // Add children data for each provider with children. + data.forEach(function (d) { + if (popoto.provider.getProvider(d.label).hasOwnProperty("children")) { + id = popoto.taxonomy.addChildrenData(d, id); + } + }); + + return data; + }; + + /** + * Add children providers data. + * @param parentData + * @param id + */ + popoto.taxonomy.addChildrenData = function (parentData, id) { + parentData.children = []; + + popoto.provider.getProvider(parentData.label).children.forEach(function (d) { + var childProvider = popoto.provider.getProvider(d); + var childData = { + "label": d, + "id": "popoto-lbl-" + id++ + }; + if (childProvider.hasOwnProperty("children")) { + id = popoto.taxonomy.addChildrenData(childData, id); + } + if (popoto.provider.getProperty(d, "isSearchable")) { + parentData.children.push(childData); + } + }); + + return id; + }; + + // TOOLS ----------------------------------------------------------------------------------------------------------- + + popoto.tools = {}; + // TODO introduce plugin mechanism to add tools + popoto.tools.CENTER_GRAPH = true; + popoto.tools.RESET_GRAPH = true; + popoto.tools.TOGGLE_TAXONOMY = true; + popoto.tools.TOGGLE_FULL_SCREEN = true; + + /** + * Reset all the graph to display the root node only. + */ + popoto.tools.reset = function () { + var label = popoto.graph.getRootNode().label; + + while (popoto.graph.force.nodes().length > 0) { + popoto.graph.force.nodes().pop(); + } + + while (popoto.graph.force.links().length > 0) { + popoto.graph.force.links().pop(); + } + + // Reinitialize internal label generator + popoto.graph.node.internalLabels = {}; + + popoto.update(); + popoto.graph.addRootNode(label); + popoto.graph.hasGraphChanged = true; + popoto.result.hasChanged = true; + popoto.update(); + popoto.tools.center(); + }; + + /** + * Reset zoom and center the view on svg center. + */ + popoto.tools.center = function () { + popoto.graph.zoom.translate([0, 0]).scale(1); + popoto.graph.svg.transition().attr("transform", "translate(" + popoto.graph.zoom.translate() + ")" + " scale(" + popoto.graph.zoom.scale() + ")"); + }; + + /** + * Show, hide taxonomy panel. + */ + popoto.tools.toggleTaxonomy = function () { + var taxo = d3.select("#" + popoto.taxonomy.containerId); + if (taxo.filter(".disabled").empty()) { + taxo.classed("disabled", true); + } else { + taxo.classed("disabled", false); + } + }; + + popoto.tools.toggleFullScreen = function () { + + var elem = document.getElementById(popoto.graph.containerId); + + if (!document.fullscreenElement && // alternative standard method + !document.mozFullScreenElement && !document.webkitFullscreenElement && !document.msFullscreenElement) { // current working methods + if (elem.requestFullscreen) { + elem.requestFullscreen(); + } else if (elem.msRequestFullscreen) { + elem.msRequestFullscreen(); + } else if (elem.mozRequestFullScreen) { + elem.mozRequestFullScreen(); + } else if (elem.webkitRequestFullscreen) { + elem.webkitRequestFullscreen(Element.ALLOW_KEYBOARD_INPUT); + } + } else { + if (document.exitFullscreen) { + document.exitFullscreen(); + } else if (document.msExitFullscreen) { + document.msExitFullscreen(); + } else if (document.mozCancelFullScreen) { + document.mozCancelFullScreen(); + } else if (document.webkitExitFullscreen) { + document.webkitExitFullscreen(); + } + } + }; + // GRAPH ----------------------------------------------------------------------------------------------------------- + + popoto.graph = {}; + + /** + * ID of the HTML component where the graph query builder elements will be generated in. + * @type {string} + */ + popoto.graph.containerId = "popoto-graph"; + popoto.graph.hasGraphChanged = true; + // Defines the min and max level of zoom available in graph query builder. + popoto.graph.zoom = d3.behavior.zoom().scaleExtent([0.1, 10]); + popoto.graph.WHEEL_ZOOM_ENABLED = true; + popoto.graph.TOOL_TAXONOMY = "Show/hide taxonomy panel"; + popoto.graph.TOOL_CENTER = "Center view"; + popoto.graph.TOOL_FULL_SCREEN = "Full screen"; + popoto.graph.TOOL_RESET = "Reset graph"; + + /** + * Define the list of listenable events on graph. + */ + popoto.graph.Events = Object.freeze({NODE_ROOT_ADD: "root.node.add", NODE_EXPAND_RELATIONSHIP: "node.expandRelationship"}); + + /** + * Generates all the HTML and SVG element needed to display the graph query builder. + * Everything will be generated in the container with id defined by popoto.graph.containerId. + */ + popoto.graph.createGraphArea = function () { + + var htmlContainer = d3.select("#" + popoto.graph.containerId); + + var toolbar = htmlContainer + .append("div") + .attr("class", "ppt-toolbar"); + + if (popoto.tools.RESET_GRAPH) { + toolbar.append("span") + .attr("id", "popoto-reset-menu") + .attr("class", "ppt-menu reset") + .attr("title", popoto.graph.TOOL_RESET) + .on("click", popoto.tools.reset); + } + + if (popoto.taxonomy.isActive && popoto.tools.TOGGLE_TAXONOMY) { + toolbar.append("span") + .attr("id", "popoto-taxonomy-menu") + .attr("class", "ppt-menu taxonomy") + .attr("title", popoto.graph.TOOL_TAXONOMY) + .on("click", popoto.tools.toggleTaxonomy); + } + + if (popoto.tools.CENTER_GRAPH) { + toolbar.append("span") + .attr("id", "popoto-center-menu") + .attr("class", "ppt-menu center") + .attr("title", popoto.graph.TOOL_CENTER) + .on("click", popoto.tools.center); + } + + if (popoto.tools.TOGGLE_FULL_SCREEN) { + toolbar.append("span") + .attr("id", "popoto-fullscreen-menu") + .attr("class", "ppt-menu fullscreen") + .attr("title", popoto.graph.TOOL_FULL_SCREEN) + .on("click", popoto.tools.toggleFullScreen); + } + + var svgTag = htmlContainer.append("svg").call(popoto.graph.zoom.on("zoom", popoto.graph.rescale)); + + svgTag.on("dblclick.zoom", null) + .attr("class", "ppt-svg-graph"); + + if (!popoto.graph.WHEEL_ZOOM_ENABLED) { + // Disable mouse wheel events. + svgTag.on("wheel.zoom", null) + .on("mousewheel.zoom", null); + } + + popoto.graph.svg = svgTag.append('svg:g'); + + // Create two separated area for links and nodes + // Links and nodes are separated in a dedicated "g" element + // and nodes are generated after links to ensure that nodes are always on foreground. + popoto.graph.svg.append("g").attr("id", popoto.graph.link.gID); + popoto.graph.svg.append("g").attr("id", popoto.graph.node.gID); + + // This listener is used to center the root node in graph during a window resize. + // TODO can the listener be limited on the parent container only? + window.addEventListener('resize', popoto.graph.centerRootNode); + }; + + popoto.graph.centerRootNode = function () { + popoto.graph.getRootNode().px = popoto.graph.getSVGWidth() / 2; + popoto.graph.getRootNode().py = popoto.graph.getSVGHeight() / 2; + popoto.update(); + }; + + /** + * Get the actual width of the SVG element containing the graph query builder. + * @returns {number} + */ + popoto.graph.getSVGWidth = function () { + if (typeof popoto.graph.svg == 'undefined' || popoto.graph.svg.empty()) { + popoto.logger.debug("popoto.graph.svg is undefined or empty."); + return 0; + } else { + return document.getElementById(popoto.graph.containerId).clientWidth; + } + }; + + /** + * Get the actual height of the SVG element containing the graph query builder. + * @returns {number} + */ + popoto.graph.getSVGHeight = function () { + if (typeof popoto.graph.svg == 'undefined' || popoto.graph.svg.empty()) { + popoto.logger.debug("popoto.graph.svg is undefined or empty."); + return 0; + } else { + return document.getElementById(popoto.graph.containerId).clientHeight; + } + }; + + /** + * Function to call on SVG zoom event to update the svg transform attribute. + */ + popoto.graph.rescale = function () { + var trans = d3.event.translate, + scale = d3.event.scale; + + popoto.graph.svg.attr("transform", + "translate(" + trans + ")" + + " scale(" + scale + ")"); + }; + + /****************************** + * Default parameters used to configure D3.js force layout. + * These parameter can be modified to change graph behavior. + ******************************/ + popoto.graph.LINK_DISTANCE = 150; + popoto.graph.LINK_STRENGTH = 1; + popoto.graph.FRICTION = 0.8; + popoto.graph.CHARGE = -1400; + popoto.graph.THETA = 0.8; + popoto.graph.GRAVITY = 0.0; + + /** + * Contains the list off root node add listeners. + */ + popoto.graph.rootNodeAddListeners = []; + popoto.graph.nodeExpandRelationsipListeners = []; + + /** + * Create the D3.js force layout for the graph query builder. + */ + popoto.graph.createForceLayout = function () { + + popoto.graph.force = d3.layout.force() + .size([popoto.graph.getSVGWidth(), popoto.graph.getSVGHeight()]) + .linkDistance(function (d) { + if (d.type === popoto.graph.link.LinkTypes.RELATION) { + return ((3 * popoto.graph.LINK_DISTANCE) / 2); + } else { + return popoto.graph.LINK_DISTANCE; + } + }) + .linkStrength(function (d) { + if (d.linkStrength) { + return d.linkStrength; + } else { + return popoto.graph.LINK_STRENGTH; + } + }) + .friction(popoto.graph.FRICTION) + .charge(function (d) { + if (d.charge) { + return d.charge; + } else { + return popoto.graph.CHARGE; + } + }) + .theta(popoto.graph.THETA) + .gravity(popoto.graph.GRAVITY) + .on("tick", popoto.graph.tick); // Function called on every position update done by D3.js + + // Disable event propagation on drag to avoid zoom and pan issues + popoto.graph.force.drag() + .on("dragstart", function (d) { + d3.event.sourceEvent.stopPropagation(); + }) + .on("dragend", function (d) { + d3.event.sourceEvent.stopPropagation(); + }); + }; + + /** + * Add a listener to the specified event. + * + * @param event name of the event to add the listener. + * @param listener the listener to add. + */ + popoto.graph.on = function (event, listener) { + if (event === popoto.graph.Events.NODE_ROOT_ADD) { + popoto.graph.rootNodeAddListeners.push(listener); + } + if (event === popoto.graph.Events.NODE_EXPAND_RELATIONSHIP) { + popoto.graph.nodeExpandRelationsipListeners.push(listener); + } + }; + + /** + * Adds graph root nodes using the label set as parameter. + * All the other nodes should have been removed first to avoid inconsistent data. + * + * @param label label of the node to add as root. + */ + popoto.graph.addRootNode = function (label) { + if (popoto.graph.force.nodes().length > 0) { + popoto.logger.debug("popoto.graph.addRootNode is called but the graph is not empty."); + } + + popoto.graph.force.nodes().push({ + "id": "0", + "type": popoto.graph.node.NodeTypes.ROOT, + // x and y coordinates are set to the center of the SVG area. + // These coordinate will never change at runtime except if the window is resized. + "x": popoto.graph.getSVGWidth() / 2, + "y": popoto.graph.getSVGHeight() / 2, + "label": label, + // The node is fixed to always remain in the center of the svg area. + // This property should not be changed at runtime to avoid issues with the zoom and pan. + "fixed": true, + // Label used internally to identify the node. + // This label is used for example as cypher query identifier. + "internalLabel": popoto.graph.node.generateInternalLabel(label) + }); + + // Notify listeners + popoto.graph.rootNodeAddListeners.forEach(function (listener) { + listener(popoto.graph.getRootNode()); + }); + }; + + /** + * Get the graph root node. + * @returns {*} + */ + popoto.graph.getRootNode = function () { + return popoto.graph.force.nodes()[0]; + }; + + /** + * Function to call on D3.js force layout tick event. + * This function will update the position of all links and nodes elements in the graph with the force layout computed coordinate. + */ + popoto.graph.tick = function () { + popoto.graph.svg.selectAll("#" + popoto.graph.link.gID + " > g") + .selectAll("path") + .attr("d", function (d) { + var parentAngle = popoto.graph.computeParentAngle(d.target); + var targetX = d.target.x + (popoto.graph.link.RADIUS * Math.cos(parentAngle)), + targetY = d.target.y - (popoto.graph.link.RADIUS * Math.sin(parentAngle)); + + var sourceX = d.source.x - (popoto.graph.link.RADIUS * Math.cos(parentAngle)), + sourceY = d.source.y + (popoto.graph.link.RADIUS * Math.sin(parentAngle)); + + if (d.source.x <= d.target.x) { + return "M" + sourceX + " " + sourceY + "L" + targetX + " " + targetY; + } else { + return "M" + targetX + " " + targetY + "L" + sourceX + " " + sourceY; + } + }); + + popoto.graph.svg.selectAll("#" + popoto.graph.node.gID + " > g") + .attr("transform", function (d) { + return "translate(" + (d.x) + "," + (d.y) + ")"; + }); + }; + + // LINKS ----------------------------------------------------------------------------------------------------------- + popoto.graph.link = {}; + + /** + * Defines the radius around the node to start link drawing. + * If set to 0 links will start from the middle of the node. + */ + popoto.graph.link.RADIUS = 25; + + // ID of the g element in SVG graph containing all the link elements. + popoto.graph.link.gID = "popoto-glinks"; + + /** + * Defines the different type of link. + * RELATION is a relation link between two nodes. + * VALUE is a link between a generic node and a value. + */ + popoto.graph.link.LinkTypes = Object.freeze({RELATION: 0, VALUE: 1}); + + /** + * Function to call to update the links after modification in the model. + * This function will update the graph with all removed, modified or added links using d3.js mechanisms. + */ + popoto.graph.link.updateLinks = function () { + popoto.graph.link.svgLinkElements = popoto.graph.svg.select("#" + popoto.graph.link.gID).selectAll("g"); + popoto.graph.link.updateData(); + popoto.graph.link.removeElements(); + popoto.graph.link.addNewElements(); + popoto.graph.link.updateElements(); + }; + + /** + * Update the links element with data coming from popoto.graph.force.links(). + */ + popoto.graph.link.updateData = function () { + popoto.graph.link.svgLinkElements = popoto.graph.link.svgLinkElements.data(popoto.graph.force.links(), function (d) { + return d.id; + }); + }; + + /** + * Clean links elements removed from the list. + */ + popoto.graph.link.removeElements = function () { + popoto.graph.link.svgLinkElements.exit().remove(); + }; + + /** + * Create new elements. + */ + popoto.graph.link.addNewElements = function () { + + var newLinkElements = popoto.graph.link.svgLinkElements.enter().append("g") + .attr("class", "ppt-glink") + .on("mouseover", popoto.graph.link.mouseOverLink) + .on("mouseout", popoto.graph.link.mouseOutLink); + + newLinkElements.append("path"); + + newLinkElements.append("text") + .attr("text-anchor", "middle") + .attr("dy", "-4") + .append("textPath") + .attr("class", "ppt-textPath") + .attr("startOffset", "50%"); + + }; + + /** + * Update all the elements (new + modified) + */ + popoto.graph.link.updateElements = function () { + popoto.graph.link.svgLinkElements + .attr("id", function (d) { + return "ppt-glink_" + d.id; + }); + + popoto.graph.link.svgLinkElements.selectAll("path") + .attr("id", function (d) { + return "ppt-path_" + d.id + }) + .attr("class", function (d) { + if (d.type === popoto.graph.link.LinkTypes.VALUE) { + return "ppt-link-value"; + } else { + if (d.target.count == 0) { + return "ppt-link-relation disabled"; + } else { + if (d.target.value !== undefined) { + return "ppt-link-relation value"; + } else { + return "ppt-link-relation"; + } + } + } + }); + + // Due to a bug on webkit browsers (as of 30/01/2014) textPath cannot be selected + // To workaround this issue the selection is done with its associated css class + popoto.graph.link.svgLinkElements.selectAll("text") + .attr("id", function (d) { + return "ppt-text_" + d.id + }) + .attr("class", function (d) { + if (d.type === popoto.graph.link.LinkTypes.VALUE) { + return "ppt-link-text-value"; + } else { + if (d.target.count == 0) { + return "ppt-link-text-relation disabled"; + } else { + if (d.target.value !== undefined) { + return "ppt-link-text-relation value"; + } else { + return "ppt-link-text-relation"; + } + } + } + }) + .selectAll(".ppt-textPath") + .attr("id", function (d) { + return "ppt-textpath_" + d.id + }) + .attr("xlink:href", function (d) { + return "#ppt-path_" + d.id + }) + .text(function (d) { + return popoto.provider.getLinkTextValue(d); + }); + }; + + /** + * Function called when mouse is over the link. + * This function is used to change the CSS class on hover of the link and query viewer element. + * + * TODO try to introduce event instead of directly access query spans here. This could be used in future extensions. + */ + popoto.graph.link.mouseOverLink = function () { + d3.select(this).select("path").classed("ppt-link-hover", true); + d3.select(this).select("text").classed("ppt-link-hover", true); + + if (popoto.queryviewer.isActive) { + var hoveredLink = d3.select(this).data()[0]; + + popoto.queryviewer.queryConstraintSpanElements.filter(function (d) { + return d.ref === hoveredLink; + }).classed("hover", true); + popoto.queryviewer.querySpanElements.filter(function (d) { + return d.ref === hoveredLink; + }).classed("hover", true); + } + }; + + /** + * Function called when mouse goes out of the link. + * This function is used to reinitialize the CSS class of the link and query viewer element. + */ + popoto.graph.link.mouseOutLink = function () { + d3.select(this).select("path").classed("ppt-link-hover", false); + d3.select(this).select("text").classed("ppt-link-hover", false); + + if (popoto.queryviewer.isActive) { + var hoveredLink = d3.select(this).data()[0]; + + popoto.queryviewer.queryConstraintSpanElements.filter(function (d) { + return d.ref === hoveredLink; + }).classed("hover", false); + popoto.queryviewer.querySpanElements.filter(function (d) { + return d.ref === hoveredLink; + }).classed("hover", false); + } + }; + + //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + // NODES ----------------------------------------------------------------------------------------------------------- + + popoto.graph.node = {}; + + // ID of the g element in SVG graph containing all the link elements. + popoto.graph.node.gID = "popoto-gnodes"; + + // Node ellipse size used by default for text nodes. + popoto.graph.node.ELLIPSE_RX = 50; + popoto.graph.node.ELLIPSE_RY = 25; + popoto.graph.node.TEXT_Y = 8; + popoto.graph.node.BACK_CIRCLE_R = 70; + // Define the max number of character displayed in ellipses. + popoto.graph.node.NODE_MAX_CHARS = 11; + + // Number of nodes displayed per page during value selection. + popoto.graph.node.PAGE_SIZE = 10; + + // Count box default size + popoto.graph.node.CountBox = {x: 16, y: 33, w: 52, h: 19}; + + // Store choose node state to avoid multiple node expand at the same time + popoto.graph.node.chooseWaiting = false; + + /** + * Defines the list of possible nodes. + * ROOT: Node used as graph root. It is the target of the query. Only one node of this type should be available in graph. + * CHOOSE: Nodes defining a generic node label. From these node is is possible to select a value or explore relations. + * VALUE: Unique node containing a value constraint. Usually replace CHOOSE nodes once a value as been selected. + * GROUP: Empty node used to group relations. No value can be selected but relations can be explored. These nodes doesn't have count. + */ + popoto.graph.node.NodeTypes = Object.freeze({ROOT: 0, CHOOSE: 1, VALUE: 2, GROUP: 3}); + + // Variable used to generate unique id for each new nodes. + popoto.graph.node.idgen = 0; + + // Used to generate unique internal labels used for example as identifier in Cypher query. + popoto.graph.node.internalLabels = {}; + + /** + * Create a normalized identifier from a node label. + * Multiple calls with the same node label will generate different unique identifier. + * + * @param nodeLabel + * @returns {string} + */ + popoto.graph.node.generateInternalLabel = function (nodeLabel) { + var label = nodeLabel.toLowerCase().replace(/ /g, ''); + + if (label in popoto.graph.node.internalLabels) { + popoto.graph.node.internalLabels[label] = popoto.graph.node.internalLabels[label] + 1; + } else { + popoto.graph.node.internalLabels[label] = 0; + return label; + } + + return label + popoto.graph.node.internalLabels[label]; + }; + + /** + * Update Nodes SVG elements using D3.js update mechanisms. + */ + popoto.graph.node.updateNodes = function () { + if (!popoto.graph.node.svgNodeElements) { + popoto.graph.node.svgNodeElements = popoto.graph.svg.select("#" + popoto.graph.node.gID).selectAll("g"); + } + popoto.graph.node.updateData(); + popoto.graph.node.removeElements(); + popoto.graph.node.addNewElements(); + popoto.graph.node.updateElements(); + }; + + /** + * Update node data with changes done in popoto.graph.force.nodes() model. + */ + popoto.graph.node.updateData = function () { + popoto.graph.node.svgNodeElements = popoto.graph.node.svgNodeElements.data(popoto.graph.force.nodes(), function (d) { + return d.id; + }); + + if (popoto.graph.hasGraphChanged) { + popoto.graph.node.updateCount(); + popoto.graph.hasGraphChanged = false; + } + }; + + /** + * Update nodes count by executing a query for every nodes with the new graph structure. + */ + popoto.graph.node.updateCount = function () { + + var statements = []; + + var counterNodes = popoto.graph.force.nodes() + .filter(function (d) { + return d.type !== popoto.graph.node.NodeTypes.VALUE && d.type !== popoto.graph.node.NodeTypes.GROUP; + }); + + counterNodes.forEach(function (node) { + var query = popoto.query.generateNodeCountCypherQuery(node); + statements.push( + { + "statement": query + } + ); + }); + + popoto.logger.info("Count nodes ==> "); + popoto.rest.post( + { + "statements": statements + }) + .done(function (returnedData) { + + if (returnedData.errors && returnedData.errors.length > 0) { + popoto.logger.error("Cypher query error:" + JSON.stringify(returnedData.errors)); + } + + if (returnedData.results && returnedData.results.length > 0) { + for (var i = 0; i < counterNodes.length; i++) { + counterNodes[i].count = returnedData.results[i].data[0].row[0]; + } + } else { + counterNodes.forEach(function (node) { + node.count = 0; + }); + } + popoto.graph.node.updateElements(); + popoto.graph.link.updateElements(); + }) + .fail(function (xhr, textStatus, errorThrown) { + popoto.logger.error(textStatus + ": error while accessing Neo4j server on URL:\"" + popoto.rest.CYPHER_URL + "\" defined in \"popoto.rest.CYPHER_URL\" property: " + errorThrown); + counterNodes.forEach(function (node) { + node.count = 0; + }); + popoto.graph.node.updateElements(); + popoto.graph.link.updateElements(); + }); + }; + + /** + * Remove old elements. + * Should be called after updateData. + */ + popoto.graph.node.removeElements = function () { + var toRemove = popoto.graph.node.svgNodeElements.exit(); + + // Nodes without parent are simply removed. + toRemove.filter(function (d) { + return !d.parent; + }).remove(); + + // Nodes with a parent are removed with an animation (nodes are collapsed to their parents before being removed) + toRemove.filter(function (d) { + return d.parent; + }).transition().duration(300).attr("transform", function (d) { + return "translate(" + d.parent.x + "," + d.parent.y + ")"; + }).remove(); + }; + + /** + * Add all new elements. + * Only the skeleton of new nodes are added custom data will be added during the element update phase. + * Should be called after updateData and before updateElements. + */ + popoto.graph.node.addNewElements = function () { + var gNewNodeElements = popoto.graph.node.svgNodeElements.enter() + .append("g") + .on("click", popoto.graph.node.nodeClick) + .on("mouseover", popoto.graph.node.mouseOverNode) + .on("mouseout", popoto.graph.node.mouseOutNode); + + // Add right click on all nodes except value + gNewNodeElements.filter(function (d) { + return d.type !== popoto.graph.node.NodeTypes.VALUE; + }).on("contextmenu", popoto.graph.node.clearSelection); + + // Disable right click context menu on value nodes + gNewNodeElements.filter(function (d) { + return d.type === popoto.graph.node.NodeTypes.VALUE; + }).on("contextmenu", function () { + // Disable context menu on + d3.event.preventDefault(); + }); + + // Most browser will generate a tooltip if a title is specified for the SVG element + // TODO Introduce an SVG tooltip instead? + gNewNodeElements.append("title").attr("class", "ppt-svg-title"); + + // Nodes are composed of 3 layouts and skeleton are created here. + popoto.graph.node.addBackgroundElements(gNewNodeElements); + popoto.graph.node.addMiddlegroundElements(gNewNodeElements); + popoto.graph.node.addForegroundElements(gNewNodeElements); + }; + + /** + * Create the background for a new node element. + * The background of a node is defined by a circle not visible by default (fill-opacity set to 0) but can be used to highlight a node with animation on this attribute. + * This circle also define the node zone that can receive events like mouse clicks. + * + * @param gNewNodeElements + */ + popoto.graph.node.addBackgroundElements = function (gNewNodeElements) { + var background = gNewNodeElements + .append("g") + .attr("class", "ppt-g-node-background"); + + background.append("circle") + .attr("class", function (d) { + var cssClass = "ppt-node-background-circle"; + if (d.value !== undefined) { + cssClass = cssClass + " selected-value"; + } else if (d.type === popoto.graph.node.NodeTypes.ROOT) { + cssClass = cssClass + " root"; + } else if (d.type === popoto.graph.node.NodeTypes.CHOOSE) { + cssClass = cssClass + " choose"; + } else if (d.type === popoto.graph.node.NodeTypes.VALUE) { + cssClass = cssClass + " value"; + } else if (d.type === popoto.graph.node.NodeTypes.GROUP) { + cssClass = cssClass + " group"; + } + + return cssClass; + }) + .style("fill-opacity", 0) + .attr("r", popoto.graph.node.BACK_CIRCLE_R); + }; + + /** + * Create the node main elements. + * + * @param gNewNodeElements + */ + popoto.graph.node.addMiddlegroundElements = function (gNewNodeElements) { + var middle = gNewNodeElements + .append("g") + .attr("class", "ppt-g-node-middleground"); + }; + + /** + * Create the node foreground elements. + * It contains node additional elements, count or tools like navigation arrows. + * + * @param gNewNodeElements + */ + popoto.graph.node.addForegroundElements = function (gNewNodeElements) { + var foreground = gNewNodeElements + .append("g") + .attr("class", "ppt-g-node-foreground"); + + // plus sign + var gRelationship = foreground.filter(function (d) { + return d.type !== popoto.graph.node.NodeTypes.VALUE; + }).append("g").attr("class", "ppt-rel-plus-icon"); + + gRelationship.append("title") + .text("Add relationship"); + + gRelationship + .append("circle") + .attr("class", "ppt-rel-plus-background") + .attr("cx", "32") + .attr("cy", "-43") + .attr("r", "16"); + + gRelationship + .append("path") + .attr("class", "ppt-rel-plus-path") + .attr("d", "M 40,-45 35,-45 35,-50 30,-50 30,-45 25,-45 25,-40 30,-40 30,-35 35,-35 35,-40 40,-40 z"); + + gRelationship + .on("mouseover", function () { + d3.select(this).select(".ppt-rel-plus-background").transition().style("fill-opacity", 0.5); + }) + .on("mouseout", function () { + d3.select(this).select(".ppt-rel-plus-background").transition().style("fill-opacity", 0); + }) + .on("click", function () { + d3.event.stopPropagation(); // To avoid click event on svg element in background + popoto.graph.node.expandRelationship.call(this); + }); + + // Minus sign + var gMinusRelationship = foreground.filter(function (d) { + return d.type !== popoto.graph.node.NodeTypes.VALUE; + }).append("g").attr("class", "ppt-rel-minus-icon"); + + gMinusRelationship.append("title") + .text("Remove relationship"); + + gMinusRelationship + .append("circle") + .attr("class", "ppt-rel-minus-background") + .attr("cx", "32") + .attr("cy", "-43") + .attr("r", "16"); + + gMinusRelationship + .append("path") + .attr("class", "ppt-rel-minus-path") + .attr("d", "M 40,-45 25,-45 25,-40 40,-40 z"); + + gMinusRelationship + .on("mouseover", function () { + d3.select(this).select(".ppt-rel-minus-background").transition().style("fill-opacity", 0.5); + }) + .on("mouseout", function () { + d3.select(this).select(".ppt-rel-minus-background").transition().style("fill-opacity", 0); + }) + .on("click", function () { + d3.event.stopPropagation(); // To avoid click event on svg element in background + popoto.graph.node.collapseRelationship.call(this); + }); + + // Arrows icons added only for root and choose nodes + var gArrow = foreground.filter(function (d) { + return d.type === popoto.graph.node.NodeTypes.ROOT || d.type === popoto.graph.node.NodeTypes.CHOOSE; + }) + .append("g") + .attr("class", "ppt-node-foreground-g-arrows"); + + var glArrow = gArrow.append("g"); + //glArrow.append("polygon") + //.attr("points", "-53,-23 -33,-33 -33,-13"); + glArrow.append("circle") + .attr("class", "ppt-larrow") + .attr("cx", "-43") + .attr("cy", "-23") + .attr("r", "17"); + + glArrow.append("path") + .attr("class", "ppt-arrow") + .attr("d", "m -44.905361,-23 6.742,-6.742 c 0.81,-0.809 0.81,-2.135 0,-2.944 l -0.737,-0.737 c -0.81,-0.811 -2.135,-0.811 -2.945,0 l -8.835,8.835 c -0.435,0.434 -0.628,1.017 -0.597,1.589 -0.031,0.571 0.162,1.154 0.597,1.588 l 8.835,8.834 c 0.81,0.811 2.135,0.811 2.945,0 l 0.737,-0.737 c 0.81,-0.808 0.81,-2.134 0,-2.943 l -6.742,-6.743 z"); + + glArrow.on("click", function (clickedNode) { + d3.event.stopPropagation(); // To avoid click event on svg element in background + + // On left arrow click page number is decreased and node expanded to display the new page + if (clickedNode.page > 1) { + clickedNode.page--; + popoto.graph.node.collapseNode(clickedNode); + popoto.graph.node.expandNode(clickedNode); + } + }); + + var grArrow = gArrow.append("g"); + //grArrow.append("polygon") + //.attr("points", "53,-23 33,-33 33,-13"); + + grArrow.append("circle") + .attr("class", "ppt-rarrow") + .attr("cx", "43") + .attr("cy", "-23") + .attr("r", "17"); + + grArrow.append("path") + .attr("class", "ppt-arrow") + .attr("d", "m 51.027875,-24.5875 -8.835,-8.835 c -0.811,-0.811 -2.137,-0.811 -2.945,0 l -0.738,0.737 c -0.81,0.81 -0.81,2.136 0,2.944 l 6.742,6.742 -6.742,6.742 c -0.81,0.81 -0.81,2.136 0,2.943 l 0.737,0.737 c 0.81,0.811 2.136,0.811 2.945,0 l 8.835,-8.836 c 0.435,-0.434 0.628,-1.017 0.597,-1.588 0.032,-0.569 -0.161,-1.152 -0.596,-1.586 z"); + + grArrow.on("click", function (clickedNode) { + d3.event.stopPropagation(); // To avoid click event on svg element in background + + if (clickedNode.page * popoto.graph.node.PAGE_SIZE < clickedNode.count) { + clickedNode.page++; + popoto.graph.node.collapseNode(clickedNode); + popoto.graph.node.expandNode(clickedNode); + } + }); + + // Count box + var countForeground = foreground.filter(function (d) { + return d.type !== popoto.graph.node.NodeTypes.GROUP; + }); + + countForeground + .append("rect") + .attr("x", popoto.graph.node.CountBox.x) + .attr("y", popoto.graph.node.CountBox.y) + .attr("width", popoto.graph.node.CountBox.w) + .attr("height", popoto.graph.node.CountBox.h) + .attr("class", "ppt-count-box"); + + countForeground + .append("text") + .attr("x", 42) + .attr("y", 48) + .attr("text-anchor", "middle") + .attr("class", "ppt-count-text"); + }; + + /** + * Updates all elements. + */ + popoto.graph.node.updateElements = function () { + popoto.graph.node.svgNodeElements.attr("id", function (d) { + return "popoto-gnode_" + d.id; + }); + + popoto.graph.node.svgNodeElements + .selectAll(".ppt-svg-title") + .text(function (d) { + return popoto.provider.getTextValue(d); + }); + + popoto.graph.node.svgNodeElements.filter(function (n) { + return n.type !== popoto.graph.node.NodeTypes.ROOT + }).call(popoto.graph.force.drag); + + popoto.graph.node.updateBackgroundElements(); + popoto.graph.node.updateMiddlegroundElements(); + popoto.graph.node.updateForegroundElements(); + }; + + popoto.graph.node.updateBackgroundElements = function () { + popoto.graph.node.svgNodeElements.selectAll(".ppt-g-node-background") + .selectAll(".ppt-node-background-circle") + .attr("class", function (d) { + var cssClass = "ppt-node-background-circle"; + + if (d.type === popoto.graph.node.NodeTypes.VALUE) { + cssClass = cssClass + " value"; + } else if (d.type === popoto.graph.node.NodeTypes.GROUP) { + cssClass = cssClass + " group"; + } else { + if (d.value !== undefined) { + if (d.type === popoto.graph.node.NodeTypes.ROOT) { + cssClass = cssClass + " selected-root-value"; + } else if (d.type === popoto.graph.node.NodeTypes.CHOOSE) { + cssClass = cssClass + " selected-value"; + } + } else { + if (d.count == 0) { + cssClass = cssClass + " disabled"; + } else { + if (d.type === popoto.graph.node.NodeTypes.ROOT) { + cssClass = cssClass + " root"; + } else if (d.type === popoto.graph.node.NodeTypes.CHOOSE) { + cssClass = cssClass + " choose"; + } + } + } + } + + return cssClass; + }) + .attr("r", popoto.graph.node.BACK_CIRCLE_R); + }; + + /** + * Update the middle layer of nodes. + * TODO refactor node generation to allow future extensions (for example add plugin with new node types...) + */ + popoto.graph.node.updateMiddlegroundElements = function () { + + var middleG = popoto.graph.node.svgNodeElements.selectAll(".ppt-g-node-middleground"); + + // Clear all content in case node type has changed + middleG.selectAll("*").remove(); + + //------------------------------- + // Update IMAGE nodes + var imageMiddle = middleG.filter(function (d) { + return popoto.provider.getNodeDisplayType(d) === popoto.provider.NodeDisplayTypes.IMAGE; + }).append("image").attr("class", "ppt-node-image"); + + imageMiddle + .attr("width", function (d) { + return popoto.provider.getImageWidth(d); + }) + .attr("height", function (d) { + return popoto.provider.getImageHeight(d); + }) + // Center the image on node + .attr("transform", function (d) { + return "translate(" + (-popoto.provider.getImageWidth(d) / 2) + "," + (-popoto.provider.getImageHeight(d) / 2) + ")"; + }) + .attr("xlink:href", function (d) { + return popoto.provider.getImagePath(d); + }); + + //------------------------- + // Update TEXT nodes + var ellipseMiddle = middleG.filter(function (d) { + return popoto.provider.getNodeDisplayType(d) === popoto.provider.NodeDisplayTypes.TEXT; + }).append("ellipse").attr("rx", popoto.graph.node.ELLIPSE_RX).attr("ry", popoto.graph.node.ELLIPSE_RY); + + // Set class according to node type + ellipseMiddle + .attr("rx", popoto.graph.node.ELLIPSE_RX) + .attr("ry", popoto.graph.node.ELLIPSE_RY) + .attr("class", function (d) { + if (d.type === popoto.graph.node.NodeTypes.ROOT) { + if (d.value) { + return "ppt-node-ellipse selected-root-value" + } else { + if (d.count == 0) { + return "ppt-node-ellipse root disabled"; + } else { + return "ppt-node-ellipse root"; + } + } + } else if (d.type === popoto.graph.node.NodeTypes.CHOOSE) { + if (d.value) { + return "ppt-node-ellipse selected-value" + } else { + if (d.count == 0) { + return "ppt-node-ellipse choose disabled"; + } else { + return "ppt-node-ellipse choose"; + } + } + } else if (d.type === popoto.graph.node.NodeTypes.VALUE) { + return "ppt-node-ellipse value"; + } else if (d.type === popoto.graph.node.NodeTypes.GROUP) { + return "ppt-node-ellipse group"; + } + }); + + //------------------------- + // Update SVG nodes + var svgMiddle = middleG.filter(function (d) { + return popoto.provider.getNodeDisplayType(d) === popoto.provider.NodeDisplayTypes.SVG; + }).append("g") + // Add D3.js nested data with all paths required to render the svg element. + .selectAll("path").data(function (d) { + return popoto.provider.getSVGPaths(d); + }); + + // Update nested data elements + svgMiddle.exit().remove(); + + svgMiddle.enter().append("path"); + + middleG + .selectAll("path") + .attr("d", function (d) { + return d.d; + }) + .attr("class", function (d) { + return d["class"]; + }); + + // Update text + var textMiddle = middleG.filter(function (d) { + return popoto.provider.isTextDisplayed(d); + }).append('text') + .attr('x', 0) + .attr('y', popoto.graph.node.TEXT_Y) + .attr('text-anchor', 'middle'); + textMiddle + .attr('y', popoto.graph.node.TEXT_Y) + .attr("class", function (d) { + switch (d.type) { + case popoto.graph.node.NodeTypes.CHOOSE: + if (d.value === undefined) { + if (d.count == 0) { + return "ppt-node-text-choose disabled"; + } else { + return "ppt-node-text-choose"; + } + } else { + return "ppt-node-text-choose selected-value"; + } + case popoto.graph.node.NodeTypes.GROUP: + return "ppt-node-text-group"; + case popoto.graph.node.NodeTypes.ROOT: + if (d.value === undefined) { + if (d.count == 0) { + return "ppt-node-text-root disabled"; + } else { + return "ppt-node-text-root"; + } + } else { + return "ppt-node-text-root selected-value"; + } + case popoto.graph.node.NodeTypes.VALUE: + return "ppt-node-text-value"; + } + }) + .text(function (d) { + if (popoto.provider.isTextDisplayed(d)) { + return popoto.provider.getTextValue(d); + } else { + return ""; + } + }); + }; + + /** + * Updates the foreground elements + */ + popoto.graph.node.updateForegroundElements = function () { + + // Updates browse arrows status + var gArrows = popoto.graph.node.svgNodeElements.selectAll(".ppt-g-node-foreground") + .selectAll(".ppt-node-foreground-g-arrows"); + gArrows.classed("active", function (d) { + return d.valueExpanded && d.data && d.data.length > popoto.graph.node.PAGE_SIZE; + }); + + gArrows.selectAll(".ppt-larrow").classed("enabled", function (d) { + return d.page > 1; + }); + + gArrows.selectAll(".ppt-rarrow").classed("enabled", function (d) { + if (d.data) { + var count = d.data.length; + return d.page * popoto.graph.node.PAGE_SIZE < count; + } else { + return false; + } + }); + + // Update count box class depending on node type + var gForegrounds = popoto.graph.node.svgNodeElements.selectAll(".ppt-g-node-foreground"); + + gForegrounds.selectAll(".ppt-count-box").filter(function (d) { + return d.type !== popoto.graph.node.NodeTypes.CHOOSE; + }).classed("root", true); + + gForegrounds.selectAll(".ppt-count-box").filter(function (d) { + return d.type === popoto.graph.node.NodeTypes.CHOOSE; + }).classed("value", true); + + gForegrounds.selectAll(".ppt-count-box").classed("disabled", function (d) { + return d.count == 0; + }); + + gForegrounds.selectAll(".ppt-count-text") + .text(function (d) { + if (d.count != null) { + return d.count; + } else { + return "..."; + } + }) + .classed("disabled", function (d) { + return d.count == 0; + }); + + // Hide/Show plus icon (set disabled CSS class) if node already has been expanded. + gForegrounds.selectAll(".ppt-rel-plus-icon") + .classed("disabled", function (d) { + return d.linkExpanded || d.count == 0 || d.linkCount == 0; + }); + + gForegrounds.selectAll(".ppt-rel-minus-icon") + .classed("disabled", function (d) { + return (!d.linkExpanded) || d.count == 0 || d.linkCount == 0; + }); + + }; + + /** + * Handle the mouse over event on nodes. + */ + popoto.graph.node.mouseOverNode = function () { + d3.event.preventDefault(); + + // TODO don't work on IE (nodes unstable) find another way to move node in foreground on mouse over? + // d3.select(this).moveToFront(); + + d3.select(this).select(".ppt-g-node-background").selectAll("circle").transition().style("fill-opacity", 0.5); + + if (popoto.queryviewer.isActive) { + // Get the hovered node data + var hoveredNode = d3.select(this).data()[0]; + + // Hover the node in query + popoto.queryviewer.queryConstraintSpanElements.filter(function (d) { + return d.ref === hoveredNode; + }).classed("hover", true); + popoto.queryviewer.querySpanElements.filter(function (d) { + return d.ref === hoveredNode; + }).classed("hover", true); + } + }; + + /** + * Handle mouse out event on nodes. + */ + popoto.graph.node.mouseOutNode = function () { + d3.event.preventDefault(); + + d3.select(this).select(".ppt-g-node-background").selectAll("circle").transition().style("fill-opacity", 0); + + if (popoto.queryviewer.isActive) { + // Get the hovered node data + var hoveredNode = d3.select(this).data()[0]; + + // Remove hover class on node. + popoto.queryviewer.queryConstraintSpanElements.filter(function (d) { + return d.ref === hoveredNode; + }).classed("hover", false); + popoto.queryviewer.querySpanElements.filter(function (d) { + return d.ref === hoveredNode; + }).classed("hover", false); + } + }; + + /** + * Handle the click event on nodes. + */ + popoto.graph.node.nodeClick = function () { + var clickedNode = d3.select(this).data()[0]; // Clicked node data + popoto.logger.debug("nodeClick (" + clickedNode.label + ")"); + + if (clickedNode.type === popoto.graph.node.NodeTypes.VALUE) { + popoto.graph.node.valueNodeClick(clickedNode); + } else if (clickedNode.type === popoto.graph.node.NodeTypes.CHOOSE || clickedNode.type === popoto.graph.node.NodeTypes.ROOT) { + if (clickedNode.valueExpanded) { + popoto.graph.node.collapseNode(clickedNode); + } else { + popoto.graph.node.chooseNodeClick(clickedNode); + } + } + }; + + /** + * Remove all the value node directly linked to clicked node. + * + * @param clickedNode + */ + popoto.graph.node.collapseNode = function (clickedNode) { + if (clickedNode.valueExpanded) { // node is collapsed only if it has been expanded first + popoto.logger.debug("collapseNode (" + clickedNode.label + ")"); + + var linksToRemove = popoto.graph.force.links().filter(function (l) { + return l.source === clickedNode && l.type === popoto.graph.link.LinkTypes.VALUE; + }); + + // Remove children nodes from model + linksToRemove.forEach(function (l) { + popoto.graph.force.nodes().splice(popoto.graph.force.nodes().indexOf(l.target), 1); + }); + + // Remove links from model + for (var i = popoto.graph.force.links().length - 1; i >= 0; i--) { + if (linksToRemove.indexOf(popoto.graph.force.links()[i]) >= 0) { + popoto.graph.force.links().splice(i, 1); + } + } + + // Node has been fixed when expanded so we unfix it back here. + if (clickedNode.type !== popoto.graph.node.NodeTypes.ROOT) { + clickedNode.fixed = false; + } + + // Parent node too if not root + if (clickedNode.parent && clickedNode.parent.type !== popoto.graph.node.NodeTypes.ROOT) { + clickedNode.parent.fixed = false; + } + + clickedNode.valueExpanded = false; + popoto.update(); + + } else { + popoto.logger.debug("collapseNode called on an unexpanded node"); + } + }; + + /** + * Function called on a value node click. + * In this case the value is added in the parent node and all the value nodes are collapsed. + * + * @param clickedNode + */ + popoto.graph.node.valueNodeClick = function (clickedNode) { + popoto.logger.debug("valueNodeClick (" + clickedNode.label + ")"); + clickedNode.parent.value = clickedNode; + popoto.result.hasChanged = true; + popoto.graph.hasGraphChanged = true; + + popoto.graph.node.collapseNode(clickedNode.parent); + }; + + /** + * Function called on choose node click. + * In this case a query is executed to get all the possible value + * @param clickedNode + * TODO optimize with cached data? + */ + popoto.graph.node.chooseNodeClick = function (clickedNode) { + popoto.logger.debug("chooseNodeClick (" + clickedNode.label + ") with waiting state set to " + popoto.graph.node.chooseWaiting); + if (!popoto.graph.node.chooseWaiting && !clickedNode.immutable) { + + // Collapse all expanded nodes first + popoto.graph.force.nodes().forEach(function (n) { + if ((n.type == popoto.graph.node.NodeTypes.ROOT || n.type == popoto.graph.node.NodeTypes.CHOOSE) && n.valueExpanded) { + popoto.graph.node.collapseNode(n); + } + }); + + // Set waiting state to true to avoid multiple call on slow query execution + popoto.graph.node.chooseWaiting = true; + + popoto.logger.info("Values (" + clickedNode.label + ") ==> "); + popoto.rest.post( + { + "statements": [ + { + "statement": popoto.query.generateValueQuery(clickedNode) + }] + }) + .done(function (data) { + clickedNode.id = (++popoto.graph.node.idgen); + clickedNode.data = popoto.graph.node.parseResultData(data); + clickedNode.page = 1; + popoto.graph.node.expandNode(clickedNode); + popoto.graph.node.chooseWaiting = false; + }) + .fail(function (xhr, textStatus, errorThrown) { + popoto.graph.node.chooseWaiting = false; + popoto.logger.error(textStatus + ": error while accessing Neo4j server on URL:\"" + popoto.rest.CYPHER_URL + "\" defined in \"popoto.rest.CYPHER_URL\" property: " + errorThrown); + }); + } + }; + + /** + * Parse query execution result and generate an array of object. + * These objects contains of a list of properties made of result attributes with their value. + * + * @param data query execution raw data + * @returns {Array} array of structured object with result attributes. + */ + popoto.graph.node.parseResultData = function (data) { + var results = []; + + for (var x = 0; x < data.results[0].data.length; x++) { + var obj = {}; + + for (var i = 0; i < data.results[0].columns.length; i++) { + obj[data.results[0].columns[i]] = data.results[0].data[x].row[i]; + } + + results.push(obj); + } + + return results; + }; + + /** + * Compute the angle in radian between the node and its parent. + * TODO: clean or add comments to explain the code... + * + * @param node node to compute angle. + * @returns {number} angle in radian. + */ + popoto.graph.computeParentAngle = function (node) { + var angleRadian = 0; + var r = 100; + if (node.parent) { + var xp = node.parent.x; + var yp = node.parent.y; + var x0 = node.x; + var y0 = node.y; + var dist = Math.sqrt(Math.pow(xp - x0, 2) + Math.pow(yp - y0, 2)); + + var k = r / (dist - r); + var xc = (x0 + (k * xp)) / (1 + k); + + var val = (xc - x0) / r; + if (val < -1) { + val = -1; + } + if (val > 1) { + val = 1; + } + + angleRadian = Math.acos(val); + + if (yp > y0) { + angleRadian = 2 * Math.PI - angleRadian; + } + } + return angleRadian; + }; + + /** + * Function called to expand a node containing values. + * This function will create the value nodes with the clicked node internal data. + * Only nodes corresponding to the current page index will be generated. + * + * @param clickedNode + */ + popoto.graph.node.expandNode = function (clickedNode) { + + // Get subset of node corresponding to the current node page and page size + var lIndex = clickedNode.page * popoto.graph.node.PAGE_SIZE; + var sIndex = lIndex - popoto.graph.node.PAGE_SIZE; + + var dataToAdd = clickedNode.data.slice(sIndex, lIndex); + var parentAngle = popoto.graph.computeParentAngle(clickedNode); + + // Then each node are created and dispatched around the clicked node using computed coordinates. + var i = 1; + dataToAdd.forEach(function (d) { + var angleDeg; + if (clickedNode.parent) { + angleDeg = (((360 / (dataToAdd.length + 1)) * i)); + } else { + angleDeg = (((360 / (dataToAdd.length)) * i)); + } + + var nx = clickedNode.x + (100 * Math.cos((angleDeg * (Math.PI / 180)) - parentAngle)), + ny = clickedNode.y + (100 * Math.sin((angleDeg * (Math.PI / 180)) - parentAngle)); + + var node = { + "id": (++popoto.graph.node.idgen), + "parent": clickedNode, + "attributes": d, + "type": popoto.graph.node.NodeTypes.VALUE, + "label": clickedNode.label, + "count": d.count, + "x": nx, + "y": ny, + "internalID": d[popoto.query.NEO4J_INTERNAL_ID.queryInternalName] + }; + + popoto.graph.force.nodes().push(node); + + popoto.graph.force.links().push( + { + id: "l" + (++popoto.graph.node.idgen), + source: clickedNode, + target: node, + type: popoto.graph.link.LinkTypes.VALUE + } + ); + + i++; + }); + + // Pin clicked node and its parent to avoid the graph to move for selection, only new value nodes will blossom around the clicked node. + clickedNode.fixed = true; + if (clickedNode.parent && clickedNode.parent.type !== popoto.graph.node.NodeTypes.ROOT) { + clickedNode.parent.fixed = true; + } + // Change node state + clickedNode.valueExpanded = true; + popoto.update(); + }; + + /** + * Function called on a right click on a node. + * + * In this case all expanded nodes in the graph will first be closed then if no relation have been added yet a Cypher query is executed to get all the related nodes. + * A first coordinate pre-computation is done to dispatch the new node correctly around the parent node and the nodes are added with a link in the model. + * + * If no relation are found or relation were already added the right click event is used to remove the node current selection. + * + */ + popoto.graph.node.expandRelationship = function () { + // Prevent default right click event opening menu. + d3.event.preventDefault(); + + // Notify listeners + popoto.graph.nodeExpandRelationsipListeners.forEach(function (listener) { + listener(this); + }); + + // Get clicked node. + var clickedNode = d3.select(this).data()[0]; + + if (!clickedNode.linkExpanded && !popoto.graph.node.linkWaiting && !clickedNode.valueExpanded) { + popoto.graph.node.linkWaiting = true; + + popoto.logger.info("Relations (" + clickedNode.label + ") ==> "); + popoto.rest.post( + { + "statements": [ + { + "statement": popoto.query.generateLinkQuery(clickedNode) + }] + }) + .done(function (data) { + var parsedData = popoto.graph.node.parseResultData(data); + + parsedData = parsedData.filter(function (d) { + return popoto.query.filterRelation(d); + }); + + if (parsedData.length <= 0) { + // Set linkExpanded to true to avoid a new query call on next right click + clickedNode.linkExpanded = true; + clickedNode.linkCount = 0; + popoto.graph.hasGraphChanged = true; + popoto.update(); + } else { + var parentAngle = popoto.graph.computeParentAngle(clickedNode); + + var i = 1; + parsedData.forEach(function (d) { + var angleDeg; + if (parentAngle) { + angleDeg = (((360 / (parsedData.length + 1)) * i)); + } else { + angleDeg = (((360 / (parsedData.length)) * i)); + } + + var nx = clickedNode.x + (100 * Math.cos((angleDeg * (Math.PI / 180)) - parentAngle)), + ny = clickedNode.y + (100 * Math.sin((angleDeg * (Math.PI / 180)) - parentAngle)); + + var isGroupNode = popoto.provider.getIsGroup(d); + // filter multiple labels + var nodeLabel = popoto.provider.getLabelFilter(d.label); + + var node = { + "id": "" + (++popoto.graph.node.idgen), + "parent": clickedNode, + "type": (isGroupNode) ? popoto.graph.node.NodeTypes.GROUP : popoto.graph.node.NodeTypes.CHOOSE, + "label": nodeLabel, + "fixed": false, + "internalLabel": popoto.graph.node.generateInternalLabel(nodeLabel), + "x": nx, + "y": ny + }; + + popoto.graph.force.nodes().push(node); + + popoto.graph.force.links().push( + { + id: "l" + (++popoto.graph.node.idgen), + source: clickedNode, + target: node, + type: popoto.graph.link.LinkTypes.RELATION, + label: d.relationship + } + ); + + i++; + }); + + popoto.graph.hasGraphChanged = true; + clickedNode.linkExpanded = true; + clickedNode.linkCount = parsedData.length; + popoto.update(); + } + popoto.graph.node.linkWaiting = false; + }) + .fail(function (xhr, textStatus, errorThrown) { + popoto.logger.error(textStatus + ": error while accessing Neo4j server on URL:\"" + popoto.rest.CYPHER_URL + "\" defined in \"popoto.rest.CYPHER_URL\" property: " + errorThrown); + popoto.graph.node.linkWaiting = false; + }); + } + }; + + /** + * Remove all relationships from context node (including children). + */ + popoto.graph.node.collapseRelationship = function () { + d3.event.preventDefault(); + + // Get clicked node. + var clickedNode = d3.select(this).data()[0]; + + if (clickedNode.linkExpanded && clickedNode.linkCount > 0 && !popoto.graph.node.linkWaiting && !clickedNode.valueExpanded) { + + // Collapse all expanded choose nodes first to avoid having invalid displayed value node if collapsed relation contains a value. + popoto.graph.force.nodes().forEach(function (n) { + if ((n.type === popoto.graph.node.NodeTypes.CHOOSE || n.type === popoto.graph.node.NodeTypes.ROOT) && n.valueExpanded) { + popoto.graph.node.collapseNode(n); + } + }); + + var linksToRemove = popoto.graph.force.links().filter(function (l) { + return l.source === clickedNode && l.type === popoto.graph.link.LinkTypes.RELATION; + }); + + // Remove children nodes from model + linksToRemove.forEach(function (l) { + popoto.graph.node.removeNode(l.target); + }); + + // Remove links from model + for (var i = popoto.graph.force.links().length - 1; i >= 0; i--) { + if (linksToRemove.indexOf(popoto.graph.force.links()[i]) >= 0) { + popoto.graph.force.links().splice(i, 1); + } + } + + clickedNode.linkExpanded = false; + popoto.result.hasChanged = true; + popoto.graph.hasGraphChanged = true; + popoto.update(); + } + }; + + /** + * Remove a node and its relationships (recursively) from the graph. + * + * @param node the node to remove. + */ + popoto.graph.node.removeNode = function (node) { + + var linksToRemove = popoto.graph.force.links().filter(function (l) { + return l.source === node; + }); + + // Remove children nodes from model + linksToRemove.forEach(function (l) { + popoto.graph.node.removeNode(l.target); + }); + + // Remove links from model + for (var i = popoto.graph.force.links().length - 1; i >= 0; i--) { + if (linksToRemove.indexOf(popoto.graph.force.links()[i]) >= 0) { + popoto.graph.force.links().splice(i, 1); + } + } + + popoto.graph.force.nodes().splice(popoto.graph.force.nodes().indexOf(node), 1); + + }; + + /** + * Function to add on node event to clear the selection. + * Call to this function on a node will remove the selected value and triger a graph update. + */ + popoto.graph.node.clearSelection = function () { + // Prevent default event like right click opening menu. + d3.event.preventDefault(); + + // Get clicked node. + var clickedNode = d3.select(this).data()[0]; + + // Collapse all expanded choose nodes first + popoto.graph.force.nodes().forEach(function (n) { + if ((n.type === popoto.graph.node.NodeTypes.CHOOSE || n.type === popoto.graph.node.NodeTypes.ROOT) && n.valueExpanded) { + popoto.graph.node.collapseNode(n); + } + }); + + if (clickedNode.value != null && !clickedNode.immutable) { + // Remove selected value of choose node + delete clickedNode.value; + + popoto.result.hasChanged = true; + popoto.graph.hasGraphChanged = true; + popoto.update(); + } + }; + +// QUERY VIEWER ----------------------------------------------------------------------------------------------------- + popoto.queryviewer = {}; + popoto.queryviewer.containerId = "popoto-query"; + popoto.queryviewer.QUERY_STARTER = "I'm looking for"; + popoto.queryviewer.CHOOSE_LABEL = "choose"; + + /** + * Create the query viewer area. + * + */ + popoto.queryviewer.createQueryArea = function () { + var id = "#" + popoto.queryviewer.containerId; + + popoto.queryviewer.queryConstraintSpanElements = d3.select(id).append("p").attr("class", "ppt-query-constraint-elements").selectAll(".queryConstraintSpan"); + popoto.queryviewer.querySpanElements = d3.select(id).append("p").attr("class", "ppt-query-elements").selectAll(".querySpan"); + }; + + /** + * Update all the elements displayed on the query viewer based on current graph. + */ + popoto.queryviewer.updateQuery = function () { + + // Remove all query span elements + popoto.queryviewer.queryConstraintSpanElements = popoto.queryviewer.queryConstraintSpanElements.data([]); + popoto.queryviewer.querySpanElements = popoto.queryviewer.querySpanElements.data([]); + + popoto.queryviewer.queryConstraintSpanElements.exit().remove(); + popoto.queryviewer.querySpanElements.exit().remove(); + + // Update data + popoto.queryviewer.queryConstraintSpanElements = popoto.queryviewer.queryConstraintSpanElements.data(popoto.queryviewer.generateConstraintData(popoto.graph.force.links(), popoto.graph.force.nodes())); + popoto.queryviewer.querySpanElements = popoto.queryviewer.querySpanElements.data(popoto.queryviewer.generateData(popoto.graph.force.links(), popoto.graph.force.nodes())); + + // Remove old span (not needed as all have been cleaned before) + // popoto.queryviewer.querySpanElements.exit().remove(); + + // Add new span + popoto.queryviewer.queryConstraintSpanElements.enter().append("span") + .on("contextmenu", popoto.queryviewer.rightClickSpan) + .on("click", popoto.queryviewer.clickSpan) + .on("mouseover", popoto.queryviewer.mouseOverSpan) + .on("mouseout", popoto.queryviewer.mouseOutSpan); + + popoto.queryviewer.querySpanElements.enter().append("span") + .on("contextmenu", popoto.queryviewer.rightClickSpan) + .on("click", popoto.queryviewer.clickSpan) + .on("mouseover", popoto.queryviewer.mouseOverSpan) + .on("mouseout", popoto.queryviewer.mouseOutSpan); + + // Update all span + popoto.queryviewer.queryConstraintSpanElements + .attr("id", function (d) { + return d.id + }) + .attr("class", function (d) { + if (d.isLink) { + return "ppt-span-link"; + } else { + if (d.type === popoto.graph.node.NodeTypes.ROOT) { + return "ppt-span-root"; + } else if (d.type === popoto.graph.node.NodeTypes.CHOOSE) { + if (d.ref.value) { + return "ppt-span-value"; + } else { + return "ppt-span-choose"; + } + } else if (d.type === popoto.graph.node.NodeTypes.VALUE) { + return "ppt-span-value"; + } else if (d.type === popoto.graph.node.NodeTypes.GROUP) { + return "ppt-span-group"; + } else { + return "ppt-span"; + } + } + }) + .text(function (d) { + return d.term + " "; + }); + + popoto.queryviewer.querySpanElements + .attr("id", function (d) { + return d.id + }) + .attr("class", function (d) { + if (d.isLink) { + return "ppt-span-link"; + } else { + if (d.type === popoto.graph.node.NodeTypes.ROOT) { + return "ppt-span-root"; + } else if (d.type === popoto.graph.node.NodeTypes.CHOOSE) { + if (d.ref.value) { + return "ppt-span-value"; + } else { + return "ppt-span-choose"; + } + } else if (d.type === popoto.graph.node.NodeTypes.VALUE) { + return "ppt-span-value"; + } else if (d.type === popoto.graph.node.NodeTypes.GROUP) { + return "ppt-span-group"; + } else { + return "ppt-span"; + } + } + }) + .text(function (d) { + return d.term + " "; + }); + }; + + popoto.queryviewer.generateConstraintData = function (links, nodes) { + var elmts = [], id = 0; + + // Add + elmts.push( + {id: id++, term: popoto.queryviewer.QUERY_STARTER} + ); + + // Add the root node as query term + if (nodes.length > 0) { + elmts.push( + {id: id++, type: nodes[0].type, term: popoto.provider.getSemanticValue(nodes[0]), ref: nodes[0]} + ); + } + + // Add a span for each link and its target node + links.forEach(function (l) { + + var sourceNode = l.source; + var targetNode = l.target; + if (l.type === popoto.graph.link.LinkTypes.RELATION && targetNode.type !== popoto.graph.node.NodeTypes.GROUP && targetNode.value) { + if (sourceNode.type === popoto.graph.node.NodeTypes.GROUP) { + elmts.push( + {id: id++, type: sourceNode.type, term: popoto.provider.getSemanticValue(sourceNode), ref: sourceNode} + ); + } + + elmts.push({id: id++, isLink: true, term: popoto.provider.getLinkSemanticValue(l), ref: l}); + + if (targetNode.type !== popoto.graph.node.NodeTypes.GROUP) { + if (targetNode.value) { + elmts.push( + {id: id++, type: targetNode.type, term: popoto.provider.getSemanticValue(targetNode), ref: targetNode} + ); + } else { + elmts.push( + {id: id++, type: targetNode.type, term: "<" + popoto.queryviewer.CHOOSE_LABEL + " " + popoto.provider.getSemanticValue(targetNode) + ">", ref: targetNode} + ); + } + } + } + }); + + return elmts; + }; + + // TODO add option nodes in generated query when no value is available + popoto.queryviewer.generateData = function (links, nodes) { + var elmts = [], options = [], id = 0; + + // Add a span for each link and its target node + links.forEach(function (l) { + + var sourceNode = l.source; + var targetNode = l.target; + + if (targetNode.type === popoto.graph.node.NodeTypes.GROUP) { + options.push( + {id: id++, type: targetNode.type, term: popoto.provider.getSemanticValue(targetNode), ref: targetNode} + ); + } + + if (l.type === popoto.graph.link.LinkTypes.RELATION && targetNode.type !== popoto.graph.node.NodeTypes.GROUP && !targetNode.value) { + if (sourceNode.type === popoto.graph.node.NodeTypes.GROUP) { + elmts.push( + {id: id++, type: sourceNode.type, term: popoto.provider.getSemanticValue(sourceNode), ref: sourceNode} + ); + } + + elmts.push({id: id++, isLink: true, term: popoto.provider.getLinkSemanticValue(l), ref: l}); + + if (targetNode.type !== popoto.graph.node.NodeTypes.GROUP) { + if (targetNode.value) { + elmts.push( + {id: id++, type: targetNode.type, term: popoto.provider.getSemanticValue(targetNode), ref: targetNode} + ); + } else { + elmts.push( + {id: id++, type: targetNode.type, term: "<" + popoto.queryviewer.CHOOSE_LABEL + " " + popoto.provider.getSemanticValue(targetNode) + ">", ref: targetNode} + ); + } + } + } + }); + + return elmts.concat(options); + }; + + /** + * + */ + popoto.queryviewer.mouseOverSpan = function () { + d3.select(this).classed("hover", function (d) { + return d.ref; + }); + + var hoveredSpan = d3.select(this).data()[0]; + + if (hoveredSpan.ref) { + var linkElmt = popoto.graph.svg.selectAll("#" + popoto.graph.link.gID + " > g").filter(function (d) { + return d === hoveredSpan.ref; + }); + linkElmt.select("path").classed("ppt-link-hover", true); + linkElmt.select("text").classed("ppt-link-hover", true); + + var nodeElmt = popoto.graph.svg.selectAll("#" + popoto.graph.node.gID + " > g").filter(function (d) { + return d === hoveredSpan.ref; + }); + + nodeElmt.select(".ppt-g-node-background").selectAll("circle").transition().style("fill-opacity", 0.5); + } + }; + + popoto.queryviewer.rightClickSpan = function () { + var hoveredSpan = d3.select(this).data()[0]; + + if (!hoveredSpan.isLink && hoveredSpan.ref) { + var nodeElmt = popoto.graph.svg.selectAll("#" + popoto.graph.node.gID + " > g").filter(function (d) { + return d === hoveredSpan.ref; + }); + + nodeElmt.on("contextmenu").call(nodeElmt.node(), hoveredSpan.ref); + } + }; + + popoto.queryviewer.clickSpan = function () { + var hoveredSpan = d3.select(this).data()[0]; + + if (!hoveredSpan.isLink && hoveredSpan.ref) { + var nodeElmt = popoto.graph.svg.selectAll("#" + popoto.graph.node.gID + " > g").filter(function (d) { + return d === hoveredSpan.ref; + }); + + nodeElmt.on("click").call(nodeElmt.node(), hoveredSpan.ref); + } + }; + + /** + * + */ + popoto.queryviewer.mouseOutSpan = function () { + d3.select(this).classed("hover", false); + + var hoveredSpan = d3.select(this).data()[0]; + + if (hoveredSpan.ref) { + var linkElmt = popoto.graph.svg.selectAll("#" + popoto.graph.link.gID + " > g").filter(function (d) { + return d === hoveredSpan.ref; + }); + linkElmt.select("path").classed("ppt-link-hover", false); + linkElmt.select("text").classed("ppt-link-hover", false); + + var nodeElmt = popoto.graph.svg.selectAll("#" + popoto.graph.node.gID + " > g").filter(function (d) { + return d === hoveredSpan.ref; + }); + nodeElmt.select(".ppt-g-node-background").selectAll("circle").transition().style("fill-opacity", 0); + } + }; + +// CYPHER VIEWER ----------------------------------------------------------------------------------------------------- + + // TODO not available yet + popoto.cypherviewer = {}; + popoto.cypherviewer.containerId = "popoto-cypher"; + +// QUERY ------------------------------------------------------------------------------------------------------------ + popoto.query = {}; + /** + * Define the number of results displayed in result list. + */ + popoto.query.RESULTS_PAGE_SIZE = 100; + popoto.query.VALUE_QUERY_LIMIT = 1000; + popoto.query.USE_PARENT_RELATION = false; + popoto.query.USE_RELATION_DIRECTION = true; + + /** + * Immutable constant object to identify Neo4j internal ID + */ + popoto.query.NEO4J_INTERNAL_ID = Object.freeze({queryInternalName: "NEO4JID"}); + + /** + * Function used to filter returned relations + * return false if the result should be filtered out. + * + * @param d relation returned object + * @returns {boolean} + */ + popoto.query.filterRelation = function (d) { + return true; + }; + + /** + * Generate the query to count nodes of a label. + * If the label is defined as distinct in configuration the query will count only distinct values on constraint attribute. + */ + popoto.query.generateTaxonomyCountQuery = function (label) { + var constraintAttr = popoto.provider.getConstraintAttribute(label); + + var whereElements = []; + + var predefinedConstraints = popoto.provider.getPredefinedConstraints(label); + predefinedConstraints.forEach(function (predefinedConstraint) { + whereElements.push(predefinedConstraint.replace(new RegExp("\\$identifier", 'g'), "n")); + }); + + if (constraintAttr === popoto.query.NEO4J_INTERNAL_ID) { + return "MATCH (n:`" + label + "`)" + ((whereElements.length > 0) ? " WHERE " + whereElements.join(" AND ") : "") + " RETURN count(DISTINCT ID(n)) as count" + } else { + return "MATCH (n:`" + label + "`)" + ((whereElements.length > 0) ? " WHERE " + whereElements.join(" AND ") : "") + " RETURN count(DISTINCT n." + constraintAttr + ") as count" + } + }; + + /** + * Generate Cypher query match and where elements from root node, selected node and a set of the graph links. + * + * @param rootNode root node in the graph. + * @param selectedNode graph target node. + * @param links list of links subset of the graph. + * @returns {{matchElements: Array, whereElements: Array}} list of match and where elements. + * @param isConstraintNeeded + */ + popoto.query.generateQueryElements = function (rootNode, selectedNode, links, isConstraintNeeded) { + var matchElements = []; + var whereElements = []; + var rel = popoto.query.USE_RELATION_DIRECTION ? "->" : "-"; + + var rootPredefinedConstraints = popoto.provider.getPredefinedConstraints(rootNode.label); + + rootPredefinedConstraints.forEach(function (predefinedConstraint) { + whereElements.push(predefinedConstraint.replace(new RegExp("\\$identifier", 'g'), rootNode.internalLabel)); + }); + + // Generate root node match element + if (rootNode.value && (isConstraintNeeded || rootNode.immutable)) { + var rootConstraintAttr = popoto.provider.getConstraintAttribute(rootNode.label); + if (rootConstraintAttr === popoto.query.NEO4J_INTERNAL_ID) { + matchElements.push("(" + rootNode.internalLabel + ":`" + rootNode.label + "`)"); + whereElements.push("ID(" + rootNode.internalLabel + ") = " + rootNode.value.internalID); + } else { + var constraintValue = rootNode.value.attributes[rootConstraintAttr]; + + if (typeof constraintValue === "boolean" || typeof constraintValue === "number") { + matchElements.push("(" + rootNode.internalLabel + ":`" + rootNode.label + "`{`" + rootConstraintAttr + "`:" + constraintValue + "})"); + } else { + matchElements.push("(" + rootNode.internalLabel + ":`" + rootNode.label + "`{`" + rootConstraintAttr + "`:\"" + constraintValue + "\"})"); + } + } + } else { + matchElements.push("(" + rootNode.internalLabel + ":`" + rootNode.label + "`)"); + } + + // Generate match elements for each links + links.forEach(function (l) { + var sourceNode = l.source; + var targetNode = l.target; + + var predefinedConstraints = popoto.provider.getPredefinedConstraints(targetNode.label); + + predefinedConstraints.forEach(function (predefinedConstraint) { + whereElements.push(predefinedConstraint.replace(new RegExp("\\$identifier", 'g'), targetNode.internalLabel)); + }); + + if (targetNode.value && targetNode !== selectedNode && (isConstraintNeeded || rootNode.immutable)) { + var constraintAttr = popoto.provider.getConstraintAttribute(targetNode.label); + var constraintValue = targetNode.value.attributes[constraintAttr]; + if (constraintAttr === popoto.query.NEO4J_INTERNAL_ID) { + matchElements.push("(" + sourceNode.internalLabel + ":`" + sourceNode.label + "`)-[:`" + l.label + "`]" + rel + "(" + targetNode.internalLabel + ":`" + targetNode.label + "`)"); + whereElements.push("ID(" + targetNode.internalLabel + ") = " + targetNode.value.internalID); + } else { + if (typeof constraintValue === "boolean" || typeof constraintValue === "number") { + matchElements.push("(" + sourceNode.internalLabel + ":`" + sourceNode.label + "`)-[:`" + l.label + "`]" + rel + "(" + targetNode.internalLabel + ":`" + targetNode.label + "`{`" + constraintAttr + "`:" + constraintValue + "})"); + } else { + matchElements.push("(" + sourceNode.internalLabel + ":`" + sourceNode.label + "`)-[:`" + l.label + "`]" + rel + "(" + targetNode.internalLabel + ":`" + targetNode.label + "`{`" + constraintAttr + "`:\"" + constraintValue + "\"})"); + } + } + } else { + matchElements.push("(" + sourceNode.internalLabel + ":`" + sourceNode.label + "`)-[:`" + l.label + "`]" + rel + "(" + targetNode.internalLabel + ":`" + targetNode.label + "`)"); + } + }); + + return {"matchElements": matchElements, "whereElements": whereElements}; + }; + + /** + * Filter links to get only paths from root to leaf containing a value or being the selectedNode. + * All other paths in the graph containing no value are ignored. + * + * @param rootNode root node of the graph. + * @param targetNode node in the graph target of the query. + * @param initialLinks list of links repreasenting the graph to filter. + * @returns {Array} list of relevant links. + */ + popoto.query.getRelevantLinks = function (rootNode, targetNode, initialLinks) { + + var links = initialLinks.slice(); + var filteredLinks = []; + var finalLinks = []; + + // Filter all links to keep only those containing a value or being the selected node. + links.forEach(function (l) { + if (l.target.value || l.target === targetNode) { + filteredLinks.push(l); + } + }); + + // All the filtered links are removed from initial links list. + filteredLinks.forEach(function (l) { + links.splice(links.indexOf(l), 1); + }); + + // Then all the intermediate links up to the root node are added to get only the relevant links. + filteredLinks.forEach(function (fl) { + var sourceNode = fl.source; + var search = true; + + while (search) { + var intermediateLink = null; + links.forEach(function (l) { + if (l.target === sourceNode) { + intermediateLink = l; + } + }); + + if (intermediateLink === null) { // no intermediate links needed + search = false + } else { + if (intermediateLink.source === rootNode) { + finalLinks.push(intermediateLink); + links.splice(links.indexOf(intermediateLink), 1); + search = false; + } else { + finalLinks.push(intermediateLink); + links.splice(links.indexOf(intermediateLink), 1); + sourceNode = intermediateLink.source; + } + } + } + }); + + return filteredLinks.concat(finalLinks); + }; + + /** + * Get the list of link defining the complete path from node to root. + * All other links are ignored. + * + * @param node The node where to start in the graph. + * @param links + */ + popoto.query.getLinksToRoot = function (node, links) { + var pathLinks = []; + var targetNode = node; + + while (targetNode !== popoto.graph.getRootNode()) { + var nodeLink; + + for (var i = 0; i < links.length; i++) { + var link = links[i]; + if (link.target === targetNode) { + nodeLink = link; + break; + } + } + + if (nodeLink) { + pathLinks.push(nodeLink); + targetNode = nodeLink.source; + } + } + + return pathLinks; + }; + + /** + * Generate a Cypher query to retrieve all the relation available for a given node. + * + * @param targetNode + * @returns {string} + */ + popoto.query.generateLinkQuery = function (targetNode) { + + var linksToRoot = popoto.query.getLinksToRoot(targetNode, popoto.graph.force.links()); + var queryElements = popoto.query.generateQueryElements(popoto.graph.getRootNode(), targetNode, linksToRoot, false); + var matchElements = queryElements.matchElements, + returnElements = [], + whereElements = queryElements.whereElements, + endElements = []; + var rel = popoto.query.USE_RELATION_DIRECTION ? "->" : "-"; + + matchElements.push("(" + targetNode.internalLabel + ":`" + targetNode.label + "`)-[r]" + rel + "(x)"); + returnElements.push("type(r) AS relationship"); + if (popoto.query.USE_PARENT_RELATION) { + returnElements.push("head(labels(x)) AS label"); + } else { + //returnElements.push("last(labels(x)) AS label"); + returnElements.push("labels(x) AS label"); + } + returnElements.push("count(r) AS count"); + endElements.push("ORDER BY count(r) DESC"); + + return "MATCH " + matchElements.join(", ") + ((whereElements.length > 0) ? " WHERE " + whereElements.join(" AND ") : "") + " RETURN " + returnElements.join(", ") + " " + endElements.join(" "); + }; + + /** + * Generate a Cypher query + * @returns {string} + */ + popoto.query.generateResultCypherQuery = function () { + + var rootNode = popoto.graph.getRootNode(); + var queryElements = popoto.query.generateQueryElements(rootNode, rootNode, popoto.query.getRelevantLinks(rootNode, rootNode, popoto.graph.force.links()), true); + var matchElements = queryElements.matchElements, + returnElements = [], + whereElements = queryElements.whereElements, + endElements = []; + + // Sort results by specified attribute + var resultOrderByAttribute = popoto.provider.getResultOrderByAttribute(rootNode.label); + if (resultOrderByAttribute) { + var order = popoto.provider.isResultOrderAscending(rootNode.label) ? "ASC" : "DESC"; + endElements.push("ORDER BY " + resultOrderByAttribute + " " + order); + } + + endElements.push("LIMIT " + popoto.query.RESULTS_PAGE_SIZE); + + var resultAttributes = popoto.provider.getReturnAttributes(rootNode.label); + var constraintAttribute = popoto.provider.getConstraintAttribute(rootNode.label); + + for (var i = 0; i < resultAttributes.length; i++) { + var attribute = resultAttributes[i]; + if (attribute === popoto.query.NEO4J_INTERNAL_ID) { + if (attribute == constraintAttribute) { + returnElements.push("ID(" + rootNode.internalLabel + ") AS " + popoto.query.NEO4J_INTERNAL_ID.queryInternalName); + } else { + returnElements.push("COLLECT(DISTINCT ID(" + rootNode.internalLabel + ")) AS " + popoto.query.NEO4J_INTERNAL_ID.queryInternalName); + } + } else { + if (attribute == constraintAttribute) { + returnElements.push(rootNode.internalLabel + "." + attribute + " AS " + attribute); + } else { + returnElements.push("COLLECT(DISTINCT " + rootNode.internalLabel + "." + attribute + ") AS " + attribute); + } + } + } + + return "MATCH " + matchElements.join(", ") + ((whereElements.length > 0) ? " WHERE " + whereElements.join(" AND ") : "") + " RETURN DISTINCT " + returnElements.join(", ") + " " + endElements.join(" "); + }; + + popoto.query.generateResultCypherQueryCount = function () { + + var rootNode = popoto.graph.getRootNode(); + var queryElements = popoto.query.generateQueryElements(rootNode, rootNode, popoto.query.getRelevantLinks(rootNode, rootNode, popoto.graph.force.links()), true); + var constraintAttribute = popoto.provider.getConstraintAttribute(rootNode.label); + var matchElements = queryElements.matchElements, + returnElements = [], + whereElements = queryElements.whereElements, + endElements = []; + + if (constraintAttribute === popoto.query.NEO4J_INTERNAL_ID) { + returnElements.push("count(DISTINCT ID(" + rootNode.internalLabel + ")) AS count"); + } else { + returnElements.push("count(DISTINCT " + rootNode.internalLabel + "." + constraintAttribute + ") AS count"); + } + + return "MATCH " + matchElements.join(", ") + ((whereElements.length > 0) ? " WHERE " + whereElements.join(" AND ") : "") + " RETURN " + returnElements.join(", ") + (endElements.length > 0 ? " " + endElements.join(" ") : ""); + }; + + /** + * Generate the query to update node counts. + * + * @param countedNode the counted node + * @returns {string} the node count cypher query; + */ + popoto.query.generateNodeCountCypherQuery = function (countedNode) { + + var queryElements = popoto.query.generateQueryElements(popoto.graph.getRootNode(), countedNode, popoto.query.getRelevantLinks(popoto.graph.getRootNode(), countedNode, popoto.graph.force.links()), true); + var matchElements = queryElements.matchElements, + whereElements = queryElements.whereElements, + returnElements = []; + + var countAttr = popoto.provider.getConstraintAttribute(countedNode.label); + + if (countAttr === popoto.query.NEO4J_INTERNAL_ID) { + returnElements.push("count(DISTINCT ID(" + countedNode.internalLabel + ")) as count"); + } else { + returnElements.push("count(DISTINCT " + countedNode.internalLabel + "." + countAttr + ") as count"); + } + + return "MATCH " + matchElements.join(", ") + ((whereElements.length > 0) ? " WHERE " + whereElements.join(" AND ") : "") + " RETURN " + returnElements.join(", "); + }; + + /** + * Generate a Cypher query from the graph model to get all the possible values for the targetNode element. + * + * @param targetNode node in the graph to get the values. + * @returns {string} the query to execute to get all the values of targetNode corresponding to the graph. + */ + popoto.query.generateValueQuery = function (targetNode) { + + var rootNode = popoto.graph.getRootNode(); + var queryElements = popoto.query.generateQueryElements(rootNode, targetNode, popoto.query.getRelevantLinks(rootNode, targetNode, popoto.graph.force.links()), true); + var matchElements = queryElements.matchElements, + endElements = [], + whereElements = queryElements.whereElements, + returnElements = []; + + // Sort results by specified attribute + var valueOrderByAttribute = popoto.provider.getValueOrderByAttribute(targetNode.label); + if (valueOrderByAttribute) { + var order = popoto.provider.isValueOrderAscending(targetNode.label) ? "ASC" : "DESC"; + endElements.push("ORDER BY " + valueOrderByAttribute + " " + order); + } + + endElements.push("LIMIT " + popoto.query.VALUE_QUERY_LIMIT); + + var resultAttributes = popoto.provider.getReturnAttributes(targetNode.label); + var constraintAttribute = popoto.provider.getConstraintAttribute(targetNode.label); + + for (var i = 0; i < resultAttributes.length; i++) { + if (resultAttributes[i] === popoto.query.NEO4J_INTERNAL_ID) { + if (resultAttributes[i] == constraintAttribute) { + returnElements.push("ID(" + targetNode.internalLabel + ") AS " + popoto.query.NEO4J_INTERNAL_ID.queryInternalName); + } else { + returnElements.push("COLLECT (DISTINCT ID(" + targetNode.internalLabel + ")) AS " + popoto.query.NEO4J_INTERNAL_ID.queryInternalName); + } + } else { + if (resultAttributes[i] == constraintAttribute) { + returnElements.push(targetNode.internalLabel + "." + resultAttributes[i] + " AS " + resultAttributes[i]); + } else { + returnElements.push("COLLECT(DISTINCT " + targetNode.internalLabel + "." + resultAttributes[i] + ") AS " + resultAttributes[i]); + } + } + } + + // Add count return attribute on root node + var rootConstraintAttr = popoto.provider.getConstraintAttribute(rootNode.label); + + if (rootConstraintAttr === popoto.query.NEO4J_INTERNAL_ID) { + returnElements.push("count(DISTINCT ID(" + rootNode.internalLabel + ")) AS count"); + } else { + returnElements.push("count(DISTINCT " + rootNode.internalLabel + "." + rootConstraintAttr + ") AS count"); + } + + return "MATCH " + matchElements.join(", ") + ((whereElements.length > 0) ? " WHERE " + whereElements.join(" AND ") : "") + " RETURN DISTINCT " + returnElements.join(", ") + " " + endElements.join(" "); + }; + + /////////////////////////////////////////////////////////////////// + // Results + + popoto.result = {}; + popoto.result.containerId = "popoto-results"; + popoto.result.hasChanged = true; + popoto.result.resultCountListeners = []; + popoto.result.resultListeners = []; + + /** + * Register a listener to the result count event. + * This listener will be called on evry result change with total result count. + */ + popoto.result.onTotalResultCount = function (listener) { + popoto.result.resultCountListeners.push(listener); + }; + + popoto.result.onResultReceived = function (listener) { + popoto.result.resultListeners.push(listener); + }; + + /** + * Parse REST returned data and generate a list of result objects. + * + * @param data + * @returns {Array} + */ + popoto.result.parseResultData = function (data) { + + var results = []; + if (data.results && data.results.length > 0) { + for (var x = 0; x < data.results[0].data.length; x++) { + + var obj = { + "resultIndex": x, + "label": popoto.graph.getRootNode().label, + "attributes": {} + }; + + for (var i = 0; i < data.results[0].columns.length; i++) { + // Some results can be an array as collect is used in query + // So all values are converted to string + obj.attributes[data.results[0].columns[i]] = "" + data.results[0].data[x].row[i]; + } + + results.push(obj); + } + } + + return results; + }; + + popoto.result.updateResults = function () { + if (popoto.result.hasChanged) { + var query = popoto.query.generateResultCypherQuery(); + + // FIXME temporary cypher query update here. To be replaced by real interactive cypher viewer. + if (popoto.cypherviewer.isActive) { + d3.select("#" + popoto.cypherviewer.containerId) + // In this temporary version only the match part of the query is displayed to avoid huge query with lot of return attributes. + .text(query.split("RETURN")[0] + " RETURN " + popoto.graph.getRootNode().internalLabel); + } + + popoto.logger.info("Results ==> "); + popoto.rest.post( + { + "statements": [ + { + "statement": query + }] + }) + .done(function (data) { + + if (data.errors && data.errors.length > 0) { + popoto.logger.error("Cypher query error:" + JSON.stringify(data.errors)); + } + + // Parse data + var resultObjects = popoto.result.parseResultData(data); + + // Notify listeners + popoto.result.resultListeners.forEach(function (listener) { + listener(resultObjects); + }); + + // Update displayed results only if needed () + if (popoto.result.isActive) { + // Clear all results + var results = d3.select("#" + popoto.result.containerId).selectAll(".ppt-result").data([]); + results.exit().remove(); + + // Update data + results = d3.select("#" + popoto.result.containerId).selectAll(".ppt-result").data(resultObjects, function (d) { + return d.resultIndex; + }); + + // Add new elements + var pElmt = results.enter() + .append("p") + .attr("class", "ppt-result") + .attr("id", function (d) { + return "popoto-result-" + d.resultIndex; + }); + + // Generate results with providers + pElmt.each(function (d) { + popoto.provider.getDisplayResultFunction(d.label)(d3.select(this)); + }); + } + + popoto.result.hasChanged = false; + }) + .fail(function (xhr, textStatus, errorThrown) { + popoto.logger.error(textStatus + ": error while accessing Neo4j server on URL:\"" + popoto.rest.CYPHER_URL + "\" defined in \"popoto.rest.CYPHER_URL\" property: " + errorThrown); + + // Notify listeners + popoto.result.resultListeners.forEach(function (listener) { + listener([]); + }); + + }); + + // Execute query to get total result count + // But only if needed, if listeners have been added + if (popoto.result.resultCountListeners.length > 0) { + popoto.logger.info("Results count ==> "); + popoto.rest.post( + { + "statements": [ + { + "statement": popoto.query.generateResultCypherQueryCount() + }] + }) + .done(function (data) { + + if (data.errors && data.errors.length > 0) { + popoto.logger.error("Cypher query error:" + JSON.stringify(data.errors)); + } + + var count = 0; + + if (data.results && data.results.length > 0) { + count = data.results[0].data[0].row[0]; + } + + popoto.result.resultCountListeners.forEach(function (listener) { + listener(count); + }); + + }) + .fail(function (xhr, textStatus, errorThrown) { + popoto.logger.error(textStatus + ": error while accessing Neo4j server on URL:\"" + popoto.rest.CYPHER_URL + "\" defined in \"popoto.rest.CYPHER_URL\" property: " + errorThrown); + + popoto.result.resultCountListeners.forEach(function (listener) { + listener(0); + }); + }); + } + } + }; + +// NODE LABEL PROVIDERS ----------------------------------------------------------------------------------------------------- + + popoto.provider = {}; + popoto.provider.linkProvider = {}; + popoto.provider.taxonomyProvider = {}; + popoto.provider.nodeProviders = {}; + + /** + * Get the text representation of a link. + * + * @param link the link to get the text representation. + * @returns {string} the text representation of the link. + */ + popoto.provider.getLinkTextValue = function (link) { + if (popoto.provider.linkProvider.hasOwnProperty("getLinkTextValue")) { + return popoto.provider.linkProvider.getLinkTextValue(link); + } else { + if (popoto.provider.DEFAULT_LINK_PROVIDER.hasOwnProperty("getLinkTextValue")) { + return popoto.provider.DEFAULT_LINK_PROVIDER.getLinkTextValue(link); + } else { + popoto.logger.error("No provider defined for getLinkTextValue"); + } + } + }; + + /** + * Get the semantic text representation of a link. + * + * @param link the link to get the semantic text representation. + * @returns {string} the semantic text representation of the link. + */ + popoto.provider.getLinkSemanticValue = function (link) { + if (popoto.provider.linkProvider.hasOwnProperty("getLinkSemanticValue")) { + return popoto.provider.linkProvider.getLinkSemanticValue(link); + } else { + if (popoto.provider.DEFAULT_LINK_PROVIDER.hasOwnProperty("getLinkSemanticValue")) { + return popoto.provider.DEFAULT_LINK_PROVIDER.getLinkSemanticValue(link); + } else { + popoto.logger.error("No provider defined for getLinkSemanticValue"); + } + } + }; + + /** + * Label provider used by default if none have been defined for a label. + * This provider can be changed if needed to customize default behavior. + * If some properties are not found in user customized providers, default values will be extracted from this provider. + */ + popoto.provider.DEFAULT_LINK_PROVIDER = Object.freeze( + { + /** + * Function used to return the text representation of a link. + * + * The default behavior is to return the internal relation name as text for relation links. + * And return the target node text value for links between a node and its expanded values but only if text is not displayed on value node. + * + * @param link the link to represent as text. + * @returns {string} the text representation of the link. + */ + "getLinkTextValue": function (link) { + if (link.type === popoto.graph.link.LinkTypes.VALUE) { + // Links between node and list of values. + + if (popoto.provider.isTextDisplayed(link.target)) { + // Don't display text on link if text is displayed on target node. + return ""; + } else { + // No text is displayed on target node then the text is displayed on link. + return popoto.provider.getTextValue(link.target); + } + + } else { + + // Link + return link.label + } + }, + + /** + * Function used to return a descriptive text representation of a link. + * This representation should be more complete than getLinkTextValue and can contain semantic data. + * This function is used for example to generate the label in the query viewer. + * + * The default behavior is to return the getLinkTextValue. + * + * @param link the link to represent as text. + * @returns {string} the text semantic representation of the link. + */ + "getLinkSemanticValue": function (link) { + return popoto.provider.getLinkTextValue(link); + } + }); + popoto.provider.linkProvider = popoto.provider.DEFAULT_LINK_PROVIDER; + + /** + * Get the text representation of a taxonomy. + * + * @param label the label used for the taxonomy. + * @returns {string} the text representation of the taxonomy. + */ + popoto.provider.getTaxonomyTextValue = function (label) { + if (popoto.provider.taxonomyProvider.hasOwnProperty("getTextValue")) { + return popoto.provider.taxonomyProvider.getTextValue(label); + } else { + if (popoto.provider.DEFAULT_TAXONOMY_PROVIDER.hasOwnProperty("getTextValue")) { + return popoto.provider.DEFAULT_TAXONOMY_PROVIDER.getTextValue(label); + } else { + popoto.logger.error("No provider defined for taxonomy getTextValue"); + } + } + }; + + /** + * Label provider used by default if none have been defined for a label. + * This provider can be changed if needed to customize default behavior. + * If some properties are not found in user customized providers, default values will be extracted from this provider. + */ + popoto.provider.DEFAULT_TAXONOMY_PROVIDER = Object.freeze( + { + /** + * Function used to return the text representation of a taxonomy. + * + * The default behavior is to return the label without changes. + * + * @param label the label used to represent the taxonomy. + * @returns {string} the text representation of the taxonomy. + */ + "getTextValue": function (label) { + return label; + } + }); + popoto.provider.taxonomyProvider = popoto.provider.DEFAULT_TAXONOMY_PROVIDER; + + /** + * Define the different type of rendering of a node for a given label. + * TEXT: default rendering type, the node will be displayed with an ellipse and a text in it. + * IMAGE: the node is displayed as an image using the image tag in the svg graph. + * In this case an image path is required. + * SVG: the node is displayed using a list of svg path, each path can contain its own color. + */ + popoto.provider.NodeDisplayTypes = Object.freeze({TEXT: 0, IMAGE: 1, SVG: 2}); + + /** + * Get the label provider for the given label. + * If no provider is defined for the label: + * First search in parent provider. + * Then if not found will create one from default provider. + * + * @param label to retrieve the corresponding label provider. + * @returns {object} corresponding label provider. + */ + popoto.provider.getProvider = function (label) { + if (label === undefined) { + popoto.logger.error("Node label is undefined, no label provider can be found."); + } else { + if (popoto.provider.nodeProviders.hasOwnProperty(label)) { + return popoto.provider.nodeProviders[label]; + } else { + popoto.logger.debug("No direct provider found for label " + label); + + // Search in all children list definitions to find the parent provider. + for (var p in popoto.provider.nodeProviders) { + if (popoto.provider.nodeProviders.hasOwnProperty(p)) { + var provider = popoto.provider.nodeProviders[p]; + if (provider.hasOwnProperty("children")) { + if (provider["children"].indexOf(label) > -1) { + popoto.logger.debug("No provider is defined for label (" + label + "), parent (" + p + ") will be used"); + // A provider containing the required label in its children definition has been found it will be cloned. + + var newProvider = {"parent": p}; + for (var pr in provider) { + if (provider.hasOwnProperty(pr) && pr != "children" && pr != "parent") { + newProvider[pr] = provider[pr]; + } + } + + popoto.provider.nodeProviders[label] = newProvider; + return popoto.provider.nodeProviders[label]; + } + } + } + } + + popoto.logger.debug("No label provider defined for label (" + label + ") default one will be created from popoto.provider.DEFAULT_PROVIDER"); + + popoto.provider.nodeProviders[label] = {}; + // Clone default provider properties in new provider. + for (var prop in popoto.provider.DEFAULT_PROVIDER) { + if (popoto.provider.DEFAULT_PROVIDER.hasOwnProperty(prop)) { + popoto.provider.nodeProviders[label][prop] = popoto.provider.DEFAULT_PROVIDER[prop]; + } + } + return popoto.provider.nodeProviders[label]; + } + } + }; + + /** + * Get the property or function defined in node label provider. + * If the property is not found search is done in parents. + * If not found in parent, property defined in popoto.provider.DEFAULT_PROVIDER is returned. + * If not found in default provider, defaultValue is set and returned. + * + * @param label node label to get the property in its provider. + * @param name name of the property to retrieve. + * @returns {*} node property defined in its label provider. + */ + popoto.provider.getProperty = function (label, name) { + var provider = popoto.provider.getProvider(label); + + if (!provider.hasOwnProperty(name)) { + var providerIterator = provider; + + // Check parents + var isPropertyFound = false; + while (providerIterator.hasOwnProperty("parent") && !isPropertyFound) { + providerIterator = popoto.provider.getProvider(providerIterator.parent); + if (providerIterator.hasOwnProperty(name)) { + + // Set attribute in child to optimize next call. + provider[name] = providerIterator[name]; + isPropertyFound = true; + } + } + + if (!isPropertyFound) { + popoto.logger.debug("No \"" + name + "\" property found for node label provider (" + label + "), default value will be used"); + if (popoto.provider.DEFAULT_PROVIDER.hasOwnProperty(name)) { + provider[name] = popoto.provider.DEFAULT_PROVIDER[name]; + } else { + popoto.logger.error("No default value for \"" + name + "\" property found for label provider (" + label + ")"); + } + } + } + return provider[name]; + }; + + /** + * Return the "isSearchable" property for the node label provider. + * Is Searchable defined whether the label can be used as graph query builder root. + * If true the label can be displayed in the taxonomy filter. + * + * @param label + * @returns {*} + */ + popoto.provider.getIsSearchable = function (label) { + return popoto.provider.getProperty(label, "isSearchable"); + }; + + /** + * Return the list of attributes defined in node label provider. + * Parents return attributes are also returned. + * + * @param label used to retrieve parent attributes. + * @returns {Array} list of return attributes for a node. + */ + popoto.provider.getReturnAttributes = function (label) { + var provider = popoto.provider.getProvider(label); + var attributes = {}; // Object is used as a Set to merge possible duplicate in parents + + if (provider.hasOwnProperty("returnAttributes")) { + for (var i = 0; i < provider.returnAttributes.length; i++) { + if (provider.returnAttributes[i] === popoto.query.NEO4J_INTERNAL_ID) { + attributes[popoto.query.NEO4J_INTERNAL_ID.queryInternalName] = true; + } else { + attributes[provider.returnAttributes[i]] = true; + } + } + } + + // Add parent attributes + while (provider.hasOwnProperty("parent")) { + provider = popoto.provider.getProvider(provider.parent); + if (provider.hasOwnProperty("returnAttributes")) { + for (var j = 0; j < provider.returnAttributes.length; j++) { + if (provider.returnAttributes[j] === popoto.query.NEO4J_INTERNAL_ID) { + attributes[popoto.query.NEO4J_INTERNAL_ID.queryInternalName] = true; + } else { + attributes[provider.returnAttributes[j]] = true; + } + } + } + } + + // Add default provider attributes if any but not internal id as this id is added only if none has been found. + if (popoto.provider.DEFAULT_PROVIDER.hasOwnProperty("returnAttributes")) { + for (var k = 0; k < popoto.provider.DEFAULT_PROVIDER.returnAttributes.length; k++) { + if (popoto.provider.DEFAULT_PROVIDER.returnAttributes[k] !== popoto.query.NEO4J_INTERNAL_ID) { + attributes[popoto.provider.DEFAULT_PROVIDER.returnAttributes[k]] = true; + } + } + } + + // Add constraint attribute in the list + var constraintAttribute = popoto.provider.getConstraintAttribute(label); + if (constraintAttribute === popoto.query.NEO4J_INTERNAL_ID) { + attributes[popoto.query.NEO4J_INTERNAL_ID.queryInternalName] = true; + } else { + attributes[constraintAttribute] = true; + } + + + // Add all in array + var attrList = []; + for (var attr in attributes) { + if (attributes.hasOwnProperty(attr)) { + if (attr == popoto.query.NEO4J_INTERNAL_ID.queryInternalName) { + attrList.push(popoto.query.NEO4J_INTERNAL_ID); + } else { + attrList.push(attr); + } + } + } + + // If no attributes have been found internal ID is used + if (attrList.length <= 0) { + attrList.push(popoto.query.NEO4J_INTERNAL_ID); + } + return attrList; + }; + + /** + * Return the attribute to use as constraint attribute for a node defined in its label provider. + * + * @param label + * @returns {*} + */ + popoto.provider.getConstraintAttribute = function (label) { + return popoto.provider.getProperty(label, "constraintAttribute"); + }; + + /** + * Return a list of predefined constraint defined in the node label configuration. + * + * @param label + * @returns {*} + */ + popoto.provider.getPredefinedConstraints = function (label) { + return popoto.provider.getProperty(label, "getPredefinedConstraints")(); + }; + + + popoto.provider.getValueOrderByAttribute = function (label) { + return popoto.provider.getProperty(label, "valueOrderByAttribute"); + }; + + popoto.provider.isValueOrderAscending = function (label) { + return popoto.provider.getProperty(label, "isValueOrderAscending"); + }; + + popoto.provider.getResultOrderByAttribute = function (label) { + return popoto.provider.getProperty(label, "resultOrderByAttribute"); + }; + + popoto.provider.isResultOrderAscending = function (label) { + return popoto.provider.getProperty(label, "isResultOrderAscending"); + }; + + /** + * Return the value of the getTextValue function defined in the label provider corresponding to the parameter node. + * If no "getTextValue" function is defined in the provider, search is done in parents. + * If none is found in parent default provider method is used. + * + * @param node + */ + popoto.provider.getTextValue = function (node) { + return popoto.provider.getProperty(node.label, "getTextValue")(node); + }; + + + /** + * Return the value of the getTextValue function defined in the label provider corresponding to the parameter node. + * If no "getTextValue" function is defined in the provider, search is done in parents. + * If none is found in parent default provider method is used. + * + * @param node + */ + popoto.provider.getTextValue = function (node) { + return popoto.provider.getProperty(node.label, "getTextValue")(node); + }; + + /** + * Return the value of the getSemanticValue function defined in the label provider corresponding to the parameter node. + * The semantic value is a more detailed description of the node used for example in the query viewer. + * If no "getTextValue" function is defined in the provider, search is done in parents. + * If none is found in parent default provider method is used. + * + * @param node + * @returns {*} + */ + popoto.provider.getSemanticValue = function (node) { + return popoto.provider.getProperty(node.label, "getSemanticValue")(node); + }; + + /** + * Return a list of SVG paths objects, each defined by a "d" property containing the path and "f" property for the color. + * + * @param node + * @returns {*} + */ + popoto.provider.getSVGPaths = function (node) { + return popoto.provider.getProperty(node.label, "getSVGPaths")(node); + }; + + /** + * Check in label provider if text must be displayed with images nodes. + * @param node + * @returns {*} + */ + popoto.provider.isTextDisplayed = function (node) { + return popoto.provider.getProperty(node.label, "getIsTextDisplayed")(node); + }; + + /** + * Return the getIsGroup property. + * + * @param node + * @returns {*} + */ + popoto.provider.getIsGroup = function (node) { + return popoto.provider.getProperty(node.label, "getIsGroup")(node); + }; + + /** + * Return the node display type. + * can be TEXT, IMAGE, SVG or GROUP. + * + * @param node + * @returns {*} + */ + popoto.provider.getNodeDisplayType = function (node) { + return popoto.provider.getProperty(node.label, "getDisplayType")(node); + }; + + /** + * Return the file path of the image defined in the provider. + * + * @param node the node to get the image path. + * @returns {string} the path of the node image. + */ + popoto.provider.getImagePath = function (node) { + return popoto.provider.getProperty(node.label, "getImagePath")(node); + }; + + /** + * Return the width size of the node image. + * + * @param node the node to get the image width. + * @returns {int} the image width. + */ + popoto.provider.getImageWidth = function (node) { + return popoto.provider.getProperty(node.label, "getImageWidth")(node); + }; + + /** + * Return the height size of the node image. + * + * @param node the node to get the image height. + * @returns {int} the image height. + */ + popoto.provider.getImageHeight = function (node) { + return popoto.provider.getProperty(node.label, "getImageHeight")(node); + }; + + /** + * Return the displayResults function defined in label parameter's provider. + * + * @param label + * @returns {*} + */ + popoto.provider.getDisplayResultFunction = function (label) { + return popoto.provider.getProperty(label, "displayResults"); + }; + + /** + * Select the label if there is more than one. + * + * Discards the label with an underscore. + */ + popoto.provider.getLabelFilter = function (nodeLabel) { + if (Array.isArray(nodeLabel)) { + // use last label + var label = nodeLabel[nodeLabel.length - 1]; + if (label.indexOf('_') != -1 && nodeLabel.length > 1) { + // skip if wrong label + label = nodeLabel[nodeLabel.length - 2]; + } + // replace array with string + nodeLabel = label; + } + return nodeLabel; + } + + /** + * Label provider used by default if none have been defined for a label. + * This provider can be changed if needed to customize default behavior. + * If some properties are not found in user customized providers, default values will be extracted from this provider. + */ + popoto.provider.DEFAULT_PROVIDER = Object.freeze( + { + /********************************************************************** + * Label specific parameters: + * + * These attributes are specific to a node label and will be used for every node having this label. + **********************************************************************/ + + /** + * Defines whether this label can be used as root element of the graph query builder. + * This property is also used to determine whether the label can be displayed in the taxonomy filter. + * + * The default value is true. + */ + "isSearchable": true, + + /** + * Defines the list of attribute to return for node of this label. + * All the attributes listed here will be added in generated cypher queries and available in result list and in node provider's functions. + * + * The default value contains only the Neo4j internal id. + * This id is used by default because it is a convenient way to identify a node when nothing is known about its attributes. + * But you should really consider using your application attributes instead, it is a bad practice to rely on this attribute. + */ + "returnAttributes": [popoto.query.NEO4J_INTERNAL_ID], + + /** + * Defines the attribute used to order the value displayed on node. + * + * Default value is "count" attribute. + */ + "valueOrderByAttribute": "count", + + /** + * Defines whether the value query order by is ascending, if false order by will be descending. + * + * Default value is false (descending) + */ + "isValueOrderAscending": false, + + /** + * Defines the attribute used to order the results. + * + * Default value is "null" to disable order by. + */ + "resultOrderByAttribute": null, + + /** + * Defines whether the result query order by is ascending, if false order by will be descending. + * + * Default value is true (ascending) + */ + "isResultOrderAscending": true, + + /** + * Defines the attribute of the node to use in query constraint for nodes of this label. + * This attribute is used in the generated cypher query to build the constraints with selected values. + * + * The default value is the Neo4j internal id. + * This id is used by default because it is a convenient way to identify a node when nothing is known about its attributes. + * But you should really consider using your application attributes instead, it is a bad practice to rely on this attribute. + */ + "constraintAttribute": popoto.query.NEO4J_INTERNAL_ID, + + /** + * Defines the attribute of the node to display as a text identifying the node. + * + * The default value is the Neo4j internal id. + */ + "displayAttribute": popoto.query.NEO4J_INTERNAL_ID, + + /** + * Return the list of predefined constraints to add for the given label. + * These constraints will be added in every generated Cypher query. + * + * For example if the returned list contain ["$identifier.born > 1976"] for "Person" nodes everywhere in popoto.js the generated Cypher query will add the constraint + * "WHERE person.born > 1976" + * + * @returns {Array} + */ + "getPredefinedConstraints": function () { + return []; + }, + + /********************************************************************** + * Node specific parameters: + * + * These attributes are specific to nodes (in graph or query viewer) for a given label. + * But they can be customized for nodes of the same label. + * The parameters are defined by a function that will be called with the node as parameter. + * In this function the node internal attributes can be used to customize the value to return. + **********************************************************************/ + + /** + * Function returning the display type of a node. + * This type defines how the node will be drawn in the graph. + * + * The result must be one of the following values: + * + * popoto.provider.NodeDisplayTypes.IMAGE + * In this case the node will be drawn as an image and "getImagePath" function is required to return the node image path. + * + * popoto.provider.NodeDisplayTypes.SVG + * In this case the node will be drawn as SVG paths and "getSVGPaths" + * + * popoto.provider.NodeDisplayTypes.TEXT + * In this case the node will be drawn as a simple ellipse. + * + * Default value is TEXT. + * + * @param node the node to extract its type. + * @returns {number} one value from popoto.provider.NodeDisplayTypes + */ + "getDisplayType": function (node) { + return popoto.provider.NodeDisplayTypes.TEXT; + }, + + /** + * Function defining whether the node is a group node. + * In this case no count are displayed and no value can be selected on the node. + * + * Default value is false. + */ + "getIsGroup": function (node) { + return false; + }, + + /** + * Function defining whether the node text representation must be displayed on graph. + * If true the value returned for getTextValue on node will be displayed on graph. + * + * This text will be added in addition to the getDisplayType representation. + * It can be displayed on all type of node display, images, SVG or text. + * + * Default value is true + * + * @param node the node to display on graph. + * @returns {boolean} true if text must be displayed on graph for the node. + */ + "getIsTextDisplayed": function (node) { + return true; + }, + + /** + * Function used to return the text representation of a node. + * + * The default behavior is to return the label of the node + * or the value of constraint attribute of the node if it contains value. + * + * The returned value is truncated using popoto.graph.node.NODE_MAX_CHARS property. + * + * @param node the node to represent as text. + * @returns {string} the text representation of the node. + */ + "getTextValue": function (node) { + var text; + var textAttr = popoto.provider.getProperty(node.label, "displayAttribute"); + if (node.type === popoto.graph.node.NodeTypes.VALUE) { + if (textAttr === popoto.query.NEO4J_INTERNAL_ID) { + text = "" + node.internalID; + } else { + text = "" + node.attributes[textAttr]; + } + } else { + if (node.value === undefined) { + text = node.label; + } else { + if (textAttr === popoto.query.NEO4J_INTERNAL_ID) { + text = "" + node.value.internalID; + } else { + text = "" + node.value.attributes[textAttr]; + } + } + } + // Text is truncated to fill the ellipse + return text.substring(0, popoto.graph.node.NODE_MAX_CHARS); + }, + + /** + * Function used to return a descriptive text representation of a link. + * This representation should be more complete than getTextValue and can contain semantic data. + * This function is used for example to generate the label in the query viewer. + * + * The default behavior is to return the getTextValue not truncated. + * + * @param node the node to represent as text. + * @returns {string} the text semantic representation of the node. + */ + "getSemanticValue": function (node) { + var text; + var textAttr = popoto.provider.getProperty(node.label, "displayAttribute"); + if (node.type === popoto.graph.node.NodeTypes.VALUE) { + if (textAttr === popoto.query.NEO4J_INTERNAL_ID) { + text = "" + node.internalID; + } else { + text = "" + node.attributes[textAttr]; + } + } else { + if (node.value === undefined) { + text = node.label; + } else { + if (textAttr === popoto.query.NEO4J_INTERNAL_ID) { + text = "" + node.value.internalID; + } else { + text = "" + node.value.attributes[textAttr]; + } + } + } + return text; + }, + + /** + * Function returning the image file path to use for a node. + * This function is only used for popoto.provider.NodeDisplayTypes.IMAGE type nodes. + * + * @param node + * @returns {string} + */ + "getImagePath": function (node) { + if (node.type === popoto.graph.node.NodeTypes.VALUE) { + return "css/image/node-yellow.png"; + } else { + if (node.value === undefined) { + if (node.type === popoto.graph.node.NodeTypes.ROOT) { + return "css/image/node-blue.png"; + } + if (node.type === popoto.graph.node.NodeTypes.CHOOSE) { + return "css/image/node-green.png"; + } + if (node.type === popoto.graph.node.NodeTypes.GROUP) { + return "css/image/node-black.png"; + } + } else { + return "css/image/node-orange.png"; + } + } + }, + + /** + * Function returning the image width of the node. + * This function is only used for popoto.provider.NodeDisplayTypes.IMAGE type nodes. + * + * @param node + * @returns {number} + */ + "getImageWidth": function (node) { + return 125; + }, + + /** + * Function returning the image height of the node. + * This function is only used for popoto.provider.NodeDisplayTypes.IMAGE type nodes. + * + * @param node + * @returns {number} + */ + "getImageHeight": function (node) { + return 125; + }, + + /********************************************************************** + * Results specific parameters: + * + * These attributes are specific to result display. + **********************************************************************/ + + /** + * Generate the result entry content using d3.js mechanisms. + * + * The parameter of the function is the <p> selected with d3.js + * + * The default behavior is to generate a <table> containing all the return attributes in a <th> and their value in a <td>. + * + * @param pElmt the <p> element generated in the result list. + */ + "displayResults": function (pElmt) { + var result = pElmt.data()[0]; + + var returnAttributes = popoto.provider.getReturnAttributes(result.label); + + var table = pElmt.append("table").attr("class", "ppt-result-table"); + + returnAttributes.forEach(function (attribute) { + var tr = table.append("tr"); + tr.append("th").text(function () { + return attribute + ":"; + }); + if (result.attributes[attribute] !== undefined) { + tr.append("td").text(function (result) { + return result.attributes[attribute]; + }); + } + }); + } + + }); + + return popoto; +}(); \ No newline at end of file