From: Steve Sutton Date: Thu, 4 Sep 2014 19:10:47 +0000 (-0400) Subject: add headway X-Git-Url: http://cvs2.gaslightmedia.com/gitweb/index.cgi?a=commitdiff_plain;h=69b0a289f23b875958d2c5626dcc4625aa246d5b;p=web%2FPetoskeyRobotics.git add headway --- diff --git a/wp-content/themes/headway/README.txt b/wp-content/themes/headway/README.txt new file mode 100644 index 0000000..d9209b9 --- /dev/null +++ b/wp-content/themes/headway/README.txt @@ -0,0 +1,10 @@ +Headway Base Installation +http://headwaythemes.com/ + +INSTALL: +1. Upload Headway Base via FTP to your wp-content/themes/ directory. +2. Go to your WordPress dashboard and select Appearance. +3. Select Headway Base and click activate. + +SUPPORT & DOCUMENTATION: +If you are looking for detailed documentation or theme support, please visit http://support.headwaythemes.com/ \ No newline at end of file diff --git a/wp-content/themes/headway/docs/license.txt b/wp-content/themes/headway/docs/license.txt new file mode 100644 index 0000000..0f780dc --- /dev/null +++ b/wp-content/themes/headway/docs/license.txt @@ -0,0 +1,281 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 51 Franklin St, Fifth Floor, Boston, MA 02110, USA + + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) 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 +this service 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 make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. 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. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute 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 and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +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 +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the 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 a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, 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. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE 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. + + END OF TERMS AND CONDITIONS + diff --git a/wp-content/themes/headway/docs/terms_of_service.txt b/wp-content/themes/headway/docs/terms_of_service.txt new file mode 100644 index 0000000..9268c55 --- /dev/null +++ b/wp-content/themes/headway/docs/terms_of_service.txt @@ -0,0 +1,152 @@ +TERMS & CONDITIONS + +This End User License Agreement is a binding legal agreement between you and Vesped, Inc, d/b/a Headway Themes, LLC (Company). Purchase, installation or use of Headway Themes (Service) provided on HeadwayThemes.com signifies that you have read, understood, and agreed to be bound by the terms outlined below. + +1. HEADWAY THEMES LICENSING + +HEADWAY THEMES GPL LICENSING + +All WordPress themes produced by Headway Themes, LLC (Company) are released under the GPL version 2.0 license (http://www.gnu.org/licenses/gpl-2.0.html GNU/GPLv2). + +THEME DELIVERY + +After your payment has been successfully received, you will receive download links and support forum registration information to the email address you provided during purchase. If you do not receive an email after this time period, contact at support@headwaythemes.com + + +2. TERMS OF SERVICE FOR MEMBERSHIP + +A. SIMPLE VERSION + +As a paid customer of the Service, you are a member of the HeadwayThemes.com website community. This allows you to get upgraded versions of Headway Themes, support in the forums, quick access to new products, and other benefits of membership, all subject to the terms and conditions contained in this document. + +HEADWAY BASE: + +The Headway Base Plan entitles you access to Headway Members only support and product updates for a period of one (1) year. You may use Headway Base on an unlimited number of domains. You may remove the footer attribution linking to headwaythemes.com if you want. + +HEADWAY STANDARD: + +The Headway Standard Plan entitles you access to Headway Members only support and product updates for a period of one (1) year. You may use Headway Standard on an unlimited number of domains. You may remove the footer attribution linking to headwaythemes.com if you want. You also get access to 3 Headway Child Themes during your year of membership. + +HEADWAY ALL-ACCESS: + +The Headway All-Access Plan entitles you access to Headway Members only support and product updates for a period of one (1) year. You may use Headway All-Access on an unlimited number of domains. You may remove the footer attribution linking to headwaythemes.com if you want. You also get access to all Headway Child Themes during your year of membership. With the All-Access plan you also have access to early beta releases and exclusive developer webinars. + +* For the above plans, you get access to updates and support for a period of one (1) year. At that time you will be required to renew your membership to receive product updates and support for another year. + +HEADWAY LIFETIME PASS: + +The Headway Lifetime Pass Plan entitles you access to Headway Members only support and product updates for life. You may use Headway Lifetime Pass Plan on an unlimited number of domains. You may remove the footer attribution linking to headwaythemes.com if you want. You also get access to all Headway Child Themes released. With the All-Access plan you also have access to early beta releases and exclusive developer webinars. + +* Access to product updates and support is for lifetime. + +Use or distribution of Headway Themes in violation of the terms and conditions of membership contained in this document will result in termination of your membership, without refund. Also, please be civil and considerate when making use of the support forums, as bad behavior is also grounds for termination of your membership. + +B. LEGAL STUFF + +Use and enjoyment of services ("Service") from Headway Themes, LLC ("Headway Themes, LLC"), owned and operated by Vesped, Inc, d/b/a Headway Themes, LLC, is provided to you ("you" or "Member") under the Headway Themes Membership Terms and Conditions of Service ("Terms and Conditions of Service" or "Agreement"). + +Headway Themes, LLC reserves the right to update and change the Terms and Conditions of Service from time to time without notice. Any new features that augment or enhance the current Service, including the release of new features and resources, shall be subject to the Terms and Conditions of Service. Continued use of the Service after any such changes shall constitute your consent to such changes. Members can review the most current version of the Terms and Conditions of Service at any time at this URL: http://headwaythemes.com/terms_of_service.txt + +Violation of any of the terms below will result in the termination of your Membership. You agree to use the Service at your own risk. + +MEMBERSHIP AND ACCOUNT TERMS + +HeadwayThemes.com is a membership website. Use of enjoyment of Membership benefits, such as product access, updates, support, training and other benefits of Membership are provided to paid Members in good standing only. You are responsible for updating your information, including contact names, addresses, telephone numbers and credit card information (as applicable) in a timely manner. + +* Members must be 18 years or older to use this Service. + +* Members are responsible for maintaining the security of accounts and passwords. Headway Themes, LLC cannot and will not be liable for any loss or damage from your failure to comply with this security obligation. + +* Members are responsible for all Content posted and activity that occurs under your account. + +* Members may not use the Service for any illegal or unauthorized purpose. You must not, in the use of the Service, violate any laws in your jurisdiction (including but not limited to copyright and trademark laws). + +LICENSE, ACKNOWLEDGMENTS AND WARRANTIES + +Headway Themes (Service) Members submitting content in forums grant Headway Themes, LLC the rights to distribute, display, reproduce, reformat, translate, archive, license, edit, modify and create derivative works and/or excerpts of any such material for purposes of distributing the material as part of Company's products and services (and the promotion of same). + +No Member Content submitted by Member shall contain any content that is obscene, libelous, slanderous or otherwise defamatory, false or misleading or which violates any copyright, right of privacy or publicity or other right of any person, and the Member Content will not contain any viruses, scripts, macros, or programs or links to macros, scripts, programs, or any code that alters, destroys or inhibits the operation of, or infiltrates, computer systems or data run through such computer systems. Member shall indemnify and hold harmless Headway Themes, LLC, its affiliates and agents, and those licensed or otherwise authorized by Headway Themes, LLC to process, transmit or distribute Member Content from and against any and all claims, losses, damages, liabilities, costs and expenses (including reasonable attorney's fees) arising out of or relating to any breach by Member of the foregoing representations and warranties or otherwise arising out of or relating to the contents or nature of the Member Content. + +MODIFICATION TO THE SERVICE AND PRICES + +Headway Themes, LLC reserves the right at any time and from time to time to modify or discontinue, temporarily or permanently, the Service (or any part thereof) with or without notice. + +Prices of all Services, including but not limited to upgrade packages and membership fees, are subject to change at anytime. + +Headway Themes, LLC shall not be liable to you or to any third party for any modification, price change, suspension or discontinuance of the Service. + +PAYMENTS AND REFUNDS + +Payment - A valid credit card or PayPal account is required for purchasing upgrades or additional products or services. + +Refunds - Headway Themes, LLC does not offer refunds. + +TERM + +Term of membership, with the exception of the Headway Lifetime Pass, is for a period of one year from date of purchase as long as Member continues to use Headway Themes, LLC services, or until such time as either party notifies the other to terminate with or without cause. These Terms and Conditions, including any revisions, remain in effect for the duration of membership. + +Term of membership for Headway Lifetime Pass is perpetual from date of purchase as long as Member continues to use Headway Themes, LLC services, or until such time as either party notifies the other to terminate with or without cause. These Terms and Conditions, including any revisions, remain in effect for the duration of membership. + +ACCESS + +During the Term, you are authorized to access the Service solely to manage your Headway Themes member account(s) or as otherwise authorized by Headway Themes, LLC in writing. You agree that you will not use the Service or any content therein or data obtained there from for any other purpose and that you will not disseminate any of this information. Your right to access your account with the Service (including, without limitation, any login or other access information) is personal to you, non-transferable and non-assignable, and is subject to any limits established by Headway Themes, LLC. You agree that you will not use any automated means, including, without limitation, agents, robots, scripts, or spiders, to access or manage your account with the Service or to monitor or copy the Service websites or the content contained therein except those automated means expressly made available by Headway Themes, LLC, if any, or authorized in advance and in writing by Headway Themes, LLC (for example, Headway Themes-approved third party tools and services). Without limitation to the foregoing, you further agree that you will not take any action that imposes an unreasonable or disproportionately large load on the Service as determined by Headway Themes, LLC. + +INDEMNITY AND LIMITATION OF LIABILITY + +Member will indemnify and hold harmless Headway Themes, LLC and its, affiliate and subsidiary companies, officers, directors, employees, licensees, successors and assigns, including those licensed or authorized by Headway Themes, LLC to transmit and distribute materials, from any and all liabilities, damages, judgments, claims, costs, losses, and expenses (including reasonable legal fees and costs) arising out of or related to any and all claims alleging conduct that would amount to a breach of any of Company's representations and warranties in the Membership Agreement, including these Terms and Conditions. + +HEADWAY THEMES, LLC SHALL NOT BE LIABLE TO MEMBER FOR ANY INDIRECT, INCIDENTAL, CONSEQUENTIAL, SPECIAL OR EXEMPLARY DAMAGES (EVEN IF HEADWAY THEMES, LLC HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES), ARISING FROM OR RELATED IN ANY WAY TO ANY PROVISION OF THIS AGREEMENT (INCLUDING SUCH DAMAGES INCURRED BY THIRD PARTIES), INCLUDING BUT NOT LIMITED TO LOSS OF REVENUE OR ANTICIPATED PROFITS OR LOST BUSINESS. IN NO EVENT SHALL HEADWAY THEMES BE LIABLE TO MEMBER FOR AN AMOUNT GREATER THAN THE PAYMENTS MADE BY MEMBER TO HEADWAY THEMES, LLC FOR PRODUCTS AND SERVICES PROVIDED PURSUANT TO THE TERMS OF THIS AGREEMENT. Some jurisdictions do not allow the exclusion of liability for incidental or consequential damages, so some or all of the above exclusions or limitations may not apply. + +CANCELLATION AND TERMINATION + +Headway Themes, LLC, in its sole discretion, has the right to suspend or terminate your account and refuse any and all current or future use of the Service, or any other Headway Themes, LLC service, for violation of these Member Terms of Service. Such termination of the Service will result in the deactivation or deletion of your Account or your access to your Account, and the forfeiture and relinquishment of all content in your account. Headway Themes, LLC reserves the right to refuse service to anyone for any reason at any time, and to refund your payment and terminate your account in the sole discretion of Headway Themes, LLC. + +If Member is dissatisfied with any aspect of the Service(s), your sole and exclusive remedy is to terminate the Agreement and/or the Service(s) Terms by requesting your account be closed. + +Reasons for Headway Themes, LLC's determination to so terminate, suspend or discontinue your account or participation may include, but is not limited to, if Headway Themes, LLC believes that you violated the Agreement or other policies or guidelines of the Service, a Third Party Product, or if Headway Themes, LLC believes Member conduct may be harmful to other consumers, members or licensees who participate in (or offer to its users) the Service Web Sites (and/or any part thereof). + +All decisions made by Headway Themes, LLC in this matter will be final and neither Headway Themes, LLC nor any of the Headway Themes, LLC Entities shall have any liability regarding such decisions. + +MAJEURE + +If Service is prevented or delayed in or from performing any of its obligations under the Agreement due to circumstances beyond its control, including but not limited to governmental acts, war, riots, strikes or trade disputes (including by and with our own employees), technical failure, general availability of the internet, power failure, communications failure, weather, flood, fire or explosion, natural or local emergency, Headway Themes, LLC shall not be liable for any resulting failure to provide services hereunder. + +NOTICES + +Any notices or communications under the agreement shall be by electronic mail or in writing and shall be deemed delivered upon receipt to the party to whom such communication is directed, at the addresses specified below. If to Headway Themes, LLC, such notices shall be addressed to support@headwaythemes.com or to Grant Griffiths, Headway Themes, LLC, 513 Prospect Street, Clay Center, Kansas 67432 , USA. If to Member, such notices shall be addressed to the electronic or mailing address specified in Members's service registration form, or such other address as either party may give the other by notice as provided in this section. It is the applicant's responsibility to provide an accurate address and to ensure that the Service is notified of any changes to applicant's address as specified in this section. + +GOVERNING LAW, VENUE AND ATTORNEYS FEES + +The Membership Agreement, including these Terms and Conditions, shall be governed by and construed in accordance with the laws of the United States and the State of Kansas. Any dispute arising under or related in any way to this Agreement shall be adjudicated in a court of competent jurisdiction in the County of Clay, Kansas. In the event of litigation to enforce any provision of the Membership Agreement, including these Terms and Conditions, the prevailing party will be entitled to recover from the other party its costs and fees, including reasonable legal fees. + +ELECTRONIC SIGNATURES EFFECTIVE + +The Agreement is an electronic contract that sets out the legally binding terms of your use of the Service's products and services, including, without limitation, the Service Web Sites. You indicate your acceptance of the Agreement and all of the terms and conditions contained or referenced in the Agreement and these Member Terms of Service and in any Programs Terms by clicking on the "I Accept" button in connection with your enrollment. This action creates an electronic signature that has the same legal force and effect as a handwritten signature. By clicking on the "I Accept" button, you accept the Agreement, including, without limitation, the Programs Terms and agree to the terms, conditions and notices contained or referenced therein. When you click on the "I Accept" button during enrollment, you also consent to have the Agreement provided to you in electronic form. You have the right to receive the Agreement in non-electronic form. + +In order to access and retain this electronic Agreement, you must have access to the World Wide Web, either directly or through devices that access web-based content, and pay any service fees associated with such access. In addition, you must use all equipment necessary to make such connection to the World Wide Web, including, without limitation, a computer and modem or other access device. Please print a copy of the Agreement for your records. To retain an electronic copy of the Agreement, you may save it into any word processing program. We will notify you of any changes in the hardware or software requirements needed to access and/or retain the Agreement that create a material risk that you will not be able to continue to access and/or retain the electronic Agreement. + +TRADEMARK INFORMATION + +All logos, product, and service name related to these TOS are trademarks of Headway Themes, LLC. Without Headway Themes, LLC's prior permission, you agree not to display or use in any manner the Headway Themes Trademarks. + +3. GENERAL CONDITIONS + +* Each Member uses the Service at Member's sole risk. The Service is provided on an "as is" and "as available" basis. +Technical support is only available via the support forum + +* Member must not use any Headway Themes, LLC digital products in a manner not permitted by the terms of Member's membership level, and must not distribute any Headway Themes, LLC digital products to third parties by any means, including but not limited to posting download links at public or private forums, websites, peer-to-peer networks, torrents, or email lists. With the exception to those as authorized by the GPL version 2.0 license (http://www.gnu.org/licenses/gpl-2.0.html GNU/GPLv2). Headway Themes, LLC reserves all rights with respect to its intellectual property, and all remedies, in law and in equity. + +* Member must not modify, adapt or hack the Service or modify another website so as to falsely imply that it is associated with the Service, Headway Themes, LLC, or any other Headway Themes, LLC service. + +* Member agree not to reproduce, duplicate, copy, sell, resell or exploit any portion of the Service, use of the Service, or access to the Service without the express written permission by Headway Themes, LLC. With the exception to those as authorized by the GPL version 2.0 license (http://www.gnu.org/licenses/gpl-2.0.html GNU/GPLv2). +Headway Themes, LLC may, but has no obligation to, remove Content and Accounts containing Content that we determine in our sole discretion are unlawful, offensive, threatening, libelous, defamatory, pornographic, obscene or otherwise objectionable or violates any party's intellectual property or these Terms of Service. + +* Verbal, physical, written or other abuse (including threats of abuse or retribution) of any Headway Themes, LLC customer, employee, member, or officer will result in immediate account termination. + +* Headway Themes, LLC does not warrant that (i) the service will meet your specific requirements, (ii) the service will be uninterrupted, timely, secure, or error-free, (iii) the results that may be obtained from the use of the service will be accurate or reliable, (iv) the quality of any products, services, information, or other material purchased or obtained by you through the service will meet your expectations, and (v) any errors in the Service will be corrected. + +* Member expressly understands and agrees that Headway Themes, LLC shall not be liable for any direct, indirect, incidental, special, consequential or exemplary damages, including but not limited to, damages for loss of profits, goodwill, use, data or other intangible losses (even if Headway Themes, LLC has been advised of the possibility of such damages), resulting from: (i) the use or the inability to use the Service; (ii) the cost of procurement of substitute goods and services resulting from any goods, data, information or services purchased or obtained or messages received or transactions entered into through or from the service; (iii) unauthorized access to or alteration of your transmissions or data; (iv) statements or conduct of any third party on the service; (v) or any other matter relating to the service. Headway Themes, LLC’s liability to you shall not, for any reason, exceed the amount actually paid by you to Headway Themes, LLC. + +* The failure of Headway Themes, LLC to exercise or enforce any right or provision of the Terms of Service shall not constitute a waiver of such right or provision. The Terms of Service constitutes the entire agreement between you and Headway Themes, LLC and govern your use of the Service, superseding any prior agreements between you and Headway Themes, LLC (including, but not limited to, any prior versions of the Terms of Service). + +Effective Date December 1st, 2011 diff --git a/wp-content/themes/headway/footer.php b/wp-content/themes/headway/footer.php new file mode 100644 index 0000000..2c1949e --- /dev/null +++ b/wp-content/themes/headway/footer.php @@ -0,0 +1,11 @@ +add_menu(array( + 'id' => 'headway', + 'title' => 'Headway', + 'href' => add_query_arg(array('visual-editor' => 'true', 'visual-editor-mode' => $default_visual_editor_mode, 've-layout' => HeadwayLayout::get_current()), home_url()) + )); + + //Visual Editor + $wp_admin_bar->add_menu(array( + 'parent' => 'headway', + 'id' => 'headway-ve', + 'title' => 'Visual Editor', + 'href' => add_query_arg(array('visual-editor' => 'true', 'visual-editor-mode' => $default_visual_editor_mode, 've-layout' => HeadwayLayout::get_current()), home_url()) + )); + + //Grid + if ( current_theme_supports('headway-grid') ) { + + $wp_admin_bar->add_menu(array( + 'parent' => 'headway-ve', + 'id' => 'headway-ve-grid', + 'title' => 'Grid', + 'href' => add_query_arg(array('visual-editor' => 'true', 'visual-editor-mode' => 'grid', 've-layout' => HeadwayLayout::get_current()), home_url()) + )); + + } + + //Design Editor + $wp_admin_bar->add_menu(array( + 'parent' => 'headway-ve', + 'id' => 'headway-ve-design', + 'title' => 'Design', + 'href' => add_query_arg(array('visual-editor' => 'true', 'visual-editor-mode' => 'design', 've-layout' => HeadwayLayout::get_current()), home_url()) + )); + + //Templates + $wp_admin_bar->add_menu(array( + 'parent' => 'headway', + 'id' => 'headway-admin-templates', + 'title' => 'Templates', + 'href' => admin_url('admin.php?page=headway-templates') + )); + + //Admin Options + $wp_admin_bar->add_menu(array( + 'parent' => 'headway', + 'id' => 'headway-admin-options', + 'title' => 'Options', + 'href' => admin_url('admin.php?page=headway-options') + )); + + $wp_admin_bar->add_menu(array( + 'parent' => 'headway-admin-options', + 'id' => 'headway-admin-options-general', + 'title' => 'General', + 'href' => admin_url('admin.php?page=headway-options#tab-general') + )); + + $wp_admin_bar->add_menu(array( + 'parent' => 'headway-admin-options', + 'id' => 'headway-admin-options-seo', + 'title' => 'Search Engine Optimization', + 'href' => admin_url('admin.php?page=headway-options#tab-seo') + )); + + $wp_admin_bar->add_menu(array( + 'parent' => 'headway-admin-options', + 'id' => 'headway-admin-options-scripts', + 'title' => 'Scripts/Analytics', + 'href' => admin_url('admin.php?page=headway-options#tab-scripts') + )); + + $wp_admin_bar->add_menu(array( + 'parent' => 'headway-admin-options', + 'id' => 'headway-admin-options-visual-editor', + 'title' => 'Visual Editor', + 'href' => admin_url('admin.php?page=headway-options#tab-visual-editor') + )); + + $wp_admin_bar->add_menu(array( + 'parent' => 'headway-admin-options', + 'id' => 'headway-admin-options-advanced', + 'title' => 'Advanced', + 'href' => admin_url('admin.php?page=headway-options#tab-advanced') + )); + + //Admin Tools + $wp_admin_bar->add_menu(array( + 'parent' => 'headway', + 'id' => 'headway-admin-tools', + 'title' => 'Tools', + 'href' => admin_url('admin.php?page=headway-tools') + )); + + $wp_admin_bar->add_menu(array( + 'parent' => 'headway-admin-tools', + 'id' => 'headway-admin-tools-system-info', + 'title' => 'System Info', + 'href' => admin_url('admin.php?page=headway-tools#tab-system-info') + )); + + $wp_admin_bar->add_menu(array( + 'parent' => 'headway-admin-tools', + 'id' => 'headway-admin-tools-reset', + 'title' => 'Reset', + 'href' => admin_url('admin.php?page=headway-tools#tab-reset') + )); + + } + + +} \ No newline at end of file diff --git a/wp-content/themes/headway/library/admin/admin-meta-boxes.php b/wp-content/themes/headway/library/admin/admin-meta-boxes.php new file mode 100644 index 0000000..d1ebe67 --- /dev/null +++ b/wp-content/themes/headway/library/admin/admin-meta-boxes.php @@ -0,0 +1,291 @@ + array( + 'id' => 'template', + 'type' => 'select', + 'options' => array(), + 'description' => 'Assign a shared layout to this entry. Shared layouts can be added and modified in the Headway Visual Editor.', + 'blank-option' => '– Do Not Use Shared Layout –' + ) + ); + + protected function modify_arguments($post = false) { + + $this->inputs['template']['options'] = HeadwayLayout::get_templates(); + + $post_type = get_post_type_object( $post->post_type ); + + $this->inputs['template']['description'] = str_replace('entry', strtolower($post_type->labels->singular_name), $this->inputs['template']['description']); + + } + +} + +headway_register_admin_meta_box('HeadwayMetaBoxTitleControl'); +class HeadwayMetaBoxTitleControl extends HeadwayAdminMetaBoxAPI { + + protected $id = 'alternate-title'; + + protected $name = 'Title Control'; + + protected $context = 'side'; + + protected $inputs = array( + 'hide-title' => array( + 'id' => 'hide-title', + 'name' => 'Hide Title', + 'type' => 'select', + 'blank-option' => '– Do Not Hide Title –', + 'options' => array( + 'singular' => 'Hide on Single View', + 'list' => 'Hide in Index and Archives', + 'both' => 'Hide on Single View, Index, and Archives' + ), + 'description' => 'Choose whether or not you would like to hide the title for this entry. This can be useful if you have advanced formatting in this entry.', + ), + + 'alternate-title' => array( + 'id' => 'alternate-title', + 'name' => 'Alternate Title', + 'type' => 'text', + 'description' => 'Using the alternate page title, you can override the title that\'s displayed in the Content Block of the page. Doing this, you can have a shorter page title in the navigation menu and <title>, but have a longer and more descriptive title in the actual page content.' + ) + ); + +} + + +headway_register_admin_meta_box('HeadwayMetaBoxDisplay'); +class HeadwayMetaBoxDisplay extends HeadwayAdminMetaBoxAPI { + + protected $id = 'display'; + + protected $name = 'Display'; + + protected $inputs = array( + 'css-class' => array( + 'id' => 'css-class', + 'name' => 'Custom CSS Class(es)', + 'type' => 'text', + 'description' => 'If you are familiar with CSS and would like to style this entry by targeting a certain CSS class (or classes), then you may enter them in here. The class will be added to the entry container\'s class along with the body class if only this entry is being viewed (e.g. single post or page view). Classes can be separated with spaces and/or commas.' + ) + ); + +} + + +headway_register_admin_meta_box('HeadwayMetaBoxPostThumbnail'); +class HeadwayMetaBoxPostThumbnail extends HeadwayAdminMetaBoxAPI { + + protected $id = 'post-thumbnail'; + + protected $name = 'Featured Image Position'; + + protected $context = 'side'; + + protected $priority = 'low'; + + protected $inputs = array( + 'position' => array( + 'id' => 'position', + 'name' => 'Featured Image Position', + 'type' => 'radio', + 'options' => array( + '' => 'Use Block Default', + 'left' => 'Left', + 'right' => 'Right', + 'above-title' => 'Above Title', + 'above-content' => 'Above Content' + ), + 'description' => 'Set the position of the featured image for this entry.', + 'default' => '', + 'group' => 'post-thumbnail' + ), + ); + +} + + +if ( !HeadwaySEO::plugin_active() ) + headway_register_admin_meta_box('HeadwayMetaBoxSEO'); +class HeadwayMetaBoxSEO extends HeadwayAdminMetaBoxAPI { + + protected $id = 'seo'; + + protected $name = 'Search Engine Optimization (SEO)'; + + protected $post_type_supports_id = 'headway-seo'; + + protected $priority = 'high'; + + protected $inputs = array( + 'seo-preview' => array( + 'id' => 'seo-preview', + 'type' => 'seo-preview' + ), + + 'title' => array( + 'id' => 'title', + 'group' => 'seo', + 'name' => 'Title', + 'type' => 'text', + 'description' => 'Custom <title> tag' + ), + + 'description' => array( + 'id' => 'description', + 'group' => 'seo', + 'name' => 'Description', + 'type' => 'textarea', + 'description' => 'Custom <meta> description' + ), + + 'noindex' => array( + 'id' => 'noindex', + 'group' => 'seo', + 'name' => 'noindex this entry.', + 'type' => 'checkbox', + 'description' => 'Index/NoIndex tells the engines whether the entry should be crawled and kept in the engines\' index for retrieval. If you check this box to opt for noindex, the entry will be excluded from the engines. Note: if you\'re not sure what this does, do not check this box.' + ), + + 'nofollow' => array( + 'id' => 'nofollow', + 'group' => 'seo', + 'name' => 'nofollow links in this entry.', + 'type' => 'checkbox', + 'description' => 'Follow/NoFollow tells the engines whether links on the entry should be crawled. If you check this box to employ "nofollow," the engines will disregard the links on the entry both for discovery and ranking purposes. Note: if you\'re not sure what this does, do not check this box.' + ), + + 'noarchive' => array( + 'id' => 'noarchive', + 'group' => 'seo', + 'name' => 'noarchive links in this entry.', + 'type' => 'checkbox', + 'description' => 'Noarchive is used to restrict search engines from saving a cached copy of the entry. By default, the engines will maintain visible copies of all pages they indexed, accessible to searchers through the "cached" link in the search results. Check this box to restrict search engines from storing cached copies of this entry.' + ), + + 'nosnippet' => array( + 'id' => 'nosnippet', + 'group' => 'seo', + 'name' => 'nosnippet links in this entry.', + 'type' => 'checkbox', + 'description' => 'Nosnippet informs the engines that they should refrain from displaying a descriptive block of text next to the entry\'s title and URL in the search results.' + ), + + 'noodp' => array( + 'id' => 'noodp', + 'group' => 'seo', + 'name' => 'noodp links in this entry.', + 'type' => 'checkbox', + 'description' => 'NoODP is a specialized tag telling the engines not to grab a descriptive snippet about a page from the Open Directory Project (DMOZ) for display in the search results.' + ), + + 'noydir' => array( + 'id' => 'noydir', + 'group' => 'seo', + 'name' => 'noydir links in this entry.', + 'type' => 'checkbox', + 'description' => 'NoYDir, like NoODP, is specific to Yahoo!, informing that engine not to use the Yahoo! Directory description of a page/site in the search results.' + ), + + 'redirect-301' => array( + 'id' => 'redirect-301', + 'group' => 'seo', + 'name' => '301 Permanent Redirect', + 'type' => 'text', + 'description' => 'The 301 Permanent Redirect can be used to forward an old post or page to a new or different location. If you ever move a page or change a page\'s permalink, use this to forward your visitors to the new location.

Want more information? Read more about 301 Redirects.' + ), + + ); + + + protected function input_seo_preview() { + + global $post; + + $date = get_the_time('M j, Y') ? get_the_time('M j, Y') : mktime('M j, Y'); + $date_text = ( $post->post_type == 'post' ) ? $date . ' ... ' : null; + + echo '

Search Engine Result Preview

'; + + echo '
'; + + echo '

' . get_bloginfo('name') . '

'; + echo '

' . $date_text . '

'; + + echo '

' . str_replace('http://', '', home_url()) . ' - Cached - Similar

'; + + echo '
'; + + echo 'Remember, this is only a predicted search engine result preview. There is no guarantee that it will look exactly this way. However, it will look similar.'; + + } + + + protected function input_text_with_counter($input) { + + echo ' + + + + + + + + + + + + + + + 130
+ + + '; + + } + + + protected function modify_arguments($post = false) { + + //Do not use this box if the page being edited is the front page since they can edit the setting in the configuration. + if ( get_option('page_on_front') == headway_get('post') && get_option('show_on_front') == 'page' ) { + + $this->info = 'Configure the SEO settings for this page (Front Page) in the Headway Search Engine Optimization settings tab in Headway » Configuration.'; + + $this->inputs = array(); + + return; + + } + + //Setup the defaults for the title and checkboxes + $current_screen = get_current_screen(); + $seo_templates_query = HeadwayOption::get('seo-templates', 'general', HeadwaySEO::output_layouts_and_defaults()); + $seo_templates = headway_get('single-' . $current_screen->id, $seo_templates_query, array()); + + $title_template = str_replace(array('%sitename%', '%SITENAME%'), get_bloginfo('name'), headway_get('title', $seo_templates)); + + echo ''; + + $this->inputs['noindex']['default'] = headway_get('noindex', $seo_templates); + $this->inputs['nofollow']['default'] = headway_get('nofollow', $seo_templates); + $this->inputs['noarchive']['default'] = headway_get('noarchive', $seo_templates); + $this->inputs['nosnippet']['default'] = headway_get('nosnippet', $seo_templates); + $this->inputs['noodp']['default'] = headway_get('noodp', $seo_templates); + $this->inputs['noydir']['default'] = headway_get('noydir', $seo_templates); + + + } + +} \ No newline at end of file diff --git a/wp-content/themes/headway/library/admin/admin-pages.php b/wp-content/themes/headway/library/admin/admin-pages.php new file mode 100644 index 0000000..4340f0b --- /dev/null +++ b/wp-content/themes/headway/library/admin/admin-pages.php @@ -0,0 +1,71 @@ +You are now being redirected. If you are not redirected within 3 seconds, click here.

'; + echo ''; + HeadwayAdmin::show_footer(); + + } + + + public static function getting_started() { + + HeadwayAdmin::show_header(); + + require_once HEADWAY_LIBRARY_DIR . '/admin/pages/getting-started.php'; + + HeadwayAdmin::show_footer(); + + } + + + public static function whats_new() { + + require_once HEADWAY_LIBRARY_DIR . '/admin/pages/whats-new.php'; + + } + + + public static function templates() { + + HeadwayAdmin::show_header(); + + require_once HEADWAY_LIBRARY_DIR . '/admin/pages/templates.php'; + + HeadwayAdmin::show_footer(); + + } + + + public static function options() { + + HeadwayAdmin::show_header(); + + require_once HEADWAY_LIBRARY_DIR . '/admin/pages/options.php'; + + HeadwayAdmin::show_footer(); + + } + + + public static function tools() { + + HeadwayAdmin::show_header(); + + require_once HEADWAY_LIBRARY_DIR . '/admin/pages/tools.php'; + + HeadwayAdmin::show_footer(); + + } + + +} \ No newline at end of file diff --git a/wp-content/themes/headway/library/admin/admin-write.php b/wp-content/themes/headway/library/admin/admin-write.php new file mode 100644 index 0000000..54a77f3 --- /dev/null +++ b/wp-content/themes/headway/library/admin/admin-write.php @@ -0,0 +1,62 @@ +post_type == 'revision' ) + return false; + + /* Figure out the layout ID */ + $layout_id = 'single-' . $post->post_type . '-' . $postid; + + /* Delete everything from the layout including blocks, wrapper, design editor instances, and the wp_options rows */ + HeadwayLayout::delete_layout($layout_id, false); + + } + + + public static function open_in_visual_editor_button($return, $id, $new_title, $new_slug) { + + global $post; + + if ( !isset($post->ID) || !is_numeric($post->ID) || $post->post_status != 'publish' || !HeadwayCapabilities::can_user_visually_edit() ) + return $return; + + $layout_id = 'single' . HeadwayLayout::$sep . $post->post_type . HeadwayLayout::$sep . $post->ID; + + if ( get_option('show_on_front') === 'page' ) { + + if ( $post->ID == get_option('page_on_front') ) + $layout_id = 'front_page'; + + if ( $post->ID == get_option('page_for_posts') ) + $layout_id = 'index'; + + } + + $visual_editor_url = home_url('/?visual-editor=true&ve-layout=' . urlencode($layout_id)); + + $return .= 'Open in Visual Editor'; + + return $return; + + } + + +} \ No newline at end of file diff --git a/wp-content/themes/headway/library/admin/admin.php b/wp-content/themes/headway/library/admin/admin.php new file mode 100644 index 0000000..6b962e0 --- /dev/null +++ b/wp-content/themes/headway/library/admin/admin.php @@ -0,0 +1,613 @@ + true, + 'admin/admin-pages', + 'admin/api-admin-inputs' + )); + + } + + + public static function setup_hooks() { + + /* Actions */ + add_action('admin_init', array(__CLASS__, 'activation'), 1); + add_action('admin_init', array(__CLASS__, 'enqueue')); + add_action('admin_init', array(__CLASS__, 'visual_editor_redirect'), 12); + + add_action('init', array(__CLASS__, 'form_action_save'), 12); // Init runs before admin_menu; admin_menu runs before admin_init + add_action('init', array(__CLASS__, 'form_action_licenses'), 12); + add_action('init', array(__CLASS__, 'form_action_reset'), 12); + + add_action('admin_menu', array(__CLASS__, 'add_menus')); + add_action('admin_head', array(__CLASS__, 'remove_system_submenus')); + + add_action('headway_admin_save_message', array(__CLASS__, 'save_message')); + add_action('headway_admin_save_error_message', array(__CLASS__, 'save_error_message')); + + add_action('admin_notices', array(__CLASS__, 'notice_no_widgets_or_menus')); + + add_filter('page_row_actions', array(__CLASS__, 'row_action_visual_editor'), 10, 2); + add_filter('post_row_actions', array(__CLASS__, 'row_action_visual_editor'), 10, 2); + add_filter('tag_row_actions', array(__CLASS__, 'row_action_visual_editor'), 10, 2); + + } + + + public static function form_action_save() { + + //Form action for all Headway configuration panels. Not in function/hook so it can load before everything else. + if ( !headway_post('headway-submit', false)) + return false; + + if ( !wp_verify_nonce(headway_post('headway-admin-nonce', false), 'headway-admin-nonce') ) { + + global $headway_admin_save_message; + $headway_admin_save_message = 'Security nonce did not match.'; + + return false; + + } + + foreach ( headway_post('headway-admin-input', array()) as $option => $value ) { + + HeadwayOption::set($option, $value); + + } + + global $headway_admin_save_message; + $headway_admin_save_message = 'Settings saved.'; + + return true; + + } + + + public static function form_action_licenses() { + + if ( !headway_post('headway-licenses', false)) + return false; + + if ( !wp_verify_nonce(headway_post('headway-admin-nonce', false), 'headway-admin-nonce') ) + return false; + + if ( !is_array(headway_post('headway-licenses')) ) + return false; + + global $headway_admin_save_message; + global $headway_admin_save_error_message; + + + /* Save and activations */ + if ( $save_and_activations = headway_get('save-and-activate', headway_post('headway-licenses')) ) { + + if ( is_array($save_and_activations) && count($save_and_activations) ) { + + foreach ( $save_and_activations as $item_slug_to_activate => $submit_value ) { + + HeadwayOption::set('license-key-' . $item_slug_to_activate, headway_get('license-key-' . $item_slug_to_activate, headway_post('headway-admin-input'))); + $activation_request = headway_activate_license($item_slug_to_activate); + + self::set_license_activation_message($activation_request); + + } + + } + + } + + /* Activations */ + if ( $activations = headway_get('activate', headway_post('headway-licenses')) ) { + + if ( is_array($activations) && count($activations) ) { + + foreach ( headway_get('activate', headway_post('headway-licenses')) as $item_slug_to_activate => $submit_value ) { + + $activation_request = headway_activate_license($item_slug_to_activate); + + self::set_license_activation_message($activation_request); + + } + + } + + } + + /* Deactivations */ + if ( $deactivations = headway_get('deactivate', headway_post('headway-licenses')) ) { + + if ( is_array($deactivations) && count($deactivations) ) { + + foreach ( headway_get('deactivate', headway_post('headway-licenses')) as $item_slug_to_deactivate => $submit_value ) { + + $deactivation_request = headway_deactivate_license($item_slug_to_deactivate); + + if ( $deactivation_request == 'deactivated' ) { + + $headway_admin_save_message = 'License deactivated.'; + + } else if ( !is_wp_error($deactivation_request) ) { + + $headway_admin_save_error_message = 'Whoops! Could not deactivate license. Please check that you have entered your license correctly.'; + + } else { + + $headway_admin_save_error_message = ' + Error While Deactivating: (' . $deactivation_request->get_error_code() . ') ' . $deactivation_request->get_error_message() . '

+ ' . __('Please contact Headway Support if this error persists.', 'headway') . ' + '; + + } + + } + + } + + } + + + return true; + + } + + + public static function set_license_activation_message($activation_request) { + + global $headway_admin_save_message; + global $headway_admin_save_error_message; + + if ( $activation_request == 'active' || $activation_request == 'valid' ) { + + $headway_admin_save_message = __('License saved and activated.', 'headway'); + + } else if ( $activation_request == 'invalid' || $activation_request == 'expired' ) { + + $headway_admin_save_error_message = __(' + Whoops! Could not activate license. Please check that you have entered your license correctly and that it has not expired.

+ Make sure you copied your license correctly from the Headway Dashboard. + ', 'headway'); + + } else if ( is_wp_error($activation_request) ) { + + $headway_admin_save_error_message = ' + Error While Activating: (' . $activation_request->get_error_code() . ') ' . $activation_request->get_error_message() . '

+ ' . __('Please contact Headway Support if this error persists.', 'headway') . ' + '; + + } + + } + + + public static function form_action_reset() { + + global $wpdb; + + if ( !defined('HEADWAY_ALLOW_RESET') || HEADWAY_ALLOW_RESET !== true ) + return false; + + //Form action for all Headway configuration panels. Not in function/hook so it can load before everything else. + if ( !headway_post('reset-headway', false) ) + return false; + + //Verify the nonce so other sites can't maliciously reset a Headway installation. + if ( !wp_verify_nonce(headway_post('headway-reset-nonce', false), 'headway-reset-nonce') ) { + + $GLOBALS['headway_admin_save_message'] = 'Security nonce did not match.'; + + return false; + + } + + /* Loop through WordPress options and delete the skin options */ + $wpdb->query( "DELETE FROM $wpdb->options WHERE option_name = 'headway'" ); + $wpdb->query( "DELETE FROM $wpdb->options WHERE option_name LIKE 'headway_%'" ); + + $wpdb->query( "DELETE FROM $wpdb->options WHERE option_name LIKE '_transient_hw_%'" ); + + /* Remove Headway post meta */ + $wpdb->query( "DELETE FROM $wpdb->postmeta WHERE meta_key LIKE '_hw_%'" ); + + /* Drop Headway tables */ + Headway::mysql_drop_tables(); + + /* Flush WP cache */ + wp_cache_flush(); + + do_action('headway_global_reset'); + + $GLOBALS['headway_admin_save_message'] = 'Headway was successfully reset.'; + + //This will hide the reset box if set to true. + $GLOBALS['headway_reset_success'] = true; + + return true; + + } + + + public static function activation() { + + if ( !is_admin() || !headway_get('activated') ) + return false; + + global $pagenow; + + if ( $pagenow !== 'themes.php' ) + return false; + + //Since they may be upgrading and files may change, let's clear the cache + do_action('headway_activation'); + + self::activation_redirect(); + + } + + + public static function activation_redirect() { + + do_action('headway_activation_redirect'); + + //If a child theme has been activated rather than Headway, then don't redirect. + //Let the child theme developer redirect if they want by using the hook above. + if ( HEADWAY_CHILD_THEME_ACTIVE === true ) + return false; + + $parent_menu = self::parent_menu(); + + //If header were sent, then don't do the redirect + if ( headers_sent() ) + return false; + + //We're all good, redirect now + wp_safe_redirect(admin_url('admin.php?page=headway-' . $parent_menu['id'])); + die(); + + } + + + public static function visual_editor_redirect() { + + if ( isset($_GET['page']) && strpos($_GET['page'], 'headway-visual-editor') !== false && !headers_sent() ) + wp_safe_redirect(home_url() . '/?visual-editor=true'); + + } + + + public static function add_admin_separator($position){ + + global $menu; + + $menu[$position] = array('', 'read', 'separator-headway', '', 'wp-menu-separator headway-separator'); + + ksort($menu); + + } + + + public static function add_admin_submenu($name, $id, $callback) { + + $parent_menu = self::parent_menu(); + + return add_submenu_page('headway-' . $parent_menu['id'], $name, $name, 'manage_options', $id, $callback); + + } + + + public static function add_menus(){ + + //If the hide menus constant is set to true, don't hide the menus! + if (defined('HEADWAY_HIDE_MENUS') && HEADWAY_HIDE_MENUS === true) + return false; + + //If user cannot access the admin panels, then don't bother running these functions + if ( !HeadwayCapabilities::can_user_visually_edit() ) + return false; + + $menu_name = ( HeadwayOption::get('hide-menu-version-number', false, true) == true ) ? 'Headway' : 'Headway ' . HEADWAY_VERSION; + + $icon = (version_compare($GLOBALS['wp_version'], '3.8', '>=') && get_user_option('admin_color') != 'light') ? 'headway-32-white.png' : 'headway-16.png'; + $icon_url = headway_url() . '/library/admin/images/' . $icon; + + $parent_menu = self::parent_menu(); + + self::add_admin_separator(48); + + add_menu_page($parent_menu['name'], $menu_name, 'manage_options', 'headway-' . $parent_menu['id'], $parent_menu['callback'], $icon_url, 49); + + switch ( $parent_menu['id'] ) { + + case 'getting-started': + self::add_admin_submenu('Getting Started', 'headway-getting-started', array('HeadwayAdminPages', 'getting_started')); + self::add_admin_submenu('Visual Editor', 'headway-visual-editor', array('HeadwayAdminPages', 'visual_editor')); + + self::add_admin_submenu('Templates', 'headway-templates', array('HeadwayAdminPages', 'templates')); + self::add_admin_submenu('Options', 'headway-options', array('HeadwayAdminPages', 'options')); + self::add_admin_submenu('Tools', 'headway-tools', array('HeadwayAdminPages', 'tools')); + break; + + case 'visual-editor': + self::add_admin_submenu('Visual Editor', 'headway-visual-editor', array('HeadwayAdminPages', 'visual_editor')); + + self::add_admin_submenu('Templates', 'headway-templates', array('HeadwayAdminPages', 'templates')); + self::add_admin_submenu('Options', 'headway-options', array('HeadwayAdminPages', 'options')); + self::add_admin_submenu('Tools', 'headway-tools', array('HeadwayAdminPages', 'tools')); + break; + + case 'options': + self::add_admin_submenu('Options', 'headway-options', array('HeadwayAdminPages', 'options')); + self::add_admin_submenu('Visual Editor', 'headway-visual-editor', array('HeadwayAdminPages', 'visual_editor')); + self::add_admin_submenu('Templates', 'headway-templates', array('HeadwayAdminPages', 'templates')); + self::add_admin_submenu('Tools', 'headway-tools', array('HeadwayAdminPages', 'tools')); + break; + + } + + self::add_admin_submenu( 'What\'s New', 'headway-whats-new', array( 'HeadwayAdminPages', 'whats_new' ) ); + + } + + + public static function remove_system_submenus() { + + $parent_menu = HeadwayAdmin::parent_menu(); + + remove_submenu_page( 'headway-' . $parent_menu['id'], 'headway-whats-new' ); + + } + + + public static function parent_menu() { + + $menu_setup = HeadwayOption::get('menu-setup', false, 'getting-started'); + + /* Figure out the primary page */ + switch ( $menu_setup ) { + + case 'getting-started': + $parent_menu = array( + 'id' => 'getting-started', + 'name' => 'Getting Started', + 'callback' => array('HeadwayAdminPages', 'getting_started') + ); + break; + + case 'visual-editor': + $parent_menu = array( + 'id' => 'visual-editor', + 'name' => 'Visual Editor', + 'callback' => array('HeadwayAdminPages', 'visual_editor') + ); + break; + + case 'options': + $parent_menu = array( + 'id' => 'options', + 'name' => 'Options', + 'callback' => array('HeadwayAdminPages', 'options') + ); + break; + + } + + return $parent_menu; + + } + + + public static function enqueue() { + + global $pagenow; + + /* Scripts Path */ + $script_folder = (defined('SCRIPT_DEBUG') && SCRIPT_DEBUG) ? 'scripts' : 'scripts-min'; + + /* Global */ + wp_enqueue_style('headway_admin_global', headway_url() . '/library/admin/css/admin-headway-global.css'); + + /* General Headway admin CSS/JS */ + if ( strpos(headway_get('page'), 'headway') !== false ) { + + wp_enqueue_script('headway_jquery_scrollto', headway_url() . '/library/admin/js/jquery.scrollto.js', array('jquery')); + wp_enqueue_script('headway_jquery_tabby', headway_url() . '/library/admin/js/jquery.tabby.js', array('jquery')); + wp_enqueue_script('headway_jquery_qtip', headway_url() . '/library/admin/js/jquery.qtip.js', array('jquery')); + wp_enqueue_script('headway_admin_js', headway_url() . '/library/admin/js/admin-headway.js', array('jquery', 'headway_jquery_qtip')); + + wp_enqueue_style('headway_admin', headway_url() . '/library/admin/css/admin-headway.css'); + wp_enqueue_style('headway_alerts', headway_url() . '/library/media/css/alerts.css'); + + } + + /* Templates */ + if ( headway_get('page') == 'headway-templates' ) { + + wp_enqueue_script('headway_knockout', headway_url() . '/library/admin/js/knockout.js', array('jquery')); + wp_enqueue_script('headway_admin_templates', headway_url() . '/library/admin/js/admin-templates.js', array('jquery')); + + wp_localize_script('headway_admin_templates', 'Headway', array( + 'ajaxURL' => admin_url('admin-ajax.php'), + 'security' => wp_create_nonce('headway-visual-editor-ajax'), + + 'templates' => HeadwayTemplates::get_all(), + 'templateActive' => HeadwayTemplates::get_active(), + + 'viewModels' => array() + )); + + add_thickbox(); + wp_enqueue_media(); + + } + + /* Meta Boxes */ + wp_enqueue_style('headway_admin_write', headway_url() . '/library/admin/css/admin-write.css'); + wp_enqueue_style('headway_alerts', headway_url() . '/library/media/css/alerts.css'); + wp_enqueue_script('headway_admin_write', headway_url() . '/library/admin/js/admin-write.js', array('jquery')); + + /* Auto Updater */ + if ( $pagenow === 'update-core.php' ) { + + wp_enqueue_script('headway_admin', headway_url() . '/library/admin/js/admin-headway.js', array('jquery')); + wp_enqueue_style('headway_admin', headway_url() . '/library/admin/css/admin-headway.css'); + wp_enqueue_style('headway_alerts', headway_url() . '/library/media/css/alerts.css'); + + } + + } + + + public static function save_message() { + + global $headway_admin_save_message; + + if ( !isset($headway_admin_save_message) || $headway_admin_save_message == false ) + return false; + + echo '

' . $headway_admin_save_message . '

'; + + } + + + public static function save_error_message() { + + global $headway_admin_save_error_message; + + if ( !isset($headway_admin_save_error_message) || $headway_admin_save_error_message == false ) + return false; + + echo '

' . $headway_admin_save_error_message . '

'; + + } + + + public static function notice_no_widgets_or_menus() { + + global $pagenow; + + if ( $pagenow != 'widgets.php' && $pagenow != 'nav-menus.php' ) + return false; + + $grid_mode_url = add_query_arg(array('visual-editor' => 'true', 'visual-editor-mode' => 'grid'), home_url()); + + //Show the widgets message if no widget blocks exist. + if ( $pagenow == 'widgets.php' ) { + + $widget_area_blocks = HeadwayBlocksData::get_blocks_by_type('widget-area'); + + if ( !empty($widget_area_blocks) ) + return; + + if ( !current_theme_supports('headway-grid') ) + return; + + echo '
+

Headway has detected that you have no Widget Area blocks. If you wish to use the WordPress widgets system with Headway, please add a Widget Area block in the Visual Editor: Grid.

+ + +
'; + + } + + //Show the navigation menus message if no navigation blocks exist. + if ( $pagenow == 'nav-menus.php' ) { + + $navigation_blocks = HeadwayBlocksData::get_blocks_by_type('navigation'); + + if ( !empty($navigation_blocks) ) + return; + + if ( !current_theme_supports('headway-grid') ) + return; + + echo '
+

Headway has detected that you have no Navigation blocks. If you wish to use the WordPress menus system with Headway, please add a Navigation block in the Visual Editor: Grid.

+
'; + + } + + } + + + public static function show_header($title = false) { + + echo '
'; + + if ( $title ) + echo '

' . $title . '

'; + + } + + + public static function show_footer() { + + echo '
'; + + } + + + public static function row_action_visual_editor($actions, $item) { + + if ( !HeadwayCapabilities::can_user_visually_edit() ) + return $actions; + + /* Post */ + if ( isset($item->post_status) ) { + + if ( $item->post_status != 'publish' ) + return $actions; + + $post_type = get_post_type_object($item->post_type); + + if ( !$post_type->public ) + return $actions; + + $layout_id = 'single' . HeadwayLayout::$sep . $item->post_type . HeadwayLayout::$sep . $item->ID; + + if ( get_option('show_on_front') === 'page' ) { + + if ( $item->ID == get_option('page_on_front') ) + $layout_id = 'front_page'; + + if ( $item->ID == get_option('page_for_posts') ) + $layout_id = 'index'; + + } + + /* Category */ + } elseif ( isset($item->term_id) && $item->taxonomy == 'category' ) { + + $layout_id = 'archive' . HeadwayLayout::$sep . 'category' . HeadwayLayout::$sep . $item->term_id; + + /* Post Tag */ + } elseif ( isset($item->term_id) && $item->taxonomy == 'post_tag' ) { + + $layout_id = 'archive' . HeadwayLayout::$sep . 'post_tag' . HeadwayLayout::$sep . $item->term_id; + + /* Taxonomy */ + } elseif ( isset($item->term_id) ) { + + $layout_id = 'archive' . HeadwayLayout::$sep . 'taxonomy' . HeadwayLayout::$sep . $item->taxonomy . HeadwayLayout::$sep . $item->term_id; + + } + + $visual_editor_url = home_url('/?visual-editor=true&ve-layout=' . urlencode($layout_id)); + + $actions['hw-visual-editor'] = 'Open in Visual Editor'; + + return $actions; + + } + + +} \ No newline at end of file diff --git a/wp-content/themes/headway/library/admin/api-admin-inputs.php b/wp-content/themes/headway/library/admin/api-admin-inputs.php new file mode 100644 index 0000000..c82849f --- /dev/null +++ b/wp-content/themes/headway/library/admin/api-admin-inputs.php @@ -0,0 +1,236 @@ +'; + + $row_count = 0; + + foreach ( $inputs as $input ) { + + $row_count++; + + if ( !method_exists(__CLASS__, 'input_' . $input['type']) ) + continue; + + $tooltip = (isset($input['tooltip']) && $input['tooltip']) ? '' : null; + $description = (isset($input['description']) && $input['description']) ? '

' . $input['description'] . '

' : null; + $suffix = (isset($input['suffix']) && $input['suffix']) ? $input['suffix'] : null; + + $id = isset($input['id']) ? $input['id'] : null; + + $row_class = ( $row_count == count($inputs) ) ? ' class="no-bottom-border"' : null; + + if ( headway_get('value', $input) && !is_int(headway_get('value', $input)) ) + $input['value'] = stripslashes(esc_attr($input['value'])); + + echo ' + + + + '; + + call_user_func(array(__CLASS__, 'input_' . $input['type']), $input); + + echo $suffix . $description; + + echo ' + '; + + } + + echo ''; + + } + + + public static function input_text($input) { + + $defaults = array( + 'size' => 'medium', + 'value' => null, + 'unit' => null, + 'tooltip' => null, + 'description' => null, + 'no-submit' => false, + 'masked' => false + ); + + $input = array_merge($defaults, $input); + + $name_attr = $input['no-submit'] ? null : ' name="headway-admin-input[' . $input['id'] . ']"'; + $type_attr = $input['masked'] ? 'password' : 'text'; + + echo ' ' . $input['unit']; + + } + + + public static function input_password($input) { + + $defaults = array( + 'size' => 'medium', + 'value' => null, + 'tooltip' => null, + 'description' => null, + 'no-submit' => false + ); + + $input = array_merge($defaults, $input); + + $name_attr = $input['no-submit'] ? null : ' name="headway-admin-input[' . $input['id'] . ']"'; + + echo ''; + + } + + + public static function input_paragraph($input) { + + $defaults = array( + 'cols' => 30, + 'rows' => 5, + 'value' => null, + 'allow-tabbing' => false, + 'no-submit' => false + ); + + $input = array_merge($defaults, $input); + + $allow_tabbing_class = $input['allow-tabbing'] ? 'class="allow-tabbing" ' : null; + + $name_attr = $input['no-submit'] ? null : ' name="headway-admin-input[' . $input['id'] . ']"'; + + echo ''; + + } + + + public static function input_checkbox($input) { + + $defaults = array( + 'no-submit' => false + ); + + $input = array_merge($defaults, $input); + + echo '
'; + + //Initialize counter for adding
's + $checkbox_count = 0; + + echo ' + ' . $input['label']. ' + '; + + foreach($input['checkboxes'] as $checkbox) { + + $checkbox_count++; + $checkbox_checked = ( isset($checkbox['checked']) && $checkbox['checked'] == true ) ? ' checked="checked"' : null; + + $name_attr = $input['no-submit'] ? null : ' name="headway-admin-input[' . $checkbox['id'] . ']"'; + + echo ''; + + //Add in
if there are multiple checkboxes + if ( count($input['checkboxes']) > 1 && $checkbox_count < count($input['checkboxes']) ) + echo '
'; + + } + + echo '
'; + + } + + + public static function input_checkboxes($input) { + + self::input_checkbox($input); + + } + + + public static function input_select($input) { + + $defaults = array( + 'value' => null, + 'no-submit' => false, + 'multiple' => false + ); + + $input = array_merge($defaults, $input); + + $name_multiple_array = $input['multiple'] ? '[]' : null; + $multiple_attr = $input['multiple'] ? ' multiple="multiple" size="10"' : null; + $name_attr = $input['no-submit'] ? null : ' name="headway-admin-input[' . $input['id'] . ']' . $name_multiple_array . '"'; + + //If there are options in the multiselect and then the user wants to remove all of the selected options, it will not save. + //This is the workaround. + if ( !$input['no-submit'] && $input['multiple'] ) + echo ''; + + echo ''; + + } + + + public static function input_radio($input) { + + $defaults = array( + 'no-submit' => false + ); + + $input = array_merge($defaults, $input); + + $name_attr = $input['no-submit'] ? null : ' name="headway-admin-input[' . $input['id'] . ']"'; + + echo '
'; + + //Initialize counter for adding
's + $radio_count = 0; + + echo ' + ' . $input['label']. ' + '; + + foreach($input['radios'] as $radio) { + + $radio_count++; + $radio_checked = ( $radio['value'] === $input['value'] ) ? ' checked="checked"' : null; + + echo ' + '; + + } + + echo '
'; + + } + + +} \ No newline at end of file diff --git a/wp-content/themes/headway/library/admin/css/admin-headway-global.css b/wp-content/themes/headway/library/admin/css/admin-headway-global.css new file mode 100644 index 0000000..5ec5d24 --- /dev/null +++ b/wp-content/themes/headway/library/admin/css/admin-headway-global.css @@ -0,0 +1,20 @@ +#adminmenu li[class*="toplevel_page_headway"] .wp-menu-image img { + width: 16px; + height: 16px; +} + +#customize-current-theme-link { + display: none; +} + +#headway-admin-notifications { + position: fixed; + top: 45px; + right: 20px; + z-index: 14; +} + +#headway-admin-notifications div { + min-width: 200px; + max-width: 400px; +} \ No newline at end of file diff --git a/wp-content/themes/headway/library/admin/css/admin-headway.css b/wp-content/themes/headway/library/admin/css/admin-headway.css new file mode 100644 index 0000000..a286d6c --- /dev/null +++ b/wp-content/themes/headway/library/admin/css/admin-headway.css @@ -0,0 +1,579 @@ +/* Important Stuff */ + .wrap.headway-page h2 { + margin-bottom: 15px; + } + +/* Regular Elements */ + abbr, acronym { + background: #eee; + cursor: help; + letter-spacing: 1px; + text-transform: uppercase; + } + + div.hr { + background: transparent; + border-top: 1px solid #eaeaea; + clear: both; + height: 1px; + margin: 24px 0; + overflow: hidden; + display: block; + width: 100%; + } +/* End Regular Elements */ + + +/* Messages */ + /* Reset */ + div.reset-alert { + width: 700px; + } + + div.reset-alert input.alert-big-button { + color: #832525; + } + /* End Reset */ + + /* Alert Buttons */ + input.alert-big-button, .wp-core-ui input.alert-big-button { + font-size: 15px !important; + width: 300px; + height: 34px; + position: relative; + margin: 15px 0 20px -158px; + left: 50%; + } + /* End Alert Buttons */ +/* End Messages */ + + +/* Wrapper */ + div.headway-small-wrap { + max-width: 1000px; + } +/* End Wrapper */ + + +/* Titles */ + h3.title { + margin: 30px 0 15px; + } + + h3.title code { font-size: 1em; } + + h3.title-hr { + border-top: 1px solid #eee; + padding-top: 30px; + } +/* End Titles */ + + +/* Tabs */ + h2.big-tabs-tabs { + opacity: 0; + margin-bottom: 20px; + } + + h2.big-tabs-tabs a.nav-tab-active { color: #D54E21; } + h2.big-tabs-tabs a:hover:not(.nav-tab-active) { color: #464646; } + + h2.big-tabs-tabs a.nav-tab-inactive { + opacity: .4; + cursor: help; + color: #aaa !important; + } + + div.big-tab { + max-width: 1100px; + display: none; + } + + div.big-tab-fading { + z-index: 1; + } + + div.big-tab-visible { } +/* End Tabs */ + + +/* Inputs */ + table.form-table tr { + border-bottom: 1px solid #f3f3f3; + } + + table.form-table tr.no-bottom-border { + border-bottom: none; + } + + table.form-table tr th, table.form-table tr td { + padding: 15px 10px; + } + + table.form-table label { + user-select: none; + -webkit-user-select: none; + } + + table.form-table textarea { + resize: none; + } + + table.form-table select { + width: 150px; + } + + label span.label-tooltip { + width: 14px; + height: 13px; + background: url(../images/help-grey.png); + display: inline-block; + text-indent: -9999px; + margin: 0 0 -1px 8px; + cursor: help; + opacity: .5; + } + + label span.label-tooltip:hover { opacity: .9; } + + label.radio-label { + margin-right: 15px; + } + + div.hr-submit { + margin: 45px 0 20px; + } + + p.submit { + padding-top: 0; + } + + table.form-table input.large-text { + width: 350px !important; + } + + input.headway-save { + width: 220px; + height: 28px !important; + } +/* End Inputs */ + + +/* Input Descriptions and Tooltips */ + p.description { + clear: both; + margin: 0; + } +/* End Input Descripts and Tooltips */ + + +/* Getting Started Page */ + h3.headway-sub-title { + color: #777; + font-size: 16px; + line-height: 25px; + font-weight: normal; + } + + div#headway-getting-started-ve-link-container { + margin: 15px 0 15px -250px; + position: relative; + left: 50%; + float: left; + clear: both; + } + + div#headway-getting-started-ve-link-container p { margin-left: 10px; } + + div#headway-getting-started-license-notice { + font-size: 13px; + } + + input.headway-big-button { + font-size: 18px !important; + width: 500px; + height: 50px !important; + } +/* End Getting Started Page */ + + +/* Templates Page */ + form#upload-skin { + display: none; + } + + .headway-templates .headway-template .theme-actions .delete-template { + color: #A00; + text-decoration: none; + border-color: rgba(0, 0, 0, 0); + box-shadow: none; + background: rgba(0, 0, 0, 0); + } + + .headway-templates .headway-template .theme-actions .delete-template:hover { + background: #D54E21; + color: #FFF; + border-color: #D54E21; + } + + .headway-templates .headway-template.missing-image .theme-screenshot { + background: url(../../visual-editor/images/logo.png) no-repeat 50% 50% !important; + } + + button#template-export-image-button { + padding-left: 5px; + } + + button#template-export-image-button span { + line-height: 18px; + display: inline-block; + width: 18px; + height: 18px; + color: #888; + vertical-align: text-top; + margin: 0 2px; + } + + button#template-export-image-button span::after { + font-family: 'dashicons'; + content: "\f128"; + font: normal 18px/1 'dashicons'; + speak: none; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + } + + img#template-export-image-preview { + max-width: 340px; + margin-top: 15px; + border: 1px solid #ddd; + } + + /* Loading indicator */ + @-webkit-keyframes spin { + from { + -webkit-transform: rotate(0deg); + } + to { + -webkit-transform: rotate(360deg); + } + } + + @-moz-keyframes spin { + from { + -moz-transform: rotate(0deg); + } + to { + -moz-transform: rotate(360deg); + } + } + + @-ms-keyframes spin { + from { + -ms-transform: rotate(0deg); + } + to { + -ms-transform: rotate(360deg); + } + } + + .template-installing .template-loading-indicator { + position: absolute; + display: block; + width: 80px; + height: 80px; + left: 50%; + top: 50%; + margin: -40px 0 0 -40px; + text-align: center; + -webkit-animation: spin 1500ms infinite linear; + -moz-animation: spin 1500ms infinite linear; + animation: spin 1500ms infinite linear; + background-image: url(data:image/svg+xml;base64,PHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgZGF0YS1pY29uPSJjb2ciIHdpZHRoPSIxMjgiIGhlaWdodD0iMTI4IiBjbGFzcz0iaWNvbmljIGljb25pYy1jb2cgaWNvbmljLW9yaWVudGF0aW9uLXNxdWFyZSIgdmlld0JveD0iMCAwIDEyOCAxMjgiPgogIDxnIGRhdGEtd2lkdGg9IjEyOCIgZGF0YS1oZWlnaHQ9IjEyOCIgY2xhc3M9Imljb25pYy1sZyIgZGlzcGxheT0iaW5saW5lIj4KICAgIDxwYXRoIGQ9Ik0xMjggNzMuOXYtMTkuOWwtMTQuMy0zLjZjLTEuMi00LjItMi44LTguMy01LTEybDcuNS0xMi43LTE0LjEtMTQuMS0xMi43IDcuNmMtMy43LTIuMS03LjgtMy44LTEyLTVsLTMuNS0xNC4yaC0xOS45bC0zLjYgMTQuM2MtNC4yIDEuMi04LjMgMi44LTEyIDVsLTEyLjctNy41LTE0IDE0IDcuNiAxMi43Yy0yLjEgMy43LTMuOCA3LjgtNSAxMmwtMTQuMyAzLjZ2MTkuOWwxNC4zIDMuNmMxLjIgNC4yIDIuOCA4LjMgNSAxMmwtNy41IDEyLjcgMTQuMSAxNC4xIDEyLjctNy42YzMuNyAyLjEgNy44IDMuOCAxMiA1bDMuNyAxNC4zaDE5LjdsMy42LTE0LjNjNC4yLTEuMiA4LjMtMi44IDEyLTVsMTIuNyA3LjUgMTQuMS0xNC4xLTcuNi0xMi43YzIuMS0zLjcgMy44LTcuOCA1LTEybDE0LjItMy42em0tNjQgMjQuMWMtMTguOCAwLTM0LTE1LjItMzQtMzRzMTUuMi0zNCAzNC0zNCAzNCAxNS4yIDM0IDM0LTE1LjIgMzQtMzQgMzR6IgogICAgY2xhc3M9Imljb25pYy1jb2ctYm9keSBpY29uaWMtZWxlbWVudC1maWxsIiAvPgogIDwvZz4KPC9zdmc+); + background-size: 80px; + opacity: .6; + } + + .headway-templates .headway-template.missing-image.template-installing div.theme-screenshot { + background: none !important; + } +/* End Templates */ + + +/* Options Page */ + /* SEO Tab */ + h3#seo-templates-title { + margin: 30px 0 -25px 125px; + font-size: 1.3em; + } + + div#seo-templates-header { + width: auto; + float: left; + border: 1px solid #e5e5e5; + padding: 5px; + border-bottom: none; + border-radius: 8px 8px 0 0; + background: #fff; + margin: 0 0 -1px 800px; + position: relative; + background: #fafafa; + } + + div#seo-templates-header span { + top: 9px; + left: -140px; + position: absolute; + width: 130px; + text-align: right; + color: #999; + } + + div#seo-templates-header select { + width: 150px; + } + + div#seo-templates-inputs { + width: 850px; + padding: 15px; + border: 1px solid #e5e5e5; + border-radius: 8px; + clear: both; + margin: 0 0 0 110px; + background: #fafafa; + box-shadow: 1px 1px 0 #ddd; + } + + div#seo-templates-inputs th { + width: 130px; + } + + div#seo-templates-inputs input.large-text, div#seo-templates-inputs textarea { + width: 100%; + } + + h3#seo-templates-advanced-options-title span { + cursor: pointer; + margin: 0 0 0 5px; + font-size: 11px; + font-weight: bold; + color: #21759B; + padding: 5px 10px; + background: #eee; + text-shadow: 1px 1px 0 #fff; + border-radius: 3px; + box-shadow: 1px 1px 0 #ddd; + } + + h3#seo-templates-advanced-options-title span:hover { + color: #D54E21; + } + + div#seo-templates-advanced-options { + display: none; + } + + p#seo-description { + margin: 25px 0 -5px 0; + } + /* End SEO Tab */ + + /* License Validation */ + div.license-key-input-table { + border: 1px solid #dadada; + border-radius: 5px; + background: #fff; + display: block; + padding: 0 30px 10px; + + margin: 10px 0 -10px; + } + + span.license-key-validation { + margin: 0 0 0 6px; + padding-bottom: 1px; + } + + span.license-key-validation.red { + border-bottom: 1px dotted #900; + } + /* End License Validation */ +/* End Options Page */ + + +/* Tools */ + /* System Info */ + textarea#system-info-textarea { + font-family: 'courier new', monospace; + margin: 10px 0 0 0; + width: 900px; + height: 400px; + } + +/* End Tools */ + + + +/* Updates */ + .headway-update-backup-reminder { + width: 650px !important; + padding: 5px 20px !important; + } +/* End Updates */ + + +/* Colored Text */ + span.red { + color: #900; + } + + span.green { + color: #090; + } +/* End Colored Text */ + + +/* Obligatory stupid jQuery stuff */ + .ui-helper-hidden { + display: none; + } + + .ui-helper-hidden-accessible { + left: -9999px; + position: absolute; + } + + .ui-helper-reset { + border: 0; + font-size: 100%; + line-height: 1.3; + list-style: none; + margin: 0; + outline: 0; + padding: 0; + text-decoration: none; + } + + .ui-helper-clearfix:after { + clear: both; + content: "."; + display: block; + height: 0; + visibility: hidden; + } + + .ui-helper-clearfix { + display: inline-block; + } + + * html .ui-helper-clearfix { + height: 1%; + } + + .ui-helper-clearfix { + display: block; + } + + .ui-helper-zfix { + filter: alpha(opacity=0); + height: 100%; + left: 0; + opacity: 0; + position: absolute; + top: 0; + width: 100%; + } + + .ui-widget-overlay { + height: 100%; + left: 0; + position: absolute; + top: 0; + width: 100%; + } + +/* Getting Started page */ +.headway-getting-started-wrap .headway-sub-title { + font-size: 18px; + margin: 20px 0; +} + +.wrap .headway-getting-started-wrap h2 { + clear: both; + margin-top: 20px; + margin-bottom: 10px; + width: 100%; +} + +.headway-sub-title img { + vertical-align: middle; + margin-right: 10px; +} + +.headway-infobox-row { + margin-top: 3%; +} + +.headway-infobox-row::after { + clear: both; + content: "."; + display: block; + height: 0; + visibility: hidden; +} + +.headway-infobox { + background: #fdfdfd; + padding: 13px 25px; + min-height: 66px; + float: left; + width: 42%; + border: solid 1px #ccc; +} + +.headway-infobox-icon { + width: 43%; + padding: 0 20px; + height: 76px; + line-height: 73px; +} + +.headway-infobox.inrow { + margin-right: 3%; +} + +.headway-infobox.big { + min-height: 150px; +} + +.headway-infobox span.dashicons { + font-size: 46px; + color: #f36341; + margin-right: 10px; + width: 46px; + height: 76px; + line-height: 76px; + position: relative; + vertical-align: middle; + float: left; +} + +.headway-infobox span.dashicons.bigfix { + font-size: 40px; +} + +.headway-infobox a.big { + font-size: 22px; + text-decoration: none; +} + +.headway-infobox a:hover { + text-decoration: underline; +} + +.headway-infobox.big h3 { + font-size: 18px; + color: #555; + font-weight: normal; + margin-top: 10px; +} diff --git a/wp-content/themes/headway/library/admin/css/admin-write.css b/wp-content/themes/headway/library/admin/css/admin-write.css new file mode 100644 index 0000000..ebc36c2 --- /dev/null +++ b/wp-content/themes/headway/library/admin/css/admin-write.css @@ -0,0 +1,92 @@ +/* ADMIN META BOXES */ +div.postbox tr.form-field input.check, tr.form-field input.radio { width: 16px; } +div.postbox table.headway-admin-meta-box tr.label:first-child th { padding: 10px 10px 3px 10px; } +div.postbox table.headway-admin-meta-box tr.label { margin-top: 15px; } +div.postbox table.headway-admin-meta-box tr.label th { padding: 20px 10px 3px 10px; } +div.postbox table.headway-admin-meta-box tr.label th label { font-weight: bold; font-size: 14px; color: #444; } +div.postbox table.headway-admin-meta-box tr.description td { padding: 0 10px 10px; } +div.postbox table.headway-admin-meta-box tr.description p { color: #777; font-size: 11.5px; margin: -3px 0 0 5px !important; } +div.postbox table.headway-admin-meta-box label.selectit { font-size: 12px; color: #333; } +div.postbox table.headway-admin-meta-box label.selectit input { margin: -4px 3px 0 0; } +div.postbox table.headway-admin-meta-box input[type='text'], div.postbox table.headway-admin-meta-box textarea { width: 100% !important; } + +div.postbox table.headway-admin-meta-box select { width: 90%; } + +div.postbox table.headway-admin-meta-box { + margin-top: 10px; +} + +div.postbox div.alert { margin: 15px 5px 0; } + +#poststuff div.postbox[id^="headway-admin-meta-box-"] h3.hndle { + background: url(../images/headway-32.png); + background-size: 16px; + background-repeat: no-repeat; + padding-left: 36px; + background-position: 12px 50%; +} +/* END ADMIN META BOXES */ + +/* LIVE SEO PREVIEW */ +#seo-preview { + display: block; + background: #fff; + border: 1px solid #bbb; + margin: 10px 10px 0; + padding: 8px; + font-family: arial,sans-serif; + color: #000; + font-size: 13px; + width: 540px; + clear: both; +} + +#seo-preview h4 { + text-decoration: underline; + color: #1111CC; + font-size: 16px; + font-weight: normal; + margin: 0; + cursor: pointer; +} + +#seo-preview p#seo-preview-description { + line-height: 16px; + margin: 2px 0 0; + font-size: 13px; + display: block; + cursor: pointer; +} + +#seo-preview p#seo-preview-bottom { + color: #767676; + margin: 0; + font-size: 13px; +} + + #seo-preview p#seo-preview-bottom span { + color: #4272DB; + } + + #seo-preview p#seo-preview-bottom span#seo-preview-url { + color: #0E774A; + } + +h4#seo-preview-title { + color: #444; + font-size: 14px; + font-weight: bold; + margin: 15px 0 15px 10px; + display: block; + clear: both; + float: left; + vertical-align: middle; +} + +small#seo-preview-disclaimer { + color:#777; + margin: 5px 0 4px 12px; + float:left; + font-style: italic; +} +/* END LIVE SEO PREVIEW */ \ No newline at end of file diff --git a/wp-content/themes/headway/library/admin/images/headway-16-white.png b/wp-content/themes/headway/library/admin/images/headway-16-white.png new file mode 100644 index 0000000..91064d5 Binary files /dev/null and b/wp-content/themes/headway/library/admin/images/headway-16-white.png differ diff --git a/wp-content/themes/headway/library/admin/images/headway-16.png b/wp-content/themes/headway/library/admin/images/headway-16.png new file mode 100644 index 0000000..393789e Binary files /dev/null and b/wp-content/themes/headway/library/admin/images/headway-16.png differ diff --git a/wp-content/themes/headway/library/admin/images/headway-32-white.png b/wp-content/themes/headway/library/admin/images/headway-32-white.png new file mode 100644 index 0000000..b53519c Binary files /dev/null and b/wp-content/themes/headway/library/admin/images/headway-32-white.png differ diff --git a/wp-content/themes/headway/library/admin/images/headway-32.png b/wp-content/themes/headway/library/admin/images/headway-32.png new file mode 100644 index 0000000..d64aee3 Binary files /dev/null and b/wp-content/themes/headway/library/admin/images/headway-32.png differ diff --git a/wp-content/themes/headway/library/admin/images/help-grey.png b/wp-content/themes/headway/library/admin/images/help-grey.png new file mode 100644 index 0000000..4bd1844 Binary files /dev/null and b/wp-content/themes/headway/library/admin/images/help-grey.png differ diff --git a/wp-content/themes/headway/library/admin/js/admin-headway.js b/wp-content/themes/headway/library/admin/js/admin-headway.js new file mode 100644 index 0000000..da123d1 --- /dev/null +++ b/wp-content/themes/headway/library/admin/js/admin-headway.js @@ -0,0 +1,252 @@ +(function($) { +$(document).ready(function() { + + /* Big Tabs */ + setupBigTabs = function() { + + if ( $('h2.big-tabs-tabs').length === 0 ) + return; + + //Bind tab buttons + $('h2.big-tabs-tabs a.nav-tab').on('click', function(event){ + + var tabID = $(this).attr('href').replace('#tab-', ''); + + //Stop all other animations + $('div.big-tabs-container div.big-tab, div.hr-submit, p.submit').stop(true, true); + + //Check to make sure tab exists + if ( $('div.big-tabs-container div#tab-' + tabID + '-content').length === 0 ) + return false; + + //Set tab as active + $(this).siblings('.nav-tab-active').removeClass('nav-tab-active'); + $(this).addClass('nav-tab-active'); + + //Hide the submit button so it can be faded in later + $('div.hr-submit, p.submit').hide(); + + //Hide/show the tabs accordingly + $('div.big-tabs-container div.big-tab-visible') + .removeClass('big-tab-visible') + .hide(); + + $('div.big-tabs-container div#tab-' + tabID + '-content') + .addClass('big-tab-visible') + .addClass('big-tab-fading') + .fadeIn(200, function() { + + $(this).removeClass('big-tab-fading'); + + $('div.hr-submit, p.submit').fadeIn(200); + + }); + + }); + + //Setup display for tabs and tab containers + if ( window.location.hash.indexOf('tab-') !== -1 && $('div.big-tabs-container div#tab-' + window.location.hash.replace('#tab-', '') + '-content').length === 1 ) { + + var tabID = window.location.hash.replace('#tab-', ''); + var tab = $('h2.big-tabs-tabs a[href="#tab-' + tabID + '"]'); + + //Set tab as active + tab.addClass('nav-tab-active'); + + //Show tab's container + $('div.big-tabs-container div#tab-' + tabID + '-content').fadeIn(200, function() { + $(this).addClass('big-tab-visible'); + }); + + } else { + + var firstTab = $('h2.big-tabs-tabs a.nav-tab:first'); + var tabID = firstTab.attr('href').replace('#tab-', ''); + + //Set the tab as active + firstTab.addClass('nav-tab-active'); + + //Show first tab's container + $('div.big-tabs-container div#tab-' + tabID + '-content').fadeIn(200, function() { + $(this).addClass('big-tab-visible'); + }); + + } + + //Show the tabs + $('h2.big-tabs-tabs').animate({opacity: 1}, 200); + + //Show the submit HR and submit button + setTimeout(function(){ + $('div.hr-submit, p.submit').fadeIn(200); + }, 300); + + } + + //Call the function now + setupBigTabs(); + /* End Big Tabs */ + + + /* Tooltips */ + if ( typeof $().qtip === 'function' ) { + + $('label span.label-tooltip').qtip({ + style: { + classes: 'qtip-headway' + }, + position: { + my: 'bottom left', + at: 'top right' + } + }); + + } + /* End Tooltips */ + + + /* Textareas */ + if ( $('textarea.allow-tabbing').length > 0 ) + $('textarea.allow-tabbing').tabby(); + + + /* System Info */ + if ( $('textarea#system-info-textarea').length > 0 ) { + + $('textarea#system-info-textarea').qtip({ + style: { + classes: 'qtip-headway' + }, + position: { + my: 'bottom center', + at: 'top center' + } + }); + + $('textarea#system-info-textarea').bind('mouseup', function() { + + $(this) + .focus() + .select(); + + }); + + } + + + /* SEO Templates */ + if ( $('div#seo-templates').length === 1 ) { + + fetchSEOTemplateValues = function(currentPage) { + + seoInputs.each(function() { + + var value = $('input#seo-' + currentPage + '-' + $(this).attr('id')).val(); + + /* + Since checkboxes and traditional inputs are handled differently we have to either + set the value of regular inputs or set the checkbox as checked. + */ + if ( $(this).attr('type') != 'checkbox' ) { + + $(this).val(value); + + } else { + + if ( value == 1 ) { + $(this).attr('checked', true); + } else { + $(this).attr('checked', false); + } + + } + + }); + + } + + /* Set Up Initial Values */ + var currentPage = $('div#seo-templates-header select').val(); + var seoInputs = $('div#seo-templates-inputs input, div#seo-templates-inputs textarea'); + + fetchSEOTemplateValues(currentPage); + + /* Bind the page select */ + $('div#seo-templates-header select').bind('change', function() { + + currentPage = $(this).val(); + + fetchSEOTemplateValues(currentPage); + + }); + + /* Bind the inputs */ + seoInputs.bind('click blur', function() { + + var hidden = $('input#seo-' + currentPage + '-' + $(this).attr('id')); + + /* + Since checkboxes and traditional inputs are handled differently we have to either + set the value of regular inputs or set the checkbox as checked. + */ + if ( $(this).attr('type') != 'checkbox' ) { + + hidden.val($(this).val()); + + } else { + + if ( $(this).is(':checked') ) { + hidden.val('1'); + } else { + hidden.val('0'); + } + + } + + }); + + /* Bind the advanced options toggle */ + $('h3#seo-templates-advanced-options-title span').bind('click', function(event) { + + if ( !$(this).hasClass('seo-advanced-visible') ) { + + $('div#seo-templates-advanced-options').fadeIn(250); + $(this).html('Hide ↑').addClass('seo-advanced-visible'); + + jQuery.scrollTo($('h3#seo-templates-advanced-options-title'), 500, { + easing: 'swing', + offset: {top:-10} + }); + + } else { + + $('div#seo-templates-advanced-options').fadeOut(200); + $(this).html('Show ↓').removeClass('seo-advanced-visible'); + + jQuery.scrollTo($('div#seo-templates'), 300, { + easing: 'swing', + offset: {top:-40} + }); + + } + + }); + + } + /* End SEO Templates */ + + + /* Reset */ + if ( $('form#reset-headway').length === 1 ) { + + $('input#reset-headway-submit').bind('click', function() { + + return confirm('Warning! ALL existing Headway data, including, but not limited to: Blocks, Design Settings, and Headway Search Engine Optimization settings will be deleted. This cannot be undone. \'OK\' to delete, \'Cancel\' to stop'); + + }); + + } + /* End Reset */ + +}); +})(jQuery); \ No newline at end of file diff --git a/wp-content/themes/headway/library/admin/js/admin-templates.js b/wp-content/themes/headway/library/admin/js/admin-templates.js new file mode 100644 index 0000000..0d698a7 --- /dev/null +++ b/wp-content/themes/headway/library/admin/js/admin-templates.js @@ -0,0 +1,445 @@ +jQuery(document).ready(function($) { + + showNotification = function(args) { + + var notification = $('

' + args.message + '

'); + + notification.appendTo('#headway-admin-notifications'); + + if ( typeof args.closeTimer != 'undefined' && args.closeTimer ) { + + setTimeout(function() { + notification.fadeOut(1000, function() { + $(this).remove(); + }); + }, args.closeTimer); + + } + + return notification; + + } + + showErrorNotification = function(args) { + + var notification = $('

' + args.message + '

'); + + notification.appendTo('#headway-admin-notifications'); + + return notification; + + } + + updateNotification = function(id, message) { + + return $('#headway-notification-' + id).children('p').html(message); + + } + + hideNotification = function(id) { + + $('#headway-notification-' + id).fadeOut(500); + + } + + + var templates = { + init: function() { + + templates.bind(); + templates.setupViewModel(); + + }, + + setupViewModel: function() { + + Headway.viewModels.templates = { + templates: ko.observableArray(Headway.templates), + active: ko.observable(Headway.templateActive), + activateSkin: function() { + + var skin = this; + + /* Don't try to activate if it's already activated */ + if ( skin.id == Headway.viewModels.templates.active().id ) + return; + + /* Send AJAX Request to switch skins */ + $.post(Headway.ajaxURL, { + security: Headway.security, + action: 'headway_visual_editor', + method: 'switch_skin', + skin: skin.id + }, function(response) { + + /* Set this skin as the activated skin */ + Headway.viewModels.templates.active(skin); + + showNotification({ + id: 'skin-switched', + message: skin.name + ' activated.', + closeTimer: 5000, + success: true + }); + + }); + + }, + deleteSkin: function() { + + var skin = this; + + if ( !confirm('Are you sure you want to delete this template? All design settings, blocks, and layout settings for this template will be deleted.') ) + return; + + /* Send AJAX Request to switch skins */ + $.post(Headway.ajaxURL, { + security: Headway.security, + action: 'headway_visual_editor', + method: 'delete_skin', + skin: skin.id + }, function(response) { + + if ( response != 'success' ) { + + return showErrorNotification({ + id: 'unable-to-delete-skin', + message: 'Unable to delete template.', + }); + + } else { + + showNotification({ + id: 'skin-deleted', + message: skin.name + ' deleted.', + closeTimer: 5000, + success: true + }); + + } + + Headway.viewModels.templates.templates.remove(skin); + + }); + + } + } + + ko.applyBindings(Headway.viewModels.templates, $('.headway-templates').get(0)); + + }, + + bind: function() { + + /* Skin Upload button */ + $('#install-template').on('click', function() { + + if ( $(this).is('[disabled]') ) + return; + + $('#upload-skin input[type="file"]').first().trigger('click'); + + }); + + + $('#upload-skin input[type="file"]').on('change', function(event) { + + if ( event.target.files[0].name.split('.').slice(-1)[0] != 'json' ) + return alert("Invalid template.\n\nPlease make sure that you have unzipped the Headway Template. You should be uploading a .json file."); + + var skinFile = $(this).get(0).files[0]; + + if ( skinFile && typeof skinFile.name != 'undefined' && typeof skinFile.type != 'undefined' ) { + + var skinReader = new FileReader(); + + skinReader.onload = function(e) { + + var skinJSON = e.target.result; + var skin = JSON.parse(skinJSON); + + /* Check to be sure that the JSON file is a layout */ + if ( skin['data-type'] != 'skin' ) + return alert('Cannot load template. Please insure that the file is a valid Headway Template.'); + + /* Deactivate install template button */ + $('#install-template').attr('disabled', 'true'); + + showNotification({ + id: 'installing-skin', + message: 'Installing Template: ' + skin['name'], + closeTimer: false, + closable: false + }); + + Headway.viewModels.templates.templates.push({ + description: null, + name: 'Installing ' + skin['name'] + '...', + installing: true, + id: null, + author: null, + active: false, + version: null + }); + + installSkin(skin); + + } + + skinReader.readAsText(skinFile); + + } else { + + alert('Cannot load template. Please insure that the file is a valid Headway Template.'); + + } + + }); + + + installSkin = function(skin) { + + if ( typeof skin['image-definitions'] == 'object' && Object.keys(skin['image-definitions']).length ) { + + var numberOfImages = Object.keys(skin['image-definitions']).length; + var importedImages = {}; + + showNotification({ + id: 'skin-importing-images', + message: 'Importing Images...', + closeTimer: false, + closable: false + }); + + var importSkinImage = function(imageID) { + + /* Update notification for image import */ + var imageIDInt = parseInt(imageID.replace('%%', '').replace('IMAGE_REPLACEMENT_', '')); + + updateNotification('skin-importing-images', 'Importing Image (' + imageIDInt + '/' + numberOfImages + ')'); + + /* Do the AJAX request to upload the image */ + var imageImportXhr = $.post(Headway.ajaxURL, { + security: Headway.security, + action: 'headway_visual_editor', + method: 'import_image', + imageID: imageID, + imageContents: skin['image-definitions'][imageID] + }, null, 'json') + .always(function(response) { + + /* Update notification */ + + /* Check if error. If so, fire notification */ + if ( typeof response['url'] == 'undefined' ) { + var response = 'ERROR'; + + showNotification({ + id: 'skin-importing-images-error-' + imageIDInt, + message: 'Error Importing Image #' + imageIDInt, + closeTimer: 10000, + closable: true, + error: true + }); + } + + /* Store uploaded image URL */ + importedImages[imageID] = response; + + /* Check if there are more images to upload. If so, upload them. */ + var nextImageID = '%%IMAGE_REPLACEMENT_' + (parseInt(imageID.replace('%%', '').replace('IMAGE_REPLACEMENT_', '')) + 1) + '%%'; + + if ( typeof skin['image-definitions'][nextImageID] != 'undefined' ) { + + importSkinImage(nextImageID); + + /* If not, finalize skin installation */ + } else { + + /* Hide notification since images are uploaded is complete */ + hideNotification('skin-importing-images'); + + /* Finalize */ + skin['imported-images'] = importedImages; + + finalizeSkinInstallation(skin); + + } + + }); + /* End doing AJAX request to upload image */ + + } + + importSkinImage('%%IMAGE_REPLACEMENT_1%%'); + + } else { + + finalizeSkinInstallation(skin); + + } + + } + + + finalizeSkinInstallation = function(skin) { + + /* Remove image definitions from skin array since they've already been imported */ + if ( typeof skin['image-definitions'] != 'undefined' ) + delete skin['image-definitions']; + + /* Do AJAX request to install skin */ + return $.post(Headway.ajaxURL, { + security: Headway.security, + action: 'headway_visual_editor', + method: 'install_skin', + skin: JSON.stringify(skin) + }).done(function(data) { + + var skin = data; + + if ( typeof skin['error'] !== 'undefined' || typeof skin['name'] == 'undefined' ) { + + if ( typeof skin['error'] == 'undefined' ) + skin['error'] = 'Could not install template.'; + + return showNotification({ + id: 'skin-not-installed', + message: 'Error: ' + skin['error'], + closable: true, + closeTimer: false, + error: true + }); + + } + + hideNotification('installing-skin'); + + showNotification({ + id: 'skin-installed', + message: skin['name'] + ' successfully installed.', + closeTimer: 5000, + success: true + }); + + /* Pop off the last skin which is going to be the loader */ + Headway.viewModels.templates.templates.pop(); + Headway.viewModels.templates.templates.push($.extend({}, {description: null}, skin)); + + /* Reactive install template button */ + $('#install-template').removeAttr('disabled'); + + }).fail(function(data) { + + showNotification({ + id: 'skin-not-installed', + message: 'Error: Could not install template.', + closable: true, + closeTimer: false, + error: true + }); + + }); + + } + + /* Skin Export */ + $('#export-template-submit').on('click', function(event) { + + event.preventDefault(); + + var params = { + 'security': Headway.security, + 'action': 'headway_visual_editor', + 'method': 'export_skin', + 'skin-info': $('#export-template-form').serialize() + } + + var exportURL = Headway.ajaxURL + '?' + $.param(params); + + return window.open(exportURL); + + }); + + /* Export Template Image */ + var HWTemplateExportImageFrame; + + $('#template-export-image-button').on('click', function (event) { + + event.preventDefault(); + + // If the media frame already exists, reopen it. + if (HWTemplateExportImageFrame) { + HWTemplateExportImageFrame.open(); + return; + } + + // Create the media frame. + HWTemplateExportImageFrame = wp.media.frames.file_frame = wp.media({ + title: 'Select Image for Template', + button: { + text: 'Select Image', + }, + multiple: false + }); + + // When an image is selected, run a callback. + HWTemplateExportImageFrame.on('select', function () { + attachment = HWTemplateExportImageFrame.state().get('selection').first().toJSON(); + + $('input#template-export-image').val(attachment.url); + + $('img#template-export-image-preview') + .attr('src', attachment.url) + .show(); + + }); + + HWTemplateExportImageFrame.open(); + }); + + + /* Add Blank Skin */ + $('#add-blank-template').on('click', function() { + + var skinName = window.prompt('Please enter a name for the new template:' , 'Template Name'); + + if ( !skinName || $('#notification-adding-blank-skin').length ) + return; + + /* Perform AJAX request to create the skin and get the ID and name */ + $.post(Headway.ajaxURL, { + security: Headway.security, + action: 'headway_visual_editor', + method: 'add_blank_skin', + skinName: skinName + }, function(response) { + + var skinID = response['id']; + var skinName = response['name']; + + showNotification({ + id: 'added-blank-skin', + message: skinName + ' successfully added.', + closeTimer: 5000, + success: true + }); + + Headway.viewModels.templates.templates.push({ + id: skinID, + name: skinName, + version: null, + author: null, + description: null + }); + + }, 'json'); + + }); + + } + } + + templates.init(); + +}); \ No newline at end of file diff --git a/wp-content/themes/headway/library/admin/js/admin-write.js b/wp-content/themes/headway/library/admin/js/admin-write.js new file mode 100644 index 0000000..d7ec413 --- /dev/null +++ b/wp-content/themes/headway/library/admin/js/admin-write.js @@ -0,0 +1,140 @@ +(function($) { +$(document).ready(function() { + + /* SEO Live Preview */ + if ( $('div#seo-preview').length == 1 ) { + + //Insert content into preview + if ( $('textarea#headway-admin-meta-box-seo-description').val().length > 0 ) { + + var description = $('textarea#headway-admin-meta-box-seo-description').val(); + + if(description.length > 150){ + description = description.substr(0, 150) + ' ...'; + } + + $('div#seo-preview p#seo-preview-description span#text').text(description); + + } else { + + var excerpt = $('textarea#content').val().replace(/(<([^>]+)>)/ig, ''); + + if ( excerpt.length > 150 ) { + excerpt = excerpt.substr(0, 150) + ' ...'; + } + + $('div#seo-preview p#seo-preview-description span#text').text(excerpt); + + } + + if ( $('input#headway-admin-meta-box-seo-title').val().length > 0 ) { + + $('div#seo-preview h4').text($('input#headway-admin-meta-box-seo-title').val()); + + } else if ( $('div#titlediv input#title').val().length > 0 ) { + + $('div#seo-preview h4').text($('input#title-seo-template').val().replace('%title%', $('div#titlediv input#title').val())); + + } + + if ( $('span#seo-preview-url').text().length == 0 ) { + + $('span#seo-preview-url').text($('span#sample-permalink').text().replace('http://', '')); + + } + + //Bind Inputs + $('input#headway-admin-meta-box-seo-title').bind('keyup blur', function() { + + if ( $(this).val().length > 0 ) { + + $('div#seo-preview h4').text($(this).val()); + + } else { + + $('div#seo-preview h4').text($('input#title-seo-template').val().replace('%title%', $('div#titlediv input#title').val())); + + } + + }); + + $('textarea#headway-admin-meta-box-seo-description').bind('keyup blur', function() { + + var description = $(this).val(); + + if ( description.length > 150 ) + description = description.substr(0, 150) + ' ...'; + + if ( $(this).val().length == 0 ) { + + var description = $('textarea#content').val().replace(/(<([^>]+)>)/ig, ''); + + if ( excerpt.length > 150 ) { + description = excerpt.substr(0, 150) + ' ...'; + } + + } + + $('div#seo-preview p#seo-preview-description span#text').text(description); + + }); + + $('div#titlediv input#title').bind('keyup blur', function() { + + if ( $('input#headway-admin-meta-box-seo-title').val().length == 0 ) { + + $('div#seo-preview h4').text($('input#title-seo-template').val().replace('%title%', $(this).val())); + + } + + }); + + //Periodically check for updates in the content + setInterval(function() { + + if ( $('textarea#headway-admin-meta-box-seo-description').val().length > 0 ) + return false; + + if ( $('textarea#content').val() != undefined ){ + var excerpt = $('textarea#content').val().replace(/(<([^>]+)>)/ig, ''); + } else { + var excerpt = $('textarea#excerpt').val(); + } + + if ( excerpt.length > 150 ) + excerpt = excerpt.substr(0, 150) + ' ...'; + + $('div#seo-preview p#seo-preview-description span#text').text(excerpt); + + }, 4000); + + //Bind Clickables + $('div#seo-preview h4').bind('click', function(event) { + + if ( $('input#headway-admin-meta-box-seo-title').val().length == 0 ) + $('input#headway-admin-meta-box-seo-title').val($(this).text()); + + $('input#headway-admin-meta-box-seo-title') + .focus() + .css({backgroundColor: '#FFF6BF'}) + .animate({backgroundColor: '#fff'}, 400); + + event.preventDefault(); + + }); + + $('div#seo-preview p#seo-preview-description').bind('click', function(event) { + + $('textarea#headway-admin-meta-box-seo-description') + .focus() + .css({backgroundColor: '#FFF6BF'}) + .animate({backgroundColor: '#fff'}, 400); + + event.preventDefault(); + + }); + } + /* End SEO Live Preview */ + +}); +})(jQuery); \ No newline at end of file diff --git a/wp-content/themes/headway/library/admin/js/jquery.masonry.js b/wp-content/themes/headway/library/admin/js/jquery.masonry.js new file mode 100644 index 0000000..f0da370 --- /dev/null +++ b/wp-content/themes/headway/library/admin/js/jquery.masonry.js @@ -0,0 +1,9 @@ +/*! + * Masonry PACKAGED v3.1.5 + * Cascading grid layout library + * http://masonry.desandro.com + * MIT License + * by David DeSandro + */ + +!function(a){function b(){}function c(a){function c(b){b.prototype.option||(b.prototype.option=function(b){a.isPlainObject(b)&&(this.options=a.extend(!0,this.options,b))})}function e(b,c){a.fn[b]=function(e){if("string"==typeof e){for(var g=d.call(arguments,1),h=0,i=this.length;i>h;h++){var j=this[h],k=a.data(j,b);if(k)if(a.isFunction(k[e])&&"_"!==e.charAt(0)){var l=k[e].apply(k,g);if(void 0!==l)return l}else f("no such method '"+e+"' for "+b+" instance");else f("cannot call methods on "+b+" prior to initialization; attempted to call '"+e+"'")}return this}return this.each(function(){var d=a.data(this,b);d?(d.option(e),d._init()):(d=new c(this,e),a.data(this,b,d))})}}if(a){var f="undefined"==typeof console?b:function(a){console.error(a)};return a.bridget=function(a,b){c(b),e(a,b)},a.bridget}}var d=Array.prototype.slice;"function"==typeof define&&define.amd?define("jquery-bridget/jquery.bridget",["jquery"],c):c(a.jQuery)}(window),function(a){function b(b){var c=a.event;return c.target=c.target||c.srcElement||b,c}var c=document.documentElement,d=function(){};c.addEventListener?d=function(a,b,c){a.addEventListener(b,c,!1)}:c.attachEvent&&(d=function(a,c,d){a[c+d]=d.handleEvent?function(){var c=b(a);d.handleEvent.call(d,c)}:function(){var c=b(a);d.call(a,c)},a.attachEvent("on"+c,a[c+d])});var e=function(){};c.removeEventListener?e=function(a,b,c){a.removeEventListener(b,c,!1)}:c.detachEvent&&(e=function(a,b,c){a.detachEvent("on"+b,a[b+c]);try{delete a[b+c]}catch(d){a[b+c]=void 0}});var f={bind:d,unbind:e};"function"==typeof define&&define.amd?define("eventie/eventie",f):"object"==typeof exports?module.exports=f:a.eventie=f}(this),function(a){function b(a){"function"==typeof a&&(b.isReady?a():f.push(a))}function c(a){var c="readystatechange"===a.type&&"complete"!==e.readyState;if(!b.isReady&&!c){b.isReady=!0;for(var d=0,g=f.length;g>d;d++){var h=f[d];h()}}}function d(d){return d.bind(e,"DOMContentLoaded",c),d.bind(e,"readystatechange",c),d.bind(a,"load",c),b}var e=a.document,f=[];b.isReady=!1,"function"==typeof define&&define.amd?(b.isReady="function"==typeof requirejs,define("doc-ready/doc-ready",["eventie/eventie"],d)):a.docReady=d(a.eventie)}(this),function(){function a(){}function b(a,b){for(var c=a.length;c--;)if(a[c].listener===b)return c;return-1}function c(a){return function(){return this[a].apply(this,arguments)}}var d=a.prototype,e=this,f=e.EventEmitter;d.getListeners=function(a){var b,c,d=this._getEvents();if(a instanceof RegExp){b={};for(c in d)d.hasOwnProperty(c)&&a.test(c)&&(b[c]=d[c])}else b=d[a]||(d[a]=[]);return b},d.flattenListeners=function(a){var b,c=[];for(b=0;be;e++)if(b=c[e]+a,"string"==typeof d[b])return b}}var c="Webkit Moz ms Ms O".split(" "),d=document.documentElement.style;"function"==typeof define&&define.amd?define("get-style-property/get-style-property",[],function(){return b}):"object"==typeof exports?module.exports=b:a.getStyleProperty=b}(window),function(a){function b(a){var b=parseFloat(a),c=-1===a.indexOf("%")&&!isNaN(b);return c&&b}function c(){for(var a={width:0,height:0,innerWidth:0,innerHeight:0,outerWidth:0,outerHeight:0},b=0,c=g.length;c>b;b++){var d=g[b];a[d]=0}return a}function d(a){function d(a){if("string"==typeof a&&(a=document.querySelector(a)),a&&"object"==typeof a&&a.nodeType){var d=f(a);if("none"===d.display)return c();var e={};e.width=a.offsetWidth,e.height=a.offsetHeight;for(var k=e.isBorderBox=!(!j||!d[j]||"border-box"!==d[j]),l=0,m=g.length;m>l;l++){var n=g[l],o=d[n];o=h(a,o);var p=parseFloat(o);e[n]=isNaN(p)?0:p}var q=e.paddingLeft+e.paddingRight,r=e.paddingTop+e.paddingBottom,s=e.marginLeft+e.marginRight,t=e.marginTop+e.marginBottom,u=e.borderLeftWidth+e.borderRightWidth,v=e.borderTopWidth+e.borderBottomWidth,w=k&&i,x=b(d.width);x!==!1&&(e.width=x+(w?0:q+u));var y=b(d.height);return y!==!1&&(e.height=y+(w?0:r+v)),e.innerWidth=e.width-(q+u),e.innerHeight=e.height-(r+v),e.outerWidth=e.width+s,e.outerHeight=e.height+t,e}}function h(a,b){if(e||-1===b.indexOf("%"))return b;var c=a.style,d=c.left,f=a.runtimeStyle,g=f&&f.left;return g&&(f.left=a.currentStyle.left),c.left=b,b=c.pixelLeft,c.left=d,g&&(f.left=g),b}var i,j=a("boxSizing");return function(){if(j){var a=document.createElement("div");a.style.width="200px",a.style.padding="1px 2px 3px 4px",a.style.borderStyle="solid",a.style.borderWidth="1px 2px 3px 4px",a.style[j]="border-box";var c=document.body||document.documentElement;c.appendChild(a);var d=f(a);i=200===b(d.width),c.removeChild(a)}}(),d}var e=a.getComputedStyle,f=e?function(a){return e(a,null)}:function(a){return a.currentStyle},g=["paddingLeft","paddingRight","paddingTop","paddingBottom","marginLeft","marginRight","marginTop","marginBottom","borderLeftWidth","borderRightWidth","borderTopWidth","borderBottomWidth"];"function"==typeof define&&define.amd?define("get-size/get-size",["get-style-property/get-style-property"],d):"object"==typeof exports?module.exports=d(require("get-style-property")):a.getSize=d(a.getStyleProperty)}(window),function(a,b){function c(a,b){return a[h](b)}function d(a){if(!a.parentNode){var b=document.createDocumentFragment();b.appendChild(a)}}function e(a,b){d(a);for(var c=a.parentNode.querySelectorAll(b),e=0,f=c.length;f>e;e++)if(c[e]===a)return!0;return!1}function f(a,b){return d(a),c(a,b)}var g,h=function(){if(b.matchesSelector)return"matchesSelector";for(var a=["webkit","moz","ms","o"],c=0,d=a.length;d>c;c++){var e=a[c],f=e+"MatchesSelector";if(b[f])return f}}();if(h){var i=document.createElement("div"),j=c(i,"div");g=j?c:f}else g=e;"function"==typeof define&&define.amd?define("matches-selector/matches-selector",[],function(){return g}):window.matchesSelector=g}(this,Element.prototype),function(a){function b(a,b){for(var c in b)a[c]=b[c];return a}function c(a){for(var b in a)return!1;return b=null,!0}function d(a){return a.replace(/([A-Z])/g,function(a){return"-"+a.toLowerCase()})}function e(a,e,f){function h(a,b){a&&(this.element=a,this.layout=b,this.position={x:0,y:0},this._create())}var i=f("transition"),j=f("transform"),k=i&&j,l=!!f("perspective"),m={WebkitTransition:"webkitTransitionEnd",MozTransition:"transitionend",OTransition:"otransitionend",transition:"transitionend"}[i],n=["transform","transition","transitionDuration","transitionProperty"],o=function(){for(var a={},b=0,c=n.length;c>b;b++){var d=n[b],e=f(d);e&&e!==d&&(a[d]=e)}return a}();b(h.prototype,a.prototype),h.prototype._create=function(){this._transn={ingProperties:{},clean:{},onEnd:{}},this.css({position:"absolute"})},h.prototype.handleEvent=function(a){var b="on"+a.type;this[b]&&this[b](a)},h.prototype.getSize=function(){this.size=e(this.element)},h.prototype.css=function(a){var b=this.element.style;for(var c in a){var d=o[c]||c;b[d]=a[c]}},h.prototype.getPosition=function(){var a=g(this.element),b=this.layout.options,c=b.isOriginLeft,d=b.isOriginTop,e=parseInt(a[c?"left":"right"],10),f=parseInt(a[d?"top":"bottom"],10);e=isNaN(e)?0:e,f=isNaN(f)?0:f;var h=this.layout.size;e-=c?h.paddingLeft:h.paddingRight,f-=d?h.paddingTop:h.paddingBottom,this.position.x=e,this.position.y=f},h.prototype.layoutPosition=function(){var a=this.layout.size,b=this.layout.options,c={};b.isOriginLeft?(c.left=this.position.x+a.paddingLeft+"px",c.right=""):(c.right=this.position.x+a.paddingRight+"px",c.left=""),b.isOriginTop?(c.top=this.position.y+a.paddingTop+"px",c.bottom=""):(c.bottom=this.position.y+a.paddingBottom+"px",c.top=""),this.css(c),this.emitEvent("layout",[this])};var p=l?function(a,b){return"translate3d("+a+"px, "+b+"px, 0)"}:function(a,b){return"translate("+a+"px, "+b+"px)"};h.prototype._transitionTo=function(a,b){this.getPosition();var c=this.position.x,d=this.position.y,e=parseInt(a,10),f=parseInt(b,10),g=e===this.position.x&&f===this.position.y;if(this.setPosition(a,b),g&&!this.isTransitioning)return void this.layoutPosition();var h=a-c,i=b-d,j={},k=this.layout.options;h=k.isOriginLeft?h:-h,i=k.isOriginTop?i:-i,j.transform=p(h,i),this.transition({to:j,onTransitionEnd:{transform:this.layoutPosition},isCleaning:!0})},h.prototype.goTo=function(a,b){this.setPosition(a,b),this.layoutPosition()},h.prototype.moveTo=k?h.prototype._transitionTo:h.prototype.goTo,h.prototype.setPosition=function(a,b){this.position.x=parseInt(a,10),this.position.y=parseInt(b,10)},h.prototype._nonTransition=function(a){this.css(a.to),a.isCleaning&&this._removeStyles(a.to);for(var b in a.onTransitionEnd)a.onTransitionEnd[b].call(this)},h.prototype._transition=function(a){if(!parseFloat(this.layout.options.transitionDuration))return void this._nonTransition(a);var b=this._transn;for(var c in a.onTransitionEnd)b.onEnd[c]=a.onTransitionEnd[c];for(c in a.to)b.ingProperties[c]=!0,a.isCleaning&&(b.clean[c]=!0);if(a.from){this.css(a.from);var d=this.element.offsetHeight;d=null}this.enableTransition(a.to),this.css(a.to),this.isTransitioning=!0};var q=j&&d(j)+",opacity";h.prototype.enableTransition=function(){this.isTransitioning||(this.css({transitionProperty:q,transitionDuration:this.layout.options.transitionDuration}),this.element.addEventListener(m,this,!1))},h.prototype.transition=h.prototype[i?"_transition":"_nonTransition"],h.prototype.onwebkitTransitionEnd=function(a){this.ontransitionend(a)},h.prototype.onotransitionend=function(a){this.ontransitionend(a)};var r={"-webkit-transform":"transform","-moz-transform":"transform","-o-transform":"transform"};h.prototype.ontransitionend=function(a){if(a.target===this.element){var b=this._transn,d=r[a.propertyName]||a.propertyName;if(delete b.ingProperties[d],c(b.ingProperties)&&this.disableTransition(),d in b.clean&&(this.element.style[a.propertyName]="",delete b.clean[d]),d in b.onEnd){var e=b.onEnd[d];e.call(this),delete b.onEnd[d]}this.emitEvent("transitionEnd",[this])}},h.prototype.disableTransition=function(){this.removeTransitionStyles(),this.element.removeEventListener(m,this,!1),this.isTransitioning=!1},h.prototype._removeStyles=function(a){var b={};for(var c in a)b[c]="";this.css(b)};var s={transitionProperty:"",transitionDuration:""};return h.prototype.removeTransitionStyles=function(){this.css(s)},h.prototype.removeElem=function(){this.element.parentNode.removeChild(this.element),this.emitEvent("remove",[this])},h.prototype.remove=function(){if(!i||!parseFloat(this.layout.options.transitionDuration))return void this.removeElem();var a=this;this.on("transitionEnd",function(){return a.removeElem(),!0}),this.hide()},h.prototype.reveal=function(){delete this.isHidden,this.css({display:""});var a=this.layout.options;this.transition({from:a.hiddenStyle,to:a.visibleStyle,isCleaning:!0})},h.prototype.hide=function(){this.isHidden=!0,this.css({display:""});var a=this.layout.options;this.transition({from:a.visibleStyle,to:a.hiddenStyle,isCleaning:!0,onTransitionEnd:{opacity:function(){this.isHidden&&this.css({display:"none"})}}})},h.prototype.destroy=function(){this.css({position:"",left:"",right:"",top:"",bottom:"",transition:"",transform:""})},h}var f=a.getComputedStyle,g=f?function(a){return f(a,null)}:function(a){return a.currentStyle};"function"==typeof define&&define.amd?define("outlayer/item",["eventEmitter/EventEmitter","get-size/get-size","get-style-property/get-style-property"],e):(a.Outlayer={},a.Outlayer.Item=e(a.EventEmitter,a.getSize,a.getStyleProperty))}(window),function(a){function b(a,b){for(var c in b)a[c]=b[c];return a}function c(a){return"[object Array]"===l.call(a)}function d(a){var b=[];if(c(a))b=a;else if(a&&"number"==typeof a.length)for(var d=0,e=a.length;e>d;d++)b.push(a[d]);else b.push(a);return b}function e(a,b){var c=n(b,a);-1!==c&&b.splice(c,1)}function f(a){return a.replace(/(.)([A-Z])/g,function(a,b,c){return b+"-"+c}).toLowerCase()}function g(c,g,l,n,o,p){function q(a,c){if("string"==typeof a&&(a=h.querySelector(a)),!a||!m(a))return void(i&&i.error("Bad "+this.constructor.namespace+" element: "+a));this.element=a,this.options=b({},this.constructor.defaults),this.option(c);var d=++r;this.element.outlayerGUID=d,s[d]=this,this._create(),this.options.isInitLayout&&this.layout()}var r=0,s={};return q.namespace="outlayer",q.Item=p,q.defaults={containerStyle:{position:"relative"},isInitLayout:!0,isOriginLeft:!0,isOriginTop:!0,isResizeBound:!0,isResizingContainer:!0,transitionDuration:"0.4s",hiddenStyle:{opacity:0,transform:"scale(0.001)"},visibleStyle:{opacity:1,transform:"scale(1)"}},b(q.prototype,l.prototype),q.prototype.option=function(a){b(this.options,a)},q.prototype._create=function(){this.reloadItems(),this.stamps=[],this.stamp(this.options.stamp),b(this.element.style,this.options.containerStyle),this.options.isResizeBound&&this.bindResize()},q.prototype.reloadItems=function(){this.items=this._itemize(this.element.children)},q.prototype._itemize=function(a){for(var b=this._filterFindItemElements(a),c=this.constructor.Item,d=[],e=0,f=b.length;f>e;e++){var g=b[e],h=new c(g,this);d.push(h)}return d},q.prototype._filterFindItemElements=function(a){a=d(a);for(var b=this.options.itemSelector,c=[],e=0,f=a.length;f>e;e++){var g=a[e];if(m(g))if(b){o(g,b)&&c.push(g);for(var h=g.querySelectorAll(b),i=0,j=h.length;j>i;i++)c.push(h[i])}else c.push(g)}return c},q.prototype.getItemElements=function(){for(var a=[],b=0,c=this.items.length;c>b;b++)a.push(this.items[b].element);return a},q.prototype.layout=function(){this._resetLayout(),this._manageStamps();var a=void 0!==this.options.isLayoutInstant?this.options.isLayoutInstant:!this._isLayoutInited;this.layoutItems(this.items,a),this._isLayoutInited=!0},q.prototype._init=q.prototype.layout,q.prototype._resetLayout=function(){this.getSize()},q.prototype.getSize=function(){this.size=n(this.element)},q.prototype._getMeasurement=function(a,b){var c,d=this.options[a];d?("string"==typeof d?c=this.element.querySelector(d):m(d)&&(c=d),this[a]=c?n(c)[b]:d):this[a]=0},q.prototype.layoutItems=function(a,b){a=this._getItemsForLayout(a),this._layoutItems(a,b),this._postLayout()},q.prototype._getItemsForLayout=function(a){for(var b=[],c=0,d=a.length;d>c;c++){var e=a[c];e.isIgnored||b.push(e)}return b},q.prototype._layoutItems=function(a,b){function c(){d.emitEvent("layoutComplete",[d,a])}var d=this;if(!a||!a.length)return void c();this._itemsOn(a,"layout",c);for(var e=[],f=0,g=a.length;g>f;f++){var h=a[f],i=this._getItemLayoutPosition(h);i.item=h,i.isInstant=b||h.isLayoutInstant,e.push(i)}this._processLayoutQueue(e)},q.prototype._getItemLayoutPosition=function(){return{x:0,y:0}},q.prototype._processLayoutQueue=function(a){for(var b=0,c=a.length;c>b;b++){var d=a[b];this._positionItem(d.item,d.x,d.y,d.isInstant)}},q.prototype._positionItem=function(a,b,c,d){d?a.goTo(b,c):a.moveTo(b,c)},q.prototype._postLayout=function(){this.resizeContainer()},q.prototype.resizeContainer=function(){if(this.options.isResizingContainer){var a=this._getContainerSize();a&&(this._setContainerMeasure(a.width,!0),this._setContainerMeasure(a.height,!1))}},q.prototype._getContainerSize=k,q.prototype._setContainerMeasure=function(a,b){if(void 0!==a){var c=this.size;c.isBorderBox&&(a+=b?c.paddingLeft+c.paddingRight+c.borderLeftWidth+c.borderRightWidth:c.paddingBottom+c.paddingTop+c.borderTopWidth+c.borderBottomWidth),a=Math.max(a,0),this.element.style[b?"width":"height"]=a+"px"}},q.prototype._itemsOn=function(a,b,c){function d(){return e++,e===f&&c.call(g),!0}for(var e=0,f=a.length,g=this,h=0,i=a.length;i>h;h++){var j=a[h];j.on(b,d)}},q.prototype.ignore=function(a){var b=this.getItem(a);b&&(b.isIgnored=!0)},q.prototype.unignore=function(a){var b=this.getItem(a);b&&delete b.isIgnored},q.prototype.stamp=function(a){if(a=this._find(a)){this.stamps=this.stamps.concat(a);for(var b=0,c=a.length;c>b;b++){var d=a[b];this.ignore(d)}}},q.prototype.unstamp=function(a){if(a=this._find(a))for(var b=0,c=a.length;c>b;b++){var d=a[b];e(d,this.stamps),this.unignore(d)}},q.prototype._find=function(a){return a?("string"==typeof a&&(a=this.element.querySelectorAll(a)),a=d(a)):void 0},q.prototype._manageStamps=function(){if(this.stamps&&this.stamps.length){this._getBoundingRect();for(var a=0,b=this.stamps.length;b>a;a++){var c=this.stamps[a];this._manageStamp(c)}}},q.prototype._getBoundingRect=function(){var a=this.element.getBoundingClientRect(),b=this.size;this._boundingRect={left:a.left+b.paddingLeft+b.borderLeftWidth,top:a.top+b.paddingTop+b.borderTopWidth,right:a.right-(b.paddingRight+b.borderRightWidth),bottom:a.bottom-(b.paddingBottom+b.borderBottomWidth)}},q.prototype._manageStamp=k,q.prototype._getElementOffset=function(a){var b=a.getBoundingClientRect(),c=this._boundingRect,d=n(a),e={left:b.left-c.left-d.marginLeft,top:b.top-c.top-d.marginTop,right:c.right-b.right-d.marginRight,bottom:c.bottom-b.bottom-d.marginBottom};return e},q.prototype.handleEvent=function(a){var b="on"+a.type;this[b]&&this[b](a)},q.prototype.bindResize=function(){this.isResizeBound||(c.bind(a,"resize",this),this.isResizeBound=!0)},q.prototype.unbindResize=function(){this.isResizeBound&&c.unbind(a,"resize",this),this.isResizeBound=!1},q.prototype.onresize=function(){function a(){b.resize(),delete b.resizeTimeout}this.resizeTimeout&&clearTimeout(this.resizeTimeout);var b=this;this.resizeTimeout=setTimeout(a,100)},q.prototype.resize=function(){this.isResizeBound&&this.needsResizeLayout()&&this.layout()},q.prototype.needsResizeLayout=function(){var a=n(this.element),b=this.size&&a;return b&&a.innerWidth!==this.size.innerWidth},q.prototype.addItems=function(a){var b=this._itemize(a);return b.length&&(this.items=this.items.concat(b)),b},q.prototype.appended=function(a){var b=this.addItems(a);b.length&&(this.layoutItems(b,!0),this.reveal(b))},q.prototype.prepended=function(a){var b=this._itemize(a);if(b.length){var c=this.items.slice(0);this.items=b.concat(c),this._resetLayout(),this._manageStamps(),this.layoutItems(b,!0),this.reveal(b),this.layoutItems(c)}},q.prototype.reveal=function(a){var b=a&&a.length;if(b)for(var c=0;b>c;c++){var d=a[c];d.reveal()}},q.prototype.hide=function(a){var b=a&&a.length;if(b)for(var c=0;b>c;c++){var d=a[c];d.hide()}},q.prototype.getItem=function(a){for(var b=0,c=this.items.length;c>b;b++){var d=this.items[b];if(d.element===a)return d}},q.prototype.getItems=function(a){if(a&&a.length){for(var b=[],c=0,d=a.length;d>c;c++){var e=a[c],f=this.getItem(e);f&&b.push(f)}return b}},q.prototype.remove=function(a){a=d(a);var b=this.getItems(a);if(b&&b.length){this._itemsOn(b,"remove",function(){this.emitEvent("removeComplete",[this,b])});for(var c=0,f=b.length;f>c;c++){var g=b[c];g.remove(),e(g,this.items)}}},q.prototype.destroy=function(){var a=this.element.style;a.height="",a.position="",a.width="";for(var b=0,c=this.items.length;c>b;b++){var d=this.items[b];d.destroy()}this.unbindResize(),delete this.element.outlayerGUID,j&&j.removeData(this.element,this.constructor.namespace)},q.data=function(a){var b=a&&a.outlayerGUID;return b&&s[b]},q.create=function(a,c){function d(){q.apply(this,arguments)}return Object.create?d.prototype=Object.create(q.prototype):b(d.prototype,q.prototype),d.prototype.constructor=d,d.defaults=b({},q.defaults),b(d.defaults,c),d.prototype.settings={},d.namespace=a,d.data=q.data,d.Item=function(){p.apply(this,arguments)},d.Item.prototype=new p,g(function(){for(var b=f(a),c=h.querySelectorAll(".js-"+b),e="data-"+b+"-options",g=0,k=c.length;k>g;g++){var l,m=c[g],n=m.getAttribute(e);try{l=n&&JSON.parse(n)}catch(o){i&&i.error("Error parsing "+e+" on "+m.nodeName.toLowerCase()+(m.id?"#"+m.id:"")+": "+o);continue}var p=new d(m,l);j&&j.data(m,a,p)}}),j&&j.bridget&&j.bridget(a,d),d},q.Item=p,q}var h=a.document,i=a.console,j=a.jQuery,k=function(){},l=Object.prototype.toString,m="object"==typeof HTMLElement?function(a){return a instanceof HTMLElement}:function(a){return a&&"object"==typeof a&&1===a.nodeType&&"string"==typeof a.nodeName},n=Array.prototype.indexOf?function(a,b){return a.indexOf(b)}:function(a,b){for(var c=0,d=a.length;d>c;c++)if(a[c]===b)return c;return-1};"function"==typeof define&&define.amd?define("outlayer/outlayer",["eventie/eventie","doc-ready/doc-ready","eventEmitter/EventEmitter","get-size/get-size","matches-selector/matches-selector","./item"],g):a.Outlayer=g(a.eventie,a.docReady,a.EventEmitter,a.getSize,a.matchesSelector,a.Outlayer.Item)}(window),function(a){function b(a,b){var d=a.create("masonry");return d.prototype._resetLayout=function(){this.getSize(),this._getMeasurement("columnWidth","outerWidth"),this._getMeasurement("gutter","outerWidth"),this.measureColumns();var a=this.cols;for(this.colYs=[];a--;)this.colYs.push(0);this.maxY=0},d.prototype.measureColumns=function(){if(this.getContainerWidth(),!this.columnWidth){var a=this.items[0],c=a&&a.element;this.columnWidth=c&&b(c).outerWidth||this.containerWidth}this.columnWidth+=this.gutter,this.cols=Math.floor((this.containerWidth+this.gutter)/this.columnWidth),this.cols=Math.max(this.cols,1)},d.prototype.getContainerWidth=function(){var a=this.options.isFitWidth?this.element.parentNode:this.element,c=b(a);this.containerWidth=c&&c.innerWidth},d.prototype._getItemLayoutPosition=function(a){a.getSize();var b=a.size.outerWidth%this.columnWidth,d=b&&1>b?"round":"ceil",e=Math[d](a.size.outerWidth/this.columnWidth);e=Math.min(e,this.cols);for(var f=this._getColGroup(e),g=Math.min.apply(Math,f),h=c(f,g),i={x:this.columnWidth*h,y:g},j=g+a.size.outerHeight,k=this.cols+1-f.length,l=0;k>l;l++)this.colYs[h+l]=j;return i},d.prototype._getColGroup=function(a){if(2>a)return this.colYs;for(var b=[],c=this.cols+1-a,d=0;c>d;d++){var e=this.colYs.slice(d,d+a);b[d]=Math.max.apply(Math,e)}return b},d.prototype._manageStamp=function(a){var c=b(a),d=this._getElementOffset(a),e=this.options.isOriginLeft?d.left:d.right,f=e+c.outerWidth,g=Math.floor(e/this.columnWidth);g=Math.max(0,g);var h=Math.floor(f/this.columnWidth);h-=f%this.columnWidth?0:1,h=Math.min(this.cols-1,h);for(var i=(this.options.isOriginTop?d.top:d.bottom)+c.outerHeight,j=g;h>=j;j++)this.colYs[j]=Math.max(i,this.colYs[j])},d.prototype._getContainerSize=function(){this.maxY=Math.max.apply(Math,this.colYs);var a={height:this.maxY};return this.options.isFitWidth&&(a.width=this._getContainerFitWidth()),a},d.prototype._getContainerFitWidth=function(){for(var a=0,b=this.cols;--b&&0===this.colYs[b];)a++;return(this.cols-a)*this.columnWidth-this.gutter},d.prototype.needsResizeLayout=function(){var a=this.containerWidth;return this.getContainerWidth(),a!==this.containerWidth},d}var c=Array.prototype.indexOf?function(a,b){return a.indexOf(b)}:function(a,b){for(var c=0,d=a.length;d>c;c++){var e=a[c];if(e===b)return c}return-1};"function"==typeof define&&define.amd?define(["outlayer/outlayer","get-size/get-size"],b):a.Masonry=b(a.Outlayer,a.getSize)}(window); \ No newline at end of file diff --git a/wp-content/themes/headway/library/admin/js/jquery.qtip.js b/wp-content/themes/headway/library/admin/js/jquery.qtip.js new file mode 100644 index 0000000..ccc6128 --- /dev/null +++ b/wp-content/themes/headway/library/admin/js/jquery.qtip.js @@ -0,0 +1,5 @@ +/* qTip2 v2.2.0 tips viewport | qtip2.com | Licensed MIT, GPL | Mon Dec 16 2013 11:39:27 */ + +!function(a,b,c){!function(a){"use strict";"function"==typeof define&&define.amd?define(["jquery"],a):jQuery&&!jQuery.fn.qtip&&a(jQuery)}(function(d){"use strict";function e(a,b,c,e){this.id=c,this.target=a,this.tooltip=E,this.elements={target:a},this._id=R+"-"+c,this.timers={img:{}},this.options=b,this.plugins={},this.cache={event:{},target:d(),disabled:D,attr:e,onTooltip:D,lastClass:""},this.rendered=this.destroyed=this.disabled=this.waiting=this.hiddenDuringWait=this.positioning=this.triggering=D}function f(a){return a===E||"object"!==d.type(a)}function g(a){return!(d.isFunction(a)||a&&a.attr||a.length||"object"===d.type(a)&&(a.jquery||a.then))}function h(a){var b,c,e,h;return f(a)?D:(f(a.metadata)&&(a.metadata={type:a.metadata}),"content"in a&&(b=a.content,f(b)||b.jquery||b.done?b=a.content={text:c=g(b)?D:b}:c=b.text,"ajax"in b&&(e=b.ajax,h=e&&e.once!==D,delete b.ajax,b.text=function(a,b){var f=c||d(this).attr(b.options.content.attr)||"Loading...",g=d.ajax(d.extend({},e,{context:b})).then(e.success,E,e.error).then(function(a){return a&&h&&b.set("content.text",a),a},function(a,c,d){b.destroyed||0===a.status||b.set("content.text",c+": "+d)});return h?f:(b.set("content.text",f),g)}),"title"in b&&(f(b.title)||(b.button=b.title.button,b.title=b.title.text),g(b.title||D)&&(b.title=D))),"position"in a&&f(a.position)&&(a.position={my:a.position,at:a.position}),"show"in a&&f(a.show)&&(a.show=a.show.jquery?{target:a.show}:a.show===C?{ready:C}:{event:a.show}),"hide"in a&&f(a.hide)&&(a.hide=a.hide.jquery?{target:a.hide}:{event:a.hide}),"style"in a&&f(a.style)&&(a.style={classes:a.style}),d.each(Q,function(){this.sanitize&&this.sanitize(a)}),a)}function i(a,b){for(var c,d=0,e=a,f=b.split(".");e=e[f[d++]];)d0?setTimeout(d.proxy(a,this),b):(a.call(this),void 0)}function n(a){return this.tooltip.hasClass(_)?D:(clearTimeout(this.timers.show),clearTimeout(this.timers.hide),this.timers.show=m.call(this,function(){this.toggle(C,a)},this.options.show.delay),void 0)}function o(a){if(this.tooltip.hasClass(_))return D;var b=d(a.relatedTarget),c=b.closest(V)[0]===this.tooltip[0],e=b[0]===this.options.show.target[0];if(clearTimeout(this.timers.show),clearTimeout(this.timers.hide),this!==b[0]&&"mouse"===this.options.position.target&&c||this.options.hide.fixed&&/mouse(out|leave|move)/.test(a.type)&&(c||e))try{a.preventDefault(),a.stopImmediatePropagation()}catch(f){}else this.timers.hide=m.call(this,function(){this.toggle(D,a)},this.options.hide.delay,this)}function p(a){return this.tooltip.hasClass(_)||!this.options.hide.inactive?D:(clearTimeout(this.timers.inactive),this.timers.inactive=m.call(this,function(){this.hide(a)},this.options.hide.inactive),void 0)}function q(a){this.rendered&&this.tooltip[0].offsetWidth>0&&this.reposition(a)}function r(a,c,e){d(b.body).delegate(a,(c.split?c:c.join(gb+" "))+gb,function(){var a=x.api[d.attr(this,T)];a&&!a.disabled&&e.apply(a,arguments)})}function s(a,c,f){var g,i,j,k,l,m=d(b.body),n=a[0]===b?m:a,o=a.metadata?a.metadata(f.metadata):E,p="html5"===f.metadata.type&&o?o[f.metadata.name]:E,q=a.data(f.metadata.name||"qtipopts");try{q="string"==typeof q?d.parseJSON(q):q}catch(r){}if(k=d.extend(C,{},x.defaults,f,"object"==typeof q?h(q):E,h(p||o)),i=k.position,k.id=c,"boolean"==typeof k.content.text){if(j=a.attr(k.content.attr),k.content.attr===D||!j)return D;k.content.text=j}if(i.container.length||(i.container=m),i.target===D&&(i.target=n),k.show.target===D&&(k.show.target=n),k.show.solo===C&&(k.show.solo=i.container.closest("body")),k.hide.target===D&&(k.hide.target=n),k.position.viewport===C&&(k.position.viewport=i.container),i.container=i.container.eq(0),i.at=new z(i.at,C),i.my=new z(i.my),a.data(R))if(k.overwrite)a.qtip("destroy",!0);else if(k.overwrite===D)return D;return a.attr(S,c),k.suppress&&(l=a.attr("title"))&&a.removeAttr("title").attr(bb,l).attr("title",""),g=new e(a,k,c,!!j),a.data(R,g),a.one("remove.qtip-"+c+" removeqtip.qtip-"+c,function(){var a;(a=d(this).data(R))&&a.destroy(!0)}),g}function t(a){return a.charAt(0).toUpperCase()+a.slice(1)}function u(a,b){var d,e,f=b.charAt(0).toUpperCase()+b.slice(1),g=(b+" "+rb.join(f+" ")+f).split(" "),h=0;if(qb[b])return a.css(qb[b]);for(;d=g[h++];)if((e=a.css(d))!==c)return qb[b]=d,e}function v(a,b){return Math.ceil(parseFloat(u(a,b)))}function w(a,b){this._ns="tip",this.options=b,this.offset=b.offset,this.size=[b.width,b.height],this.init(this.qtip=a)}var x,y,z,A,B,C=!0,D=!1,E=null,F="x",G="y",H="width",I="height",J="top",K="left",L="bottom",M="right",N="center",O="flipinvert",P="shift",Q={},R="qtip",S="data-hasqtip",T="data-qtip-id",U=["ui-widget","ui-tooltip"],V="."+R,W="click dblclick mousedown mouseup mousemove mouseleave mouseenter".split(" "),X=R+"-fixed",Y=R+"-default",Z=R+"-focus",$=R+"-hover",_=R+"-disabled",ab="_replacedByqTip",bb="oldtitle",cb={ie:function(){for(var a=3,c=b.createElement("div");(c.innerHTML="")&&c.getElementsByTagName("i")[0];);return a>4?a:0/0}(),iOS:parseFloat((""+(/CPU.*OS ([0-9_]{1,5})|(CPU like).*AppleWebKit.*Mobile/i.exec(navigator.userAgent)||[0,""])[1]).replace("undefined","3_2").replace("_",".").replace("_",""))||D};y=e.prototype,y._when=function(a){return d.when.apply(d,a)},y.render=function(a){if(this.rendered||this.destroyed)return this;var b,c=this,e=this.options,f=this.cache,g=this.elements,h=e.content.text,i=e.content.title,j=e.content.button,k=e.position,l=("."+this._id+" ",[]);return d.attr(this.target[0],"aria-describedby",this._id),this.tooltip=g.tooltip=b=d("
",{id:this._id,"class":[R,Y,e.style.classes,R+"-pos-"+e.position.my.abbrev()].join(" "),width:e.style.width||"",height:e.style.height||"",tracking:"mouse"===k.target&&k.adjust.mouse,role:"alert","aria-live":"polite","aria-atomic":D,"aria-describedby":this._id+"-content","aria-hidden":C}).toggleClass(_,this.disabled).attr(T,this.id).data(R,this).appendTo(k.container).append(g.content=d("
",{"class":R+"-content",id:this._id+"-content","aria-atomic":C})),this.rendered=-1,this.positioning=C,i&&(this._createTitle(),d.isFunction(i)||l.push(this._updateTitle(i,D))),j&&this._createButton(),d.isFunction(h)||l.push(this._updateContent(h,D)),this.rendered=C,this._setWidget(),d.each(Q,function(a){var b;"render"===this.initialize&&(b=this(c))&&(c.plugins[a]=b)}),this._unassignEvents(),this._assignEvents(),this._when(l).then(function(){c._trigger("render"),c.positioning=D,c.hiddenDuringWait||!e.show.ready&&!a||c.toggle(C,f.event,D),c.hiddenDuringWait=D}),x.api[this.id]=this,this},y.destroy=function(a){function b(){if(!this.destroyed){this.destroyed=C;var a=this.target,b=a.attr(bb);this.rendered&&this.tooltip.stop(1,0).find("*").remove().end().remove(),d.each(this.plugins,function(){this.destroy&&this.destroy()}),clearTimeout(this.timers.show),clearTimeout(this.timers.hide),this._unassignEvents(),a.removeData(R).removeAttr(T).removeAttr(S).removeAttr("aria-describedby"),this.options.suppress&&b&&a.attr("title",b).removeAttr(bb),this._unbind(a),this.options=this.elements=this.cache=this.timers=this.plugins=this.mouse=E,delete x.api[this.id]}}return this.destroyed?this.target:(a===C&&"hide"!==this.triggering||!this.rendered?b.call(this):(this.tooltip.one("tooltiphidden",d.proxy(b,this)),!this.triggering&&this.hide()),this.target)},A=y.checks={builtin:{"^id$":function(a,b,c,e){var f=c===C?x.nextid:c,g=R+"-"+f;f!==D&&f.length>0&&!d("#"+g).length?(this._id=g,this.rendered&&(this.tooltip[0].id=this._id,this.elements.content[0].id=this._id+"-content",this.elements.title[0].id=this._id+"-title")):a[b]=e},"^prerender":function(a,b,c){c&&!this.rendered&&this.render(this.options.show.ready)},"^content.text$":function(a,b,c){this._updateContent(c)},"^content.attr$":function(a,b,c,d){this.options.content.text===this.target.attr(d)&&this._updateContent(this.target.attr(c))},"^content.title$":function(a,b,c){return c?(c&&!this.elements.title&&this._createTitle(),this._updateTitle(c),void 0):this._removeTitle()},"^content.button$":function(a,b,c){this._updateButton(c)},"^content.title.(text|button)$":function(a,b,c){this.set("content."+b,c)},"^position.(my|at)$":function(a,b,c){"string"==typeof c&&(a[b]=new z(c,"at"===b))},"^position.container$":function(a,b,c){this.rendered&&this.tooltip.appendTo(c)},"^show.ready$":function(a,b,c){c&&(!this.rendered&&this.render(C)||this.toggle(C))},"^style.classes$":function(a,b,c,d){this.rendered&&this.tooltip.removeClass(d).addClass(c)},"^style.(width|height)":function(a,b,c){this.rendered&&this.tooltip.css(b,c)},"^style.widget|content.title":function(){this.rendered&&this._setWidget()},"^style.def":function(a,b,c){this.rendered&&this.tooltip.toggleClass(Y,!!c)},"^events.(render|show|move|hide|focus|blur)$":function(a,b,c){this.rendered&&this.tooltip[(d.isFunction(c)?"":"un")+"bind"]("tooltip"+b,c)},"^(show|hide|position).(event|target|fixed|inactive|leave|distance|viewport|adjust)":function(){if(this.rendered){var a=this.options.position;this.tooltip.attr("tracking","mouse"===a.target&&a.adjust.mouse),this._unassignEvents(),this._assignEvents()}}}},y.get=function(a){if(this.destroyed)return this;var b=i(this.options,a.toLowerCase()),c=b[0][b[1]];return c.precedance?c.string():c};var db=/^position\.(my|at|adjust|target|container|viewport)|style|content|show\.ready/i,eb=/^prerender|show\.ready/i;y.set=function(a,b){if(this.destroyed)return this;{var c,e=this.rendered,f=D,g=this.options;this.checks}return"string"==typeof a?(c=a,a={},a[c]=b):a=d.extend({},a),d.each(a,function(b,c){if(e&&eb.test(b))return delete a[b],void 0;var h,j=i(g,b.toLowerCase());h=j[0][j[1]],j[0][j[1]]=c&&c.nodeType?d(c):c,f=db.test(b)||f,a[b]=[j[0],j[1],c,h]}),h(g),this.positioning=C,d.each(a,d.proxy(j,this)),this.positioning=D,this.rendered&&this.tooltip[0].offsetWidth>0&&f&&this.reposition("mouse"===g.position.target?E:this.cache.event),this},y._update=function(a,b){var c=this,e=this.cache;return this.rendered&&a?(d.isFunction(a)&&(a=a.call(this.elements.target,e.event,this)||""),d.isFunction(a.then)?(e.waiting=C,a.then(function(a){return e.waiting=D,c._update(a,b)},E,function(a){return c._update(a,b)})):a===D||!a&&""!==a?D:(a.jquery&&a.length>0?b.empty().append(a.css({display:"block",visibility:"visible"})):b.html(a),this._waitForContent(b).then(function(a){a.images&&a.images.length&&c.rendered&&c.tooltip[0].offsetWidth>0&&c.reposition(e.event,!a.length)}))):D},y._waitForContent=function(a){var b=this.cache;return b.waiting=C,(d.fn.imagesLoaded?a.imagesLoaded():d.Deferred().resolve([])).done(function(){b.waiting=D}).promise()},y._updateContent=function(a,b){this._update(a,this.elements.content,b)},y._updateTitle=function(a,b){this._update(a,this.elements.title,b)===D&&this._removeTitle(D)},y._createTitle=function(){var a=this.elements,b=this._id+"-title";a.titlebar&&this._removeTitle(),a.titlebar=d("
",{"class":R+"-titlebar "+(this.options.style.widget?k("header"):"")}).append(a.title=d("
",{id:b,"class":R+"-title","aria-atomic":C})).insertBefore(a.content).delegate(".qtip-close","mousedown keydown mouseup keyup mouseout",function(a){d(this).toggleClass("ui-state-active ui-state-focus","down"===a.type.substr(-4))}).delegate(".qtip-close","mouseover mouseout",function(a){d(this).toggleClass("ui-state-hover","mouseover"===a.type)}),this.options.content.button&&this._createButton()},y._removeTitle=function(a){var b=this.elements;b.title&&(b.titlebar.remove(),b.titlebar=b.title=b.button=E,a!==D&&this.reposition())},y.reposition=function(c,e){if(!this.rendered||this.positioning||this.destroyed)return this;this.positioning=C;var f,g,h=this.cache,i=this.tooltip,j=this.options.position,k=j.target,l=j.my,m=j.at,n=j.viewport,o=j.container,p=j.adjust,q=p.method.split(" "),r=i.outerWidth(D),s=i.outerHeight(D),t=0,u=0,v=i.css("position"),w={left:0,top:0},x=i[0].offsetWidth>0,y=c&&"scroll"===c.type,z=d(a),A=o[0].ownerDocument,B=this.mouse;if(d.isArray(k)&&2===k.length)m={x:K,y:J},w={left:k[0],top:k[1]};else if("mouse"===k)m={x:K,y:J},!B||!B.pageX||!p.mouse&&c&&c.pageX?c&&c.pageX||((!p.mouse||this.options.show.distance)&&h.origin&&h.origin.pageX?c=h.origin:(!c||c&&("resize"===c.type||"scroll"===c.type))&&(c=h.event)):c=B,"static"!==v&&(w=o.offset()),A.body.offsetWidth!==(a.innerWidth||A.documentElement.clientWidth)&&(g=d(b.body).offset()),w={left:c.pageX-w.left+(g&&g.left||0),top:c.pageY-w.top+(g&&g.top||0)},p.mouse&&y&&B&&(w.left-=(B.scrollX||0)-z.scrollLeft(),w.top-=(B.scrollY||0)-z.scrollTop());else{if("event"===k?c&&c.target&&"scroll"!==c.type&&"resize"!==c.type?h.target=d(c.target):c.target||(h.target=this.elements.target):"event"!==k&&(h.target=d(k.jquery?k:this.elements.target)),k=h.target,k=d(k).eq(0),0===k.length)return this;k[0]===b||k[0]===a?(t=cb.iOS?a.innerWidth:k.width(),u=cb.iOS?a.innerHeight:k.height(),k[0]===a&&(w={top:(n||k).scrollTop(),left:(n||k).scrollLeft()})):Q.imagemap&&k.is("area")?f=Q.imagemap(this,k,m,Q.viewport?q:D):Q.svg&&k&&k[0].ownerSVGElement?f=Q.svg(this,k,m,Q.viewport?q:D):(t=k.outerWidth(D),u=k.outerHeight(D),w=k.offset()),f&&(t=f.width,u=f.height,g=f.offset,w=f.position),w=this.reposition.offset(k,w,o),(cb.iOS>3.1&&cb.iOS<4.1||cb.iOS>=4.3&&cb.iOS<4.33||!cb.iOS&&"fixed"===v)&&(w.left-=z.scrollLeft(),w.top-=z.scrollTop()),(!f||f&&f.adjustable!==D)&&(w.left+=m.x===M?t:m.x===N?t/2:0,w.top+=m.y===L?u:m.y===N?u/2:0)}return w.left+=p.x+(l.x===M?-r:l.x===N?-r/2:0),w.top+=p.y+(l.y===L?-s:l.y===N?-s/2:0),Q.viewport?(w.adjusted=Q.viewport(this,w,j,t,u,r,s),g&&w.adjusted.left&&(w.left+=g.left),g&&w.adjusted.top&&(w.top+=g.top)):w.adjusted={left:0,top:0},this._trigger("move",[w,n.elem||n],c)?(delete w.adjusted,e===D||!x||isNaN(w.left)||isNaN(w.top)||"mouse"===k||!d.isFunction(j.effect)?i.css(w):d.isFunction(j.effect)&&(j.effect.call(i,this,d.extend({},w)),i.queue(function(a){d(this).css({opacity:"",height:""}),cb.ie&&this.style.removeAttribute("filter"),a()})),this.positioning=D,this):this},y.reposition.offset=function(a,c,e){function f(a,b){c.left+=b*a.scrollLeft(),c.top+=b*a.scrollTop()}if(!e[0])return c;var g,h,i,j,k=d(a[0].ownerDocument),l=!!cb.ie&&"CSS1Compat"!==b.compatMode,m=e[0];do"static"!==(h=d.css(m,"position"))&&("fixed"===h?(i=m.getBoundingClientRect(),f(k,-1)):(i=d(m).position(),i.left+=parseFloat(d.css(m,"borderLeftWidth"))||0,i.top+=parseFloat(d.css(m,"borderTopWidth"))||0),c.left-=i.left+(parseFloat(d.css(m,"marginLeft"))||0),c.top-=i.top+(parseFloat(d.css(m,"marginTop"))||0),g||"hidden"===(j=d.css(m,"overflow"))||"visible"===j||(g=d(m)));while(m=m.offsetParent);return g&&(g[0]!==k[0]||l)&&f(g,1),c};var fb=(z=y.reposition.Corner=function(a,b){a=(""+a).replace(/([A-Z])/," $1").replace(/middle/gi,N).toLowerCase(),this.x=(a.match(/left|right/i)||a.match(/center/)||["inherit"])[0].toLowerCase(),this.y=(a.match(/top|bottom|center/i)||["inherit"])[0].toLowerCase(),this.forceY=!!b;var c=a.charAt(0);this.precedance="t"===c||"b"===c?G:F}).prototype;fb.invert=function(a,b){this[a]=this[a]===K?M:this[a]===M?K:b||this[a]},fb.string=function(){var a=this.x,b=this.y;return a===b?a:this.precedance===G||this.forceY&&"center"!==b?b+" "+a:a+" "+b},fb.abbrev=function(){var a=this.string().split(" ");return a[0].charAt(0)+(a[1]&&a[1].charAt(0)||"")},fb.clone=function(){return new z(this.string(),this.forceY)},y.toggle=function(a,c){var e=this.cache,f=this.options,g=this.tooltip;if(c){if(/over|enter/.test(c.type)&&/out|leave/.test(e.event.type)&&f.show.target.add(c.target).length===f.show.target.length&&g.has(c.relatedTarget).length)return this;e.event=l(c)}if(this.waiting&&!a&&(this.hiddenDuringWait=C),!this.rendered)return a?this.render(1):this;if(this.destroyed||this.disabled)return this;var h,i,j,k=a?"show":"hide",m=this.options[k],n=(this.options[a?"hide":"show"],this.options.position),o=this.options.content,p=this.tooltip.css("width"),q=this.tooltip.is(":visible"),r=a||1===m.target.length,s=!c||m.target.length<2||e.target[0]===c.target;return(typeof a).search("boolean|number")&&(a=!q),h=!g.is(":animated")&&q===a&&s,i=h?E:!!this._trigger(k,[90]),this.destroyed?this:(i!==D&&a&&this.focus(c),!i||h?this:(d.attr(g[0],"aria-hidden",!a),a?(e.origin=l(this.mouse),d.isFunction(o.text)&&this._updateContent(o.text,D),d.isFunction(o.title)&&this._updateTitle(o.title,D),!B&&"mouse"===n.target&&n.adjust.mouse&&(d(b).bind("mousemove."+R,this._storeMouse),B=C),p||g.css("width",g.outerWidth(D)),this.reposition(c,arguments[2]),p||g.css("width",""),m.solo&&("string"==typeof m.solo?d(m.solo):d(V,m.solo)).not(g).not(m.target).qtip("hide",d.Event("tooltipsolo"))):(clearTimeout(this.timers.show),delete e.origin,B&&!d(V+'[tracking="true"]:visible',m.solo).not(g).length&&(d(b).unbind("mousemove."+R),B=D),this.blur(c)),j=d.proxy(function(){a?(cb.ie&&g[0].style.removeAttribute("filter"),g.css("overflow",""),"string"==typeof m.autofocus&&d(this.options.show.autofocus,g).focus(),this.options.show.target.trigger("qtip-"+this.id+"-inactive")):g.css({display:"",visibility:"",opacity:"",left:"",top:""}),this._trigger(a?"visible":"hidden")},this),m.effect===D||r===D?(g[k](),j()):d.isFunction(m.effect)?(g.stop(1,1),m.effect.call(g,this),g.queue("fx",function(a){j(),a()})):g.fadeTo(90,a?1:0,j),a&&m.target.trigger("qtip-"+this.id+"-inactive"),this))},y.show=function(a){return this.toggle(C,a)},y.hide=function(a){return this.toggle(D,a)},y.focus=function(a){if(!this.rendered||this.destroyed)return this;var b=d(V),c=this.tooltip,e=parseInt(c[0].style.zIndex,10),f=x.zindex+b.length;return c.hasClass(Z)||this._trigger("focus",[f],a)&&(e!==f&&(b.each(function(){this.style.zIndex>e&&(this.style.zIndex=this.style.zIndex-1)}),b.filter("."+Z).qtip("blur",a)),c.addClass(Z)[0].style.zIndex=f),this},y.blur=function(a){return!this.rendered||this.destroyed?this:(this.tooltip.removeClass(Z),this._trigger("blur",[this.tooltip.css("zIndex")],a),this)},y.disable=function(a){return this.destroyed?this:("toggle"===a?a=!(this.rendered?this.tooltip.hasClass(_):this.disabled):"boolean"!=typeof a&&(a=C),this.rendered&&this.tooltip.toggleClass(_,a).attr("aria-disabled",a),this.disabled=!!a,this)},y.enable=function(){return this.disable(D)},y._createButton=function(){var a=this,b=this.elements,c=b.tooltip,e=this.options.content.button,f="string"==typeof e,g=f?e:"Close tooltip";b.button&&b.button.remove(),b.button=e.jquery?e:d("",{"class":"qtip-close "+(this.options.style.widget?"":R+"-icon"),title:g,"aria-label":g}).prepend(d("",{"class":"ui-icon ui-icon-close",html:"×"})),b.button.appendTo(b.titlebar||c).attr("role","button").click(function(b){return c.hasClass(_)||a.hide(b),D})},y._updateButton=function(a){if(!this.rendered)return D;var b=this.elements.button;a?this._createButton():b.remove()},y._setWidget=function(){var a=this.options.style.widget,b=this.elements,c=b.tooltip,d=c.hasClass(_);c.removeClass(_),_=a?"ui-state-disabled":"qtip-disabled",c.toggleClass(_,d),c.toggleClass("ui-helper-reset "+k(),a).toggleClass(Y,this.options.style.def&&!a),b.content&&b.content.toggleClass(k("content"),a),b.titlebar&&b.titlebar.toggleClass(k("header"),a),b.button&&b.button.toggleClass(R+"-icon",!a)},y._storeMouse=function(a){(this.mouse=l(a)).type="mousemove"},y._bind=function(a,b,c,e,f){var g="."+this._id+(e?"-"+e:"");b.length&&d(a).bind((b.split?b:b.join(g+" "))+g,d.proxy(c,f||this))},y._unbind=function(a,b){d(a).unbind("."+this._id+(b?"-"+b:""))};var gb="."+R;d(function(){r(V,["mouseenter","mouseleave"],function(a){var b="mouseenter"===a.type,c=d(a.currentTarget),e=d(a.relatedTarget||a.target),f=this.options;b?(this.focus(a),c.hasClass(X)&&!c.hasClass(_)&&clearTimeout(this.timers.hide)):"mouse"===f.position.target&&f.hide.event&&f.show.target&&!e.closest(f.show.target[0]).length&&this.hide(a),c.toggleClass($,b)}),r("["+T+"]",W,p)}),y._trigger=function(a,b,c){var e=d.Event("tooltip"+a);return e.originalEvent=c&&d.extend({},c)||this.cache.event||E,this.triggering=a,this.tooltip.trigger(e,[this].concat(b||[])),this.triggering=D,!e.isDefaultPrevented()},y._bindEvents=function(a,b,c,e,f,g){if(e.add(c).length===e.length){var h=[];b=d.map(b,function(b){var c=d.inArray(b,a);return c>-1?(h.push(a.splice(c,1)[0]),void 0):b}),h.length&&this._bind(c,h,function(a){var b=this.rendered?this.tooltip[0].offsetWidth>0:!1;(b?g:f).call(this,a)})}this._bind(c,a,f),this._bind(e,b,g)},y._assignInitialEvents=function(a){function b(a){return this.disabled||this.destroyed?D:(this.cache.event=l(a),this.cache.target=a?d(a.target):[c],clearTimeout(this.timers.show),this.timers.show=m.call(this,function(){this.render("object"==typeof a||e.show.ready)},e.show.delay),void 0)}var e=this.options,f=e.show.target,g=e.hide.target,h=e.show.event?d.trim(""+e.show.event).split(" "):[],i=e.hide.event?d.trim(""+e.hide.event).split(" "):[];/mouse(over|enter)/i.test(e.show.event)&&!/mouse(out|leave)/i.test(e.hide.event)&&i.push("mouseleave"),this._bind(f,"mousemove",function(a){this._storeMouse(a),this.cache.onTarget=C}),this._bindEvents(h,i,f,g,b,function(){clearTimeout(this.timers.show)}),(e.show.ready||e.prerender)&&b.call(this,a)},y._assignEvents=function(){var c=this,e=this.options,f=e.position,g=this.tooltip,h=e.show.target,i=e.hide.target,j=f.container,k=f.viewport,l=d(b),m=(d(b.body),d(a)),r=e.show.event?d.trim(""+e.show.event).split(" "):[],s=e.hide.event?d.trim(""+e.hide.event).split(" "):[];d.each(e.events,function(a,b){c._bind(g,"toggle"===a?["tooltipshow","tooltiphide"]:["tooltip"+a],b,null,g)}),/mouse(out|leave)/i.test(e.hide.event)&&"window"===e.hide.leave&&this._bind(l,["mouseout","blur"],function(a){/select|option/.test(a.target.nodeName)||a.relatedTarget||this.hide(a)}),e.hide.fixed?i=i.add(g.addClass(X)):/mouse(over|enter)/i.test(e.show.event)&&this._bind(i,"mouseleave",function(){clearTimeout(this.timers.show)}),(""+e.hide.event).indexOf("unfocus")>-1&&this._bind(j.closest("html"),["mousedown","touchstart"],function(a){var b=d(a.target),c=this.rendered&&!this.tooltip.hasClass(_)&&this.tooltip[0].offsetWidth>0,e=b.parents(V).filter(this.tooltip[0]).length>0;b[0]===this.target[0]||b[0]===this.tooltip[0]||e||this.target.has(b[0]).length||!c||this.hide(a)}),"number"==typeof e.hide.inactive&&(this._bind(h,"qtip-"+this.id+"-inactive",p),this._bind(i.add(g),x.inactiveEvents,p,"-inactive")),this._bindEvents(r,s,h,i,n,o),this._bind(h.add(g),"mousemove",function(a){if("number"==typeof e.hide.distance){var b=this.cache.origin||{},c=this.options.hide.distance,d=Math.abs;(d(a.pageX-b.pageX)>=c||d(a.pageY-b.pageY)>=c)&&this.hide(a)}this._storeMouse(a)}),"mouse"===f.target&&f.adjust.mouse&&(e.hide.event&&this._bind(h,["mouseenter","mouseleave"],function(a){this.cache.onTarget="mouseenter"===a.type}),this._bind(l,"mousemove",function(a){this.rendered&&this.cache.onTarget&&!this.tooltip.hasClass(_)&&this.tooltip[0].offsetWidth>0&&this.reposition(a)})),(f.adjust.resize||k.length)&&this._bind(d.event.special.resize?k:m,"resize",q),f.adjust.scroll&&this._bind(m.add(f.container),"scroll",q)},y._unassignEvents=function(){var c=[this.options.show.target[0],this.options.hide.target[0],this.rendered&&this.tooltip[0],this.options.position.container[0],this.options.position.viewport[0],this.options.position.container.closest("html")[0],a,b];this._unbind(d([]).pushStack(d.grep(c,function(a){return"object"==typeof a})))},x=d.fn.qtip=function(a,b,e){var f=(""+a).toLowerCase(),g=E,i=d.makeArray(arguments).slice(1),j=i[i.length-1],k=this[0]?d.data(this[0],R):E;return!arguments.length&&k||"api"===f?k:"string"==typeof a?(this.each(function(){var a=d.data(this,R);if(!a)return C;if(j&&j.timeStamp&&(a.cache.event=j),!b||"option"!==f&&"options"!==f)a[f]&&a[f].apply(a,i);else{if(e===c&&!d.isPlainObject(b))return g=a.get(b),D;a.set(b,e)}}),g!==E?g:this):"object"!=typeof a&&arguments.length?void 0:(k=h(d.extend(C,{},a)),this.each(function(a){var b,c;return c=d.isArray(k.id)?k.id[a]:k.id,c=!c||c===D||c.length<1||x.api[c]?x.nextid++:c,b=s(d(this),c,k),b===D?C:(x.api[c]=b,d.each(Q,function(){"initialize"===this.initialize&&this(b)}),b._assignInitialEvents(j),void 0)}))},d.qtip=e,x.api={},d.each({attr:function(a,b){if(this.length){var c=this[0],e="title",f=d.data(c,"qtip");if(a===e&&f&&"object"==typeof f&&f.options.suppress)return arguments.length<2?d.attr(c,bb):(f&&f.options.content.attr===e&&f.cache.attr&&f.set("content.text",b),this.attr(bb,b))}return d.fn["attr"+ab].apply(this,arguments)},clone:function(a){var b=(d([]),d.fn["clone"+ab].apply(this,arguments));return a||b.filter("["+bb+"]").attr("title",function(){return d.attr(this,bb)}).removeAttr(bb),b}},function(a,b){if(!b||d.fn[a+ab])return C;var c=d.fn[a+ab]=d.fn[a];d.fn[a]=function(){return b.apply(this,arguments)||c.apply(this,arguments)}}),d.ui||(d["cleanData"+ab]=d.cleanData,d.cleanData=function(a){for(var b,c=0;(b=d(a[c])).length;c++)if(b.attr(S))try{b.triggerHandler("removeqtip")}catch(e){}d["cleanData"+ab].apply(this,arguments)}),x.version="2.2.0",x.nextid=0,x.inactiveEvents=W,x.zindex=15e3,x.defaults={prerender:D,id:D,overwrite:C,suppress:C,content:{text:C,attr:"title",title:D,button:D},position:{my:"top left",at:"bottom right",target:D,container:D,viewport:D,adjust:{x:0,y:0,mouse:C,scroll:C,resize:C,method:"flipinvert flipinvert"},effect:function(a,b){d(this).animate(b,{duration:200,queue:D})}},show:{target:D,event:"mouseenter",effect:C,delay:90,solo:D,ready:D,autofocus:D},hide:{target:D,event:"mouseleave",effect:C,delay:0,fixed:D,inactive:D,leave:"window",distance:D},style:{classes:"",widget:D,width:D,height:D,def:C},events:{render:E,move:E,show:E,hide:E,toggle:E,visible:E,hidden:E,focus:E,blur:E}};var hb,ib="margin",jb="border",kb="color",lb="background-color",mb="transparent",nb=" !important",ob=!!b.createElement("canvas").getContext,pb=/rgba?\(0, 0, 0(, 0)?\)|transparent|#123456/i,qb={},rb=["Webkit","O","Moz","ms"];if(ob)var sb=a.devicePixelRatio||1,tb=function(){var a=b.createElement("canvas").getContext("2d");return a.backingStorePixelRatio||a.webkitBackingStorePixelRatio||a.mozBackingStorePixelRatio||a.msBackingStorePixelRatio||a.oBackingStorePixelRatio||1}(),ub=sb/tb;else var vb=function(a,b,c){return"'};d.extend(w.prototype,{init:function(a){var b,c;c=this.element=a.elements.tip=d("
",{"class":R+"-tip"}).prependTo(a.tooltip),ob?(b=d("").appendTo(this.element)[0].getContext("2d"),b.lineJoin="miter",b.miterLimit=1e5,b.save()):(b=vb("shape",'coordorigin="0,0"',"position:absolute;"),this.element.html(b+b),a._bind(d("*",c).add(c),["click","mousedown"],function(a){a.stopPropagation()},this._ns)),a._bind(a.tooltip,"tooltipmove",this.reposition,this._ns,this),this.create()},_swapDimensions:function(){this.size[0]=this.options.height,this.size[1]=this.options.width},_resetDimensions:function(){this.size[0]=this.options.width,this.size[1]=this.options.height},_useTitle:function(a){var b=this.qtip.elements.titlebar;return b&&(a.y===J||a.y===N&&this.element.position().top+this.size[1]/2+this.options.offsetl&&!pb.test(e[1])&&(e[0]=e[1]),this.border=l=p.border!==C?p.border:l):this.border=l=0,k=this.size=this._calculateSize(b),n.css({width:k[0],height:k[1],lineHeight:k[1]+"px"}),j=b.precedance===G?[s(r.x===K?l:r.x===M?k[0]-q[0]-l:(k[0]-q[0])/2),s(r.y===J?k[1]-q[1]:0)]:[s(r.x===K?k[0]-q[0]:0),s(r.y===J?l:r.y===L?k[1]-q[1]-l:(k[1]-q[1])/2)],ob?(g=o[0].getContext("2d"),g.restore(),g.save(),g.clearRect(0,0,6e3,6e3),h=this._calculateTip(r,q,ub),i=this._calculateTip(r,this.size,ub),o.attr(H,k[0]*ub).attr(I,k[1]*ub),o.css(H,k[0]).css(I,k[1]),this._drawCoords(g,i),g.fillStyle=e[1],g.fill(),g.translate(j[0]*ub,j[1]*ub),this._drawCoords(g,h),g.fillStyle=e[0],g.fill()):(h=this._calculateTip(r),h="m"+h[0]+","+h[1]+" l"+h[2]+","+h[3]+" "+h[4]+","+h[5]+" xe",j[2]=l&&/^(r|b)/i.test(b.string())?8===cb.ie?2:1:0,o.css({coordsize:k[0]+l+" "+(k[1]+l),antialias:""+(r.string().indexOf(N)>-1),left:j[0]-j[2]*Number(f===F),top:j[1]-j[2]*Number(f===G),width:k[0]+l,height:k[1]+l}).each(function(a){var b=d(this);b[b.prop?"prop":"attr"]({coordsize:k[0]+l+" "+(k[1]+l),path:h,fillcolor:e[0],filled:!!a,stroked:!a}).toggle(!(!l&&!a)),!a&&b.html(vb("stroke",'weight="'+2*l+'px" color="'+e[1]+'" miterlimit="1000" joinstyle="miter"'))})),a.opera&&setTimeout(function(){m.tip.css({display:"inline-block",visibility:"visible"})},1),c!==D&&this.calculate(b,k)},calculate:function(a,b){if(!this.enabled)return D;var c,e,f=this,g=this.qtip.elements,h=this.element,i=this.options.offset,j=(g.tooltip.hasClass("ui-widget"),{});return a=a||this.corner,c=a.precedance,b=b||this._calculateSize(a),e=[a.x,a.y],c===F&&e.reverse(),d.each(e,function(d,e){var h,k,l;e===N?(h=c===G?K:J,j[h]="50%",j[ib+"-"+h]=-Math.round(b[c===G?0:1]/2)+i):(h=f._parseWidth(a,e,g.tooltip),k=f._parseWidth(a,e,g.content),l=f._parseRadius(a),j[e]=Math.max(-f.border,d?k:i+(l>h?l:-h)))}),j[a[c]]-=b[c===F?0:1],h.css({margin:"",top:"",bottom:"",left:"",right:""}).css(j),j +},reposition:function(a,b,d){function e(a,b,c,d,e){a===P&&j.precedance===b&&k[d]&&j[c]!==N?j.precedance=j.precedance===F?G:F:a!==P&&k[d]&&(j[b]=j[b]===N?k[d]>0?d:e:j[b]===d?e:d)}function f(a,b,e){j[a]===N?p[ib+"-"+b]=o[a]=g[ib+"-"+b]-k[b]:(h=g[e]!==c?[k[b],-g[b]]:[-k[b],g[b]],(o[a]=Math.max(h[0],h[1]))>h[0]&&(d[b]-=k[b],o[b]=D),p[g[e]!==c?e:b]=o[a])}if(this.enabled){var g,h,i=b.cache,j=this.corner.clone(),k=d.adjusted,l=b.options.position.adjust.method.split(" "),m=l[0],n=l[1]||l[0],o={left:D,top:D,x:0,y:0},p={};this.corner.fixed!==C&&(e(m,F,G,K,M),e(n,G,F,J,L),j.string()===i.corner.string()||i.cornerTop===k.top&&i.cornerLeft===k.left||this.update(j,D)),g=this.calculate(j),g.right!==c&&(g.left=-g.right),g.bottom!==c&&(g.top=-g.bottom),g.user=this.offset,(o.left=m===P&&!!k.left)&&f(F,K,M),(o.top=n===P&&!!k.top)&&f(G,J,L),this.element.css(p).toggle(!(o.x&&o.y||j.x===N&&o.y||j.y===N&&o.x)),d.left-=g.left.charAt?g.user:m!==P||o.top||!o.left&&!o.top?g.left+this.border:0,d.top-=g.top.charAt?g.user:n!==P||o.left||!o.left&&!o.top?g.top+this.border:0,i.cornerLeft=k.left,i.cornerTop=k.top,i.corner=j.clone()}},destroy:function(){this.qtip._unbind(this.qtip.tooltip,this._ns),this.qtip.elements.tip&&this.qtip.elements.tip.find("*").remove().end().remove()}}),hb=Q.tip=function(a){return new w(a,a.options.style.tip)},hb.initialize="render",hb.sanitize=function(a){if(a.style&&"tip"in a.style){var b=a.style.tip;"object"!=typeof b&&(b=a.style.tip={corner:b}),/string|boolean/i.test(typeof b.corner)||(b.corner=C)}},A.tip={"^position.my|style.tip.(corner|mimic|border)$":function(){this.create(),this.qtip.reposition()},"^style.tip.(height|width)$":function(a){this.size=[a.width,a.height],this.update(),this.qtip.reposition()},"^content.title|style.(classes|widget)$":function(){this.update()}},d.extend(C,x.defaults,{style:{tip:{corner:C,mimic:D,width:6,height:6,border:C,offset:0}}}),Q.viewport=function(c,d,e,f,g,h,i){function j(a,b,c,e,f,g,h,i,j){var k=d[f],m=v[a],t=w[a],u=c===P,x=m===f?j:m===g?-j:-j/2,y=t===f?i:t===g?-i:-i/2,z=r[f]+s[f]-(o?0:n[f]),A=z-k,B=k+j-(h===H?p:q)-z,C=x-(v.precedance===a||m===v[b]?y:0)-(t===N?i/2:0);return u?(C=(m===f?1:-1)*x,d[f]+=A>0?A:B>0?-B:0,d[f]=Math.max(-n[f]+s[f],k-C,Math.min(Math.max(-n[f]+s[f]+(h===H?p:q),k+C),d[f],"center"===m?k-x:1e9))):(e*=c===O?2:0,A>0&&(m!==f||B>0)?(d[f]-=C+e,l.invert(a,f)):B>0&&(m!==g||A>0)&&(d[f]-=(m===N?-C:C)+e,l.invert(a,g)),d[f]B&&(d[f]=k,l=v.clone())),d[f]-k}var k,l,m,n,o,p,q,r,s,t=e.target,u=c.elements.tooltip,v=e.my,w=e.at,x=e.adjust,y=x.method.split(" "),z=y[0],A=y[1]||y[0],B=e.viewport,C=e.container,E=c.cache,Q={left:0,top:0};return B.jquery&&t[0]!==a&&t[0]!==b.body&&"none"!==x.method?(n=C.offset()||Q,o="static"===C.css("position"),k="fixed"===u.css("position"),p=B[0]===a?B.width():B.outerWidth(D),q=B[0]===a?B.height():B.outerHeight(D),r={left:k?0:B.scrollLeft(),top:k?0:B.scrollTop()},s=B.offset()||Q,("shift"!==z||"shift"!==A)&&(l=v.clone()),Q={left:"none"!==z?j(F,G,z,x.x,K,M,H,f,h):0,top:"none"!==A?j(G,F,A,x.y,J,L,I,g,i):0},l&&E.lastClass!==(m=R+"-pos-"+l.abbrev())&&u.removeClass(c.cache.lastClass).addClass(c.cache.lastClass=m),Q):Q}})}(window,document); +//# sourceMappingURL=http://cdnjs.cloudflare.com/ajax/libs/qtip2/2.2.0//var/www/qtip2/build/tmp/tmp-9404f1j0t40/jquery.qtip.min.map \ No newline at end of file diff --git a/wp-content/themes/headway/library/admin/js/jquery.scrollto.js b/wp-content/themes/headway/library/admin/js/jquery.scrollto.js new file mode 100644 index 0000000..5e78778 --- /dev/null +++ b/wp-content/themes/headway/library/admin/js/jquery.scrollto.js @@ -0,0 +1,11 @@ +/** + * jQuery.ScrollTo - Easy element scrolling using jQuery. + * Copyright (c) 2007-2009 Ariel Flesler - aflesler(at)gmail(dot)com | http://flesler.blogspot.com + * Dual licensed under MIT and GPL. + * Date: 5/25/2009 + * @author Ariel Flesler + * @version 1.4.2 + * + * http://flesler.blogspot.com/2007/10/jqueryscrollto.html + */ +;(function(d){var k=d.scrollTo=function(a,i,e){d(window).scrollTo(a,i,e)};k.defaults={axis:'xy',duration:parseFloat(d.fn.jquery)>=1.3?0:1};k.window=function(a){return d(window)._scrollable()};d.fn._scrollable=function(){return this.map(function(){var a=this,i=!a.nodeName||d.inArray(a.nodeName.toLowerCase(),['iframe','#document','html','body'])!=-1;if(!i)return a;var e=(a.contentWindow||a).document||a.ownerDocument||a;return d.browser.safari||e.compatMode=='BackCompat'?e.body:e.documentElement})};d.fn.scrollTo=function(n,j,b){if(typeof j=='object'){b=j;j=0}if(typeof b=='function')b={onAfter:b};if(n=='max')n=9e9;b=d.extend({},k.defaults,b);j=j||b.speed||b.duration;b.queue=b.queue&&b.axis.length>1;if(b.queue)j/=2;b.offset=p(b.offset);b.over=p(b.over);return this._scrollable().each(function(){var q=this,r=d(q),f=n,s,g={},u=r.is('html,body');switch(typeof f){case'number':case'string':if(/^([+-]=)?\d+(\.\d+)?(px|%)?$/.test(f)){f=p(f);break}f=d(f,this);case'object':if(f.is||f.style)s=(f=d(f)).offset()}d.each(b.axis.split(''),function(a,i){var e=i=='x'?'Left':'Top',h=e.toLowerCase(),c='scroll'+e,l=q[c],m=k.max(q,i);if(s){g[c]=s[h]+(u?0:l-r.offset()[h]);if(b.margin){g[c]-=parseInt(f.css('margin'+e))||0;g[c]-=parseInt(f.css('border'+e+'Width'))||0}g[c]+=b.offset[h]||0;if(b.over[h])g[c]+=f[i=='x'?'width':'height']()*b.over[h]}else{var o=f[h];g[c]=o.slice&&o.slice(-1)=='%'?parseFloat(o)/100*m:o}if(/^\d+$/.test(g[c]))g[c]=g[c]<=0?0:Math.min(g[c],m);if(!a&&b.queue){if(l!=g[c])t(b.onAfterFirst);delete g[c]}});t(b.onAfter);function t(a){r.animate(g,j,b.easing,a&&function(){a.call(this,n,b)})}}).end()};k.max=function(a,i){var e=i=='x'?'Width':'Height',h='scroll'+e;if(!d(a).is('html,body'))return a[h]-d(a)[e.toLowerCase()]();var c='client'+e,l=a.ownerDocument.documentElement,m=a.ownerDocument.body;return Math.max(l[h],m[h])-Math.min(l[c],m[c])};function p(a){return typeof a=='object'?a:{top:a,left:a}}})(jQuery); \ No newline at end of file diff --git a/wp-content/themes/headway/library/admin/js/jquery.tabby.js b/wp-content/themes/headway/library/admin/js/jquery.tabby.js new file mode 100644 index 0000000..6c36dd4 --- /dev/null +++ b/wp-content/themes/headway/library/admin/js/jquery.tabby.js @@ -0,0 +1,8 @@ +/* + * Tabby jQuery plugin version 0.12 + * + * Ted Devito - http://teddevito.com/demos/textarea.html + * + * Copyright (c) 2009 Ted Devito + */ + (function(d){d.fn.tabby=function(f){var g=d.extend({},d.fn.tabby.defaults,f);var h=d.fn.tabby.pressed;return this.each(function(){$this=d(this);var i=d.meta?d.extend({},g,$this.data()):g;$this.bind("keydown",function(k){var j=d.fn.tabby.catch_kc(k);if(16==j){h.shft=true}if(17==j){h.ctrl=true;setTimeout("$.fn.tabby.pressed.ctrl = false;",1000)}if(18==j){h.alt=true;setTimeout("$.fn.tabby.pressed.alt = false;",1000)}if(9==j&&!h.ctrl&&!h.alt){k.preventDefault;h.last=j;setTimeout("$.fn.tabby.pressed.last = null;",0);e(d(k.target).get(0),h.shft,i);return false}}).bind("keyup",function(j){if(16==d.fn.tabby.catch_kc(j)){h.shft=false}}).bind("blur",function(j){if(9==h.last){d(j.target).one("focus",function(k){h.last=null}).get(0).focus()}})})};d.fn.tabby.catch_kc=function(f){return f.keyCode?f.keyCode:f.charCode?f.charCode:f.which};d.fn.tabby.pressed={shft:false,ctrl:false,alt:false,last:null};function b(f){if(window.console&&window.console.log){window.console.log("textarea count: "+f.size())}}function e(i,h,g){var f=i.scrollTop;if(i.setSelectionRange){a(i,h,g)}else{if(document.selection){c(i,h,g)}}i.scrollTop=f}d.fn.tabby.defaults={tabString:String.fromCharCode(9)};function a(j,f,u){var t=j.selectionStart;var r=j.selectionEnd;if(t==r){if(f){if(t-u.tabString==j.value.substring(t-u.tabString.length,t)){j.value=j.value.substring(0,t-u.tabString.length)+j.value.substring(t);j.focus();j.setSelectionRange(t-u.tabString.length,t-u.tabString.length)}else{if(t-u.tabString==j.value.substring(t,t+u.tabString.length)){j.value=j.value.substring(0,t)+j.value.substring(t+u.tabString.length);j.focus();j.setSelectionRange(t,t)}}}else{j.value=j.value.substring(0,t)+u.tabString+j.value.substring(t);j.focus();j.setSelectionRange(t+u.tabString.length,t+u.tabString.length)}}else{while(tt)||(h>=r&&lt&&h0)?u.tabString.length:(k<0)?-u.tabString.length:0);var m=r+k;j.setSelectionRange(p,m)}}function c(q,w,f){var p=document.selection.createRange();if(q==p.parentElement()){if(""==p.text){if(w){var l=p.getBookmark();p.moveStart("character",-f.tabString.length);if(f.tabString==p.text){p.text=""}else{p.moveToBookmark(l);p.moveEnd("character",f.tabString.length);if(f.tabString==p.text){p.text=""}}p.collapse(true);p.select()}else{p.text=f.tabString;p.collapse(false);p.select()}}else{var k=p.text;var n=k.length;var u=k.split("\r\n");var z=document.body.createTextRange();z.moveToElementText(q);z.setEndPoint("EndToStart",p);var m=z.text;var x=m.split("\r\n");var r=m.length;var y=document.body.createTextRange();y.moveToElementText(q);y.setEndPoint("StartToEnd",p);var v=y.text;var g=document.body.createTextRange();g.moveToElementText(q);g.setEndPoint("StartToEnd",z);var s=g.text;var h=d(q).html();d("#r3").text(r+" + "+n+" + "+v.length+" = "+h.length);if((r+s.length) tag) - put directly in global namespace + factory(window['ko'] = {}); + } +}(function(koExports){ +// Internally, all KO objects are attached to koExports (even the non-exported ones whose names will be minified by the closure compiler). +// In the future, the following "ko" variable may be made distinct from "koExports" so that private objects are not externally reachable. +var ko = typeof koExports !== 'undefined' ? koExports : {}; +// Google Closure Compiler helpers (used only to make the minified file smaller) +ko.exportSymbol = function(koPath, object) { + var tokens = koPath.split("."); + + // In the future, "ko" may become distinct from "koExports" (so that non-exported objects are not reachable) + // At that point, "target" would be set to: (typeof koExports !== "undefined" ? koExports : ko) + var target = ko; + + for (var i = 0; i < tokens.length - 1; i++) + target = target[tokens[i]]; + target[tokens[tokens.length - 1]] = object; +}; +ko.exportProperty = function(owner, publicName, object) { + owner[publicName] = object; +}; +ko.version = "3.1.0"; + +ko.exportSymbol('version', ko.version); +ko.utils = (function () { + function objectForEach(obj, action) { + for (var prop in obj) { + if (obj.hasOwnProperty(prop)) { + action(prop, obj[prop]); + } + } + } + + function extend(target, source) { + if (source) { + for(var prop in source) { + if(source.hasOwnProperty(prop)) { + target[prop] = source[prop]; + } + } + } + return target; + } + + function setPrototypeOf(obj, proto) { + obj.__proto__ = proto; + return obj; + } + + var canSetPrototype = ({ __proto__: [] } instanceof Array); + + // Represent the known event types in a compact way, then at runtime transform it into a hash with event name as key (for fast lookup) + var knownEvents = {}, knownEventTypesByEventName = {}; + var keyEventTypeName = (navigator && /Firefox\/2/i.test(navigator.userAgent)) ? 'KeyboardEvent' : 'UIEvents'; + knownEvents[keyEventTypeName] = ['keyup', 'keydown', 'keypress']; + knownEvents['MouseEvents'] = ['click', 'dblclick', 'mousedown', 'mouseup', 'mousemove', 'mouseover', 'mouseout', 'mouseenter', 'mouseleave']; + objectForEach(knownEvents, function(eventType, knownEventsForType) { + if (knownEventsForType.length) { + for (var i = 0, j = knownEventsForType.length; i < j; i++) + knownEventTypesByEventName[knownEventsForType[i]] = eventType; + } + }); + var eventsThatMustBeRegisteredUsingAttachEvent = { 'propertychange': true }; // Workaround for an IE9 issue - https://github.com/SteveSanderson/knockout/issues/406 + + // Detect IE versions for bug workarounds (uses IE conditionals, not UA string, for robustness) + // Note that, since IE 10 does not support conditional comments, the following logic only detects IE < 10. + // Currently this is by design, since IE 10+ behaves correctly when treated as a standard browser. + // If there is a future need to detect specific versions of IE10+, we will amend this. + var ieVersion = document && (function() { + var version = 3, div = document.createElement('div'), iElems = div.getElementsByTagName('i'); + + // Keep constructing conditional HTML blocks until we hit one that resolves to an empty fragment + while ( + div.innerHTML = '', + iElems[0] + ) {} + return version > 4 ? version : undefined; + }()); + var isIe6 = ieVersion === 6, + isIe7 = ieVersion === 7; + + function isClickOnCheckableElement(element, eventType) { + if ((ko.utils.tagNameLower(element) !== "input") || !element.type) return false; + if (eventType.toLowerCase() != "click") return false; + var inputType = element.type; + return (inputType == "checkbox") || (inputType == "radio"); + } + + return { + fieldsIncludedWithJsonPost: ['authenticity_token', /^__RequestVerificationToken(_.*)?$/], + + arrayForEach: function (array, action) { + for (var i = 0, j = array.length; i < j; i++) + action(array[i], i); + }, + + arrayIndexOf: function (array, item) { + if (typeof Array.prototype.indexOf == "function") + return Array.prototype.indexOf.call(array, item); + for (var i = 0, j = array.length; i < j; i++) + if (array[i] === item) + return i; + return -1; + }, + + arrayFirst: function (array, predicate, predicateOwner) { + for (var i = 0, j = array.length; i < j; i++) + if (predicate.call(predicateOwner, array[i], i)) + return array[i]; + return null; + }, + + arrayRemoveItem: function (array, itemToRemove) { + var index = ko.utils.arrayIndexOf(array, itemToRemove); + if (index > 0) { + array.splice(index, 1); + } + else if (index === 0) { + array.shift(); + } + }, + + arrayGetDistinctValues: function (array) { + array = array || []; + var result = []; + for (var i = 0, j = array.length; i < j; i++) { + if (ko.utils.arrayIndexOf(result, array[i]) < 0) + result.push(array[i]); + } + return result; + }, + + arrayMap: function (array, mapping) { + array = array || []; + var result = []; + for (var i = 0, j = array.length; i < j; i++) + result.push(mapping(array[i], i)); + return result; + }, + + arrayFilter: function (array, predicate) { + array = array || []; + var result = []; + for (var i = 0, j = array.length; i < j; i++) + if (predicate(array[i], i)) + result.push(array[i]); + return result; + }, + + arrayPushAll: function (array, valuesToPush) { + if (valuesToPush instanceof Array) + array.push.apply(array, valuesToPush); + else + for (var i = 0, j = valuesToPush.length; i < j; i++) + array.push(valuesToPush[i]); + return array; + }, + + addOrRemoveItem: function(array, value, included) { + var existingEntryIndex = ko.utils.arrayIndexOf(ko.utils.peekObservable(array), value); + if (existingEntryIndex < 0) { + if (included) + array.push(value); + } else { + if (!included) + array.splice(existingEntryIndex, 1); + } + }, + + canSetPrototype: canSetPrototype, + + extend: extend, + + setPrototypeOf: setPrototypeOf, + + setPrototypeOfOrExtend: canSetPrototype ? setPrototypeOf : extend, + + objectForEach: objectForEach, + + objectMap: function(source, mapping) { + if (!source) + return source; + var target = {}; + for (var prop in source) { + if (source.hasOwnProperty(prop)) { + target[prop] = mapping(source[prop], prop, source); + } + } + return target; + }, + + emptyDomNode: function (domNode) { + while (domNode.firstChild) { + ko.removeNode(domNode.firstChild); + } + }, + + moveCleanedNodesToContainerElement: function(nodes) { + // Ensure it's a real array, as we're about to reparent the nodes and + // we don't want the underlying collection to change while we're doing that. + var nodesArray = ko.utils.makeArray(nodes); + + var container = document.createElement('div'); + for (var i = 0, j = nodesArray.length; i < j; i++) { + container.appendChild(ko.cleanNode(nodesArray[i])); + } + return container; + }, + + cloneNodes: function (nodesArray, shouldCleanNodes) { + for (var i = 0, j = nodesArray.length, newNodesArray = []; i < j; i++) { + var clonedNode = nodesArray[i].cloneNode(true); + newNodesArray.push(shouldCleanNodes ? ko.cleanNode(clonedNode) : clonedNode); + } + return newNodesArray; + }, + + setDomNodeChildren: function (domNode, childNodes) { + ko.utils.emptyDomNode(domNode); + if (childNodes) { + for (var i = 0, j = childNodes.length; i < j; i++) + domNode.appendChild(childNodes[i]); + } + }, + + replaceDomNodes: function (nodeToReplaceOrNodeArray, newNodesArray) { + var nodesToReplaceArray = nodeToReplaceOrNodeArray.nodeType ? [nodeToReplaceOrNodeArray] : nodeToReplaceOrNodeArray; + if (nodesToReplaceArray.length > 0) { + var insertionPoint = nodesToReplaceArray[0]; + var parent = insertionPoint.parentNode; + for (var i = 0, j = newNodesArray.length; i < j; i++) + parent.insertBefore(newNodesArray[i], insertionPoint); + for (var i = 0, j = nodesToReplaceArray.length; i < j; i++) { + ko.removeNode(nodesToReplaceArray[i]); + } + } + }, + + fixUpContinuousNodeArray: function(continuousNodeArray, parentNode) { + // Before acting on a set of nodes that were previously outputted by a template function, we have to reconcile + // them against what is in the DOM right now. It may be that some of the nodes have already been removed, or that + // new nodes might have been inserted in the middle, for example by a binding. Also, there may previously have been + // leading comment nodes (created by rewritten string-based templates) that have since been removed during binding. + // So, this function translates the old "map" output array into its best guess of the set of current DOM nodes. + // + // Rules: + // [A] Any leading nodes that have been removed should be ignored + // These most likely correspond to memoization nodes that were already removed during binding + // See https://github.com/SteveSanderson/knockout/pull/440 + // [B] We want to output a continuous series of nodes. So, ignore any nodes that have already been removed, + // and include any nodes that have been inserted among the previous collection + + if (continuousNodeArray.length) { + // The parent node can be a virtual element; so get the real parent node + parentNode = (parentNode.nodeType === 8 && parentNode.parentNode) || parentNode; + + // Rule [A] + while (continuousNodeArray.length && continuousNodeArray[0].parentNode !== parentNode) + continuousNodeArray.shift(); + + // Rule [B] + if (continuousNodeArray.length > 1) { + var current = continuousNodeArray[0], last = continuousNodeArray[continuousNodeArray.length - 1]; + // Replace with the actual new continuous node set + continuousNodeArray.length = 0; + while (current !== last) { + continuousNodeArray.push(current); + current = current.nextSibling; + if (!current) // Won't happen, except if the developer has manually removed some DOM elements (then we're in an undefined scenario) + return; + } + continuousNodeArray.push(last); + } + } + return continuousNodeArray; + }, + + setOptionNodeSelectionState: function (optionNode, isSelected) { + // IE6 sometimes throws "unknown error" if you try to write to .selected directly, whereas Firefox struggles with setAttribute. Pick one based on browser. + if (ieVersion < 7) + optionNode.setAttribute("selected", isSelected); + else + optionNode.selected = isSelected; + }, + + stringTrim: function (string) { + return string === null || string === undefined ? '' : + string.trim ? + string.trim() : + string.toString().replace(/^[\s\xa0]+|[\s\xa0]+$/g, ''); + }, + + stringTokenize: function (string, delimiter) { + var result = []; + var tokens = (string || "").split(delimiter); + for (var i = 0, j = tokens.length; i < j; i++) { + var trimmed = ko.utils.stringTrim(tokens[i]); + if (trimmed !== "") + result.push(trimmed); + } + return result; + }, + + stringStartsWith: function (string, startsWith) { + string = string || ""; + if (startsWith.length > string.length) + return false; + return string.substring(0, startsWith.length) === startsWith; + }, + + domNodeIsContainedBy: function (node, containedByNode) { + if (node === containedByNode) + return true; + if (node.nodeType === 11) + return false; // Fixes issue #1162 - can't use node.contains for document fragments on IE8 + if (containedByNode.contains) + return containedByNode.contains(node.nodeType === 3 ? node.parentNode : node); + if (containedByNode.compareDocumentPosition) + return (containedByNode.compareDocumentPosition(node) & 16) == 16; + while (node && node != containedByNode) { + node = node.parentNode; + } + return !!node; + }, + + domNodeIsAttachedToDocument: function (node) { + return ko.utils.domNodeIsContainedBy(node, node.ownerDocument.documentElement); + }, + + anyDomNodeIsAttachedToDocument: function(nodes) { + return !!ko.utils.arrayFirst(nodes, ko.utils.domNodeIsAttachedToDocument); + }, + + tagNameLower: function(element) { + // For HTML elements, tagName will always be upper case; for XHTML elements, it'll be lower case. + // Possible future optimization: If we know it's an element from an XHTML document (not HTML), + // we don't need to do the .toLowerCase() as it will always be lower case anyway. + return element && element.tagName && element.tagName.toLowerCase(); + }, + + registerEventHandler: function (element, eventType, handler) { + var mustUseAttachEvent = ieVersion && eventsThatMustBeRegisteredUsingAttachEvent[eventType]; + if (!mustUseAttachEvent && jQuery) { + jQuery(element)['bind'](eventType, handler); + } else if (!mustUseAttachEvent && typeof element.addEventListener == "function") + element.addEventListener(eventType, handler, false); + else if (typeof element.attachEvent != "undefined") { + var attachEventHandler = function (event) { handler.call(element, event); }, + attachEventName = "on" + eventType; + element.attachEvent(attachEventName, attachEventHandler); + + // IE does not dispose attachEvent handlers automatically (unlike with addEventListener) + // so to avoid leaks, we have to remove them manually. See bug #856 + ko.utils.domNodeDisposal.addDisposeCallback(element, function() { + element.detachEvent(attachEventName, attachEventHandler); + }); + } else + throw new Error("Browser doesn't support addEventListener or attachEvent"); + }, + + triggerEvent: function (element, eventType) { + if (!(element && element.nodeType)) + throw new Error("element must be a DOM node when calling triggerEvent"); + + // For click events on checkboxes and radio buttons, jQuery toggles the element checked state *after* the + // event handler runs instead of *before*. (This was fixed in 1.9 for checkboxes but not for radio buttons.) + // IE doesn't change the checked state when you trigger the click event using "fireEvent". + // In both cases, we'll use the click method instead. + var useClickWorkaround = isClickOnCheckableElement(element, eventType); + + if (jQuery && !useClickWorkaround) { + jQuery(element)['trigger'](eventType); + } else if (typeof document.createEvent == "function") { + if (typeof element.dispatchEvent == "function") { + var eventCategory = knownEventTypesByEventName[eventType] || "HTMLEvents"; + var event = document.createEvent(eventCategory); + event.initEvent(eventType, true, true, window, 0, 0, 0, 0, 0, false, false, false, false, 0, element); + element.dispatchEvent(event); + } + else + throw new Error("The supplied element doesn't support dispatchEvent"); + } else if (useClickWorkaround && element.click) { + element.click(); + } else if (typeof element.fireEvent != "undefined") { + element.fireEvent("on" + eventType); + } else { + throw new Error("Browser doesn't support triggering events"); + } + }, + + unwrapObservable: function (value) { + return ko.isObservable(value) ? value() : value; + }, + + peekObservable: function (value) { + return ko.isObservable(value) ? value.peek() : value; + }, + + toggleDomNodeCssClass: function (node, classNames, shouldHaveClass) { + if (classNames) { + var cssClassNameRegex = /\S+/g, + currentClassNames = node.className.match(cssClassNameRegex) || []; + ko.utils.arrayForEach(classNames.match(cssClassNameRegex), function(className) { + ko.utils.addOrRemoveItem(currentClassNames, className, shouldHaveClass); + }); + node.className = currentClassNames.join(" "); + } + }, + + setTextContent: function(element, textContent) { + var value = ko.utils.unwrapObservable(textContent); + if ((value === null) || (value === undefined)) + value = ""; + + // We need there to be exactly one child: a text node. + // If there are no children, more than one, or if it's not a text node, + // we'll clear everything and create a single text node. + var innerTextNode = ko.virtualElements.firstChild(element); + if (!innerTextNode || innerTextNode.nodeType != 3 || ko.virtualElements.nextSibling(innerTextNode)) { + ko.virtualElements.setDomNodeChildren(element, [element.ownerDocument.createTextNode(value)]); + } else { + innerTextNode.data = value; + } + + ko.utils.forceRefresh(element); + }, + + setElementName: function(element, name) { + element.name = name; + + // Workaround IE 6/7 issue + // - https://github.com/SteveSanderson/knockout/issues/197 + // - http://www.matts411.com/post/setting_the_name_attribute_in_ie_dom/ + if (ieVersion <= 7) { + try { + element.mergeAttributes(document.createElement(""), false); + } + catch(e) {} // For IE9 with doc mode "IE9 Standards" and browser mode "IE9 Compatibility View" + } + }, + + forceRefresh: function(node) { + // Workaround for an IE9 rendering bug - https://github.com/SteveSanderson/knockout/issues/209 + if (ieVersion >= 9) { + // For text nodes and comment nodes (most likely virtual elements), we will have to refresh the container + var elem = node.nodeType == 1 ? node : node.parentNode; + if (elem.style) + elem.style.zoom = elem.style.zoom; + } + }, + + ensureSelectElementIsRenderedCorrectly: function(selectElement) { + // Workaround for IE9 rendering bug - it doesn't reliably display all the text in dynamically-added select boxes unless you force it to re-render by updating the width. + // (See https://github.com/SteveSanderson/knockout/issues/312, http://stackoverflow.com/questions/5908494/select-only-shows-first-char-of-selected-option) + // Also fixes IE7 and IE8 bug that causes selects to be zero width if enclosed by 'if' or 'with'. (See issue #839) + if (ieVersion) { + var originalWidth = selectElement.style.width; + selectElement.style.width = 0; + selectElement.style.width = originalWidth; + } + }, + + range: function (min, max) { + min = ko.utils.unwrapObservable(min); + max = ko.utils.unwrapObservable(max); + var result = []; + for (var i = min; i <= max; i++) + result.push(i); + return result; + }, + + makeArray: function(arrayLikeObject) { + var result = []; + for (var i = 0, j = arrayLikeObject.length; i < j; i++) { + result.push(arrayLikeObject[i]); + }; + return result; + }, + + isIe6 : isIe6, + isIe7 : isIe7, + ieVersion : ieVersion, + + getFormFields: function(form, fieldName) { + var fields = ko.utils.makeArray(form.getElementsByTagName("input")).concat(ko.utils.makeArray(form.getElementsByTagName("textarea"))); + var isMatchingField = (typeof fieldName == 'string') + ? function(field) { return field.name === fieldName } + : function(field) { return fieldName.test(field.name) }; // Treat fieldName as regex or object containing predicate + var matches = []; + for (var i = fields.length - 1; i >= 0; i--) { + if (isMatchingField(fields[i])) + matches.push(fields[i]); + }; + return matches; + }, + + parseJson: function (jsonString) { + if (typeof jsonString == "string") { + jsonString = ko.utils.stringTrim(jsonString); + if (jsonString) { + if (JSON && JSON.parse) // Use native parsing where available + return JSON.parse(jsonString); + return (new Function("return " + jsonString))(); // Fallback on less safe parsing for older browsers + } + } + return null; + }, + + stringifyJson: function (data, replacer, space) { // replacer and space are optional + if (!JSON || !JSON.stringify) + throw new Error("Cannot find JSON.stringify(). Some browsers (e.g., IE < 8) don't support it natively, but you can overcome this by adding a script reference to json2.js, downloadable from http://www.json.org/json2.js"); + return JSON.stringify(ko.utils.unwrapObservable(data), replacer, space); + }, + + postJson: function (urlOrForm, data, options) { + options = options || {}; + var params = options['params'] || {}; + var includeFields = options['includeFields'] || this.fieldsIncludedWithJsonPost; + var url = urlOrForm; + + // If we were given a form, use its 'action' URL and pick out any requested field values + if((typeof urlOrForm == 'object') && (ko.utils.tagNameLower(urlOrForm) === "form")) { + var originalForm = urlOrForm; + url = originalForm.action; + for (var i = includeFields.length - 1; i >= 0; i--) { + var fields = ko.utils.getFormFields(originalForm, includeFields[i]); + for (var j = fields.length - 1; j >= 0; j--) + params[fields[j].name] = fields[j].value; + } + } + + data = ko.utils.unwrapObservable(data); + var form = document.createElement("form"); + form.style.display = "none"; + form.action = url; + form.method = "post"; + for (var key in data) { + // Since 'data' this is a model object, we include all properties including those inherited from its prototype + var input = document.createElement("input"); + input.name = key; + input.value = ko.utils.stringifyJson(ko.utils.unwrapObservable(data[key])); + form.appendChild(input); + } + objectForEach(params, function(key, value) { + var input = document.createElement("input"); + input.name = key; + input.value = value; + form.appendChild(input); + }); + document.body.appendChild(form); + options['submitter'] ? options['submitter'](form) : form.submit(); + setTimeout(function () { form.parentNode.removeChild(form); }, 0); + } + } +}()); + +ko.exportSymbol('utils', ko.utils); +ko.exportSymbol('utils.arrayForEach', ko.utils.arrayForEach); +ko.exportSymbol('utils.arrayFirst', ko.utils.arrayFirst); +ko.exportSymbol('utils.arrayFilter', ko.utils.arrayFilter); +ko.exportSymbol('utils.arrayGetDistinctValues', ko.utils.arrayGetDistinctValues); +ko.exportSymbol('utils.arrayIndexOf', ko.utils.arrayIndexOf); +ko.exportSymbol('utils.arrayMap', ko.utils.arrayMap); +ko.exportSymbol('utils.arrayPushAll', ko.utils.arrayPushAll); +ko.exportSymbol('utils.arrayRemoveItem', ko.utils.arrayRemoveItem); +ko.exportSymbol('utils.extend', ko.utils.extend); +ko.exportSymbol('utils.fieldsIncludedWithJsonPost', ko.utils.fieldsIncludedWithJsonPost); +ko.exportSymbol('utils.getFormFields', ko.utils.getFormFields); +ko.exportSymbol('utils.peekObservable', ko.utils.peekObservable); +ko.exportSymbol('utils.postJson', ko.utils.postJson); +ko.exportSymbol('utils.parseJson', ko.utils.parseJson); +ko.exportSymbol('utils.registerEventHandler', ko.utils.registerEventHandler); +ko.exportSymbol('utils.stringifyJson', ko.utils.stringifyJson); +ko.exportSymbol('utils.range', ko.utils.range); +ko.exportSymbol('utils.toggleDomNodeCssClass', ko.utils.toggleDomNodeCssClass); +ko.exportSymbol('utils.triggerEvent', ko.utils.triggerEvent); +ko.exportSymbol('utils.unwrapObservable', ko.utils.unwrapObservable); +ko.exportSymbol('utils.objectForEach', ko.utils.objectForEach); +ko.exportSymbol('utils.addOrRemoveItem', ko.utils.addOrRemoveItem); +ko.exportSymbol('unwrap', ko.utils.unwrapObservable); // Convenient shorthand, because this is used so commonly + +if (!Function.prototype['bind']) { + // Function.prototype.bind is a standard part of ECMAScript 5th Edition (December 2009, http://www.ecma-international.org/publications/files/ECMA-ST/ECMA-262.pdf) + // In case the browser doesn't implement it natively, provide a JavaScript implementation. This implementation is based on the one in prototype.js + Function.prototype['bind'] = function (object) { + var originalFunction = this, args = Array.prototype.slice.call(arguments), object = args.shift(); + return function () { + return originalFunction.apply(object, args.concat(Array.prototype.slice.call(arguments))); + }; + }; +} + +ko.utils.domData = new (function () { + var uniqueId = 0; + var dataStoreKeyExpandoPropertyName = "__ko__" + (new Date).getTime(); + var dataStore = {}; + + function getAll(node, createIfNotFound) { + var dataStoreKey = node[dataStoreKeyExpandoPropertyName]; + var hasExistingDataStore = dataStoreKey && (dataStoreKey !== "null") && dataStore[dataStoreKey]; + if (!hasExistingDataStore) { + if (!createIfNotFound) + return undefined; + dataStoreKey = node[dataStoreKeyExpandoPropertyName] = "ko" + uniqueId++; + dataStore[dataStoreKey] = {}; + } + return dataStore[dataStoreKey]; + } + + return { + get: function (node, key) { + var allDataForNode = getAll(node, false); + return allDataForNode === undefined ? undefined : allDataForNode[key]; + }, + set: function (node, key, value) { + if (value === undefined) { + // Make sure we don't actually create a new domData key if we are actually deleting a value + if (getAll(node, false) === undefined) + return; + } + var allDataForNode = getAll(node, true); + allDataForNode[key] = value; + }, + clear: function (node) { + var dataStoreKey = node[dataStoreKeyExpandoPropertyName]; + if (dataStoreKey) { + delete dataStore[dataStoreKey]; + node[dataStoreKeyExpandoPropertyName] = null; + return true; // Exposing "did clean" flag purely so specs can infer whether things have been cleaned up as intended + } + return false; + }, + + nextKey: function () { + return (uniqueId++) + dataStoreKeyExpandoPropertyName; + } + }; +})(); + +ko.exportSymbol('utils.domData', ko.utils.domData); +ko.exportSymbol('utils.domData.clear', ko.utils.domData.clear); // Exporting only so specs can clear up after themselves fully + +ko.utils.domNodeDisposal = new (function () { + var domDataKey = ko.utils.domData.nextKey(); + var cleanableNodeTypes = { 1: true, 8: true, 9: true }; // Element, Comment, Document + var cleanableNodeTypesWithDescendants = { 1: true, 9: true }; // Element, Document + + function getDisposeCallbacksCollection(node, createIfNotFound) { + var allDisposeCallbacks = ko.utils.domData.get(node, domDataKey); + if ((allDisposeCallbacks === undefined) && createIfNotFound) { + allDisposeCallbacks = []; + ko.utils.domData.set(node, domDataKey, allDisposeCallbacks); + } + return allDisposeCallbacks; + } + function destroyCallbacksCollection(node) { + ko.utils.domData.set(node, domDataKey, undefined); + } + + function cleanSingleNode(node) { + // Run all the dispose callbacks + var callbacks = getDisposeCallbacksCollection(node, false); + if (callbacks) { + callbacks = callbacks.slice(0); // Clone, as the array may be modified during iteration (typically, callbacks will remove themselves) + for (var i = 0; i < callbacks.length; i++) + callbacks[i](node); + } + + // Erase the DOM data + ko.utils.domData.clear(node); + + // Perform cleanup needed by external libraries (currently only jQuery, but can be extended) + ko.utils.domNodeDisposal["cleanExternalData"](node); + + // Clear any immediate-child comment nodes, as these wouldn't have been found by + // node.getElementsByTagName("*") in cleanNode() (comment nodes aren't elements) + if (cleanableNodeTypesWithDescendants[node.nodeType]) + cleanImmediateCommentTypeChildren(node); + } + + function cleanImmediateCommentTypeChildren(nodeWithChildren) { + var child, nextChild = nodeWithChildren.firstChild; + while (child = nextChild) { + nextChild = child.nextSibling; + if (child.nodeType === 8) + cleanSingleNode(child); + } + } + + return { + addDisposeCallback : function(node, callback) { + if (typeof callback != "function") + throw new Error("Callback must be a function"); + getDisposeCallbacksCollection(node, true).push(callback); + }, + + removeDisposeCallback : function(node, callback) { + var callbacksCollection = getDisposeCallbacksCollection(node, false); + if (callbacksCollection) { + ko.utils.arrayRemoveItem(callbacksCollection, callback); + if (callbacksCollection.length == 0) + destroyCallbacksCollection(node); + } + }, + + cleanNode : function(node) { + // First clean this node, where applicable + if (cleanableNodeTypes[node.nodeType]) { + cleanSingleNode(node); + + // ... then its descendants, where applicable + if (cleanableNodeTypesWithDescendants[node.nodeType]) { + // Clone the descendants list in case it changes during iteration + var descendants = []; + ko.utils.arrayPushAll(descendants, node.getElementsByTagName("*")); + for (var i = 0, j = descendants.length; i < j; i++) + cleanSingleNode(descendants[i]); + } + } + return node; + }, + + removeNode : function(node) { + ko.cleanNode(node); + if (node.parentNode) + node.parentNode.removeChild(node); + }, + + "cleanExternalData" : function (node) { + // Special support for jQuery here because it's so commonly used. + // Many jQuery plugins (including jquery.tmpl) store data using jQuery's equivalent of domData + // so notify it to tear down any resources associated with the node & descendants here. + if (jQuery && (typeof jQuery['cleanData'] == "function")) + jQuery['cleanData']([node]); + } + } +})(); +ko.cleanNode = ko.utils.domNodeDisposal.cleanNode; // Shorthand name for convenience +ko.removeNode = ko.utils.domNodeDisposal.removeNode; // Shorthand name for convenience +ko.exportSymbol('cleanNode', ko.cleanNode); +ko.exportSymbol('removeNode', ko.removeNode); +ko.exportSymbol('utils.domNodeDisposal', ko.utils.domNodeDisposal); +ko.exportSymbol('utils.domNodeDisposal.addDisposeCallback', ko.utils.domNodeDisposal.addDisposeCallback); +ko.exportSymbol('utils.domNodeDisposal.removeDisposeCallback', ko.utils.domNodeDisposal.removeDisposeCallback); +(function () { + var leadingCommentRegex = /^(\s*)/; + + function simpleHtmlParse(html) { + // Based on jQuery's "clean" function, but only accounting for table-related elements. + // If you have referenced jQuery, this won't be used anyway - KO will use jQuery's "clean" function directly + + // Note that there's still an issue in IE < 9 whereby it will discard comment nodes that are the first child of + // a descendant node. For example: "
abc
" will get parsed as "
abc
" + // This won't affect anyone who has referenced jQuery, and there's always the workaround of inserting a dummy node + // (possibly a text node) in front of the comment. So, KO does not attempt to workaround this IE issue automatically at present. + + // Trim whitespace, otherwise indexOf won't work as expected + var tags = ko.utils.stringTrim(html).toLowerCase(), div = document.createElement("div"); + + // Finds the first match from the left column, and returns the corresponding "wrap" data from the right column + var wrap = tags.match(/^<(thead|tbody|tfoot)/) && [1, "", "
"] || + !tags.indexOf("", ""] || + (!tags.indexOf("", ""] || + /* anything else */ [0, "", ""]; + + // Go to html and back, then peel off extra wrappers + // Note that we always prefix with some dummy text, because otherwise, IE<9 will strip out leading comment nodes in descendants. Total madness. + var markup = "ignored
" + wrap[1] + html + wrap[2] + "
"; + if (typeof window['innerShiv'] == "function") { + div.appendChild(window['innerShiv'](markup)); + } else { + div.innerHTML = markup; + } + + // Move to the right depth + while (wrap[0]--) + div = div.lastChild; + + return ko.utils.makeArray(div.lastChild.childNodes); + } + + function jQueryHtmlParse(html) { + // jQuery's "parseHTML" function was introduced in jQuery 1.8.0 and is a documented public API. + if (jQuery['parseHTML']) { + return jQuery['parseHTML'](html) || []; // Ensure we always return an array and never null + } else { + // For jQuery < 1.8.0, we fall back on the undocumented internal "clean" function. + var elems = jQuery['clean']([html]); + + // As of jQuery 1.7.1, jQuery parses the HTML by appending it to some dummy parent nodes held in an in-memory document fragment. + // Unfortunately, it never clears the dummy parent nodes from the document fragment, so it leaks memory over time. + // Fix this by finding the top-most dummy parent element, and detaching it from its owner fragment. + if (elems && elems[0]) { + // Find the top-most parent element that's a direct child of a document fragment + var elem = elems[0]; + while (elem.parentNode && elem.parentNode.nodeType !== 11 /* i.e., DocumentFragment */) + elem = elem.parentNode; + // ... then detach it + if (elem.parentNode) + elem.parentNode.removeChild(elem); + } + + return elems; + } + } + + ko.utils.parseHtmlFragment = function(html) { + return jQuery ? jQueryHtmlParse(html) // As below, benefit from jQuery's optimisations where possible + : simpleHtmlParse(html); // ... otherwise, this simple logic will do in most common cases. + }; + + ko.utils.setHtml = function(node, html) { + ko.utils.emptyDomNode(node); + + // There's no legitimate reason to display a stringified observable without unwrapping it, so we'll unwrap it + html = ko.utils.unwrapObservable(html); + + if ((html !== null) && (html !== undefined)) { + if (typeof html != 'string') + html = html.toString(); + + // jQuery contains a lot of sophisticated code to parse arbitrary HTML fragments, + // for example elements which are not normally allowed to exist on their own. + // If you've referenced jQuery we'll use that rather than duplicating its code. + if (jQuery) { + jQuery(node)['html'](html); + } else { + // ... otherwise, use KO's own parsing logic. + var parsedNodes = ko.utils.parseHtmlFragment(html); + for (var i = 0; i < parsedNodes.length; i++) + node.appendChild(parsedNodes[i]); + } + } + }; +})(); + +ko.exportSymbol('utils.parseHtmlFragment', ko.utils.parseHtmlFragment); +ko.exportSymbol('utils.setHtml', ko.utils.setHtml); + +ko.memoization = (function () { + var memos = {}; + + function randomMax8HexChars() { + return (((1 + Math.random()) * 0x100000000) | 0).toString(16).substring(1); + } + function generateRandomId() { + return randomMax8HexChars() + randomMax8HexChars(); + } + function findMemoNodes(rootNode, appendToArray) { + if (!rootNode) + return; + if (rootNode.nodeType == 8) { + var memoId = ko.memoization.parseMemoText(rootNode.nodeValue); + if (memoId != null) + appendToArray.push({ domNode: rootNode, memoId: memoId }); + } else if (rootNode.nodeType == 1) { + for (var i = 0, childNodes = rootNode.childNodes, j = childNodes.length; i < j; i++) + findMemoNodes(childNodes[i], appendToArray); + } + } + + return { + memoize: function (callback) { + if (typeof callback != "function") + throw new Error("You can only pass a function to ko.memoization.memoize()"); + var memoId = generateRandomId(); + memos[memoId] = callback; + return ""; + }, + + unmemoize: function (memoId, callbackParams) { + var callback = memos[memoId]; + if (callback === undefined) + throw new Error("Couldn't find any memo with ID " + memoId + ". Perhaps it's already been unmemoized."); + try { + callback.apply(null, callbackParams || []); + return true; + } + finally { delete memos[memoId]; } + }, + + unmemoizeDomNodeAndDescendants: function (domNode, extraCallbackParamsArray) { + var memos = []; + findMemoNodes(domNode, memos); + for (var i = 0, j = memos.length; i < j; i++) { + var node = memos[i].domNode; + var combinedParams = [node]; + if (extraCallbackParamsArray) + ko.utils.arrayPushAll(combinedParams, extraCallbackParamsArray); + ko.memoization.unmemoize(memos[i].memoId, combinedParams); + node.nodeValue = ""; // Neuter this node so we don't try to unmemoize it again + if (node.parentNode) + node.parentNode.removeChild(node); // If possible, erase it totally (not always possible - someone else might just hold a reference to it then call unmemoizeDomNodeAndDescendants again) + } + }, + + parseMemoText: function (memoText) { + var match = memoText.match(/^\[ko_memo\:(.*?)\]$/); + return match ? match[1] : null; + } + }; +})(); + +ko.exportSymbol('memoization', ko.memoization); +ko.exportSymbol('memoization.memoize', ko.memoization.memoize); +ko.exportSymbol('memoization.unmemoize', ko.memoization.unmemoize); +ko.exportSymbol('memoization.parseMemoText', ko.memoization.parseMemoText); +ko.exportSymbol('memoization.unmemoizeDomNodeAndDescendants', ko.memoization.unmemoizeDomNodeAndDescendants); +ko.extenders = { + 'throttle': function(target, timeout) { + // Throttling means two things: + + // (1) For dependent observables, we throttle *evaluations* so that, no matter how fast its dependencies + // notify updates, the target doesn't re-evaluate (and hence doesn't notify) faster than a certain rate + target['throttleEvaluation'] = timeout; + + // (2) For writable targets (observables, or writable dependent observables), we throttle *writes* + // so the target cannot change value synchronously or faster than a certain rate + var writeTimeoutInstance = null; + return ko.dependentObservable({ + 'read': target, + 'write': function(value) { + clearTimeout(writeTimeoutInstance); + writeTimeoutInstance = setTimeout(function() { + target(value); + }, timeout); + } + }); + }, + + 'rateLimit': function(target, options) { + var timeout, method, limitFunction; + + if (typeof options == 'number') { + timeout = options; + } else { + timeout = options['timeout']; + method = options['method']; + } + + limitFunction = method == 'notifyWhenChangesStop' ? debounce : throttle; + target.limit(function(callback) { + return limitFunction(callback, timeout); + }); + }, + + 'notify': function(target, notifyWhen) { + target["equalityComparer"] = notifyWhen == "always" ? + null : // null equalityComparer means to always notify + valuesArePrimitiveAndEqual; + } +}; + +var primitiveTypes = { 'undefined':1, 'boolean':1, 'number':1, 'string':1 }; +function valuesArePrimitiveAndEqual(a, b) { + var oldValueIsPrimitive = (a === null) || (typeof(a) in primitiveTypes); + return oldValueIsPrimitive ? (a === b) : false; +} + +function throttle(callback, timeout) { + var timeoutInstance; + return function () { + if (!timeoutInstance) { + timeoutInstance = setTimeout(function() { + timeoutInstance = undefined; + callback(); + }, timeout); + } + }; +} + +function debounce(callback, timeout) { + var timeoutInstance; + return function () { + clearTimeout(timeoutInstance); + timeoutInstance = setTimeout(callback, timeout); + }; +} + +function applyExtenders(requestedExtenders) { + var target = this; + if (requestedExtenders) { + ko.utils.objectForEach(requestedExtenders, function(key, value) { + var extenderHandler = ko.extenders[key]; + if (typeof extenderHandler == 'function') { + target = extenderHandler(target, value) || target; + } + }); + } + return target; +} + +ko.exportSymbol('extenders', ko.extenders); + +ko.subscription = function (target, callback, disposeCallback) { + this.target = target; + this.callback = callback; + this.disposeCallback = disposeCallback; + this.isDisposed = false; + ko.exportProperty(this, 'dispose', this.dispose); +}; +ko.subscription.prototype.dispose = function () { + this.isDisposed = true; + this.disposeCallback(); +}; + +ko.subscribable = function () { + ko.utils.setPrototypeOfOrExtend(this, ko.subscribable['fn']); + this._subscriptions = {}; +} + +var defaultEvent = "change"; + +var ko_subscribable_fn = { + subscribe: function (callback, callbackTarget, event) { + var self = this; + + event = event || defaultEvent; + var boundCallback = callbackTarget ? callback.bind(callbackTarget) : callback; + + var subscription = new ko.subscription(self, boundCallback, function () { + ko.utils.arrayRemoveItem(self._subscriptions[event], subscription); + }); + + // This will force a computed with deferEvaluation to evaluate before any subscriptions + // are registered. + if (self.peek) { + self.peek(); + } + + if (!self._subscriptions[event]) + self._subscriptions[event] = []; + self._subscriptions[event].push(subscription); + return subscription; + }, + + "notifySubscribers": function (valueToNotify, event) { + event = event || defaultEvent; + if (this.hasSubscriptionsForEvent(event)) { + try { + ko.dependencyDetection.begin(); // Begin suppressing dependency detection (by setting the top frame to undefined) + for (var a = this._subscriptions[event].slice(0), i = 0, subscription; subscription = a[i]; ++i) { + // In case a subscription was disposed during the arrayForEach cycle, check + // for isDisposed on each subscription before invoking its callback + if (!subscription.isDisposed) + subscription.callback(valueToNotify); + } + } finally { + ko.dependencyDetection.end(); // End suppressing dependency detection + } + } + }, + + limit: function(limitFunction) { + var self = this, selfIsObservable = ko.isObservable(self), + isPending, previousValue, pendingValue, beforeChange = 'beforeChange'; + + if (!self._origNotifySubscribers) { + self._origNotifySubscribers = self["notifySubscribers"]; + self["notifySubscribers"] = function(value, event) { + if (!event || event === defaultEvent) { + self._rateLimitedChange(value); + } else if (event === beforeChange) { + self._rateLimitedBeforeChange(value); + } else { + self._origNotifySubscribers(value, event); + } + }; + } + + var finish = limitFunction(function() { + // If an observable provided a reference to itself, access it to get the latest value. + // This allows computed observables to delay calculating their value until needed. + if (selfIsObservable && pendingValue === self) { + pendingValue = self(); + } + isPending = false; + if (self.isDifferent(previousValue, pendingValue)) { + self._origNotifySubscribers(previousValue = pendingValue); + } + }); + + self._rateLimitedChange = function(value) { + isPending = true; + pendingValue = value; + finish(); + }; + self._rateLimitedBeforeChange = function(value) { + if (!isPending) { + previousValue = value; + self._origNotifySubscribers(value, beforeChange); + } + }; + }, + + hasSubscriptionsForEvent: function(event) { + return this._subscriptions[event] && this._subscriptions[event].length; + }, + + getSubscriptionsCount: function () { + var total = 0; + ko.utils.objectForEach(this._subscriptions, function(eventName, subscriptions) { + total += subscriptions.length; + }); + return total; + }, + + isDifferent: function(oldValue, newValue) { + return !this['equalityComparer'] || !this['equalityComparer'](oldValue, newValue); + }, + + extend: applyExtenders +}; + +ko.exportProperty(ko_subscribable_fn, 'subscribe', ko_subscribable_fn.subscribe); +ko.exportProperty(ko_subscribable_fn, 'extend', ko_subscribable_fn.extend); +ko.exportProperty(ko_subscribable_fn, 'getSubscriptionsCount', ko_subscribable_fn.getSubscriptionsCount); + +// For browsers that support proto assignment, we overwrite the prototype of each +// observable instance. Since observables are functions, we need Function.prototype +// to still be in the prototype chain. +if (ko.utils.canSetPrototype) { + ko.utils.setPrototypeOf(ko_subscribable_fn, Function.prototype); +} + +ko.subscribable['fn'] = ko_subscribable_fn; + + +ko.isSubscribable = function (instance) { + return instance != null && typeof instance.subscribe == "function" && typeof instance["notifySubscribers"] == "function"; +}; + +ko.exportSymbol('subscribable', ko.subscribable); +ko.exportSymbol('isSubscribable', ko.isSubscribable); + +ko.computedContext = ko.dependencyDetection = (function () { + var outerFrames = [], + currentFrame, + lastId = 0; + + // Return a unique ID that can be assigned to an observable for dependency tracking. + // Theoretically, you could eventually overflow the number storage size, resulting + // in duplicate IDs. But in JavaScript, the largest exact integral value is 2^53 + // or 9,007,199,254,740,992. If you created 1,000,000 IDs per second, it would + // take over 285 years to reach that number. + // Reference http://blog.vjeux.com/2010/javascript/javascript-max_int-number-limits.html + function getId() { + return ++lastId; + } + + function begin(options) { + outerFrames.push(currentFrame); + currentFrame = options; + } + + function end() { + currentFrame = outerFrames.pop(); + } + + return { + begin: begin, + + end: end, + + registerDependency: function (subscribable) { + if (currentFrame) { + if (!ko.isSubscribable(subscribable)) + throw new Error("Only subscribable things can act as dependencies"); + currentFrame.callback(subscribable, subscribable._id || (subscribable._id = getId())); + } + }, + + ignore: function (callback, callbackTarget, callbackArgs) { + try { + begin(); + return callback.apply(callbackTarget, callbackArgs || []); + } finally { + end(); + } + }, + + getDependenciesCount: function () { + if (currentFrame) + return currentFrame.computed.getDependenciesCount(); + }, + + isInitial: function() { + if (currentFrame) + return currentFrame.isInitial; + } + }; +})(); + +ko.exportSymbol('computedContext', ko.computedContext); +ko.exportSymbol('computedContext.getDependenciesCount', ko.computedContext.getDependenciesCount); +ko.exportSymbol('computedContext.isInitial', ko.computedContext.isInitial); +ko.observable = function (initialValue) { + var _latestValue = initialValue; + + function observable() { + if (arguments.length > 0) { + // Write + + // Ignore writes if the value hasn't changed + if (observable.isDifferent(_latestValue, arguments[0])) { + observable.valueWillMutate(); + _latestValue = arguments[0]; + if (DEBUG) observable._latestValue = _latestValue; + observable.valueHasMutated(); + } + return this; // Permits chained assignments + } + else { + // Read + ko.dependencyDetection.registerDependency(observable); // The caller only needs to be notified of changes if they did a "read" operation + return _latestValue; + } + } + ko.subscribable.call(observable); + ko.utils.setPrototypeOfOrExtend(observable, ko.observable['fn']); + + if (DEBUG) observable._latestValue = _latestValue; + observable.peek = function() { return _latestValue }; + observable.valueHasMutated = function () { observable["notifySubscribers"](_latestValue); } + observable.valueWillMutate = function () { observable["notifySubscribers"](_latestValue, "beforeChange"); } + + ko.exportProperty(observable, 'peek', observable.peek); + ko.exportProperty(observable, "valueHasMutated", observable.valueHasMutated); + ko.exportProperty(observable, "valueWillMutate", observable.valueWillMutate); + + return observable; +} + +ko.observable['fn'] = { + "equalityComparer": valuesArePrimitiveAndEqual +}; + +var protoProperty = ko.observable.protoProperty = "__ko_proto__"; +ko.observable['fn'][protoProperty] = ko.observable; + +// Note that for browsers that don't support proto assignment, the +// inheritance chain is created manually in the ko.observable constructor +if (ko.utils.canSetPrototype) { + ko.utils.setPrototypeOf(ko.observable['fn'], ko.subscribable['fn']); +} + +ko.hasPrototype = function(instance, prototype) { + if ((instance === null) || (instance === undefined) || (instance[protoProperty] === undefined)) return false; + if (instance[protoProperty] === prototype) return true; + return ko.hasPrototype(instance[protoProperty], prototype); // Walk the prototype chain +}; + +ko.isObservable = function (instance) { + return ko.hasPrototype(instance, ko.observable); +} +ko.isWriteableObservable = function (instance) { + // Observable + if ((typeof instance == "function") && instance[protoProperty] === ko.observable) + return true; + // Writeable dependent observable + if ((typeof instance == "function") && (instance[protoProperty] === ko.dependentObservable) && (instance.hasWriteFunction)) + return true; + // Anything else + return false; +} + + +ko.exportSymbol('observable', ko.observable); +ko.exportSymbol('isObservable', ko.isObservable); +ko.exportSymbol('isWriteableObservable', ko.isWriteableObservable); +ko.observableArray = function (initialValues) { + initialValues = initialValues || []; + + if (typeof initialValues != 'object' || !('length' in initialValues)) + throw new Error("The argument passed when initializing an observable array must be an array, or null, or undefined."); + + var result = ko.observable(initialValues); + ko.utils.setPrototypeOfOrExtend(result, ko.observableArray['fn']); + return result.extend({'trackArrayChanges':true}); +}; + +ko.observableArray['fn'] = { + 'remove': function (valueOrPredicate) { + var underlyingArray = this.peek(); + var removedValues = []; + var predicate = typeof valueOrPredicate == "function" && !ko.isObservable(valueOrPredicate) ? valueOrPredicate : function (value) { return value === valueOrPredicate; }; + for (var i = 0; i < underlyingArray.length; i++) { + var value = underlyingArray[i]; + if (predicate(value)) { + if (removedValues.length === 0) { + this.valueWillMutate(); + } + removedValues.push(value); + underlyingArray.splice(i, 1); + i--; + } + } + if (removedValues.length) { + this.valueHasMutated(); + } + return removedValues; + }, + + 'removeAll': function (arrayOfValues) { + // If you passed zero args, we remove everything + if (arrayOfValues === undefined) { + var underlyingArray = this.peek(); + var allValues = underlyingArray.slice(0); + this.valueWillMutate(); + underlyingArray.splice(0, underlyingArray.length); + this.valueHasMutated(); + return allValues; + } + // If you passed an arg, we interpret it as an array of entries to remove + if (!arrayOfValues) + return []; + return this['remove'](function (value) { + return ko.utils.arrayIndexOf(arrayOfValues, value) >= 0; + }); + }, + + 'destroy': function (valueOrPredicate) { + var underlyingArray = this.peek(); + var predicate = typeof valueOrPredicate == "function" && !ko.isObservable(valueOrPredicate) ? valueOrPredicate : function (value) { return value === valueOrPredicate; }; + this.valueWillMutate(); + for (var i = underlyingArray.length - 1; i >= 0; i--) { + var value = underlyingArray[i]; + if (predicate(value)) + underlyingArray[i]["_destroy"] = true; + } + this.valueHasMutated(); + }, + + 'destroyAll': function (arrayOfValues) { + // If you passed zero args, we destroy everything + if (arrayOfValues === undefined) + return this['destroy'](function() { return true }); + + // If you passed an arg, we interpret it as an array of entries to destroy + if (!arrayOfValues) + return []; + return this['destroy'](function (value) { + return ko.utils.arrayIndexOf(arrayOfValues, value) >= 0; + }); + }, + + 'indexOf': function (item) { + var underlyingArray = this(); + return ko.utils.arrayIndexOf(underlyingArray, item); + }, + + 'replace': function(oldItem, newItem) { + var index = this['indexOf'](oldItem); + if (index >= 0) { + this.valueWillMutate(); + this.peek()[index] = newItem; + this.valueHasMutated(); + } + } +}; + +// Populate ko.observableArray.fn with read/write functions from native arrays +// Important: Do not add any additional functions here that may reasonably be used to *read* data from the array +// because we'll eval them without causing subscriptions, so ko.computed output could end up getting stale +ko.utils.arrayForEach(["pop", "push", "reverse", "shift", "sort", "splice", "unshift"], function (methodName) { + ko.observableArray['fn'][methodName] = function () { + // Use "peek" to avoid creating a subscription in any computed that we're executing in the context of + // (for consistency with mutating regular observables) + var underlyingArray = this.peek(); + this.valueWillMutate(); + this.cacheDiffForKnownOperation(underlyingArray, methodName, arguments); + var methodCallResult = underlyingArray[methodName].apply(underlyingArray, arguments); + this.valueHasMutated(); + return methodCallResult; + }; +}); + +// Populate ko.observableArray.fn with read-only functions from native arrays +ko.utils.arrayForEach(["slice"], function (methodName) { + ko.observableArray['fn'][methodName] = function () { + var underlyingArray = this(); + return underlyingArray[methodName].apply(underlyingArray, arguments); + }; +}); + +// Note that for browsers that don't support proto assignment, the +// inheritance chain is created manually in the ko.observableArray constructor +if (ko.utils.canSetPrototype) { + ko.utils.setPrototypeOf(ko.observableArray['fn'], ko.observable['fn']); +} + +ko.exportSymbol('observableArray', ko.observableArray); +var arrayChangeEventName = 'arrayChange'; +ko.extenders['trackArrayChanges'] = function(target) { + // Only modify the target observable once + if (target.cacheDiffForKnownOperation) { + return; + } + var trackingChanges = false, + cachedDiff = null, + pendingNotifications = 0, + underlyingSubscribeFunction = target.subscribe; + + // Intercept "subscribe" calls, and for array change events, ensure change tracking is enabled + target.subscribe = target['subscribe'] = function(callback, callbackTarget, event) { + if (event === arrayChangeEventName) { + trackChanges(); + } + return underlyingSubscribeFunction.apply(this, arguments); + }; + + function trackChanges() { + // Calling 'trackChanges' multiple times is the same as calling it once + if (trackingChanges) { + return; + } + + trackingChanges = true; + + // Intercept "notifySubscribers" to track how many times it was called. + var underlyingNotifySubscribersFunction = target['notifySubscribers']; + target['notifySubscribers'] = function(valueToNotify, event) { + if (!event || event === defaultEvent) { + ++pendingNotifications; + } + return underlyingNotifySubscribersFunction.apply(this, arguments); + }; + + // Each time the array changes value, capture a clone so that on the next + // change it's possible to produce a diff + var previousContents = [].concat(target.peek() || []); + cachedDiff = null; + target.subscribe(function(currentContents) { + // Make a copy of the current contents and ensure it's an array + currentContents = [].concat(currentContents || []); + + // Compute the diff and issue notifications, but only if someone is listening + if (target.hasSubscriptionsForEvent(arrayChangeEventName)) { + var changes = getChanges(previousContents, currentContents); + if (changes.length) { + target['notifySubscribers'](changes, arrayChangeEventName); + } + } + + // Eliminate references to the old, removed items, so they can be GCed + previousContents = currentContents; + cachedDiff = null; + pendingNotifications = 0; + }); + } + + function getChanges(previousContents, currentContents) { + // We try to re-use cached diffs. + // The scenarios where pendingNotifications > 1 are when using rate-limiting or the Deferred Updates + // plugin, which without this check would not be compatible with arrayChange notifications. Normally, + // notifications are issued immediately so we wouldn't be queueing up more than one. + if (!cachedDiff || pendingNotifications > 1) { + cachedDiff = ko.utils.compareArrays(previousContents, currentContents, { 'sparse': true }); + } + + return cachedDiff; + } + + target.cacheDiffForKnownOperation = function(rawArray, operationName, args) { + // Only run if we're currently tracking changes for this observable array + // and there aren't any pending deferred notifications. + if (!trackingChanges || pendingNotifications) { + return; + } + var diff = [], + arrayLength = rawArray.length, + argsLength = args.length, + offset = 0; + + function pushDiff(status, value, index) { + return diff[diff.length] = { 'status': status, 'value': value, 'index': index }; + } + switch (operationName) { + case 'push': + offset = arrayLength; + case 'unshift': + for (var index = 0; index < argsLength; index++) { + pushDiff('added', args[index], offset + index); + } + break; + + case 'pop': + offset = arrayLength - 1; + case 'shift': + if (arrayLength) { + pushDiff('deleted', rawArray[offset], offset); + } + break; + + case 'splice': + // Negative start index means 'from end of array'. After that we clamp to [0...arrayLength]. + // See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/splice + var startIndex = Math.min(Math.max(0, args[0] < 0 ? arrayLength + args[0] : args[0]), arrayLength), + endDeleteIndex = argsLength === 1 ? arrayLength : Math.min(startIndex + (args[1] || 0), arrayLength), + endAddIndex = startIndex + argsLength - 2, + endIndex = Math.max(endDeleteIndex, endAddIndex), + additions = [], deletions = []; + for (var index = startIndex, argsIndex = 2; index < endIndex; ++index, ++argsIndex) { + if (index < endDeleteIndex) + deletions.push(pushDiff('deleted', rawArray[index], index)); + if (index < endAddIndex) + additions.push(pushDiff('added', args[argsIndex], index)); + } + ko.utils.findMovesInArrayComparison(deletions, additions); + break; + + default: + return; + } + cachedDiff = diff; + }; +}; +ko.computed = ko.dependentObservable = function (evaluatorFunctionOrOptions, evaluatorFunctionTarget, options) { + var _latestValue, + _needsEvaluation = true, + _isBeingEvaluated = false, + _suppressDisposalUntilDisposeWhenReturnsFalse = false, + _isDisposed = false, + readFunction = evaluatorFunctionOrOptions; + + if (readFunction && typeof readFunction == "object") { + // Single-parameter syntax - everything is on this "options" param + options = readFunction; + readFunction = options["read"]; + } else { + // Multi-parameter syntax - construct the options according to the params passed + options = options || {}; + if (!readFunction) + readFunction = options["read"]; + } + if (typeof readFunction != "function") + throw new Error("Pass a function that returns the value of the ko.computed"); + + function addSubscriptionToDependency(subscribable, id) { + if (!_subscriptionsToDependencies[id]) { + _subscriptionsToDependencies[id] = subscribable.subscribe(evaluatePossiblyAsync); + ++_dependenciesCount; + } + } + + function disposeAllSubscriptionsToDependencies() { + _isDisposed = true; + ko.utils.objectForEach(_subscriptionsToDependencies, function (id, subscription) { + subscription.dispose(); + }); + _subscriptionsToDependencies = {}; + _dependenciesCount = 0; + _needsEvaluation = false; + } + + function evaluatePossiblyAsync() { + var throttleEvaluationTimeout = dependentObservable['throttleEvaluation']; + if (throttleEvaluationTimeout && throttleEvaluationTimeout >= 0) { + clearTimeout(evaluationTimeoutInstance); + evaluationTimeoutInstance = setTimeout(evaluateImmediate, throttleEvaluationTimeout); + } else if (dependentObservable._evalRateLimited) { + dependentObservable._evalRateLimited(); + } else { + evaluateImmediate(); + } + } + + function evaluateImmediate() { + if (_isBeingEvaluated) { + // If the evaluation of a ko.computed causes side effects, it's possible that it will trigger its own re-evaluation. + // This is not desirable (it's hard for a developer to realise a chain of dependencies might cause this, and they almost + // certainly didn't intend infinite re-evaluations). So, for predictability, we simply prevent ko.computeds from causing + // their own re-evaluation. Further discussion at https://github.com/SteveSanderson/knockout/pull/387 + return; + } + + // Do not evaluate (and possibly capture new dependencies) if disposed + if (_isDisposed) { + return; + } + + if (disposeWhen && disposeWhen()) { + // See comment below about _suppressDisposalUntilDisposeWhenReturnsFalse + if (!_suppressDisposalUntilDisposeWhenReturnsFalse) { + dispose(); + return; + } + } else { + // It just did return false, so we can stop suppressing now + _suppressDisposalUntilDisposeWhenReturnsFalse = false; + } + + _isBeingEvaluated = true; + try { + // Initially, we assume that none of the subscriptions are still being used (i.e., all are candidates for disposal). + // Then, during evaluation, we cross off any that are in fact still being used. + var disposalCandidates = _subscriptionsToDependencies, disposalCount = _dependenciesCount; + ko.dependencyDetection.begin({ + callback: function(subscribable, id) { + if (!_isDisposed) { + if (disposalCount && disposalCandidates[id]) { + // Don't want to dispose this subscription, as it's still being used + _subscriptionsToDependencies[id] = disposalCandidates[id]; + ++_dependenciesCount; + delete disposalCandidates[id]; + --disposalCount; + } else { + // Brand new subscription - add it + addSubscriptionToDependency(subscribable, id); + } + } + }, + computed: dependentObservable, + isInitial: !_dependenciesCount // If we're evaluating when there are no previous dependencies, it must be the first time + }); + + _subscriptionsToDependencies = {}; + _dependenciesCount = 0; + + try { + var newValue = evaluatorFunctionTarget ? readFunction.call(evaluatorFunctionTarget) : readFunction(); + + } finally { + ko.dependencyDetection.end(); + + // For each subscription no longer being used, remove it from the active subscriptions list and dispose it + if (disposalCount) { + ko.utils.objectForEach(disposalCandidates, function(id, toDispose) { + toDispose.dispose(); + }); + } + + _needsEvaluation = false; + } + + if (dependentObservable.isDifferent(_latestValue, newValue)) { + dependentObservable["notifySubscribers"](_latestValue, "beforeChange"); + + _latestValue = newValue; + if (DEBUG) dependentObservable._latestValue = _latestValue; + + // If rate-limited, the notification will happen within the limit function. Otherwise, + // notify as soon as the value changes. Check specifically for the throttle setting since + // it overrides rateLimit. + if (!dependentObservable._evalRateLimited || dependentObservable['throttleEvaluation']) { + dependentObservable["notifySubscribers"](_latestValue); + } + } + } finally { + _isBeingEvaluated = false; + } + + if (!_dependenciesCount) + dispose(); + } + + function dependentObservable() { + if (arguments.length > 0) { + if (typeof writeFunction === "function") { + // Writing a value + writeFunction.apply(evaluatorFunctionTarget, arguments); + } else { + throw new Error("Cannot write a value to a ko.computed unless you specify a 'write' option. If you wish to read the current value, don't pass any parameters."); + } + return this; // Permits chained assignments + } else { + // Reading the value + if (_needsEvaluation) + evaluateImmediate(); + ko.dependencyDetection.registerDependency(dependentObservable); + return _latestValue; + } + } + + function peek() { + // Peek won't re-evaluate, except to get the initial value when "deferEvaluation" is set. + // That's the only time that both of these conditions will be satisfied. + if (_needsEvaluation && !_dependenciesCount) + evaluateImmediate(); + return _latestValue; + } + + function isActive() { + return _needsEvaluation || _dependenciesCount > 0; + } + + // By here, "options" is always non-null + var writeFunction = options["write"], + disposeWhenNodeIsRemoved = options["disposeWhenNodeIsRemoved"] || options.disposeWhenNodeIsRemoved || null, + disposeWhenOption = options["disposeWhen"] || options.disposeWhen, + disposeWhen = disposeWhenOption, + dispose = disposeAllSubscriptionsToDependencies, + _subscriptionsToDependencies = {}, + _dependenciesCount = 0, + evaluationTimeoutInstance = null; + + if (!evaluatorFunctionTarget) + evaluatorFunctionTarget = options["owner"]; + + ko.subscribable.call(dependentObservable); + ko.utils.setPrototypeOfOrExtend(dependentObservable, ko.dependentObservable['fn']); + + dependentObservable.peek = peek; + dependentObservable.getDependenciesCount = function () { return _dependenciesCount; }; + dependentObservable.hasWriteFunction = typeof options["write"] === "function"; + dependentObservable.dispose = function () { dispose(); }; + dependentObservable.isActive = isActive; + + // Replace the limit function with one that delays evaluation as well. + var originalLimit = dependentObservable.limit; + dependentObservable.limit = function(limitFunction) { + originalLimit.call(dependentObservable, limitFunction); + dependentObservable._evalRateLimited = function() { + dependentObservable._rateLimitedBeforeChange(_latestValue); + + _needsEvaluation = true; // Mark as dirty + + // Pass the observable to the rate-limit code, which will access it when + // it's time to do the notification. + dependentObservable._rateLimitedChange(dependentObservable); + } + }; + + ko.exportProperty(dependentObservable, 'peek', dependentObservable.peek); + ko.exportProperty(dependentObservable, 'dispose', dependentObservable.dispose); + ko.exportProperty(dependentObservable, 'isActive', dependentObservable.isActive); + ko.exportProperty(dependentObservable, 'getDependenciesCount', dependentObservable.getDependenciesCount); + + // Add a "disposeWhen" callback that, on each evaluation, disposes if the node was removed without using ko.removeNode. + if (disposeWhenNodeIsRemoved) { + // Since this computed is associated with a DOM node, and we don't want to dispose the computed + // until the DOM node is *removed* from the document (as opposed to never having been in the document), + // we'll prevent disposal until "disposeWhen" first returns false. + _suppressDisposalUntilDisposeWhenReturnsFalse = true; + + // Only watch for the node's disposal if the value really is a node. It might not be, + // e.g., { disposeWhenNodeIsRemoved: true } can be used to opt into the "only dispose + // after first false result" behaviour even if there's no specific node to watch. This + // technique is intended for KO's internal use only and shouldn't be documented or used + // by application code, as it's likely to change in a future version of KO. + if (disposeWhenNodeIsRemoved.nodeType) { + disposeWhen = function () { + return !ko.utils.domNodeIsAttachedToDocument(disposeWhenNodeIsRemoved) || (disposeWhenOption && disposeWhenOption()); + }; + } + } + + // Evaluate, unless deferEvaluation is true + if (options['deferEvaluation'] !== true) + evaluateImmediate(); + + // Attach a DOM node disposal callback so that the computed will be proactively disposed as soon as the node is + // removed using ko.removeNode. But skip if isActive is false (there will never be any dependencies to dispose). + if (disposeWhenNodeIsRemoved && isActive() && disposeWhenNodeIsRemoved.nodeType) { + dispose = function() { + ko.utils.domNodeDisposal.removeDisposeCallback(disposeWhenNodeIsRemoved, dispose); + disposeAllSubscriptionsToDependencies(); + }; + ko.utils.domNodeDisposal.addDisposeCallback(disposeWhenNodeIsRemoved, dispose); + } + + return dependentObservable; +}; + +ko.isComputed = function(instance) { + return ko.hasPrototype(instance, ko.dependentObservable); +}; + +var protoProp = ko.observable.protoProperty; // == "__ko_proto__" +ko.dependentObservable[protoProp] = ko.observable; + +ko.dependentObservable['fn'] = { + "equalityComparer": valuesArePrimitiveAndEqual +}; +ko.dependentObservable['fn'][protoProp] = ko.dependentObservable; + +// Note that for browsers that don't support proto assignment, the +// inheritance chain is created manually in the ko.dependentObservable constructor +if (ko.utils.canSetPrototype) { + ko.utils.setPrototypeOf(ko.dependentObservable['fn'], ko.subscribable['fn']); +} + +ko.exportSymbol('dependentObservable', ko.dependentObservable); +ko.exportSymbol('computed', ko.dependentObservable); // Make "ko.computed" an alias for "ko.dependentObservable" +ko.exportSymbol('isComputed', ko.isComputed); + +(function() { + var maxNestedObservableDepth = 10; // Escape the (unlikely) pathalogical case where an observable's current value is itself (or similar reference cycle) + + ko.toJS = function(rootObject) { + if (arguments.length == 0) + throw new Error("When calling ko.toJS, pass the object you want to convert."); + + // We just unwrap everything at every level in the object graph + return mapJsObjectGraph(rootObject, function(valueToMap) { + // Loop because an observable's value might in turn be another observable wrapper + for (var i = 0; ko.isObservable(valueToMap) && (i < maxNestedObservableDepth); i++) + valueToMap = valueToMap(); + return valueToMap; + }); + }; + + ko.toJSON = function(rootObject, replacer, space) { // replacer and space are optional + var plainJavaScriptObject = ko.toJS(rootObject); + return ko.utils.stringifyJson(plainJavaScriptObject, replacer, space); + }; + + function mapJsObjectGraph(rootObject, mapInputCallback, visitedObjects) { + visitedObjects = visitedObjects || new objectLookup(); + + rootObject = mapInputCallback(rootObject); + var canHaveProperties = (typeof rootObject == "object") && (rootObject !== null) && (rootObject !== undefined) && (!(rootObject instanceof Date)) && (!(rootObject instanceof String)) && (!(rootObject instanceof Number)) && (!(rootObject instanceof Boolean)); + if (!canHaveProperties) + return rootObject; + + var outputProperties = rootObject instanceof Array ? [] : {}; + visitedObjects.save(rootObject, outputProperties); + + visitPropertiesOrArrayEntries(rootObject, function(indexer) { + var propertyValue = mapInputCallback(rootObject[indexer]); + + switch (typeof propertyValue) { + case "boolean": + case "number": + case "string": + case "function": + outputProperties[indexer] = propertyValue; + break; + case "object": + case "undefined": + var previouslyMappedValue = visitedObjects.get(propertyValue); + outputProperties[indexer] = (previouslyMappedValue !== undefined) + ? previouslyMappedValue + : mapJsObjectGraph(propertyValue, mapInputCallback, visitedObjects); + break; + } + }); + + return outputProperties; + } + + function visitPropertiesOrArrayEntries(rootObject, visitorCallback) { + if (rootObject instanceof Array) { + for (var i = 0; i < rootObject.length; i++) + visitorCallback(i); + + // For arrays, also respect toJSON property for custom mappings (fixes #278) + if (typeof rootObject['toJSON'] == 'function') + visitorCallback('toJSON'); + } else { + for (var propertyName in rootObject) { + visitorCallback(propertyName); + } + } + }; + + function objectLookup() { + this.keys = []; + this.values = []; + }; + + objectLookup.prototype = { + constructor: objectLookup, + save: function(key, value) { + var existingIndex = ko.utils.arrayIndexOf(this.keys, key); + if (existingIndex >= 0) + this.values[existingIndex] = value; + else { + this.keys.push(key); + this.values.push(value); + } + }, + get: function(key) { + var existingIndex = ko.utils.arrayIndexOf(this.keys, key); + return (existingIndex >= 0) ? this.values[existingIndex] : undefined; + } + }; +})(); + +ko.exportSymbol('toJS', ko.toJS); +ko.exportSymbol('toJSON', ko.toJSON); +(function () { + var hasDomDataExpandoProperty = '__ko__hasDomDataOptionValue__'; + + // Normally, SELECT elements and their OPTIONs can only take value of type 'string' (because the values + // are stored on DOM attributes). ko.selectExtensions provides a way for SELECTs/OPTIONs to have values + // that are arbitrary objects. This is very convenient when implementing things like cascading dropdowns. + ko.selectExtensions = { + readValue : function(element) { + switch (ko.utils.tagNameLower(element)) { + case 'option': + if (element[hasDomDataExpandoProperty] === true) + return ko.utils.domData.get(element, ko.bindingHandlers.options.optionValueDomDataKey); + return ko.utils.ieVersion <= 7 + ? (element.getAttributeNode('value') && element.getAttributeNode('value').specified ? element.value : element.text) + : element.value; + case 'select': + return element.selectedIndex >= 0 ? ko.selectExtensions.readValue(element.options[element.selectedIndex]) : undefined; + default: + return element.value; + } + }, + + writeValue: function(element, value, allowUnset) { + switch (ko.utils.tagNameLower(element)) { + case 'option': + switch(typeof value) { + case "string": + ko.utils.domData.set(element, ko.bindingHandlers.options.optionValueDomDataKey, undefined); + if (hasDomDataExpandoProperty in element) { // IE <= 8 throws errors if you delete non-existent properties from a DOM node + delete element[hasDomDataExpandoProperty]; + } + element.value = value; + break; + default: + // Store arbitrary object using DomData + ko.utils.domData.set(element, ko.bindingHandlers.options.optionValueDomDataKey, value); + element[hasDomDataExpandoProperty] = true; + + // Special treatment of numbers is just for backward compatibility. KO 1.2.1 wrote numerical values to element.value. + element.value = typeof value === "number" ? value : ""; + break; + } + break; + case 'select': + if (value === "" || value === null) // A blank string or null value will select the caption + value = undefined; + var selection = -1; + for (var i = 0, n = element.options.length, optionValue; i < n; ++i) { + optionValue = ko.selectExtensions.readValue(element.options[i]); + // Include special check to handle selecting a caption with a blank string value + if (optionValue == value || (optionValue == "" && value === undefined)) { + selection = i; + break; + } + } + if (allowUnset || selection >= 0 || (value === undefined && element.size > 1)) { + element.selectedIndex = selection; + } + break; + default: + if ((value === null) || (value === undefined)) + value = ""; + element.value = value; + break; + } + } + }; +})(); + +ko.exportSymbol('selectExtensions', ko.selectExtensions); +ko.exportSymbol('selectExtensions.readValue', ko.selectExtensions.readValue); +ko.exportSymbol('selectExtensions.writeValue', ko.selectExtensions.writeValue); +ko.expressionRewriting = (function () { + var javaScriptReservedWords = ["true", "false", "null", "undefined"]; + + // Matches something that can be assigned to--either an isolated identifier or something ending with a property accessor + // This is designed to be simple and avoid false negatives, but could produce false positives (e.g., a+b.c). + // This also will not properly handle nested brackets (e.g., obj1[obj2['prop']]; see #911). + var javaScriptAssignmentTarget = /^(?:[$_a-z][$\w]*|(.+)(\.\s*[$_a-z][$\w]*|\[.+\]))$/i; + + function getWriteableValue(expression) { + if (ko.utils.arrayIndexOf(javaScriptReservedWords, expression) >= 0) + return false; + var match = expression.match(javaScriptAssignmentTarget); + return match === null ? false : match[1] ? ('Object(' + match[1] + ')' + match[2]) : expression; + } + + // The following regular expressions will be used to split an object-literal string into tokens + + // These two match strings, either with double quotes or single quotes + var stringDouble = '"(?:[^"\\\\]|\\\\.)*"', + stringSingle = "'(?:[^'\\\\]|\\\\.)*'", + // Matches a regular expression (text enclosed by slashes), but will also match sets of divisions + // as a regular expression (this is handled by the parsing loop below). + stringRegexp = '/(?:[^/\\\\]|\\\\.)*/\w*', + // These characters have special meaning to the parser and must not appear in the middle of a + // token, except as part of a string. + specials = ',"\'{}()/:[\\]', + // Match text (at least two characters) that does not contain any of the above special characters, + // although some of the special characters are allowed to start it (all but the colon and comma). + // The text can contain spaces, but leading or trailing spaces are skipped. + everyThingElse = '[^\\s:,/][^' + specials + ']*[^\\s' + specials + ']', + // Match any non-space character not matched already. This will match colons and commas, since they're + // not matched by "everyThingElse", but will also match any other single character that wasn't already + // matched (for example: in "a: 1, b: 2", each of the non-space characters will be matched by oneNotSpace). + oneNotSpace = '[^\\s]', + + // Create the actual regular expression by or-ing the above strings. The order is important. + bindingToken = RegExp(stringDouble + '|' + stringSingle + '|' + stringRegexp + '|' + everyThingElse + '|' + oneNotSpace, 'g'), + + // Match end of previous token to determine whether a slash is a division or regex. + divisionLookBehind = /[\])"'A-Za-z0-9_$]+$/, + keywordRegexLookBehind = {'in':1,'return':1,'typeof':1}; + + function parseObjectLiteral(objectLiteralString) { + // Trim leading and trailing spaces from the string + var str = ko.utils.stringTrim(objectLiteralString); + + // Trim braces '{' surrounding the whole object literal + if (str.charCodeAt(0) === 123) str = str.slice(1, -1); + + // Split into tokens + var result = [], toks = str.match(bindingToken), key, values, depth = 0; + + if (toks) { + // Append a comma so that we don't need a separate code block to deal with the last item + toks.push(','); + + for (var i = 0, tok; tok = toks[i]; ++i) { + var c = tok.charCodeAt(0); + // A comma signals the end of a key/value pair if depth is zero + if (c === 44) { // "," + if (depth <= 0) { + if (key) + result.push(values ? {key: key, value: values.join('')} : {'unknown': key}); + key = values = depth = 0; + continue; + } + // Simply skip the colon that separates the name and value + } else if (c === 58) { // ":" + if (!values) + continue; + // A set of slashes is initially matched as a regular expression, but could be division + } else if (c === 47 && i && tok.length > 1) { // "/" + // Look at the end of the previous token to determine if the slash is actually division + var match = toks[i-1].match(divisionLookBehind); + if (match && !keywordRegexLookBehind[match[0]]) { + // The slash is actually a division punctuator; re-parse the remainder of the string (not including the slash) + str = str.substr(str.indexOf(tok) + 1); + toks = str.match(bindingToken); + toks.push(','); + i = -1; + // Continue with just the slash + tok = '/'; + } + // Increment depth for parentheses, braces, and brackets so that interior commas are ignored + } else if (c === 40 || c === 123 || c === 91) { // '(', '{', '[' + ++depth; + } else if (c === 41 || c === 125 || c === 93) { // ')', '}', ']' + --depth; + // The key must be a single token; if it's a string, trim the quotes + } else if (!key && !values) { + key = (c === 34 || c === 39) /* '"', "'" */ ? tok.slice(1, -1) : tok; + continue; + } + if (values) + values.push(tok); + else + values = [tok]; + } + } + return result; + } + + // Two-way bindings include a write function that allow the handler to update the value even if it's not an observable. + var twoWayBindings = {}; + + function preProcessBindings(bindingsStringOrKeyValueArray, bindingOptions) { + bindingOptions = bindingOptions || {}; + + function processKeyValue(key, val) { + var writableVal; + function callPreprocessHook(obj) { + return (obj && obj['preprocess']) ? (val = obj['preprocess'](val, key, processKeyValue)) : true; + } + if (!callPreprocessHook(ko['getBindingHandler'](key))) + return; + + if (twoWayBindings[key] && (writableVal = getWriteableValue(val))) { + // For two-way bindings, provide a write method in case the value + // isn't a writable observable. + propertyAccessorResultStrings.push("'" + key + "':function(_z){" + writableVal + "=_z}"); + } + + // Values are wrapped in a function so that each value can be accessed independently + if (makeValueAccessors) { + val = 'function(){return ' + val + ' }'; + } + resultStrings.push("'" + key + "':" + val); + } + + var resultStrings = [], + propertyAccessorResultStrings = [], + makeValueAccessors = bindingOptions['valueAccessors'], + keyValueArray = typeof bindingsStringOrKeyValueArray === "string" ? + parseObjectLiteral(bindingsStringOrKeyValueArray) : bindingsStringOrKeyValueArray; + + ko.utils.arrayForEach(keyValueArray, function(keyValue) { + processKeyValue(keyValue.key || keyValue['unknown'], keyValue.value); + }); + + if (propertyAccessorResultStrings.length) + processKeyValue('_ko_property_writers', "{" + propertyAccessorResultStrings.join(",") + " }"); + + return resultStrings.join(","); + } + + return { + bindingRewriteValidators: [], + + twoWayBindings: twoWayBindings, + + parseObjectLiteral: parseObjectLiteral, + + preProcessBindings: preProcessBindings, + + keyValueArrayContainsKey: function(keyValueArray, key) { + for (var i = 0; i < keyValueArray.length; i++) + if (keyValueArray[i]['key'] == key) + return true; + return false; + }, + + // Internal, private KO utility for updating model properties from within bindings + // property: If the property being updated is (or might be) an observable, pass it here + // If it turns out to be a writable observable, it will be written to directly + // allBindings: An object with a get method to retrieve bindings in the current execution context. + // This will be searched for a '_ko_property_writers' property in case you're writing to a non-observable + // key: The key identifying the property to be written. Example: for { hasFocus: myValue }, write to 'myValue' by specifying the key 'hasFocus' + // value: The value to be written + // checkIfDifferent: If true, and if the property being written is a writable observable, the value will only be written if + // it is !== existing value on that writable observable + writeValueToProperty: function(property, allBindings, key, value, checkIfDifferent) { + if (!property || !ko.isObservable(property)) { + var propWriters = allBindings.get('_ko_property_writers'); + if (propWriters && propWriters[key]) + propWriters[key](value); + } else if (ko.isWriteableObservable(property) && (!checkIfDifferent || property.peek() !== value)) { + property(value); + } + } + }; +})(); + +ko.exportSymbol('expressionRewriting', ko.expressionRewriting); +ko.exportSymbol('expressionRewriting.bindingRewriteValidators', ko.expressionRewriting.bindingRewriteValidators); +ko.exportSymbol('expressionRewriting.parseObjectLiteral', ko.expressionRewriting.parseObjectLiteral); +ko.exportSymbol('expressionRewriting.preProcessBindings', ko.expressionRewriting.preProcessBindings); + +// Making bindings explicitly declare themselves as "two way" isn't ideal in the long term (it would be better if +// all bindings could use an official 'property writer' API without needing to declare that they might). However, +// since this is not, and has never been, a public API (_ko_property_writers was never documented), it's acceptable +// as an internal implementation detail in the short term. +// For those developers who rely on _ko_property_writers in their custom bindings, we expose _twoWayBindings as an +// undocumented feature that makes it relatively easy to upgrade to KO 3.0. However, this is still not an official +// public API, and we reserve the right to remove it at any time if we create a real public property writers API. +ko.exportSymbol('expressionRewriting._twoWayBindings', ko.expressionRewriting.twoWayBindings); + +// For backward compatibility, define the following aliases. (Previously, these function names were misleading because +// they referred to JSON specifically, even though they actually work with arbitrary JavaScript object literal expressions.) +ko.exportSymbol('jsonExpressionRewriting', ko.expressionRewriting); +ko.exportSymbol('jsonExpressionRewriting.insertPropertyAccessorsIntoJson', ko.expressionRewriting.preProcessBindings); +(function() { + // "Virtual elements" is an abstraction on top of the usual DOM API which understands the notion that comment nodes + // may be used to represent hierarchy (in addition to the DOM's natural hierarchy). + // If you call the DOM-manipulating functions on ko.virtualElements, you will be able to read and write the state + // of that virtual hierarchy + // + // The point of all this is to support containerless templates (e.g., blah) + // without having to scatter special cases all over the binding and templating code. + + // IE 9 cannot reliably read the "nodeValue" property of a comment node (see https://github.com/SteveSanderson/knockout/issues/186) + // but it does give them a nonstandard alternative property called "text" that it can read reliably. Other browsers don't have that property. + // So, use node.text where available, and node.nodeValue elsewhere + var commentNodesHaveTextProperty = document && document.createComment("test").text === ""; + + var startCommentRegex = commentNodesHaveTextProperty ? /^$/ : /^\s*ko(?:\s+([\s\S]+))?\s*$/; + var endCommentRegex = commentNodesHaveTextProperty ? /^$/ : /^\s*\/ko\s*$/; + var htmlTagsWithOptionallyClosingChildren = { 'ul': true, 'ol': true }; + + function isStartComment(node) { + return (node.nodeType == 8) && startCommentRegex.test(commentNodesHaveTextProperty ? node.text : node.nodeValue); + } + + function isEndComment(node) { + return (node.nodeType == 8) && endCommentRegex.test(commentNodesHaveTextProperty ? node.text : node.nodeValue); + } + + function getVirtualChildren(startComment, allowUnbalanced) { + var currentNode = startComment; + var depth = 1; + var children = []; + while (currentNode = currentNode.nextSibling) { + if (isEndComment(currentNode)) { + depth--; + if (depth === 0) + return children; + } + + children.push(currentNode); + + if (isStartComment(currentNode)) + depth++; + } + if (!allowUnbalanced) + throw new Error("Cannot find closing comment tag to match: " + startComment.nodeValue); + return null; + } + + function getMatchingEndComment(startComment, allowUnbalanced) { + var allVirtualChildren = getVirtualChildren(startComment, allowUnbalanced); + if (allVirtualChildren) { + if (allVirtualChildren.length > 0) + return allVirtualChildren[allVirtualChildren.length - 1].nextSibling; + return startComment.nextSibling; + } else + return null; // Must have no matching end comment, and allowUnbalanced is true + } + + function getUnbalancedChildTags(node) { + // e.g., from
OK
Another, returns: Another + // from
OK
, returns: + var childNode = node.firstChild, captureRemaining = null; + if (childNode) { + do { + if (captureRemaining) // We already hit an unbalanced node and are now just scooping up all subsequent nodes + captureRemaining.push(childNode); + else if (isStartComment(childNode)) { + var matchingEndComment = getMatchingEndComment(childNode, /* allowUnbalanced: */ true); + if (matchingEndComment) // It's a balanced tag, so skip immediately to the end of this virtual set + childNode = matchingEndComment; + else + captureRemaining = [childNode]; // It's unbalanced, so start capturing from this point + } else if (isEndComment(childNode)) { + captureRemaining = [childNode]; // It's unbalanced (if it wasn't, we'd have skipped over it already), so start capturing + } + } while (childNode = childNode.nextSibling); + } + return captureRemaining; + } + + ko.virtualElements = { + allowedBindings: {}, + + childNodes: function(node) { + return isStartComment(node) ? getVirtualChildren(node) : node.childNodes; + }, + + emptyNode: function(node) { + if (!isStartComment(node)) + ko.utils.emptyDomNode(node); + else { + var virtualChildren = ko.virtualElements.childNodes(node); + for (var i = 0, j = virtualChildren.length; i < j; i++) + ko.removeNode(virtualChildren[i]); + } + }, + + setDomNodeChildren: function(node, childNodes) { + if (!isStartComment(node)) + ko.utils.setDomNodeChildren(node, childNodes); + else { + ko.virtualElements.emptyNode(node); + var endCommentNode = node.nextSibling; // Must be the next sibling, as we just emptied the children + for (var i = 0, j = childNodes.length; i < j; i++) + endCommentNode.parentNode.insertBefore(childNodes[i], endCommentNode); + } + }, + + prepend: function(containerNode, nodeToPrepend) { + if (!isStartComment(containerNode)) { + if (containerNode.firstChild) + containerNode.insertBefore(nodeToPrepend, containerNode.firstChild); + else + containerNode.appendChild(nodeToPrepend); + } else { + // Start comments must always have a parent and at least one following sibling (the end comment) + containerNode.parentNode.insertBefore(nodeToPrepend, containerNode.nextSibling); + } + }, + + insertAfter: function(containerNode, nodeToInsert, insertAfterNode) { + if (!insertAfterNode) { + ko.virtualElements.prepend(containerNode, nodeToInsert); + } else if (!isStartComment(containerNode)) { + // Insert after insertion point + if (insertAfterNode.nextSibling) + containerNode.insertBefore(nodeToInsert, insertAfterNode.nextSibling); + else + containerNode.appendChild(nodeToInsert); + } else { + // Children of start comments must always have a parent and at least one following sibling (the end comment) + containerNode.parentNode.insertBefore(nodeToInsert, insertAfterNode.nextSibling); + } + }, + + firstChild: function(node) { + if (!isStartComment(node)) + return node.firstChild; + if (!node.nextSibling || isEndComment(node.nextSibling)) + return null; + return node.nextSibling; + }, + + nextSibling: function(node) { + if (isStartComment(node)) + node = getMatchingEndComment(node); + if (node.nextSibling && isEndComment(node.nextSibling)) + return null; + return node.nextSibling; + }, + + hasBindingValue: isStartComment, + + virtualNodeBindingValue: function(node) { + var regexMatch = (commentNodesHaveTextProperty ? node.text : node.nodeValue).match(startCommentRegex); + return regexMatch ? regexMatch[1] : null; + }, + + normaliseVirtualElementDomStructure: function(elementVerified) { + // Workaround for https://github.com/SteveSanderson/knockout/issues/155 + // (IE <= 8 or IE 9 quirks mode parses your HTML weirdly, treating closing tags as if they don't exist, thereby moving comment nodes + // that are direct descendants of
    into the preceding
  • ) + if (!htmlTagsWithOptionallyClosingChildren[ko.utils.tagNameLower(elementVerified)]) + return; + + // Scan immediate children to see if they contain unbalanced comment tags. If they do, those comment tags + // must be intended to appear *after* that child, so move them there. + var childNode = elementVerified.firstChild; + if (childNode) { + do { + if (childNode.nodeType === 1) { + var unbalancedTags = getUnbalancedChildTags(childNode); + if (unbalancedTags) { + // Fix up the DOM by moving the unbalanced tags to where they most likely were intended to be placed - *after* the child + var nodeToInsertBefore = childNode.nextSibling; + for (var i = 0; i < unbalancedTags.length; i++) { + if (nodeToInsertBefore) + elementVerified.insertBefore(unbalancedTags[i], nodeToInsertBefore); + else + elementVerified.appendChild(unbalancedTags[i]); + } + } + } + } while (childNode = childNode.nextSibling); + } + } + }; +})(); +ko.exportSymbol('virtualElements', ko.virtualElements); +ko.exportSymbol('virtualElements.allowedBindings', ko.virtualElements.allowedBindings); +ko.exportSymbol('virtualElements.emptyNode', ko.virtualElements.emptyNode); +//ko.exportSymbol('virtualElements.firstChild', ko.virtualElements.firstChild); // firstChild is not minified +ko.exportSymbol('virtualElements.insertAfter', ko.virtualElements.insertAfter); +//ko.exportSymbol('virtualElements.nextSibling', ko.virtualElements.nextSibling); // nextSibling is not minified +ko.exportSymbol('virtualElements.prepend', ko.virtualElements.prepend); +ko.exportSymbol('virtualElements.setDomNodeChildren', ko.virtualElements.setDomNodeChildren); +(function() { + var defaultBindingAttributeName = "data-bind"; + + ko.bindingProvider = function() { + this.bindingCache = {}; + }; + + ko.utils.extend(ko.bindingProvider.prototype, { + 'nodeHasBindings': function(node) { + switch (node.nodeType) { + case 1: return node.getAttribute(defaultBindingAttributeName) != null; // Element + case 8: return ko.virtualElements.hasBindingValue(node); // Comment node + default: return false; + } + }, + + 'getBindings': function(node, bindingContext) { + var bindingsString = this['getBindingsString'](node, bindingContext); + return bindingsString ? this['parseBindingsString'](bindingsString, bindingContext, node) : null; + }, + + 'getBindingAccessors': function(node, bindingContext) { + var bindingsString = this['getBindingsString'](node, bindingContext); + return bindingsString ? this['parseBindingsString'](bindingsString, bindingContext, node, {'valueAccessors':true}) : null; + }, + + // The following function is only used internally by this default provider. + // It's not part of the interface definition for a general binding provider. + 'getBindingsString': function(node, bindingContext) { + switch (node.nodeType) { + case 1: return node.getAttribute(defaultBindingAttributeName); // Element + case 8: return ko.virtualElements.virtualNodeBindingValue(node); // Comment node + default: return null; + } + }, + + // The following function is only used internally by this default provider. + // It's not part of the interface definition for a general binding provider. + 'parseBindingsString': function(bindingsString, bindingContext, node, options) { + try { + var bindingFunction = createBindingsStringEvaluatorViaCache(bindingsString, this.bindingCache, options); + return bindingFunction(bindingContext, node); + } catch (ex) { + ex.message = "Unable to parse bindings.\nBindings value: " + bindingsString + "\nMessage: " + ex.message; + throw ex; + } + } + }); + + ko.bindingProvider['instance'] = new ko.bindingProvider(); + + function createBindingsStringEvaluatorViaCache(bindingsString, cache, options) { + var cacheKey = bindingsString + (options && options['valueAccessors'] || ''); + return cache[cacheKey] + || (cache[cacheKey] = createBindingsStringEvaluator(bindingsString, options)); + } + + function createBindingsStringEvaluator(bindingsString, options) { + // Build the source for a function that evaluates "expression" + // For each scope variable, add an extra level of "with" nesting + // Example result: with(sc1) { with(sc0) { return (expression) } } + var rewrittenBindings = ko.expressionRewriting.preProcessBindings(bindingsString, options), + functionBody = "with($context){with($data||{}){return{" + rewrittenBindings + "}}}"; + return new Function("$context", "$element", functionBody); + } +})(); + +ko.exportSymbol('bindingProvider', ko.bindingProvider); +(function () { + ko.bindingHandlers = {}; + + // The following element types will not be recursed into during binding. In the future, we + // may consider adding