sagenb-1.0.1/000077500000000000000000000000001311436262400127525ustar00rootroot00000000000000sagenb-1.0.1/.gitignore000066400000000000000000000004071311436262400147430ustar00rootroot00000000000000# Boring file regexps: *.scssc *.sassc *~ /.hg /.hgtags *.orig *.patch *.pyc *.pyo /*.gitk-tmp* # sage files to ignore: /build /dist MANIFEST PKG-INFO release_notes.txt /sass/src/.sass-cache /sagenb/data/jmol /sagenb.egg-info sagenb/data/jsmath/fonts /setup.cfg sagenb-1.0.1/COPYING000066400000000000000000001056621311436262400140170ustar00rootroot00000000000000sagenb - a web interface for the Sage mathematical software system Copyright (c) 2009-2013, sagenb contributors (see `git log`) This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License (below) for more details. GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007 Copyright (C) 2007 Free Software Foundation, Inc. Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The GNU General Public License is a free, copyleft license for software and other kinds of works. The licenses for most software and other practical works are designed to take away your freedom to share and change the works. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change all versions of a program--to make sure it remains free software for all its users. We, the Free Software Foundation, use the GNU General Public License for most of our software; it applies also to any other work released this way by its authors. You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for them if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs, and that you know you can do these things. To protect your rights, we need to prevent others from denying you these rights or asking you to surrender the rights. Therefore, you have certain responsibilities if you distribute copies of the software, or if you modify it: responsibilities to respect the freedom of others. For example, if you distribute copies of such a program, whether gratis or for a fee, you must pass on to the recipients the same freedoms that you received. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. Developers that use the GNU GPL protect your rights with two steps: (1) assert copyright on the software, and (2) offer you this License giving you legal permission to copy, distribute and/or modify it. For the developers' and authors' protection, the GPL clearly explains that there is no warranty for this free software. For both users' and authors' sake, the GPL requires that modified versions be marked as changed, so that their problems will not be attributed erroneously to authors of previous versions. Some devices are designed to deny users access to install or run modified versions of the software inside them, although the manufacturer can do so. This is fundamentally incompatible with the aim of protecting users' freedom to change the software. The systematic pattern of such abuse occurs in the area of products for individuals to use, which is precisely where it is most unacceptable. Therefore, we have designed this version of the GPL to prohibit the practice for those products. If such problems arise substantially in other domains, we stand ready to extend this provision to those domains in future versions of the GPL, as needed to protect the freedom of users. Finally, every program is threatened constantly by software patents. States should not allow patents to restrict development and use of software on general-purpose computers, but in those that do, we wish to avoid the special danger that patents applied to a free program could make it effectively proprietary. To prevent this, the GPL assures that patents cannot be used to render the program non-free. The precise terms and conditions for copying, distribution and modification follow. TERMS AND CONDITIONS 0. Definitions. "This License" refers to version 3 of the GNU General Public License. "Copyright" also means copyright-like laws that apply to other kinds of works, such as semiconductor masks. "The Program" refers to any copyrightable work licensed under this License. Each licensee is addressed as "you". "Licensees" and "recipients" may be individuals or organizations. To "modify" a work means to copy from or adapt all or part of the work in a fashion requiring copyright permission, other than the making of an exact copy. The resulting work is called a "modified version" of the earlier work or a work "based on" the earlier work. A "covered work" means either the unmodified Program or a work based on the Program. To "propagate" a work means to do anything with it that, without permission, would make you directly or secondarily liable for infringement under applicable copyright law, except executing it on a computer or modifying a private copy. Propagation includes copying, distribution (with or without modification), making available to the public, and in some countries other activities as well. To "convey" a work means any kind of propagation that enables other parties to make or receive copies. Mere interaction with a user through a computer network, with no transfer of a copy, is not conveying. An interactive user interface displays "Appropriate Legal Notices" to the extent that it includes a convenient and prominently visible feature that (1) displays an appropriate copyright notice, and (2) tells the user that there is no warranty for the work (except to the extent that warranties are provided), that licensees may convey the work under this License, and how to view a copy of this License. If the interface presents a list of user commands or options, such as a menu, a prominent item in the list meets this criterion. 1. Source Code. The "source code" for a work means the preferred form of the work for making modifications to it. "Object code" means any non-source form of a work. A "Standard Interface" means an interface that either is an official standard defined by a recognized standards body, or, in the case of interfaces specified for a particular programming language, one that is widely used among developers working in that language. The "System Libraries" of an executable work include anything, other than the work as a whole, that (a) is included in the normal form of packaging a Major Component, but which is not part of that Major Component, and (b) serves only to enable use of the work with that Major Component, or to implement a Standard Interface for which an implementation is available to the public in source code form. A "Major Component", in this context, means a major essential component (kernel, window system, and so on) of the specific operating system (if any) on which the executable work runs, or a compiler used to produce the work, or an object code interpreter used to run it. The "Corresponding Source" for a work in object code form means all the source code needed to generate, install, and (for an executable work) run the object code and to modify the work, including scripts to control those activities. However, it does not include the work's System Libraries, or general-purpose tools or generally available free programs which are used unmodified in performing those activities but which are not part of the work. For example, Corresponding Source includes interface definition files associated with source files for the work, and the source code for shared libraries and dynamically linked subprograms that the work is specifically designed to require, such as by intimate data communication or control flow between those subprograms and other parts of the work. The Corresponding Source need not include anything that users can regenerate automatically from other parts of the Corresponding Source. The Corresponding Source for a work in source code form is that same work. 2. Basic Permissions. All rights granted under this License are granted for the term of copyright on the Program, and are irrevocable provided the stated conditions are met. This License explicitly affirms your unlimited permission to run the unmodified Program. The output from running a covered work is covered by this License only if the output, given its content, constitutes a covered work. This License acknowledges your rights of fair use or other equivalent, as provided by copyright law. You may make, run and propagate covered works that you do not convey, without conditions so long as your license otherwise remains in force. You may convey covered works to others for the sole purpose of having them make modifications exclusively for you, or provide you with facilities for running those works, provided that you comply with the terms of this License in conveying all material for which you do not control copyright. Those thus making or running the covered works for you must do so exclusively on your behalf, under your direction and control, on terms that prohibit them from making any copies of your copyrighted material outside their relationship with you. Conveying under any other circumstances is permitted solely under the conditions stated below. Sublicensing is not allowed; section 10 makes it unnecessary. 3. Protecting Users' Legal Rights From Anti-Circumvention Law. No covered work shall be deemed part of an effective technological measure under any applicable law fulfilling obligations under article 11 of the WIPO copyright treaty adopted on 20 December 1996, or similar laws prohibiting or restricting circumvention of such measures. When you convey a covered work, you waive any legal power to forbid circumvention of technological measures to the extent such circumvention is effected by exercising rights under this License with respect to the covered work, and you disclaim any intention to limit operation or modification of the work as a means of enforcing, against the work's users, your or third parties' legal rights to forbid circumvention of technological measures. 4. Conveying Verbatim Copies. You may convey verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice; keep intact all notices stating that this License and any non-permissive terms added in accord with section 7 apply to the code; keep intact all notices of the absence of any warranty; and give all recipients a copy of this License along with the Program. You may charge any price or no price for each copy that you convey, and you may offer support or warranty protection for a fee. 5. Conveying Modified Source Versions. You may convey a work based on the Program, or the modifications to produce it from the Program, in the form of source code under the terms of section 4, provided that you also meet all of these conditions: a) The work must carry prominent notices stating that you modified it, and giving a relevant date. b) The work must carry prominent notices stating that it is released under this License and any conditions added under section 7. This requirement modifies the requirement in section 4 to "keep intact all notices". c) You must license the entire work, as a whole, under this License to anyone who comes into possession of a copy. This License will therefore apply, along with any applicable section 7 additional terms, to the whole of the work, and all its parts, regardless of how they are packaged. This License gives no permission to license the work in any other way, but it does not invalidate such permission if you have separately received it. d) If the work has interactive user interfaces, each must display Appropriate Legal Notices; however, if the Program has interactive interfaces that do not display Appropriate Legal Notices, your work need not make them do so. A compilation of a covered work with other separate and independent works, which are not by their nature extensions of the covered work, and which are not combined with it such as to form a larger program, in or on a volume of a storage or distribution medium, is called an "aggregate" if the compilation and its resulting copyright are not used to limit the access or legal rights of the compilation's users beyond what the individual works permit. Inclusion of a covered work in an aggregate does not cause this License to apply to the other parts of the aggregate. 6. Conveying Non-Source Forms. You may convey a covered work in object code form under the terms of sections 4 and 5, provided that you also convey the machine-readable Corresponding Source under the terms of this License, in one of these ways: a) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by the Corresponding Source fixed on a durable physical medium customarily used for software interchange. b) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by a written offer, valid for at least three years and valid for as long as you offer spare parts or customer support for that product model, to give anyone who possesses the object code either (1) a copy of the Corresponding Source for all the software in the product that is covered by this License, on a durable physical medium customarily used for software interchange, for a price no more than your reasonable cost of physically performing this conveying of source, or (2) access to copy the Corresponding Source from a network server at no charge. c) Convey individual copies of the object code with a copy of the written offer to provide the Corresponding Source. This alternative is allowed only occasionally and noncommercially, and only if you received the object code with such an offer, in accord with subsection 6b. d) Convey the object code by offering access from a designated place (gratis or for a charge), and offer equivalent access to the Corresponding Source in the same way through the same place at no further charge. You need not require recipients to copy the Corresponding Source along with the object code. If the place to copy the object code is a network server, the Corresponding Source may be on a different server (operated by you or a third party) that supports equivalent copying facilities, provided you maintain clear directions next to the object code saying where to find the Corresponding Source. Regardless of what server hosts the Corresponding Source, you remain obligated to ensure that it is available for as long as needed to satisfy these requirements. e) Convey the object code using peer-to-peer transmission, provided you inform other peers where the object code and Corresponding Source of the work are being offered to the general public at no charge under subsection 6d. A separable portion of the object code, whose source code is excluded from the Corresponding Source as a System Library, need not be included in conveying the object code work. A "User Product" is either (1) a "consumer product", which means any tangible personal property which is normally used for personal, family, or household purposes, or (2) anything designed or sold for incorporation into a dwelling. In determining whether a product is a consumer product, doubtful cases shall be resolved in favor of coverage. For a particular product received by a particular user, "normally used" refers to a typical or common use of that class of product, regardless of the status of the particular user or of the way in which the particular user actually uses, or expects or is expected to use, the product. A product is a consumer product regardless of whether the product has substantial commercial, industrial or non-consumer uses, unless such uses represent the only significant mode of use of the product. "Installation Information" for a User Product means any methods, procedures, authorization keys, or other information required to install and execute modified versions of a covered work in that User Product from a modified version of its Corresponding Source. The information must suffice to ensure that the continued functioning of the modified object code is in no case prevented or interfered with solely because modification has been made. If you convey an object code work under this section in, or with, or specifically for use in, a User Product, and the conveying occurs as part of a transaction in which the right of possession and use of the User Product is transferred to the recipient in perpetuity or for a fixed term (regardless of how the transaction is characterized), the Corresponding Source conveyed under this section must be accompanied by the Installation Information. But this requirement does not apply if neither you nor any third party retains the ability to install modified object code on the User Product (for example, the work has been installed in ROM). The requirement to provide Installation Information does not include a requirement to continue to provide support service, warranty, or updates for a work that has been modified or installed by the recipient, or for the User Product in which it has been modified or installed. Access to a network may be denied when the modification itself materially and adversely affects the operation of the network or violates the rules and protocols for communication across the network. Corresponding Source conveyed, and Installation Information provided, in accord with this section must be in a format that is publicly documented (and with an implementation available to the public in source code form), and must require no special password or key for unpacking, reading or copying. 7. Additional Terms. "Additional permissions" are terms that supplement the terms of this License by making exceptions from one or more of its conditions. Additional permissions that are applicable to the entire Program shall be treated as though they were included in this License, to the extent that they are valid under applicable law. If additional permissions apply only to part of the Program, that part may be used separately under those permissions, but the entire Program remains governed by this License without regard to the additional permissions. When you convey a copy of a covered work, you may at your option remove any additional permissions from that copy, or from any part of it. (Additional permissions may be written to require their own removal in certain cases when you modify the work.) You may place additional permissions on material, added by you to a covered work, for which you have or can give appropriate copyright permission. Notwithstanding any other provision of this License, for material you add to a covered work, you may (if authorized by the copyright holders of that material) supplement the terms of this License with terms: a) Disclaiming warranty or limiting liability differently from the terms of sections 15 and 16 of this License; or b) Requiring preservation of specified reasonable legal notices or author attributions in that material or in the Appropriate Legal Notices displayed by works containing it; or c) Prohibiting misrepresentation of the origin of that material, or requiring that modified versions of such material be marked in reasonable ways as different from the original version; or d) Limiting the use for publicity purposes of names of licensors or authors of the material; or e) Declining to grant rights under trademark law for use of some trade names, trademarks, or service marks; or f) Requiring indemnification of licensors and authors of that material by anyone who conveys the material (or modified versions of it) with contractual assumptions of liability to the recipient, for any liability that these contractual assumptions directly impose on those licensors and authors. All other non-permissive additional terms are considered "further restrictions" within the meaning of section 10. If the Program as you received it, or any part of it, contains a notice stating that it is governed by this License along with a term that is a further restriction, you may remove that term. If a license document contains a further restriction but permits relicensing or conveying under this License, you may add to a covered work material governed by the terms of that license document, provided that the further restriction does not survive such relicensing or conveying. If you add terms to a covered work in accord with this section, you must place, in the relevant source files, a statement of the additional terms that apply to those files, or a notice indicating where to find the applicable terms. Additional terms, permissive or non-permissive, may be stated in the form of a separately written license, or stated as exceptions; the above requirements apply either way. 8. Termination. You may not propagate or modify a covered work except as expressly provided under this License. Any attempt otherwise to propagate or modify it is void, and will automatically terminate your rights under this License (including any patent licenses granted under the third paragraph of section 11). However, if you cease all violation of this License, then your license from a particular copyright holder is reinstated (a) provisionally, unless and until the copyright holder explicitly and finally terminates your license, and (b) permanently, if the copyright holder fails to notify you of the violation by some reasonable means prior to 60 days after the cessation. Moreover, your license from a particular copyright holder is reinstated permanently if the copyright holder notifies you of the violation by some reasonable means, this is the first time you have received notice of violation of this License (for any work) from that copyright holder, and you cure the violation prior to 30 days after your receipt of the notice. Termination of your rights under this section does not terminate the licenses of parties who have received copies or rights from you under this License. If your rights have been terminated and not permanently reinstated, you do not qualify to receive new licenses for the same material under section 10. 9. Acceptance Not Required for Having Copies. You are not required to accept this License in order to receive or run a copy of the Program. Ancillary propagation of a covered work occurring solely as a consequence of using peer-to-peer transmission to receive a copy likewise does not require acceptance. However, nothing other than this License grants you permission to propagate or modify any covered work. These actions infringe copyright if you do not accept this License. Therefore, by modifying or propagating a covered work, you indicate your acceptance of this License to do so. 10. Automatic Licensing of Downstream Recipients. Each time you convey a covered work, the recipient automatically receives a license from the original licensors, to run, modify and propagate that work, subject to this License. You are not responsible for enforcing compliance by third parties with this License. An "entity transaction" is a transaction transferring control of an organization, or substantially all assets of one, or subdividing an organization, or merging organizations. If propagation of a covered work results from an entity transaction, each party to that transaction who receives a copy of the work also receives whatever licenses to the work the party's predecessor in interest had or could give under the previous paragraph, plus a right to possession of the Corresponding Source of the work from the predecessor in interest, if the predecessor has it or can get it with reasonable efforts. You may not impose any further restrictions on the exercise of the rights granted or affirmed under this License. For example, you may not impose a license fee, royalty, or other charge for exercise of rights granted under this License, and you may not initiate litigation (including a cross-claim or counterclaim in a lawsuit) alleging that any patent claim is infringed by making, using, selling, offering for sale, or importing the Program or any portion of it. 11. Patents. A "contributor" is a copyright holder who authorizes use under this License of the Program or a work on which the Program is based. The work thus licensed is called the contributor's "contributor version". A contributor's "essential patent claims" are all patent claims owned or controlled by the contributor, whether already acquired or hereafter acquired, that would be infringed by some manner, permitted by this License, of making, using, or selling its contributor version, but do not include claims that would be infringed only as a consequence of further modification of the contributor version. For purposes of this definition, "control" includes the right to grant patent sublicenses in a manner consistent with the requirements of this License. Each contributor grants you a non-exclusive, worldwide, royalty-free patent license under the contributor's essential patent claims, to make, use, sell, offer for sale, import and otherwise run, modify and propagate the contents of its contributor version. In the following three paragraphs, a "patent license" is any express agreement or commitment, however denominated, not to enforce a patent (such as an express permission to practice a patent or covenant not to sue for patent infringement). To "grant" such a patent license to a party means to make such an agreement or commitment not to enforce a patent against the party. If you convey a covered work, knowingly relying on a patent license, and the Corresponding Source of the work is not available for anyone to copy, free of charge and under the terms of this License, through a publicly available network server or other readily accessible means, then you must either (1) cause the Corresponding Source to be so available, or (2) arrange to deprive yourself of the benefit of the patent license for this particular work, or (3) arrange, in a manner consistent with the requirements of this License, to extend the patent license to downstream recipients. "Knowingly relying" means you have actual knowledge that, but for the patent license, your conveying the covered work in a country, or your recipient's use of the covered work in a country, would infringe one or more identifiable patents in that country that you have reason to believe are valid. If, pursuant to or in connection with a single transaction or arrangement, you convey, or propagate by procuring conveyance of, a covered work, and grant a patent license to some of the parties receiving the covered work authorizing them to use, propagate, modify or convey a specific copy of the covered work, then the patent license you grant is automatically extended to all recipients of the covered work and works based on it. A patent license is "discriminatory" if it does not include within the scope of its coverage, prohibits the exercise of, or is conditioned on the non-exercise of one or more of the rights that are specifically granted under this License. You may not convey a covered work if you are a party to an arrangement with a third party that is in the business of distributing software, under which you make payment to the third party based on the extent of your activity of conveying the work, and under which the third party grants, to any of the parties who would receive the covered work from you, a discriminatory patent license (a) in connection with copies of the covered work conveyed by you (or copies made from those copies), or (b) primarily for and in connection with specific products or compilations that contain the covered work, unless you entered into that arrangement, or that patent license was granted, prior to 28 March 2007. Nothing in this License shall be construed as excluding or limiting any implied license or other defenses to infringement that may otherwise be available to you under applicable patent law. 12. No Surrender of Others' Freedom. If conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot convey a covered work so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not convey it at all. For example, if you agree to terms that obligate you to collect a royalty for further conveying from those to whom you convey the Program, the only way you could satisfy both those terms and this License would be to refrain entirely from conveying the Program. 13. Use with the GNU Affero General Public License. Notwithstanding any other provision of this License, you have permission to link or combine any covered work with a work licensed under version 3 of the GNU Affero General Public License into a single combined work, and to convey the resulting work. The terms of this License will continue to apply to the part which is the covered work, but the special requirements of the GNU Affero General Public License, section 13, concerning interaction through a network will apply to the combination as such. 14. Revised Versions of this License. The Free Software Foundation may publish revised and/or new versions of the GNU General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies that a certain numbered version of the GNU General Public License "or any later version" applies to it, you have the option of following the terms and conditions either of that numbered version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of the GNU General Public License, you may choose any version ever published by the Free Software Foundation. If the Program specifies that a proxy can decide which future versions of the GNU General Public License can be used, that proxy's public statement of acceptance of a version permanently authorizes you to choose that version for the Program. Later license versions may give you additional or different permissions. However, no additional obligations are imposed on any author or copyright holder as a result of your choosing to follow a later version. 15. Disclaimer of Warranty. THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 16. Limitation of Liability. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 17. Interpretation of Sections 15 and 16. If the disclaimer of warranty and limitation of liability provided above cannot be given local legal effect according to their terms, reviewing courts shall apply local law that most closely approximates an absolute waiver of all civil liability in connection with the Program, unless a warranty or assumption of liability accompanies a copy of the Program in return for a fee. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively state the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . Also add information on how to contact you by electronic and paper mail. If the program does terminal interaction, make it output a short notice like this when it starts in an interactive mode: Copyright (C) This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, your program's commands might be different; for a GUI interface, you would use an "about box". You should also get your employer (if you work as a programmer) or school, if any, to sign a "copyright disclaimer" for the program, if necessary. For more information on this, and how to apply and follow the GNU GPL, see . The GNU General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. But first, please read . sagenb-1.0.1/Changes000066400000000000000000000052611311436262400142510ustar00rootroot000000000000001.0 May 24 2017 - variours py3 compatibility changes - absolute imports - see https://github.com/sagemath/sagenb/commits/master for complete list 0.13 May 9 2016 - fix location of stylesheet with Sphinx 1.4 - improvements towards Python 3 compatibility 0.12 Apr 7 2016 - package sagenb as a normal Python package - remove bundled mathjax 0.11.7 Feb 23 2016 - change imports for Sage changes - small documentation fixes - use new Sage documentation variables 0.11.6.1 Dec 14 2015 - fix doctests 0.11.6 Dec 12 2015 - pexpect upgrade - fixes for autoescape 0.11.5 Dec 02 2015 - Ukrainian translation - security update in Jinja2 - file move update and other smaller changes 0.11.4 Jan 29 2015 - Email default changed to empty list 0.11.3 Jan 22 2015 - Spanish language update - some smaller fixes - allow custom server_pool communication directory - update various instructions and manifest 0.11.2 Dec 22 2014 - Improved language support - Fixed several bugs - init.sage works again - Email configuration for crash report 0.11.1 Nov 10 2014 - Live documentation fixes - Release Manager and other developer instruction updates 0.11.0 Oct 27 2014 - Update default color selector in interacts - Update jQuery - Update to Jsmol for js 3d graphic default (trac #16004) - Make snapshots work again - A few other minor fixes 0.10.8.3 Sep 21 2014 - New Spanish translation - New French translation - Update sagenb and documentation for new development workflow - Numerous bug fixes for settings, jmol, user management, and text fields 0.10.8.2 Feb 03 2014 - Change doctest (#197) 0.10.8.1 Feb 03 2014 - Fix a bug in import of latex macros for mathjax (#195) 0.10.8 Dec 29 2013 - Add Flask-OldSessions to dependency list and fix #184 - Restrict pytz version to at most 2013b 0.10.7.3 Dec 22 2013 - Minor fix for trac ticket #15510 - Fix for Issue #135 - unicode "open your browser" message - change URL for bug reports to sagemath.com/report-issue 0.10.7.2 Aug 08 2013 - Minor fix for trac ticket 14469 0.10.7.1 Jun 25 2013 - revert published worksheet sanitization as it is not optional 0.10.7 Jun 24 2013 - Update license to GPLv3+ from GPLv2+ - Update MathJax to 2.2 - Allow new doctest continuation format in livedocs - Sanitization for published worksheets - Various bug fixes 0.10.6 Apr 27 2013 - Allow more actions in live documentation. - Add tools for converting sws files to rst files. - Add parameter "doc_timeout" for controlling timeouts of live worksheets. 0.10.5 Apr 01 2013 - Add support for LDAP authentication. - Remove the old notebook. sagenb-1.0.1/HACKING.rst000066400000000000000000000056271311436262400145620ustar00rootroot00000000000000================================ Development of the Sage notebook ================================ Unlike most other parts of Sage (as of January 2013), development of sagenb is done on a moving target, namely a git repository on GitHub. Rather than making changes to the version of sagenb that came with your copy of Sage, please first clone `the sagenb git repository`_ and install it into your copy of Sage before you start coding. Details on how to do this are as follows. #. Install `the latest development version of Sage`_ from sagemath.org. #. Sign up for an account at github.com, if you don't already have one, and log in; set up your SSH keys for authentication as directed by the instructions. #. Create your own fork of sagenb on the GitHub website. To do this, go to `the sagenb git repository`_ page and click on "Fork" in the upper right corner of the webpage. #. Clone your fork of sagenb to somewhere on your local disk, for example ``~/src/sagenb-git``:: $ cd ~/src $ git clone git@github.com:/sagenb sagenb-git #. Where ``SAGE_ROOT`` represents the base path of your Sage installation, perform the following commands. If you have more than one sagenb installation in ``SAGE_ROOT/local/lib/python2.7/site-packages``, then change directory into the latest version:: $ cd SAGE_ROOT/local/lib/python2.7/site-packages/ $ mv sagenb sagenb-old $ ln -s ~/src/sagenb-git/sagenb sagenb # or wherever your clone is $ cd ~/src/sagenb-git $ SAGE_ROOT/sage --python setup.py develop $ ln -s SAGE_ROOT/sage/local/share/mathjax sagenb/data/mathjax #. You can also add the `sagenb`_ git repository as a remote branch called ``upstream``:: $ git remote add upstream git@github.com:sagemath/sagenb $ git remote update upstream This will allow you to update your local repository as other people's changes are merged. Such an operation might look something like this:: $ git remote update upstream # learn what has changed $ git checkout master # move to local master $ git merge upstream/master # merge changes to local master This completes the installation process. Now you can modify files in your ``sagenb-git`` directory and submit your modifications to us using pull requests on GitHub. (A full walkthrough of using git and GitHub are beyond the scope of this file -- for more information see `the relevant section in the Sage manual`_.) If you ever need to switch to using another Sage installation for your sagenb development, you only need to repeat step 5 with the new value of ``SAGE_ROOT``. .. _the sagenb git repository: http://github.com/sagemath/sagenb .. _the latest development version of Sage: http://sagemath.org/download-latest.html .. _the relevant section in the Sage manual: http://sagemath.org/doc/developer/sagenb/index.html sagenb-1.0.1/INSTALL.rst000066400000000000000000000016741311436262400146220ustar00rootroot00000000000000================================= Installation of the Sage notebook ================================= Currently, standalone usage of the Sage notebook is not supported, though this is one of our goals for the future. For now, please use sagenb with a copy of `Sage`_. The `latest version of Sage`_ should come with a somewhat recent version of the Sage notebook, and the `latest development version of Sage`_ a possibly more recent version. Alternatively, see HACKING.rst for instructions on how to install the truly latest, development version of sagenb into an already installed copy of Sage. This is only recommended for people who want to modify the code of sagenb, since the development version may be buggy or otherwise unsuitable for daily use (standard disclaimer). .. _Sage: http://sagemath.org/ .. _latest version of Sage: http://sagemath.org/download.html .. _latest development version of Sage: http://sagemath.org/download-latest.html sagenb-1.0.1/MANIFEST.in000066400000000000000000000003371311436262400145130ustar00rootroot00000000000000graft sagenb graft sass graft util prune sass/src/.sass-cache include *.txt *.rst *.md MANIFEST.in .gitignore dist.sh COPYING Changes prune .git global-exclude *.pyc *.pyo *.orig *.rej *~ \#* *\# *.sassc *.scssc *.DS_Store sagenb-1.0.1/README.rst000066400000000000000000000107041311436262400144430ustar00rootroot00000000000000.. nodoctest .. This README does not explain how to handle installation into versions of Sage which do not yet ship the flask notebook, as the packaging of the notebook's dependencies is still in flux. Please see http://code.google.com/r/jasongrout-flask-sagenb/ for more information. # XXX 2011-12-22 This is the standalone Sage Notebook. Most of the notebook does not depend on having Sage installed. Only a few miscellaneous functions are imported from Sage. We welcome help in making the notebook completely independent from Sage, or indeed, any other help with the Sage notebook. Sage notebook development discussions happen on the sage-notebook_ mailing list. .. _sage-notebook: http://groups.google.com/group/sage-notebook Installation ============ Install Sage, then do ``sage -python setup.py install`` in the current directory. Then run the notebook from within Sage as follows:: sage: import sagenb.notebook.notebook_object as nb sage: nb.notebook(directory="mynotebook") This will create a directory ``mynotebook.sagenb``, and all notebook data is stored in that directory. SSL support ----------- SSL is required for OpenID and HTTPS support in the notebook. OpenID only requires Python's built-in SSL support, whereas HTTPS support also requires the Python library pyOpenSSL. In order to ensure that these are installed, please follow the instructions in Sage's own README file (look for the section about SSL). If you don't intend to use OpenID for user logins, or HTTPS for connecting to the server, you can safely ignore this section. In particular, if you're installing a copy of Sage for your personal use only, you probably won't need OpenID or HTTPS support in the notebook. LDAP authentication ------------------- HTTPS support in the Python library is required to download and install files, in order to install LDAP authentication support. To enable HTTPS support read the section on SSL in Sage's own README file. Enabling LDAP authentication also requires one to install the LDAP development headers. You can install the LDAP development headers to your system by using your package manager. For instance, on a Debian/Ubuntu Linux system you may install LDAP and SSL by running the following command:: $ sudo apt-get install libldap2-dev libsasl2-dev libssl-dev Next, use the following commands to install the python-ldap package in Sage:: $ /path/to/sage -sh $ easy_install python-ldap Once python-ldap is installed, (re)start the notebook server and the options to setup LDAP authentication will be visible in the "Notebook Settings" section of the "Settings." Development =========== Development and issue tracking of sagenb happens primarily on Github at https://github.com/sagemath/sagenb, with certain discussions at the sage-notebook Google group https://groups.google.com/forum/#!forum/sage-notebook. Instructions for getting started with sagenb development are found in the file ``HACKING.rst``, including how to link a local clone of the source to an existing Sage installation. See the Sage Developer's guide, part of the Sage documentation, at http://www.sagemath.org/doc/developer/index.html for some further instructions. There is also a useful, if somewhat outdated, overview of the directory structure, evaluation and serving flow at http://wiki.sagemath.org/devel/SageNotebook Stylesheets (CSS) ----------------- See ``sass/readme.txt`` for information about how to use sagenb's SCSS files to update its CSS *properly*. Localization ------------ The Sage notebook has various localizations available, and welcomes updates to those as well as new ones. The current localizations are available in ``sagenb/translations``. The file ``util/translations.py`` encapsulates much of the Python Babel localization utility in an easy-to-use interface meant for the Sage notebook. We recommend its use to update and create new translations. Full help is available by running the file in the Sage Python shell with the ``-h`` argument:: cd $SAGENB_ROOT sage -python ./util/translations.py -h A more advanced introduction is in preparation. Release Instructions -------------------- Currently, sagenb is an upstream project from Sage proper. That means any new sagenb release needs to be packaged properly in order to be included in Sage. Read ``ReleaseInstr.md`` for step-by-step details on how to create such a release, including minor changes needed on the Sage side to ``build/pkgs/sagenb/package-version.txt`` and the checksum file. sagenb-1.0.1/ReleaseInstr.md000066400000000000000000000102661311436262400157010ustar00rootroot00000000000000## Steps to create a Sagenb package Throughout the steps below, replace `` with the actual version, for example, `0.10.8.3`. Also, we will assume that `github.org/sagemath/sagenb` is present as `upstream` remote repository in your local `SAGENB_ROOT`. 1. It wouldn't hurt to make sure the notebook actually runs before you start, or alerting to any major changes needed in localizations, either. 1. Any new or updated dependencies should be corrected in the file `setup.py`. 1. Change into the sagenb git directory, and update to the latest `upstream/master`. We assume that all the required merges to the `upstream/master` have happened already and that your master is at a previous or current commit (same hash) of `upstream/master`; if not, use `git merge upstream/master` instead of `git rebase`. ```sh cd SAGENB_ROOT git checkout master git fetch upstream git rebase upstream/master ``` 1. Edit `Changes` file to highlight the main changes. Edit `setup.py` to update the version for Sagenb (this is *important*). Example diff: ```diff --- a/setup.py +++ b/setup.py @@ -44,7 +44,7 @@ if __name__ == '__main__': distutils.log.set_threshold(distutils.log.DEBUG) code = setup(name = 'sagenb', - version = '0.10.8.2', + version = '0.10.8.3', description = 'The Sage Notebook', license = 'GNU General Public License (GPL) v3+', author = 'William Stein et al.', ``` 1. Commit the updated version change. ```sh git add Changes git add setup.py git commit -m "Update Sagenb version to " ``` 1. Create the sagenb tarball: ```sh ./dist.sh ``` 1. Let Sage know about the new sagenb and update its checksums, and then try out the new sagenb and test it. Here we are not yet committing, in case of any errors. ```sh cd SAGE_ROOT echo "" > build/pkgs/sagenb/package-version.txt ./sage --fix-pkg-checksums ./sage -tp --long --sagenb # test sagenb make ptestlong # test sage ``` If you are not using your sagenb repository directly inside Sage as described in the file HACKING.rst, you may need to use the following command before actually testing it out. ```sh ./sage -f sagenb # if necessary to install the new sagenb ``` 1. (Optional) Check that the Selenium tests pass. 1. (Optional) If you encounter errors or realize there was a mistake, you can try to fix them back in sagenb, after reverting the last change (the updated sagenb version). ```sh cd SAGENB_ROOT git reset --mixed HEAD^ git commit -m 'Fix doctests' # or whatever is appropriate git add Changes git add setup.py git commit ``` Now return to the previous steps for creating the distribution and new tar files, update checksums etc. as needed, and then proceed. 1. Now we can create a branch for the ticket ``, commit our changes, and push to Trac. Warning: do not use `git commit -a` unless you are sure (see `git status`) that you don't have anything else in your directory that shouldn't be added; otherwise do `git add` the correct files first. ```sh git checkout develop -b ticket/ # or "git trac create" or "git trac checkout", etc git commit -a -m "Upgrade sagenb to version " ./sage -tp --long --sagenb # test sagenb again make ptestlong # test sage again if need be git trac push ``` You will want to upload the sagenb tar.bz2 file somewhere convenient and put a link to it on the appropriate Trac ticket as well. 1. Now that everything is fine, update the sagenb in Github with the new changes. ```sh cd SAGENB_ROOT git tag git push upstream master git checkout release git merge git push upstream release git push upstream --tags # This will automatically create sagenb.tar.gz in Github ``` sagenb-1.0.1/dist.sh000077500000000000000000000001671311436262400142600ustar00rootroot00000000000000#!/usr/bin/env bash # This script creates a new tarball for SageNB. rm -rf dist exec ./setup.py sdist --format=bztar sagenb-1.0.1/sagenb/000077500000000000000000000000001311436262400142115ustar00rootroot00000000000000sagenb-1.0.1/sagenb/__init__.py000066400000000000000000000000661311436262400163240ustar00rootroot00000000000000# -*- coding: utf-8 -* # init from . import storage sagenb-1.0.1/sagenb/babel.cfg000066400000000000000000000007441311436262400157440ustar00rootroot00000000000000#To find translatable strings, #run on terminal: pybabel -v extract -F /path/to/babel.cfg /path/to/project -o name_of_project.pot #It'll create the file /path/to/project/name_of_project.pot [python: **/sagenb/notebook/**.py] [python: **/sagenb/flask_version/**.py] [jinja2: **/sagenb/data/sage/html/**.html] encoding = utf-8 extensions=jinja2.ext.autoescape,jinja2.ext.with_ [jinja2: **/sagenb/data/sage/js/**.js] encoding = utf-8 extensions=jinja2.ext.autoescape,jinja2.ext.with_ sagenb-1.0.1/sagenb/data/000077500000000000000000000000001311436262400151225ustar00rootroot00000000000000sagenb-1.0.1/sagenb/data/graph_editor/000077500000000000000000000000001311436262400175715ustar00rootroot00000000000000sagenb-1.0.1/sagenb/data/graph_editor/README.txt000066400000000000000000000053641311436262400212770ustar00rootroot00000000000000SAGE GRAPH EDITOR AUTHORS: - Radoslav Kirov - Mitesh Patel The following files in this directory are needed to run the graph editor: a. sage/graphs/graph_editor.py b. graph_editor.html c. graph_editor.js d. processing.editor.min.js What do they do? Evaluating graph_editor(G) in an input cell generates the code/markup for an inline frame, which the notebook inserts into the corresponding output cell. The iframe loads (b) as its content. In turn, (b) draws in jQuery / UI, the layout algorithms in (c), and the HTML5 canvas rendering engine in (d). Here's how the server and editor communicate with each other: Server -> Editor: The Python function graph_to_js() in (a) makes a string representation of the relevant graph data (currently, adjacency lists and vertex coordinates) and puts it in a hidden HTML input element. This element goes into the relevant cell's output. How does the editor find the data? The function just adds the cell ID to the editor's URL, e.g., [...]/graph_editor.html?cell_id=7. When the iframe loads, the setup code in graph_editor.js extracts the ID, gets the data, and creates a visual representation of the graph. Processing.js supplies the graphics and dynamic primitives, i.e., for drawing circles and lines, controlling animation, etc. Editor -> Server: When the user clicks "Save", the notebook gets the latest graph data, formats it for the Sage library's graph methods (e.g., the Graph constructor and Graph.set_pos), optionally replaces the cell's input (see the replace_input option in (a)), and evaluates the cell. File (d) is slightly modified version of the JS library Processing.JS (http://processingjs.org/). The only change is that mouse events are attached to the whole document, rather than to the current element. attach(curElement,"mousemove",function(e)... ----> attach(document,"mousemove",function(e)... This makes it possible to drag vertices outside the canvas for the erasing maneuver. For reference, the original Processing.JS library and its minified source files are also included here: e. processing.js f. processing.min.js There's also an un-minified (http://jsbeautifier.org/) version of processing.editor.min.js: g. processing.editor.js Possibilities for the future: * Improved or alternate layout algorithms. The function Edge.prototype.shrink., in graph_editor.js, runs the current spring model. * Directed graphs! We could use Bezier curves here. * Edge and vertex colors. * Edge and vertex labels. * Use JSON for the graph data. This is much safer than eval. It would also help if it were possible to construct Graphs directly from stringified JSON objects. Have fun! sagenb-1.0.1/sagenb/data/graph_editor/graph_editor.html000066400000000000000000000046601311436262400231340ustar00rootroot00000000000000 Graph Editor
live:
variable name:
strength:
length:
  • move vertex

    Vertices are draggable.
  • create vertex

    Click on empty space not too close to existing vertices.
  • select a vertex

    Click on existing vertex.
  • create/erase edge

    Select the first vertex. Click on another vertex (different than the selected one) to turn on/off (toggle) the edge between them.
  • keep the selected vertex

    Hold 'SHIFT' to perserve the selected vertex after creating/erasing an edge.
  • delete vertex

    Double click on vertex or drag to the edge for the frame (be careful, there is no UNDO yet!).
sagenb-1.0.1/sagenb/data/graph_editor/graph_editor.js000066400000000000000000000217621311436262400226060ustar00rootroot00000000000000/*global $, document, p: true, Processing, top, window */ /*jslint white: false, onevar: true, undef: true, nomen: true, eqeqeq: true, plusplus: true, bitwise: true, regexp: true, strict: true, newcap: true, immed: true */ "use strict"; var edge_list = [], nodes = [], NODES, EDGES, SIZE, NEW_RADIUS, DOUBLECLICK, LIVE, SPRING, FIXED_LENGTH, selected_node, dragged_node, dragging_flag, last_click_time, initial_x, initial_y, p, edges = [], num_vertices = null, pos = null; NODES = 10; EDGES = 20; SIZE = 350; NEW_RADIUS = 20; DOUBLECLICK = 250; LIVE = false; SPRING = 0.999; FIXED_LENGTH = 100.0; function rand(a, b) { return a + Math.floor(Math.random() * (b - a)); } function Node(x, y) { this.x = x; this.y = y; this.size = 7; } Node.prototype.display = function () { p.stroke(0); if (this.selected) { p.fill(255, 0, 0); p.ellipse(this.x, this.y, this.size, this.size); } else { p.fill(0); p.ellipse(this.x, this.y, this.size, this.size); } }; Node.prototype.distance_to = function (x, y) { return Math.sqrt(Math.pow((x - this.x), 2) + Math.pow((y - this.y), 2)); }; Node.prototype.is_hit = function (x, y) { return Math.abs(x - this.x) < this.size && Math.abs(y - this.y) < this.size; }; function Edge(node1, node2) { this.node1 = node1; this.node2 = node2; } Edge.prototype.shrink = function () { var d, gx, gy, mx, my; mx = (this.node1.x + this.node2.x) / 2; my = (this.node1.y + this.node2.y) / 2; if (this.node1 !== dragged_node) { d = this.node1.distance_to(mx, my); gx = mx + (this.node1.x - mx) / d * FIXED_LENGTH / 2; gy = my + (this.node1.y - my) / d * FIXED_LENGTH / 2; this.node1.x = gx + (this.node1.x - gx) * SPRING; this.node1.y = gy + (this.node1.y - gy) * SPRING; } if (this.node2 !== dragged_node) { d = this.node2.distance_to(mx, my); gx = mx + (this.node2.x - mx) / d * FIXED_LENGTH / 2; gy = my + (this.node2.y - my) / d * FIXED_LENGTH / 2; this.node2.x = gx + (this.node2.x - gx) * SPRING; this.node2.y = gy + (this.node2.y - gy) * SPRING; } }; Edge.prototype.display = function () { if (this.node1.x > SIZE || this.node1.y > SIZE || this.node1.x < 0 || this.node1.y < 0 || this.node2.x > SIZE || this.node2.y > SIZE || this.node2.x < 0 || this.node2.y < 0) { p.stroke(255, 0, 0); } else { if (this.node1.selected || this.node2.selected) { p.stroke(0, 0, 200); } else { p.stroke(0); } } p.line(this.node1.x, this.node1.y, this.node2.x, this.node2.y); }; function add_node(node) { if (nodes.indexOf(node) === -1) { nodes.push(node); } } function remove_node(node) { var edge, i, index; for (i = edge_list.length - 1; i > -1; i -= 1) { edge = edge_list[i]; if (edge.node1 === node || edge.node2 === node) { edge_list.splice(i, 1); } } index = nodes.indexOf(node); if (index !== -1) { nodes.splice(index, 1); } } function add_edge_between_nodes(node1, node2) { if (node1 === node2) { // Only simple graphs are implemented so far. return; } edge_list.push(new Edge(node1, node2)); if (nodes.indexOf(node1) === -1) { nodes.add(node1); } if (nodes.indexOf(node2) === -1) { nodes.add(node2); } } function toggle_edge(node1, node2) { var edge, existing = false, i, new_edge; if (node1 === node2) { // Only simple graphs are implemented so far. return; } new_edge = new Edge(node1, node2); for (i = edge_list.length - 1; i > -1; i -= 1) { edge = edge_list[i]; if ((edge.node1 === new_edge.node1 && edge.node2 === new_edge.node2) || (edge.node1 === new_edge.node2 && edge.node2 === new_edge.node1)) { existing = true; break; } } if (existing) { edge_list.splice(i, 1); } else { edge_list.push(new_edge); } } function set_graph() { var i, n1, n2; if (!pos) { for (i = 0; i < NODES; i += 1) { add_node(new Node(rand(0, SIZE), rand(0, SIZE))); } for (i = 0; i < EDGES; i += 1) { n1 = rand(0, NODES); n2 = rand(0, NODES); add_edge_between_nodes(nodes[n1], nodes[n2]); } } for (i = 0; i < num_vertices; i += 1) { if (pos) { add_node(new Node(pos[i][0] * 8 * SIZE / 10 + SIZE / 10, pos[i][1] * 8 * SIZE / 10 + SIZE / 10)); } else { add_node(new Node(rand(0, SIZE), rand(0, SIZE))); } } for (i = 0; i < edges.length; i += 1) { add_edge_between_nodes(nodes[edges[i][0]], nodes[edges[i][1]]); } p.draw(); } function display_graph() { var i; for (i = 0; i < edge_list.length; i += 1) { edge_list[i].display(); if (LIVE) { edge_list[i].shrink(); } } for (i = 0; i < nodes.length; i += 1) { nodes[i].display(); } } function setup() { p.size(SIZE, SIZE); set_graph(); p.rectMode(p.RADIUS); p.ellipseMode(p.RADIUS); p.noLoop(); } function update_sliders() { SPRING = (1 - 1e-2) + 1e-4 * (100 - $('#val_edge').val()); FIXED_LENGTH = $('#val_fixed_length').val(); } function draw() { update_sliders(); p.background(255); display_graph(); } function toggle_live() { if (LIVE) { LIVE = false; p.noLoop(); } else { LIVE = true; p.loop(); } } function mousePressed() { var clicked_node, closest_distance, i, new_distance; if (!LIVE) { p.loop(); } for (i = 0; i < nodes.length; i += 1) { if (nodes[i].is_hit(p.mouseX, p.mouseY)) { clicked_node = nodes[i]; break; } } if (!clicked_node) { closest_distance = SIZE; for (i = 0; i < nodes.length; i += 1) { new_distance = nodes[i].distance_to(p.mouseX, p.mouseY); if (new_distance < closest_distance) { closest_distance = new_distance; } } if (closest_distance > NEW_RADIUS) { add_node(new Node(p.mouseX, p.mouseY)); } return; } else { dragged_node = clicked_node; initial_x = dragged_node.x; initial_y = dragged_node.y; } } function mouseDragged() { if (dragged_node) { dragging_flag = true; dragged_node.x = p.mouseX; dragged_node.y = p.mouseY; } } function mouseReleased() { if (dragged_node) { if (dragging_flag) { dragging_flag = false; if (dragged_node.x > SIZE || dragged_node.y > SIZE || dragged_node.x < 0 || dragged_node.y < 0) { remove_node(dragged_node); if (selected_node === dragged_node) { selected_node = false; } dragged_node = false; } } else { if (p.millis() - last_click_time < DOUBLECLICK) { remove_node(dragged_node); if (selected_node === dragged_node) { selected_node = false; } } else if (selected_node) { toggle_edge(selected_node, dragged_node); if (!p.keyPressed) { selected_node.selected = false; selected_node = false; } else { if (selected_node === dragged_node) { selected_node.selected = false; selected_node = false; } } } else { selected_node = dragged_node; selected_node.selected = true; } } dragged_node = false; last_click_time = p.millis(); p.redraw(); } if (!LIVE) { p.noLoop(); } } function mouse_out() { if (dragged_node) { dragged_node.x = initial_x; dragged_node.y = initial_y; dragged_node = false; } } function positions_dict() { var i, out; out = "{"; for (i = 0; i < nodes.length; i += 1) { out += i + ":[" + nodes[i].x + "," + (SIZE - nodes[i].y) + "],"; } return out.substring(0, out.length - 1) + "}"; } function adjacency_lists_dict() { var edge, empty, i, j, node, out; out = "{"; for (i = 0; i < nodes.length; i += 1) { out += i + ":["; node = nodes[i]; empty = true; for (j = 0; j < edge_list.length; j += 1) { edge = edge_list[j]; if (edge.node1 === node) { if (!empty) { out += ","; } empty = false; out += nodes.indexOf(edge.node2); } if (edge.node2 === node) { if (!empty) { out+=","; } empty = false; out += nodes.indexOf(edge.node1); } } out += "],"; } return out.substring(0, out.length - 1) + "}"; } function update_sage() { return [adjacency_lists_dict(), positions_dict(), $('#graph_name').val()]; } $(document).ready(function () { var cell_id, cell_outer, loc; // Retrieve graph data and name from parent document. loc = window.location.href; cell_id = parseInt(loc.slice(loc.search('cell_id=') + 8), 10); cell_outer = $('#cell_outer_' + cell_id, top.document); eval($('#graph_data_' + cell_id, cell_outer).val()); $('#graph_name').val($('#graph_name_' + cell_id, cell_outer).val()); // Set up processing.js. p = Processing($('#canvas')[0], ''); p.setup = setup; p.draw = draw; p.mouseDragged = mouseDragged; p.mousePressed = mousePressed; p.mouseReleased = mouseReleased; p.init(); $('#help').hide(); $('#help_button').click(function () { $('#help').toggle(); }); $('#live').click(function() { toggle_live(); }); $('#slider_edge').slider({ min: 0, max: 100, value: 50, slide: function(event, ui) { $('#val_edge').val(ui.value); } }); $('#slider_fixed_length').slider({ min: 0, max: 200, value: 100, slide: function(event, ui) { $('#val_fixed_length').val(ui.value); } }); }); sagenb-1.0.1/sagenb/data/graph_editor/processing.editor.js000066400000000000000000001172061311436262400235770ustar00rootroot00000000000000(function() { this.Processing = function Processing(aElement, aCode) { if (typeof aElement == "string") aElement = document.getElementById(aElement); var p = buildProcessing(aElement); if (aCode) p.init(aCode); return p; }; function log() { try { console.log.apply(console, arguments); } catch(e) { try { opera.postError.apply(opera, arguments); } catch(e) {} } } var parse = Processing.parse = function parse(aCode, p) { aCode = aCode.replace(/\/\/ .*\n/g, "\n"); aCode = aCode.replace(/([^\s])%([^\s])/g, "$1 % $2"); aCode = aCode.replace(/(?:static )?(\w+ )(\w+)\s*(\([^\)]*\)\s*{)/g, function(all, type, name, args) { if (name == "if" || name == "for" || name == "while") { return all; } else { return "Processing." + name + " = function " + name + args; } }); aCode = aCode.replace(/\.length\(\)/g, ".length"); aCode = aCode.replace(/([\(,]\s*)(\w+)((?:\[\])+| )\s*(\w+\s*[\),])/g, "$1$4"); aCode = aCode.replace(/([\(,]\s*)(\w+)((?:\[\])+| )\s*(\w+\s*[\),])/g, "$1$4"); aCode = aCode.replace(/new (\w+)((?:\[([^\]]*)\])+)/g, function(all, name, args) { return "new ArrayList(" + args.slice(1, -1).split("][").join(", ") + ")"; }); aCode = aCode.replace(/(?:static )?\w+\[\]\s*(\w+)\[?\]?\s*=\s*{.*?};/g, function(all) { return all.replace(/{/g, "[").replace(/}/g, "]"); }); var intFloat = /(\n\s*(?:int|float)(?:\[\])?(?:\s*|[^\(]*?,\s*))([a-z]\w*)(;|,)/i; while (intFloat.test(aCode)) { aCode = aCode.replace(new RegExp(intFloat), function(all, type, name, sep) { return type + " " + name + " = 0" + sep; }); } aCode = aCode.replace(/(?:static )?(\w+)((?:\[\])+| ) *(\w+)\[?\]?(\s*[=,;])/g, function(all, type, arr, name, sep) { if (type == "return") return all; else return "var " + name + sep; }); aCode = aCode.replace(/=\s*{((.|\s)*?)};/g, function(all, data) { return "= [" + data.replace(/{/g, "[").replace(/}/g, "]") + "]"; }); aCode = aCode.replace(/static\s*{((.|\n)*?)}/g, function(all, init) { return init; }); aCode = aCode.replace(/super\(/g, "superMethod("); var classes = ["int", "float", "boolean", "string"]; function ClassReplace(all, name, extend, vars, last) { classes.push(name); var static = ""; vars = vars.replace(/final\s+var\s+(\w+\s*=\s*.*?;)/g, function(all, set) { static += " " + name + "." + set; return ""; }); return "function " + name + "() {with(this){\n " + (extend ? "var __self=this;function superMethod(){extendClass(__self,arguments," + extend + ");}\n" : "") + vars.replace(/,\s?/g, ";\n this.").replace(/\b(var |final |public )+\s*/g, "this.").replace(/this.(\w+);/g, "this.$1 = null;") + (extend ? "extendClass(this, " + extend + ");\n" : "") + "" + (typeof last == "string" ? last : name + "("); } var matchClasses = /(?:public |abstract |static )*class (\w+)\s*(?:extends\s*(\w+)\s*)?{\s*((?:.|\n)*?)\b\1\s*\(/g; var matchNoCon = /(?:public |abstract |static )*class (\w+)\s*(?:extends\s*(\w+)\s*)?{\s*((?:.|\n)*?)(Processing)/g; aCode = aCode.replace(matchClasses, ClassReplace); aCode = aCode.replace(matchNoCon, ClassReplace); var matchClass = //, m; while ((m = aCode.match(matchClass))) { var left = RegExp.leftContext, allRest = RegExp.rightContext, rest = nextBrace(allRest), className = m[1], staticVars = m[2] || ""; allRest = allRest.slice(rest.length + 1); rest = rest.replace(new RegExp("\\b" + className + "\\(([^\\)]*?)\\)\\s*{", "g"), function(all, args) { args = args.split(/,\s*?/); if (args[0].match(/^\s*$/)) args.shift(); var fn = "if ( arguments.length == " + args.length + " ) {\n"; for (var i = 0; i < args.length; i++) { fn += " var " + args[i] + " = arguments[" + i + "];\n"; } return fn; }); rest = rest.replace(/(?:public )?Processing.\w+ = function (\w+)\((.*?)\)/g, function(all, name, args) { return "ADDMETHOD(this, '" + name + "', function(" + args + ")"; }); var matchMethod = /ADDMETHOD([\s\S]*?{)/, mc; var methods = ""; while ((mc = rest.match(matchMethod))) { var prev = RegExp.leftContext, allNext = RegExp.rightContext, next = nextBrace(allNext); methods += "addMethod" + mc[1] + next + "});" rest = prev + allNext.slice(next.length + 1); } rest = methods + rest; aCode = left + rest + "\n}}" + staticVars + allRest; } aCode = aCode.replace(/Processing.\w+ = function addMethod/g, "addMethod"); function nextBrace(right) { var rest = right; var position = 0; var leftCount = 1, rightCount = 0; while (leftCount != rightCount) { var nextLeft = rest.indexOf("{"); var nextRight = rest.indexOf("}"); if (nextLeft < nextRight && nextLeft != -1) { leftCount++; rest = rest.slice(nextLeft + 1); position += nextLeft + 1; } else { rightCount++; rest = rest.slice(nextRight + 1); position += nextRight + 1; } } return right.slice(0, position - 1); } aCode = aCode.replace(/\(int\)/g, "0|"); aCode = aCode.replace(new RegExp("\\((" + classes.join("|") + ")(\\[\\])?\\)", "g"), ""); aCode = aCode.replace(/(\d+)f/g, "$1"); aCode = aCode.replace(/('[a-zA-Z0-9]')/g, "$1.charCodeAt(0)"); aCode = aCode.replace(/#([a-f0-9]{6})/ig, function(m, hex) { var num = toNumbers(hex); return "color(" + num[0] + "," + num[1] + "," + num[2] + ")"; }); function toNumbers(str) { var ret = []; str.replace(/(..)/g, function(str) { ret.push(parseInt(str, 16)); }); return ret; } return aCode; }; function buildProcessing(curElement) { var p = {}; p.PI = Math.PI; p.TWO_PI = 2 * p.PI; p.HALF_PI = p.PI / 2; p.P3D = 3; p.CORNER = 0; p.RADIUS = 1; p.CENTER_RADIUS = 1; p.CENTER = 2; p.POLYGON = 2; p.QUADS = 5; p.TRIANGLES = 6; p.POINTS = 7; p.LINES = 8; p.TRIANGLE_STRIP = 9; p.TRIANGLE_FAN = 4; p.QUAD_STRIP = 3; p.CORNERS = 10; p.CLOSE = true; p.RGB = 1; p.HSB = 2; p.CENTER = 88888880; p.CODED = 88888888; p.UP = 88888870; p.RIGHT = 88888871; p.DOWN = 88888872; p.LEFT = 88888869; p.codedKeys = [69, 70, 71, 72]; var curContext = curElement.getContext("2d"); var doFill = true; var doStroke = true; var loopStarted = false; var hasBackground = false; var doLoop = true; var looping = 0; var curRectMode = p.CORNER; var curEllipseMode = p.CENTER; var inSetup = false; var inDraw = false; var curBackground = "rgba(204,204,204,1)"; var curFrameRate = 1000; var curShape = p.POLYGON; var curShapeCount = 0; var curvePoints = []; var curTightness = 0; var opacityRange = 255; var redRange = 255; var greenRange = 255; var blueRange = 255; var pathOpen = false; var mousePressed = false; var keyPressed = false; var firstX, firstY, secondX, secondY, prevX, prevY; var curColorMode = p.RGB; var curTint = -1; var curTextSize = 12; var curTextFont = "Arial"; var getLoaded = false; var start = (new Date).getTime(); p.pmouseX = 0; p.pmouseY = 0; p.mouseX = 0; p.mouseY = 0; p.mouseButton = 0; p.mouseDragged = undefined; p.mouseMoved = undefined; p.mousePressed = undefined; p.mouseReleased = undefined; p.keyPressed = undefined; p.keyReleased = undefined; p.draw = undefined; p.setup = undefined; p.width = curElement.width - 0; p.height = curElement.height - 0; p.frameCount = 0; p.ajax = function(url) { if (window.XMLHttpRequest) { AJAX = new XMLHttpRequest(); } else { AJAX = new ActiveXObject("Microsoft.XMLHTTP"); } if (AJAX) { AJAX.open("GET", url, false); AJAX.send(null); return AJAX.responseText; } else { return false; } } p.loadStrings = function loadStrings(url) { return p.ajax(url).split("\n"); }; p.color = function color(aValue1, aValue2, aValue3, aValue4) { var aColor = ""; if (arguments.length == 3) { aColor = p.color(aValue1, aValue2, aValue3, opacityRange); } else if (arguments.length == 4) { var a = aValue4 / opacityRange; a = isNaN(a) ? 1 : a; if (curColorMode == p.HSB) { var rgb = HSBtoRGB(aValue1, aValue2, aValue3); var r = rgb[0], g = rgb[1], b = rgb[2]; } else { var r = getColor(aValue1, redRange); var g = getColor(aValue2, greenRange); var b = getColor(aValue3, blueRange); } aColor = "rgba(" + r + "," + g + "," + b + "," + a + ")"; } else if (typeof aValue1 == "string") { aColor = aValue1; if (arguments.length == 2) { var c = aColor.split(","); c[3] = (aValue2 / opacityRange) + ")"; aColor = c.join(","); } } else if (arguments.length == 2) { aColor = p.color(aValue1, aValue1, aValue1, aValue2); } else if (typeof aValue1 == "number") { aColor = p.color(aValue1, aValue1, aValue1, opacityRange); } else { aColor = p.color(redRange, greenRange, blueRange, opacityRange); } function HSBtoRGB(h, s, b) { h = (h / redRange) * 100; s = (s / greenRange) * 100; b = (b / blueRange) * 100; if (s == 0) { return [b, b, b]; } else { var hue = h % 360; var f = hue % 60; var br = Math.round(b / 100 * 255); var p = Math.round((b * (100 - s)) / 10000 * 255); var q = Math.round((b * (6000 - s * f)) / 600000 * 255); var t = Math.round((b * (6000 - s * (60 - f))) / 600000 * 255); switch (Math.floor(hue / 60)) { case 0: return [br, t, p]; case 1: return [q, br, p]; case 2: return [p, br, t]; case 3: return [p, q, br]; case 4: return [t, p, br]; case 5: return [br, p, q]; } } } function getColor(aValue, range) { return Math.round(255 * (aValue / range)); } return aColor; } p.red = function(aColor) { return parseInt(verifyChannel(aColor).slice(5)); }; p.green = function(aColor) { return parseInt(verifyChannel(aColor).split(",")[1]); }; p.blue = function(aColor) { return parseInt(verifyChannel(aColor).split(",")[2]); }; p.alpha = function(aColor) { return parseInt(parseFloat(verifyChannel(aColor).split(",")[3]) * 255); }; function verifyChannel(aColor) { if (aColor.constructor == Array) { return aColor; } else { return p.color(aColor); } } p.lerpColor = function lerpColor(c1, c2, amt) { var colors1 = p.color(c1).split(","); var r1 = parseInt(colors1[0].split("(")[1]); var g1 = parseInt(colors1[1]); var b1 = parseInt(colors1[2]); var a1 = parseFloat(colors1[3].split(")")[0]); var colors2 = p.color(c2).split(","); var r2 = parseInt(colors2[0].split("(")[1]); var g2 = parseInt(colors2[1]); var b2 = parseInt(colors2[2]); var a2 = parseFloat(colors2[3].split(")")[0]); var r = parseInt(p.lerp(r1, r2, amt)); var g = parseInt(p.lerp(g1, g2, amt)); var b = parseInt(p.lerp(b1, b2, amt)); var a = parseFloat(p.lerp(a1, a2, amt)); aColor = "rgba(" + r + "," + g + "," + b + "," + a + ")"; return aColor; } p.nf = function(num, pad) { var str = "" + num; while (pad - str.length) str = "0" + str; return str; }; p.AniSprite = function(prefix, frames) { this.images = []; this.pos = 0; for (var i = 0; i < frames; i++) { this.images.push(prefix + p.nf(i, ("" + frames).length) + ".gif"); } this.display = function(x, y) { p.image(this.images[this.pos], x, y); if (++this.pos >= frames) this.pos = 0; }; this.getWidth = function() { return getImage(this.images[0]).width; }; this.getHeight = function() { return getImage(this.images[0]).height; }; }; function buildImageObject(obj) { var pixels = obj.data; var data = p.createImage(obj.width, obj.height); if (data.__defineGetter__ && data.__lookupGetter__ && !data.__lookupGetter__("pixels")) { var pixelsDone; data.__defineGetter__("pixels", function() { if (pixelsDone) return pixelsDone; pixelsDone = []; for (var i = 0; i < pixels.length; i += 4) { pixelsDone.push(p.color(pixels[i], pixels[i + 1], pixels[i + 2], pixels[i + 3])); } return pixelsDone; }); } else { data.pixels = []; for (var i = 0; i < pixels.length; i += 4) { data.pixels.push(p.color(pixels[i], pixels[i + 1], pixels[i + 2], pixels[i + 3])); } } return data; } p.createImage = function createImage(w, h, mode) { var data = {}; data.width = w; data.height = h; data.data = []; if (curContext.createImageData) { data = curContext.createImageData(w, h); } data.pixels = new Array(w * h); data.get = function(x, y) { return this.pixels[w * y + x]; }; data._mask = null; data.mask = function(img) { this._mask = img; }; data.loadPixels = function() {}; data.updatePixels = function() {}; return data; }; p.createGraphics = function createGraphics(w, h) { var canvas = document.createElement("canvas"); var ret = buildProcessing(canvas); ret.size(w, h); ret.canvas = canvas; return ret; }; p.beginDraw = function beginDraw() {}; p.endDraw = function endDraw() {}; p.tint = function tint(rgb, a) { curTint = a; }; function getImage(img) { if (typeof img == "string") { return document.getElementById(img); } if (img.img || img.canvas) { return img.img || img.canvas; } for (var i = 0, l = img.pixels.length; i < l; i++) { var pos = i * 4; var c = (img.pixels[i] || "rgba(0,0,0,1)").slice(5, -1).split(","); img.data[pos] = parseInt(c[0]); img.data[pos + 1] = parseInt(c[1]); img.data[pos + 2] = parseInt(c[2]); img.data[pos + 3] = parseFloat(c[3]) * 100; } var canvas = document.createElement("canvas") canvas.width = img.width; canvas.height = img.height; var context = canvas.getContext("2d"); context.putImageData(img, 0, 0); img.canvas = canvas; return canvas; } p.image = function image(img, x, y, w, h) { x = x || 0; y = y || 0; var obj = getImage(img); if (curTint >= 0) { var oldAlpha = curContext.globalAlpha; curContext.globalAlpha = curTint / opacityRange; } if (arguments.length == 3) { curContext.drawImage(obj, x, y); } else { curContext.drawImage(obj, x, y, w, h); } if (curTint >= 0) { curContext.globalAlpha = oldAlpha; } if (img._mask) { var oldComposite = curContext.globalCompositeOperation; curContext.globalCompositeOperation = "darker"; p.image(img._mask, x, y); curContext.globalCompositeOperation = oldComposite; } }; p.exit = function exit() { clearInterval(looping); }; p.save = function save(file) {}; p.loadImage = function loadImage(file) { var img = document.getElementById(file); if (!img) return; var h = img.height, w = img.width; var canvas = document.createElement("canvas"); canvas.width = w; canvas.height = h; var context = canvas.getContext("2d"); context.drawImage(img, 0, 0); var data = buildImageObject(context.getImageData(0, 0, w, h)); data.img = img; return data; }; p.loadFont = function loadFont(name) { return { name: name, width: function(str) { if (curContext.mozMeasureText) return curContext.mozMeasureText(typeof str == "number" ? String.fromCharCode(str) : str) / curTextSize; else return 0; } }; }; p.textFont = function textFont(name, size) { curTextFont = name; p.textSize(size); }; p.textSize = function textSize(size) { if (size) { curTextSize = size; } }; p.textAlign = function textAlign() {}; p.text = function text(str, x, y) { if (str && curContext.mozDrawText) { curContext.save(); curContext.mozTextStyle = curTextSize + "px " + curTextFont.name; curContext.translate(x, y); curContext.mozDrawText(typeof str == "number" ? String.fromCharCode(str) : str); curContext.restore(); } }; p.print = function print(output) { alert(output); } p.println = p.print; p.char = function char(key) { return key; }; p.map = function map(value, istart, istop, ostart, ostop) { return ostart + (ostop - ostart) * ((value - istart) / (istop - istart)); }; String.prototype.replaceAll = function(re, replace) { return this.replace(new RegExp(re, "g"), replace); }; p.Point = function Point(x, y) { this.x = x; this.y = y; this.copy = function() { return new Point(x, y); } }; p.Random = function() { var haveNextNextGaussian = false; var nextNextGaussian; this.nextGaussian = function() { if (haveNextNextGaussian) { haveNextNextGaussian = false; return nextNextGaussian; } else { var v1, v2, s; do { v1 = 2 * p.random(1) - 1; v2 = 2 * p.random(1) - 1; s = v1 * v1 + v2 * v2; } while (s >= 1 || s == 0); var multiplier = Math.sqrt(-2 * Math.log(s) / s); nextNextGaussian = v2 * multiplier; haveNextNextGaussian = true; return v1 * multiplier; } }; }; p.ArrayList = function ArrayList(size, size2, size3) { var array = new Array(0 | size); if (size2) { for (var i = 0; i < size; i++) { array[i] = []; for (var j = 0; j < size2; j++) { var a = array[i][j] = size3 ? new Array(size3) : 0; for (var k = 0; k < size3; k++) { a[k] = 0; } } } } else { for (var i = 0; i < size; i++) { array[i] = 0; } } array.size = function() { return this.length; }; array.get = function(i) { return this[i]; }; array.remove = function(i) { return this.splice(i, 1); }; array.add = function(item) { return this.push(item); }; array.clone = function() { var a = new ArrayList(size); for (var i = 0; i < size; i++) { a[i] = this[i]; } return a; }; array.isEmpty = function() { return !this.length; }; array.clear = function() { this.length = 0; }; return array; }; p.colorMode = function colorMode(mode, range1, range2, range3, range4) { curColorMode = mode; if (arguments.length >= 4) { redRange = range1; greenRange = range2; blueRange = range3; } if (arguments.length == 5) { opacityRange = range4; } if (arguments.length == 2) { p.colorMode(mode, range1, range1, range1, range1); } }; p.beginShape = function beginShape(type) { curShape = type; curShapeCount = 0; curvePoints = []; }; p.endShape = function endShape(close) { if (curShapeCount != 0) { if (close || doFill) curContext.lineTo(firstX, firstY); if (doFill) curContext.fill(); if (doStroke) curContext.stroke(); curContext.closePath(); curShapeCount = 0; pathOpen = false; } if (pathOpen) { if (doFill) curContext.fill(); if (doStroke) curContext.stroke(); curContext.closePath(); curShapeCount = 0; pathOpen = false; } }; p.vertex = function vertex(x, y, x2, y2, x3, y3) { if (curShapeCount == 0 && curShape != p.POINTS) { pathOpen = true; curContext.beginPath(); curContext.moveTo(x, y); firstX = x; firstY = y; } else { if (curShape == p.POINTS) { p.point(x, y); } else if (arguments.length == 2) { if (curShape != p.QUAD_STRIP || curShapeCount != 2) curContext.lineTo(x, y); if (curShape == p.TRIANGLE_STRIP) { if (curShapeCount == 2) { p.endShape(p.CLOSE); pathOpen = true; curContext.beginPath(); curContext.moveTo(prevX, prevY); curContext.lineTo(x, y); curShapeCount = 1; } firstX = prevX; firstY = prevY; } if (curShape == p.TRIANGLE_FAN && curShapeCount == 2) { p.endShape(p.CLOSE); pathOpen = true; curContext.beginPath(); curContext.moveTo(firstX, firstY); curContext.lineTo(x, y); curShapeCount = 1; } if (curShape == p.QUAD_STRIP && curShapeCount == 3) { curContext.lineTo(prevX, prevY); p.endShape(p.CLOSE); pathOpen = true; curContext.beginPath(); curContext.moveTo(prevX, prevY); curContext.lineTo(x, y); curShapeCount = 1; } if (curShape == p.QUAD_STRIP) { firstX = secondX; firstY = secondY; secondX = prevX; secondY = prevY; } } else if (arguments.length == 4) { if (curShapeCount > 1) { curContext.moveTo(prevX, prevY); curContext.quadraticCurveTo(firstX, firstY, x, y); curShapeCount = 1; } } else if (arguments.length == 6) { curContext.bezierCurveTo(x, y, x2, y2, x3, y3); } } prevX = x; prevY = y; curShapeCount++; if (curShape == p.LINES && curShapeCount == 2 || (curShape == p.TRIANGLES) && curShapeCount == 3 || (curShape == p.QUADS) && curShapeCount == 4) { p.endShape(p.CLOSE); } }; p.curveVertex = function(x, y, x2, y2) { if (curvePoints.length < 3) { curvePoints.push([x, y]); } else { var b = [], s = 1 - curTightness; curvePoints.push([x, y]); b[0] = [curvePoints[1][0], curvePoints[1][1]]; b[1] = [curvePoints[1][0] + (s * curvePoints[2][0] - s * curvePoints[0][0]) / 6, curvePoints[1][1] + (s * curvePoints[2][1] - s * curvePoints[0][1]) / 6]; b[2] = [curvePoints[2][0] + (s * curvePoints[1][0] - s * curvePoints[3][0]) / 6, curvePoints[2][1] + (s * curvePoints[1][1] - s * curvePoints[3][1]) / 6]; b[3] = [curvePoints[2][0], curvePoints[2][1]]; if (!pathOpen) { p.vertex(b[0][0], b[0][1]); } else { curShapeCount = 1; } p.vertex(b[1][0], b[1][1], b[2][0], b[2][1], b[3][0], b[3][1]); curvePoints.shift(); } }; p.curveTightness = function(tightness) { curTightness = tightness; }; p.bezierVertex = p.vertex; p.rectMode = function rectMode(aRectMode) { curRectMode = aRectMode; }; p.imageMode = function() {}; p.ellipseMode = function ellipseMode(aEllipseMode) { curEllipseMode = aEllipseMode; }; p.dist = function dist(x1, y1, x2, y2) { return Math.sqrt(Math.pow(x2 - x1, 2) + Math.pow(y2 - y1, 2)); }; p.year = function year() { return (new Date).getYear() + 1900; }; p.month = function month() { return (new Date).getMonth(); }; p.day = function day() { return (new Date).getDay(); }; p.hour = function hour() { return (new Date).getHours(); }; p.minute = function minute() { return (new Date).getMinutes(); }; p.second = function second() { return (new Date).getSeconds(); }; p.millis = function millis() { return (new Date).getTime() - start; }; p.ortho = function ortho() {}; p.translate = function translate(x, y) { curContext.translate(x, y); }; p.scale = function scale(x, y) { curContext.scale(x, y || x); }; p.rotate = function rotate(aAngle) { curContext.rotate(aAngle); }; p.pushMatrix = function pushMatrix() { curContext.save(); }; p.popMatrix = function popMatrix() { curContext.restore(); }; p.redraw = function redraw() { if (hasBackground) { p.background(); } p.frameCount++; inDraw = true; p.pushMatrix(); p.draw(); p.popMatrix(); inDraw = false; }; p.loop = function loop() { if (loopStarted) return; looping = setInterval(function() { try { if (!p.paused) { p.redraw(); } } catch(e) { clearInterval(looping); throw e; } }, 1000 / curFrameRate); loopStarted = true; }; p.frameRate = function frameRate(aRate) { curFrameRate = aRate; }; p.background = function background(img) { if (arguments.length) { if (img && img.img) { curBackground = img; } else { curBackground = p.color.apply(this, arguments); } } if (curBackground.img) { p.image(curBackground, 0, 0); } else { var oldFill = curContext.fillStyle; curContext.fillStyle = curBackground + ""; curContext.fillRect(0, 0, p.width, p.height); curContext.fillStyle = oldFill; } }; p.clear = function clear(x, y, width, height) { arguments.length == 0 ? curContext.clearRect(0, 0, p.width, p.height) : curContext.clearRect(x, y, width, height); } p.str = function str(aNumber) { return aNumber + ''; } p.sq = function sq(aNumber) { return aNumber * aNumber; }; p.sqrt = function sqrt(aNumber) { return Math.sqrt(aNumber); }; p.ngsqrt = function ngsqrt(aNumber) { if (aNumber <= 0) { return Math.sqrt(-aNumber); } else { return Math.sqrt(aNumber); } }; p.int = function int(aNumber) { return Math.floor(aNumber); }; p.min = function min(aNumber, aNumber2) { return Math.min(aNumber, aNumber2); }; p.max = function max(aNumber, aNumber2) { return Math.max(aNumber, aNumber2); }; p.ceil = function ceil(aNumber) { return Math.ceil(aNumber); }; p.round = function round(aNumber) { return Math.round(aNumber); }; p.norm = function norm(aNumber, low, high) { var range = high - low; return ((1 / range) * aNumber) - ((1 / range) * low); }; p.lerp = function lerp(value1, value2, amt) { var range = value2 - value1; return (range * amt) + value1; } p.floor = function floor(aNumber) { return Math.floor(aNumber); }; p.float = function float(aNumber) { return parseFloat(aNumber); }; p.byte = function byte(aNumber) { return aNumber || 0; }; p.random = function random(aMin, aMax) { return arguments.length == 2 ? aMin + (Math.random() * (aMax - aMin)) : Math.random() * aMin; }; p.noise = function(x, y, z) { return arguments.length >= 2 ? PerlinNoise_2D(x, y) : PerlinNoise_2D(x, x); }; function Noise(x, y) { var n = x + y * 57; n = (n << 13) ^ n; return Math.abs(1.0 - (((n * ((n * n * 15731) + 789221) + 1376312589) & 0x7fffffff) / 1073741824.0)); }; function SmoothedNoise(x, y) { var corners = (Noise(x - 1, y - 1) + Noise(x + 1, y - 1) + Noise(x - 1, y + 1) + Noise(x + 1, y + 1)) / 16; var sides = (Noise(x - 1, y) + Noise(x + 1, y) + Noise(x, y - 1) + Noise(x, y + 1)) / 8; var center = Noise(x, y) / 4; return corners + sides + center; }; function InterpolatedNoise(x, y) { var integer_X = Math.floor(x); var fractional_X = x - integer_X; var integer_Y = Math.floor(y); var fractional_Y = y - integer_Y; var v1 = SmoothedNoise(integer_X, integer_Y); var v2 = SmoothedNoise(integer_X + 1, integer_Y); var v3 = SmoothedNoise(integer_X, integer_Y + 1); var v4 = SmoothedNoise(integer_X + 1, integer_Y + 1); var i1 = Interpolate(v1, v2, fractional_X); var i2 = Interpolate(v3, v4, fractional_X); return Interpolate(i1, i2, fractional_Y); } function PerlinNoise_2D(x, y) { var total = 0; var p = 0.25; var n = 3; for (var i = 0; i <= n; i++) { var frequency = Math.pow(2, i); var amplitude = Math.pow(p, i); total = total + InterpolatedNoise(x * frequency, y * frequency) * amplitude; } return total; } function Interpolate(a, b, x) { var ft = x * p.PI; var f = (1 - p.cos(ft)) * .5; return a * (1 - f) + b * f; } p.abs = function abs(aNumber) { return Math.abs(aNumber); }; p.cos = function cos(aNumber) { return Math.cos(aNumber); }; p.sin = function sin(aNumber) { return Math.sin(aNumber); }; p.pow = function pow(aNumber, aExponent) { return Math.pow(aNumber, aExponent); }; p.constrain = function constrain(aNumber, aMin, aMax) { return Math.min(Math.max(aNumber, aMin), aMax); }; p.sqrt = function sqrt(aNumber) { return Math.sqrt(aNumber); }; p.atan2 = function atan2(aNumber, aNumber2) { return Math.atan2(aNumber, aNumber2); }; p.radians = function radians(aAngle) { return (aAngle / 180) * p.PI; }; p.degrees = function degrees(aAngle) { aAngle = (aAngle * 180) / p.PI; if (aAngle < 0) { aAngle = 360 + aAngle } return aAngle; }; p.size = function size(aWidth, aHeight) { var fillStyle = curContext.fillStyle; var strokeStyle = curContext.strokeStyle; curElement.width = p.width = aWidth; curElement.height = p.height = aHeight; curContext.fillStyle = fillStyle; curContext.strokeStyle = strokeStyle; }; p.noStroke = function noStroke() { doStroke = false; }; p.noFill = function noFill() { doFill = false; }; p.smooth = function smooth() {}; p.noSmooth = function noSmooth() {}; p.noLoop = function noLoop() { clearInterval(looping); loopStarted = false; doLoop = false; }; p.fill = function fill() { doFill = true; curContext.fillStyle = p.color.apply(this, arguments); }; p.stroke = function stroke() { doStroke = true; curContext.strokeStyle = p.color.apply(this, arguments); }; p.strokeWeight = function strokeWeight(w) { curContext.lineWidth = w; }; p.point = function point(x, y) { var oldFill = curContext.fillStyle; curContext.fillStyle = curContext.strokeStyle; curContext.fillRect(Math.round(x), Math.round(y), 1, 1); curContext.fillStyle = oldFill; }; p.get = function get(x, y) { if (arguments.length == 0) { var c = p.createGraphics(p.width, p.height); c.image(curContext, 0, 0); return c; } if (!getLoaded) { getLoaded = buildImageObject(curContext.getImageData(0, 0, p.width, p.height)); } return getLoaded.get(x, y); }; p.set = function set(x, y, obj) { if (obj && obj.img) { p.image(obj, x, y); } else { var oldFill = curContext.fillStyle; var color = obj; curContext.fillStyle = color; curContext.fillRect(Math.round(x), Math.round(y), 1, 1); curContext.fillStyle = oldFill; } }; p.arc = function arc(x, y, width, height, start, stop) { if (width <= 0) return; if (curEllipseMode == p.CORNER) { x += width / 2; y += height / 2; } curContext.moveTo(x, y); curContext.beginPath(); curContext.arc(x, y, curEllipseMode == p.CENTER_RADIUS ? width : width / 2, start, stop, false); if (doStroke) curContext.stroke(); curContext.lineTo(x, y); if (doFill) curContext.fill(); curContext.closePath(); }; p.line = function line(x1, y1, x2, y2) { curContext.lineCap = "round"; curContext.beginPath(); curContext.moveTo(x1 || 0, y1 || 0); curContext.lineTo(x2 || 0, y2 || 0); curContext.stroke(); curContext.closePath(); }; p.bezier = function bezier(x1, y1, x2, y2, x3, y3, x4, y4) { curContext.lineCap = "butt"; curContext.beginPath(); curContext.moveTo(x1, y1); curContext.bezierCurveTo(x2, y2, x3, y3, x4, y4); curContext.stroke(); curContext.closePath(); }; p.triangle = function triangle(x1, y1, x2, y2, x3, y3) { p.beginShape(); p.vertex(x1, y1); p.vertex(x2, y2); p.vertex(x3, y3); p.endShape(); }; p.quad = function quad(x1, y1, x2, y2, x3, y3, x4, y4) { curContext.lineCap = "square"; p.beginShape(); p.vertex(x1, y1); p.vertex(x2, y2); p.vertex(x3, y3); p.vertex(x4, y4); p.endShape(); }; p.rect = function rect(x, y, width, height) { if (width == 0 && height == 0) return; curContext.beginPath(); var offsetStart = 0; var offsetEnd = 0; if (curRectMode == p.CORNERS) { width -= x; height -= y; } if (curRectMode == p.RADIUS) { width *= 2; height *= 2; } if (curRectMode == p.CENTER || curRectMode == p.RADIUS) { x -= width / 2; y -= height / 2; } curContext.rect(Math.round(x) - offsetStart, Math.round(y) - offsetStart, Math.round(width) + offsetEnd, Math.round(height) + offsetEnd); if (doFill) curContext.fill(); if (doStroke) curContext.stroke(); curContext.closePath(); }; p.ellipse = function ellipse(x, y, width, height) { x = x || 0; y = y || 0; if (width <= 0 && height <= 0) return; curContext.beginPath(); if (curEllipseMode == p.RADIUS) { width *= 2; height *= 2; } var offsetStart = 0; if (width == height) { curContext.arc(x - offsetStart, y - offsetStart, width / 2, 0, Math.PI * 2, false); } else { var w = width / 2; var h = height / 2; var C = 0.5522847498307933; var c_x = C * w; var c_y = C * h; curContext.moveTo(x + w, y); curContext.bezierCurveTo(x + w, y - c_y, x + c_x, y - h, x, y - h); curContext.bezierCurveTo(x - c_x, y - h, x - w, y - c_y, x - w, y); curContext.bezierCurveTo(x - w, y + c_y, x - c_x, y + h, x, y + h); curContext.bezierCurveTo(x + c_x, y + h, x + w, y + c_y, x + w, y); } if (doFill) curContext.fill(); if (doStroke) curContext.stroke(); curContext.closePath(); }; p.link = function(href, target) { window.location = href; }; p.loadPixels = function() { p.pixels = buildImageObject(curContext.getImageData(0, 0, p.width, p.height)).pixels; }; p.updatePixels = function() { var colors = /(\d+),(\d+),(\d+),(\d+)/; var pixels = {}; pixels.width = p.width; pixels.height = p.height; pixels.data = []; if (curContext.createImageData) { pixels = curContext.createImageData(p.width, p.height); } var data = pixels.data; var pos = 0; for (var i = 0, l = p.pixels.length; i < l; i++) { var c = (p.pixels[i] || "rgba(0,0,0,1)").match(colors); data[pos] = parseInt(c[1]); data[pos + 1] = parseInt(c[2]); data[pos + 2] = parseInt(c[3]); data[pos + 3] = parseFloat(c[4]) * 255; pos += 4; } curContext.putImageData(pixels, 0, 0); }; p.extendClass = function extendClass(obj, args, fn) { if (arguments.length == 3) { fn.apply(obj, args); } else { args.call(obj); } }; p.addMethod = function addMethod(object, name, fn) { if (object[name]) { var args = fn.length; var oldfn = object[name]; object[name] = function() { if (arguments.length == args) return fn.apply(this, arguments); else return oldfn.apply(this, arguments); }; } else { object[name] = fn; } }; p.init = function init(code) { p.stroke(0); p.fill(255); curContext.translate(0.5, 0.5); if (code) { (function(Processing) { with(p) { eval(parse(code, p)); } })(p); } if (p.setup) { inSetup = true; p.setup(); } inSetup = false; if (p.draw) { if (!doLoop) { p.redraw(); } else { p.loop(); } } attach(document, "mousemove", function(e) { var scrollX = window.scrollX != null ? window.scrollX : window.pageXOffset; var scrollY = window.scrollY != null ? window.scrollY : window.pageYOffset; p.pmouseX = p.mouseX; p.pmouseY = p.mouseY; p.mouseX = e.clientX - curElement.offsetLeft + scrollX; p.mouseY = e.clientY - curElement.offsetTop + scrollY; if (p.mouseMoved) { p.mouseMoved(); } if (mousePressed && p.mouseDragged) { p.mouseDragged(); } }); attach(curElement, "mousedown", function(e) { mousePressed = true; switch (e.which) { case 1: p.mouseButton = p.LEFT; break; case 2: p.mouseButton = p.CENTER; break; case 3: p.mouseButton = p.RIGHT; break; } if (typeof p.mousePressed == "function") { p.mousePressed(); } else { p.mousePressed = true; } }); attach(curElement, "contextmenu", function(e) { e.preventDefault(); e.stopPropagation(); }); attach(document, "mouseup", function(e) { mousePressed = false; if (typeof p.mousePressed != "function") { p.mousePressed = false; } if (p.mouseReleased) { p.mouseReleased(); } }); attach(document, "keydown", function(e) { keyPressed = true; p.key = e.keyCode + 32; var i; for (i = 0; i < p.codedKeys.length; i++) { if (p.key == p.codedKeys[i]) { switch (p.key) { case 70: p.keyCode = p.UP; break; case 71: p.keyCode = p.RIGHT; break; case 72: p.keyCode = p.DOWN; break; case 69: p.keyCode = p.LEFT; break; } p.key = p.CODED; } } if (e.shiftKey) { p.key = String.fromCharCode(p.key).toUpperCase().charCodeAt(0); } if (typeof p.keyPressed == "function") { p.keyPressed(); } else { p.keyPressed = true; } }); attach(document, "keyup", function(e) { keyPressed = false; if (typeof p.keyPressed != "function") { p.keyPressed = false; } if (p.keyReleased) { p.keyReleased(); } }); function attach(elem, type, fn) { if (elem.addEventListener) elem.addEventListener(type, fn, false); else elem.attachEvent("on" + type, fn); } }; return p; } })(); sagenb-1.0.1/sagenb/data/graph_editor/processing.js000066400000000000000000002172131311436262400223110ustar00rootroot00000000000000/* P R O C E S S I N G - 0 . 0 . J S a port of the Processing visualization language License : MIT Developer : John Resig: http://ejohn.org Web Site : http://processingjs.org Java Version : http://processing.org Github Repo. : http://github.com/jeresig/processing-js Bug Tracking : http://processing-js.lighthouseapp.com Mozilla POW! : http://wiki.Mozilla.org/Education/Projects/ProcessingForTheWeb Maintained by : Seneca: http://zenit.senecac.on.ca/wiki/index.php/Processing.js Hyper-Metrix: http://hyper-metrix.com/#Processing */ (function(){ // Attach Processing to the window this.Processing = function Processing( aElement, aCode ){ // Get the DOM element if string was passed if( typeof aElement == "string" ){ aElement = document.getElementById( aElement ); } // Build an Processing functions and env. vars into 'p' var p = buildProcessing( aElement ); // Send aCode Processing syntax to be converted to JavaScript if( aCode ){ p.init( aCode ); } return p; }; // IE Unfriendly AJAX Method var ajax=function( url ){ var AJAX; if( AJAX = new XMLHttpRequest() ){ AJAX.open( "GET", url, false ); AJAX.send( null ); return AJAX.responseText; }else{ return false; } }; // Automatic Initialization Method var init = function(){ var canvas = document.getElementsByTagName( 'canvas' ), datasrc = undefined; for( var i = 0; l = i < canvas.length; i++ ){ if( datasrc = canvas[ i ].getAttribute( 'datasrc' ) ){ Processing( canvas[ i ], ajax( datasrc ) ); } } }; addEventListener( 'DOMContentLoaded', function(){ init(); }, false ); // Parse Processing (Java-like) syntax to JavaScript syntax with Regex var parse = Processing.parse = function parse( aCode, p ){ // Remove end-of-line comments aCode = aCode.replace( /\/\/ .*\n/g, "\n" ); // Weird parsing errors with % aCode = aCode.replace( /([^\s])%([^\s])/g, "$1 % $2" ); // Simple convert a function-like thing to function aCode = aCode.replace( /(?:static )?(\w+ )(\w+)\s*(\([^\)]*\)\s*{)/g, function( all, type, name, args ){ if ( name == "if" || name == "for" || name == "while" ) { return all; } else { return "Processing." + name + " = function " + name + args; } }); // Attach import() to p{} bypassing JS command, allowing for extrernal library loading aCode = aCode.replace( /import \(|import\(/g, "p.Import(" ); // Force .length() to be .length aCode = aCode.replace( /\.length\(\)/g, ".length" ); // foo( int foo, float bar ) aCode = aCode.replace( /([\(,]\s*)(\w+)((?:\[\])+| )\s*(\w+\s*[\),])/g, "$1$4" ); aCode = aCode.replace( /([\(,]\s*)(\w+)((?:\[\])+| )\s*(\w+\s*[\),])/g, "$1$4" ); // float[] foo = new float[5]; aCode = aCode.replace( /new (\w+)((?:\[([^\]]*)\])+)/g, function( all, name, args ){ return "new ArrayList(" + args.slice(1,-1).split("][").join(", ") + ")"; }); // What does this do? aCode = aCode.replace( /(?:static )?\w+\[\]\s*(\w+)\[?\]?\s*=\s*{.*?};/g, function( all ){ return all.replace( /{/g, "[").replace(/}/g, "]" ); }); // int|float foo; var intFloat = /(\n\s*(?:int|float)(?:\[\])?(?:\s*|[^\(]*?,\s*))([a-z]\w*)(;|,)/i; while( intFloat.test(aCode) ){ aCode = aCode.replace( new RegExp( intFloat ), function( all, type, name, sep ){ return type + " " + name + " = 0" + sep; }); } // float foo = 5; aCode = aCode.replace( /(?:static )?(\w+)((?:\[\])+| ) *(\w+)\[?\]?(\s*[=,;])/g, function( all, type, arr, name, sep ){ if ( type == "return" ) return all; else return "var " + name + sep; }); // Fix Array[] foo = {...} to [...] aCode = aCode.replace( /=\s*{((.|\s)*?)};/g, function(all,data){ return "= [" + data.replace(/{/g, "[").replace(/}/g, "]") + "]"; }); // super() is a reserved word aCode = aCode.replace( /super\(/g, "superMethod(" ); var classes = [ "int", "float", "boolean", "string" ]; function ClassReplace( all, name, extend, vars, last ){ classes.push( name ); var static = ""; vars = vars.replace( /final\s+var\s+(\w+\s*=\s*.*?;)/g, function( all, set ){ static += " " + name + "." + set; return ""; }); // Move arguments up from constructor and wrap contents with // a with(this), and unwrap constructor return "function " + name + "() {with(this){\n " + ( extend ? "var __self=this;function superMethod(){extendClass(__self,arguments," + extend + ");}\n" : "" ) + // Replace var foo = 0; with this.foo = 0; // and force var foo; to become this.foo = null; vars .replace( /,\s?/g, ";\n this." ) .replace( /\b(var |final |public )+\s*/g, "this." ) .replace( /\b(var |final |public )+\s*/g, "this." ) .replace( /this.(\w+);/g, "this.$1 = null;" ) + ( extend ? "extendClass(this, " + extend + ");\n" : "" ) + "" + ( typeof last == "string" ? last : name + "(" ); } var matchClasses = /(?:public |abstract |static )*class (\w+)\s*(?:extends\s*(\w+)\s*)?{\s*((?:.|\n)*?)\b\1\s*\(/g; var matchNoCon = /(?:public |abstract |static )*class (\w+)\s*(?:extends\s*(\w+)\s*)?{\s*((?:.|\n)*?)(Processing)/g; aCode = aCode.replace( matchClasses, ClassReplace ); aCode = aCode.replace( matchNoCon, ClassReplace ); var matchClass = //, m; while ( ( m = aCode.match( matchClass ) ) ){ var left = RegExp.leftContext, allRest = RegExp.rightContext, rest = nextBrace( allRest ), className = m[ 1 ], staticVars = m[ 2 ] || ""; allRest = allRest.slice( rest.length + 1 ); rest = rest.replace( new RegExp("\\b" + className + "\\(([^\\)]*?)\\)\\s*{", "g"), function( all, args ){ args = args.split( /,\s*?/ ); if( args[ 0 ].match( /^\s*$/ ) ){ args.shift(); } var fn = "if ( arguments.length == " + args.length + " ) {\n"; for ( var i = 0; i < args.length; i++ ) { fn += " var " + args[ i ] + " = arguments["+ i +"];\n"; } return fn; }); // Fix class method names // this.collide = function() { ... } // and add closing } for with(this) ... rest = rest.replace( /(?:public )?Processing.\w+ = function (\w+)\((.*?)\)/g, function( all, name, args ){ return "ADDMETHOD(this, '" + name + "', function(" + args + ")"; }); var matchMethod = /ADDMETHOD([\s\S]*?{)/, mc; var methods = ""; while ( ( mc = rest.match( matchMethod ) ) ){ var prev = RegExp.leftContext, allNext = RegExp.rightContext, next = nextBrace(allNext); methods += "addMethod" + mc[ 1 ] + next + "});"; rest = prev + allNext.slice( next.length + 1 ); } rest = methods + rest; aCode = left + rest + "\n}}" + staticVars + allRest; } // Do some tidying up, where necessary aCode = aCode.replace( /Processing.\w+ = function addMethod/g, "addMethod" ); function nextBrace( right ) { var rest = right, position = 0, leftCount = 1, rightCount = 0; while( leftCount != rightCount ) { var nextLeft = rest.indexOf( "{" ), nextRight = rest.indexOf( "}" ); if( nextLeft < nextRight && nextLeft != - 1 ) { leftCount++; rest = rest.slice( nextLeft + 1 ); position += nextLeft + 1; }else{ rightCount++; rest = rest.slice( nextRight + 1 ); position += nextRight + 1; } } return right.slice( 0, position - 1 ); } // Handle (int) Casting aCode = aCode.replace( /\(int\)/g, "0|" ); // Remove Casting aCode = aCode.replace( new RegExp("\\((" + classes.join("|") + ")(\\[\\])?\\)", "g"), "" ); // Convert 3.0f to just 3.0 aCode = aCode.replace( /(\d+)f[^a-zA-Z0-9]/g, "$1" ); // Force numbers to exist // //aCode = aCode.replace(/([^.])(\w+)\s*\+=/g, "$1$2 = ($2||0) +"); //! // Force characters-as-bytes to work --> Ping: Andor aCode = aCode.replace(/('[a-zA-Z0-9]')/g, "$1.charCodeAt(0)"); // Convert #aaaaaa into color aCode = aCode.replace(/#([a-f0-9]{6})/ig, function(m, hex){ var num = toNumbers(hex); return "DefaultColor(" + num[0] + "," + num[1] + "," + num[2] + ")"; }); function toNumbers( str ){ var ret = []; str.replace( /(..)/g, function( str ){ ret.push( parseInt( str, 16 ) ); }); return ret; } return aCode; }; // Attach Processing functions to 'p' function buildProcessing( curElement ){ // Create the 'p' object var p = {}; // Set Processing defaults / environment variables p.name = 'Processing.js Instance'; p.PI = Math.PI; p.TWO_PI = 2 * p.PI; p.HALF_PI = p.PI / 2; p.P3D = 3; p.CORNER = 0; p.RADIUS = 1; p.CENTER_RADIUS = 1; p.CENTER = 2; p.POLYGON = 2; p.QUADS = 5; p.TRIANGLES = 6; p.POINTS = 7; p.LINES = 8; p.TRIANGLE_STRIP = 9; p.TRIANGLE_FAN = 4; p.QUAD_STRIP = 3; p.CORNERS = 10; p.CLOSE = true; p.RGB = 1; p.HSB = 2; // KeyCode table p.CENTER = 88888880; p.CODED = 88888888; p.UP = 88888870; p.RIGHT = 88888871; p.DOWN = 88888872; p.LEFT = 88888869; //! // Description required... p.codedKeys = [ 69, 70, 71, 72 ]; // "Private" variables used to maintain state var curContext = curElement.getContext( "2d" ), doFill = true, doStroke = true, loopStarted = false, hasBackground = false, doLoop = true, looping = 0, curRectMode = p.CORNER, curEllipseMode = p.CENTER, inSetup = false, inDraw = false, curBackground = "rgba( 204, 204, 204, 1 )", curFrameRate = 1000, curMsPerFrame = 1, curShape = p.POLYGON, curShapeCount = 0, curvePoints = [], curTightness = 0, opacityRange = 255, redRange = 255, greenRange = 255, blueRange = 255, pathOpen = false, mousePressed = false, keyPressed = false, curColorMode = p.RGB; curTint = - 1, curTextSize = 12, curTextFont = "Arial", getLoaded = false, start = ( new Date ).getTime(); var firstX, firstY, secondX, secondY, prevX, prevY; // Store a line for println(), print() handline p.ln = ""; // Glyph path storage for textFonts p.glyphTable = {}; // Global vars for tracking mouse position p.pmouseX = 0; p.pmouseY = 0; p.mouseX = 0; p.mouseY = 0; p.mouseButton = 0; p.mouseDown = false; // Undefined event handlers to be replaced by user when needed p.mouseClicked = undefined; p.mouseDragged = undefined; p.mouseMoved = undefined; p.mousePressed = undefined; p.mouseReleased = undefined; p.keyPressed = undefined; p.keyReleased = undefined; p.draw = undefined; p.setup = undefined; // The height/width of the canvas p.width = curElement.width - 0; p.height = curElement.height - 0; // The current animation frame p.frameCount = 0; //////////////////////////////////////////////////////////////////////////// // Array handling //////////////////////////////////////////////////////////////////////////// p.shorten = function( ary ){ var newary = new Array(); // copy array into new array var len = ary.length; for( var i = 0; i < len; i++ ){ newary[ i ] = ary[ i ]; } newary.pop(); return newary; } p.expand = function( ary, newSize ){ var newary = new Array(); var len = ary.length for( var i = 0; i < len; i++ ){ newary[ i ] = ary[ i ]; } if( arguments.length == 1 ){ // double size of array newary.length *= 2; }else if( arguments.length == 2 ){ // size is newSize newary.length = newSize; } return newary; } p.ArrayList = function ArrayList( size, size2, size3 ){ var array = new Array( 0 | size ); if( size2 ){ for( var i = 0; i < size; i++ ){ array[ i ] = []; for( var j = 0; j < size2; j++ ){ var a = array[ i ][ j ] = size3 ? new Array( size3 ) : 0 ; for( var k = 0; k < size3; k++ ){ a[ k ] = 0; } } } }else{ for( var i = 0; i < size; i++ ){ array[ i ] = 0; } } array.get = function( i ){ return this[ i ]; }; array.add = function( item ){ return this.push( item ); }; array.size = function( ){ return this.length; }; array.clear = function( ){ this.length = 0; }; array.remove = function( i ){ return this.splice( i, 1 ); }; array.isEmpty = function( ){ return !this.length; }; array.clone = function( ){ var a = new ArrayList( size ); for( var i = 0; i < size; i++ ){ a[ i ] = this[ i ]; } return a; }; return array; }; //////////////////////////////////////////////////////////////////////////// // Color functions //////////////////////////////////////////////////////////////////////////// // In case I ever need to do HSV conversion: // http://srufaculty.sru.edu/david.dailey/javascript/js/5rml.js p.color = function color( aValue1, aValue2, aValue3, aValue4 ) { var aColor = ""; if ( arguments.length == 3 ) { aColor = p.color( aValue1, aValue2, aValue3, opacityRange ); } else if ( arguments.length == 4 ) { var a = aValue4 / opacityRange; a = isNaN(a) ? 1 : a; if ( curColorMode == p.HSB ) { var rgb = HSBtoRGB(aValue1, aValue2, aValue3); var r = rgb[0], g = rgb[1], b = rgb[2]; } else { var r = getColor(aValue1, redRange); var g = getColor(aValue2, greenRange); var b = getColor(aValue3, blueRange); } aColor = "rgba(" + r + "," + g + "," + b + "," + a + ")"; } else if ( typeof aValue1 == "string" ) { aColor = aValue1; if ( arguments.length == 2 ) { var c = aColor.split(","); c[3] = (aValue2 / opacityRange) + ")"; aColor = c.join(","); } } else if ( arguments.length == 2 ) { aColor = p.color( aValue1, aValue1, aValue1, aValue2 ); } else if ( typeof aValue1 == "number" && aValue1 < 256 && aValue1 >= 0) { aColor = p.color( aValue1, aValue1, aValue1, opacityRange ); } else if ( typeof aValue1 == "number" ) { var intcolor = 0; if( aValue1 < 0 ){ intcolor = 4294967296 - ( aValue1 * -1 ); }else{ intcolor = aValue1; } var ac = Math.floor((intcolor % 4294967296) / 16777216); var rc = Math.floor((intcolor % 16777216) / 65536); var gc = Math.floor((intcolor % 65536) / 256); var bc = intcolor % 256; aColor = p.color( rc, gc, bc, ac ); } else { aColor = p.color( redRange, greenRange, blueRange, opacityRange ); } // HSB conversion function from Mootools, MIT Licensed function HSBtoRGB(h, s, b) { h = (h / redRange) * 360; s = (s / greenRange) * 100; b = (b / blueRange) * 100; var br = Math.round(b / 100 * 255); if (s == 0){ return [br, br, br]; } else { var hue = h % 360; var f = hue % 60; var p = Math.round((b * (100 - s)) / 10000 * 255); var q = Math.round((b * (6000 - s * f)) / 600000 * 255); var t = Math.round((b * (6000 - s * (60 - f))) / 600000 * 255); switch (Math.floor(hue / 60)){ case 0: return [br, t, p]; case 1: return [q, br, p]; case 2: return [p, br, t]; case 3: return [p, q, br]; case 4: return [t, p, br]; case 5: return [br, p, q]; } } } function getColor( aValue, range ) { return Math.round(255 * (aValue / range)); } return aColor; } p.red = function( aColor ){ return parseInt( verifyChannel( aColor ).slice( 5 ) ); }; p.green = function( aColor ){ return parseInt( verifyChannel( aColor ).split( "," )[ 1 ] ); }; p.blue = function( aColor ){ return parseInt( verifyChannel( aColor ).split( "," )[ 2 ] ); }; p.alpha = function( aColor ){ return parseInt( parseFloat( verifyChannel( aColor ).split( "," )[ 3 ] ) * 255 ); }; function verifyChannel( aColor ){ if( aColor.constructor == Array ){ return aColor; } else { return p.color( aColor ); } } p.lerpColor = function lerpColor( c1, c2, amt ){ // Get RGBA values for Color 1 to floats var colors1 = p.color( c1 ).split( "," ); var r1 = parseInt( colors1[ 0 ].split( "(" )[ 1 ] ); var g1 = parseInt( colors1[ 1 ] ); var b1 = parseInt( colors1[ 2 ] ); var a1 = parseFloat( colors1[ 3 ].split( ")" )[ 0 ] ); // Get RGBA values for Color 2 to floats var colors2 = p.color( c2 ).split( "," ); var r2 = parseInt( colors2[ 0 ].split( "(" )[ 1 ] ); var g2 = parseInt( colors2[ 1 ] ); var b2 = parseInt( colors2[ 2 ] ); var a2 = parseFloat( colors2[ 3 ].split( ")" )[ 0 ] ); // Return lerp value for each channel, INT for color, Float for Alpha-range var r = parseInt( p.lerp( r1, r2, amt ) ); var g = parseInt( p.lerp( g1, g2, amt ) ); var b = parseInt( p.lerp( b1, b2, amt ) ); var a = parseFloat( p.lerp( a1, a2, amt ) ); return aColor = "rgba("+ r +","+ g +","+ b +","+ a +")"; } // Forced default color mode for #aaaaaa style p.DefaultColor = function( aValue1, aValue2, aValue3 ){ var tmpColorMode = curColorMode; curColorMode = p.RGB; var c = p.color(aValue1 / 255 * redRange, aValue2 / 255 * greenRange, aValue3 / 255 * blueRange ); curColorMode = tmpColorMode; return c; } p.colorMode = function colorMode( mode, range1, range2, range3, range4 ){ curColorMode = mode; if( arguments.length >= 4 ){ redRange = range1; greenRange = range2; blueRange = range3; } if( arguments.length == 5 ){ opacityRange = range4; } if( arguments.length == 2 ){ p.colorMode( mode, range1, range1, range1, range1 ); } }; //////////////////////////////////////////////////////////////////////////// // Canvas-Matrix manipulation //////////////////////////////////////////////////////////////////////////// p.translate = function translate( x, y ){ curContext.translate( x, y ); }; p.scale = function scale( x, y ) { curContext.scale( x, y || x ); }; p.rotate = function rotate( aAngle ) { curContext.rotate( aAngle ); }; p.pushMatrix = function pushMatrix() { curContext.save(); }; p.popMatrix = function popMatrix() { curContext.restore(); }; p.ortho = function ortho(){}; //////////////////////////////////////////////////////////////////////////// //Time based functions //////////////////////////////////////////////////////////////////////////// p.year = function year() { return ( new Date ).getYear() + 1900; }; p.month = function month() { return ( new Date ).getMonth(); }; p.day = function day() { return ( new Date ).getDay(); }; p.hour = function hour() { return ( new Date ).getHours(); }; p.minute = function minute(){ return ( new Date ).getMinutes(); }; p.second = function second(){ return ( new Date ).getSeconds(); }; p.millis = function millis(){ return ( new Date ) .getTime() - start; }; p.noLoop = function noLoop(){ doLoop = false; }; p.redraw = function redraw(){ if( hasBackground ){ p.background(); } p.frameCount++; inDraw = true; p.pushMatrix(); p.draw(); p.popMatrix(); inDraw = false; }; p.loop = function loop(){ if( loopStarted ){ return; } looping = setInterval( function(){ try { p.redraw(); } catch( e ){ clearInterval( looping ); throw e; } }, curMsPerFrame ); loopStarted = true; }; p.frameRate = function frameRate( aRate ){ curFrameRate = aRate; curMsPerFrame = 1000 / curFrameRate; }; p.exit = function exit(){ clearInterval( looping ); }; //////////////////////////////////////////////////////////////////////////// // MISC functions //////////////////////////////////////////////////////////////////////////// p.cursor = function(mode){ document.body.style.cursor=mode; } p.link = function( href, target ) { window.location = href; }; p.beginDraw = function beginDraw(){}; p.endDraw = function endDraw(){}; p.ajax = ajax; // Imports an external Processing.js library p.Import = function Import( lib ){ eval( p.ajax( lib ) ); } //////////////////////////////////////////////////////////////////////////// // String functions //////////////////////////////////////////////////////////////////////////// p.nfs = function( num, left, right){ var str; // array handling if (typeof num == "object"){ str = new Array(); len = num.length; for(var i=0; i < len; i++){ str[i] = p.nfs(num[i], left, right); } } else if (arguments.length == 3){ var negative = false; if (num < 0) negative = true; str = "" + Math.abs(num); var digits = ("" + Math.floor(Math.abs(num))).length; var count = left - digits; while (count > 0){ str = "0" + str; count--; } // get the number of decimal places, if none will be -1 var decimals = ("" + Math.abs(num)).length - digits - 1; if (decimals == -1 && right > 0) str = str + "."; if (decimals != -1) count = right - decimals; else if (decimals == -1 && right > 0){ count = right; } else count = 0; while (count > 0){ str = str + "0"; count--; } str = (negative ? "-" : " ") + str; } else if (arguments.length == 2){ str = p.nfs(num, left, 0); } return str; } p.unhex = function( str ){ var value = 0, multiplier = 1, num = 0; var len = str.length - 1; for (var i = len ; i >= 0; i--){ try{ switch(str[i]){ case "0": num = 0; break; case "1": num = 1; break; case "2": num = 2; break; case "3": num = 3; break; case "4": num = 4; break; case "5": num = 5; break; case "6": num = 6; break; case "7": num = 7; break; case "8": num = 8; break; case "9": num = 9; break; case "A": case "a": num = 10; break; case "B": case "b": num = 11; break; case "C": case "c": num = 12; break; case "D": case "d": num = 13; break; case "E": case "e": num = 14; break; case "F": case "f": num = 15; break; default:return 0; break; } value += num * multiplier; multiplier *= 16; }catch(e){;} // correct for int overflow java expectation if (value > 2147483647) { value -= 4294967296; } } return value; } // Load a file or URL into strings p.loadStrings = function loadStrings( url ){ return p.ajax( url ).split( "\n" ); }; p.nf = function( num, pad ){ var str = "" + num; while ( pad - str.length ){ str = "0" + str; } return str; }; String.prototype.replaceAll = function( re, replace ){ return this.replace( new RegExp( re, "g" ), replace ); }; // Returns a line to lnPrinted() for user handling p.lnPrinted = function lnPrinted(){}; p.printed = function printed() {}; // Event to send output to user control function print()/println() p.println = function println(){ // Not working on Safari :( find work around! if( arguments.callee.caller ){ var Caller = arguments.callee.caller.name.toString(); if( arguments.length > 1 ){ Caller != "print" ? p.ln = arguments : p.ln = arguments[ 0 ] ; }else{ p.ln = arguments[ 0 ] ; } //Returns a line to lnPrinted() for user error handling/debugging Caller == "print" ? p.printed( arguments ) : p.lnPrinted() ; } }; // Converts a number to a string p.str = function str( aNumber ){ return aNumber+''; } p.print = function print(){ p.println(arguments[ 0 ] ) }; p.char = function char( key ){ return key; }; //////////////////////////////////////////////////////////////////////////// // Math functions //////////////////////////////////////////////////////////////////////////// p.sq = function sq ( aNumber ){ return aNumber * aNumber; }; p.sqrt = function sqrt ( aNumber ){ return Math.sqrt( aNumber ); }; p.int = function int ( aNumber ){ return Math.floor( aNumber ); }; p.min = function min ( aNumber, aNumber2 ){ return Math.min( aNumber, aNumber2 ); }; p.max = function max ( aNumber, aNumber2 ){ return Math.max( aNumber, aNumber2 ); }; p.floor = function floor ( aNumber ){ return Math.floor( aNumber ); }; p.float = function float ( aNumber ){ return parseFloat( aNumber ); }; p.ceil = function ceil ( aNumber ){ return Math.ceil( aNumber ); }; p.round = function round ( aNumber ){ return Math.round( aNumber ); }; p.lerp = function lerp ( value1, value2, amt ){ return ( ( value2 - value1 ) * amt ) + value1; }; p.abs = function abs ( aNumber ){ return Math.abs( aNumber ); }; p.cos = function cos ( aNumber ){ return Math.cos( aNumber ); }; p.sin = function sin ( aNumber ){ return Math.sin( aNumber ); }; p.pow = function pow ( aNumber, aExponent ){ return Math.pow( aNumber, aExponent ); }; p.sqrt = function sqrt ( aNumber ){ return Math.sqrt( aNumber ); }; p.atan2 = function atan2 ( aNumber, aNumber2 ){ return Math.atan2( aNumber, aNumber2 ); }; p.radians = function radians( aAngle ){ return ( aAngle / 180 ) * p.PI; }; p.dist = function dist( x1, y1, x2, y2 ){ return Math.sqrt( Math.pow( x2 - x1, 2 ) + Math.pow( y2 - y1, 2 ) ); }; p.map = function map( value, istart, istop, ostart, ostop ){ return ostart + ( ostop - ostart ) * ( ( value - istart ) / ( istop - istart ) ); }; p.Random = function(){ var haveNextNextGaussian = false, nextNextGaussian; this.nextGaussian = function(){ if( haveNextNextGaussian ){ haveNextNextGaussian = false; return nextNextGaussian; }else{ var v1, v2, s; do{ v1 = 2 * p.random( 1 ) - 1; // between -1.0 and 1.0 v2 = 2 * p.random( 1 ) - 1; // between -1.0 and 1.0 s = v1 * v1 + v2 * v2; } while( s >= 1 || s == 0 ); var multiplier = Math.sqrt( - 2 * Math.log( s ) / s ); nextNextGaussian = v2 * multiplier; haveNextNextGaussian = true; return v1 * multiplier; } }; }; //! This can't be right... right? p.byte = function byte( aNumber ){ return aNumber || 0; }; p.norm = function norm( aNumber, low, high ){ var range = high-low; return ( ( 1 / range ) * aNumber ) - ( ( 1 / range ) * low ); }; p.random = function random( aMin, aMax ) { return arguments.length == 2 ? aMin + ( Math.random() * ( aMax - aMin ) ) : Math.random() * aMin ; }; // From: http://freespace.virgin.net/hugo.elias/models/m_perlin.htm p.noise = function( x, y, z ){ return arguments.length >= 2 ? PerlinNoise_2D( x, y, z ) : PerlinNoise_3D( x, x, z ) ; }; function Noise( x, y ){ var n = x + y * 57; n = ( n << 13 ) ^ n; return Math.abs( 1.0 - ( ( ( n * ( ( n * n * 15731 ) + 789221 ) + 1376312589 ) & 0x7fffffff ) / 1073741824.0 ) ); }; function SmoothedNoise( x, y ){ var corners = ( Noise( x - 1, y - 1 ) + Noise( x + 1, y - 1 ) + Noise( x - 1, y + 1 ) + Noise( x + 1, y + 1 ) ) / 16, sides = ( Noise( x - 1, y ) + Noise( x + 1, y ) + Noise( x, y - 1 ) + Noise( x, y + 1 ) ) / 8, center = Noise( x, y ) / 4; return corners + sides + center; }; function InterpolatedNoise( x, y ){ var integer_X = Math.floor( x ); var fractional_X = x - integer_X; var integer_Y = Math.floor( y ); var fractional_Y = y - integer_Y; var v1 = SmoothedNoise( integer_X, integer_Y ), v2 = SmoothedNoise( integer_X + 1, integer_Y ), v3 = SmoothedNoise( integer_X, integer_Y + 1 ), v4 = SmoothedNoise( integer_X + 1, integer_Y + 1 ); var i1 = Interpolate( v1, v2, fractional_X ), i2 = Interpolate( v3, v4, fractional_X ); return Interpolate( i1, i2, fractional_Y ); } function PerlinNoise_2D( x, y ){ var total = 0, p = 0.25, n = 3; for( var i = 0; i <= n; i++ ){ var frequency = Math.pow( 2, i ); var amplitude = Math.pow( p, i ); total += InterpolatedNoise( x * frequency, y * frequency ) * amplitude; } return total; } function Interpolate( a, b, x ){ var ft = x * p.PI; var f = (1 - Math.cos( ft ) ) * .5; return a * ( 1 - f ) + b * f; } p.constrain = function constrain( aNumber, aMin, aMax ){ return Math.min( Math.max( aNumber, aMin ), aMax ); }; p.degrees = function degrees( aAngle ){ aAngle = ( aAngle * 180 ) / p.PI; if (aAngle < 0) {aAngle = 360 + aAngle} return aAngle; }; p.size = function size( aWidth, aHeight ){ var fillStyle = curContext.fillStyle, strokeStyle = curContext.strokeStyle; curElement.width = p.width = aWidth; curElement.height = p.height = aHeight; curContext.fillStyle = fillStyle; curContext.strokeStyle = strokeStyle; }; //////////////////////////////////////////////////////////////////////////// // Style functions //////////////////////////////////////////////////////////////////////////// p.noStroke = function noStroke() { doStroke = false; }; p.noFill = function noFill() { doFill = false; }; p.smooth = function smooth() {}; p.noSmooth = function noSmooth() {}; p.fill = function fill(){ doFill = true; curContext.fillStyle = p.color.apply( this, arguments ); }; p.stroke = function stroke(){ doStroke = true; curContext.strokeStyle = p.color.apply( this, arguments ); }; p.strokeWeight = function strokeWeight( w ){ curContext.lineWidth = w; }; //////////////////////////////////////////////////////////////////////////// // Vector drawing functions //////////////////////////////////////////////////////////////////////////// p.Point = function Point( x, y ){ this.x = x; this.y = y; this.copy = function(){ return new Point( x, y ); } }; p.point = function point( x, y ){ var oldFill = curContext.fillStyle; curContext.fillStyle = curContext.strokeStyle; curContext.fillRect( Math.round( x ), Math.round( y ), 1, 1 ); curContext.fillStyle = oldFill; }; p.beginShape = function beginShape( type ){ curShape = type; curShapeCount = 0; curvePoints = []; }; p.endShape = function endShape( close ){ if( curShapeCount != 0 ){ if( close || doFill ){ curContext.lineTo( firstX, firstY ); } if( doFill ){ curContext.fill(); } if( doStroke ){ curContext.stroke(); } curContext.closePath(); curShapeCount = 0; pathOpen = false; } if( pathOpen ){ if ( doFill ){ curContext.fill(); } if ( doStroke ){ curContext.stroke(); } curContext.closePath(); curShapeCount = 0; pathOpen = false; } }; p.vertex = function vertex( x, y, x2, y2, x3, y3 ){ if( curShapeCount == 0 && curShape != p.POINTS ){ pathOpen = true; curContext.beginPath(); curContext.moveTo( x, y ); firstX = x; firstY = y; }else{ if( curShape == p.POINTS ){ p.point( x, y ); }else if( arguments.length == 2 ){ if( curShape != p.QUAD_STRIP || curShapeCount != 2 ){ curContext.lineTo( x, y ); } if( curShape == p.TRIANGLE_STRIP ){ if( curShapeCount == 2 ){ // finish shape p.endShape( p.CLOSE ); pathOpen = true; curContext.beginPath(); // redraw last line to start next shape curContext.moveTo( prevX, prevY ); curContext.lineTo( x, y ); curShapeCount = 1; } firstX = prevX; firstY = prevY; } if( curShape == p.TRIANGLE_FAN && curShapeCount == 2 ){ // finish shape p.endShape( p.CLOSE) ; pathOpen = true; curContext.beginPath(); // redraw last line to start next shape curContext.moveTo( firstX, firstY ); curContext.lineTo( x, y ); curShapeCount = 1; } if( curShape == p.QUAD_STRIP && curShapeCount == 3 ){ // finish shape curContext.lineTo( prevX, prevY ); p.endShape(p.CLOSE); pathOpen = true; curContext.beginPath(); // redraw lines to start next shape curContext.moveTo( prevX, prevY ); curContext.lineTo( x, y ); curShapeCount = 1; } if( curShape == p.QUAD_STRIP ){ firstX = secondX; firstY = secondY; secondX = prevX; secondY = prevY; } }else if( arguments.length == 4 ){ if( curShapeCount > 1 ){ curContext.moveTo( prevX, prevY ); curContext.quadraticCurveTo( firstX, firstY, x, y ); curShapeCount = 1; } }else if( arguments.length == 6 ){ curContext.bezierCurveTo( x, y, x2, y2, x3, y3 ); } } prevX = x; prevY = y; curShapeCount ++; if( curShape == p.LINES && curShapeCount == 2 || ( curShape == p.TRIANGLES ) && curShapeCount == 3 || ( curShape == p.QUADS ) && curShapeCount == 4 ){ p.endShape( p.CLOSE ); } }; p.curveVertex = function( x, y, x2, y2 ){ if( curvePoints.length < 3 ){ curvePoints.push( [ x, y ] ); }else{ var b = [], s = 1 - curTightness; /* * Matrix to convert from Catmull-Rom to cubic Bezier * where t = curTightness * |0 1 0 0 | * |(t-1)/6 1 (1-t)/6 0 | * |0 (1-t)/6 1 (t-1)/6 | * |0 0 0 0 | */ curvePoints.push( [ x, y ] ); b[ 0 ] = [ curvePoints[ 1 ][ 0 ], curvePoints[ 1 ][ 1 ] ]; b[ 1 ] = [ curvePoints[ 1 ][ 0 ] + ( s * curvePoints[ 2 ][ 0 ] - s * curvePoints[ 0 ][ 0 ] ) / 6, curvePoints[ 1 ][ 1 ] + ( s * curvePoints[ 2 ][ 1 ] - s * curvePoints[ 0 ][ 1 ] ) / 6 ]; b[ 2 ] = [ curvePoints[ 2 ][ 0 ] + ( s * curvePoints[ 1 ][ 0 ] - s * curvePoints[ 3 ][ 0 ] ) / 6, curvePoints[ 2 ][ 1 ] + ( s * curvePoints[ 1 ][ 1 ] - s * curvePoints[ 3 ][ 1 ] ) / 6 ]; b[ 3 ] = [ curvePoints[ 2 ][ 0 ], curvePoints[ 2 ][ 1 ] ]; if( !pathOpen ){ p.vertex( b[ 0 ][ 0 ], b[ 0 ][ 1 ] ); }else{ curShapeCount = 1; } p.vertex( b[ 1 ][ 0 ], b[ 1 ][ 1 ], b[ 2 ][ 0 ], b[ 2 ][ 1 ], b[ 3 ][ 0 ], b[ 3 ][ 1 ] ); curvePoints.shift(); } }; p.curveTightness = function( tightness ){ curTightness = tightness; }; p.bezierVertex = p.vertex; p.rectMode = function rectMode( aRectMode ){ curRectMode = aRectMode; }; p.imageMode = function (){}; p.ellipseMode = function ellipseMode( aEllipseMode ) { curEllipseMode = aEllipseMode; }; p.arc = function arc( x, y, width, height, start, stop ){ if( width <= 0 ){ return; } if( curEllipseMode == p.CORNER ){ x += width / 2; y += height / 2; } curContext.moveTo( x, y ); curContext.beginPath(); curContext.arc( x, y, curEllipseMode == p.CENTER_RADIUS ? width : width/2, start, stop, false ); if( doStroke ){ curContext.stroke(); } curContext.lineTo( x, y ); if( doFill ){ curContext.fill(); } curContext.closePath(); }; p.line = function line( x1, y1, x2, y2 ){ curContext.lineCap = "round"; curContext.beginPath(); curContext.moveTo( x1 || 0, y1 || 0 ); curContext.lineTo( x2 || 0, y2 || 0 ); curContext.stroke(); curContext.closePath(); }; p.bezier = function bezier( x1, y1, x2, y2, x3, y3, x4, y4 ){ curContext.lineCap = "butt"; curContext.beginPath(); curContext.moveTo( x1, y1 ); curContext.bezierCurveTo( x2, y2, x3, y3, x4, y4 ); curContext.stroke(); curContext.closePath(); }; p.triangle = function triangle( x1, y1, x2, y2, x3, y3 ){ p.beginShape(); p.vertex( x1, y1 ); p.vertex( x2, y2 ); p.vertex( x3, y3 ); p.endShape(); }; p.quad = function quad( x1, y1, x2, y2, x3, y3, x4, y4 ){ curContext.lineCap = "square"; p.beginShape(); p.vertex( x1, y1 ); p.vertex( x2, y2 ); p.vertex( x3, y3 ); p.vertex( x4, y4 ); p.endShape(); }; p.rect = function rect( x, y, width, height ){ if( !( width + height ) ){ return; } curContext.beginPath(); var offsetStart = 0; var offsetEnd = 0; if( curRectMode == p.CORNERS ){ width -= x; height -= y; } if( curRectMode == p.RADIUS ){ width *= 2; height *= 2; } if( curRectMode == p.CENTER || curRectMode == p.RADIUS ){ x -= width / 2; y -= height / 2; } curContext.rect( Math.round( x ) - offsetStart, Math.round( y ) - offsetStart, Math.round( width ) + offsetEnd, Math.round( height ) + offsetEnd ); if( doFill ){ curContext.fill(); } if( doStroke ){ curContext.stroke() }; curContext.closePath(); }; p.ellipse = function ellipse( x, y, width, height ){ x = x || 0; y = y || 0; if( width <= 0 && height <= 0 ){ return; } curContext.beginPath(); if( curEllipseMode == p.RADIUS ){ width *= 2; height *= 2; } var offsetStart = 0; // Shortcut for drawing a circle if( width == height ){ curContext.arc( x - offsetStart, y - offsetStart, width / 2, 0, p.TWO_PI, false ); }else{ var w = width/2, h = height/2, C = 0.5522847498307933; var c_x = C * w, c_y = C * h; //! Do we still need this? I hope the Canvas arc() more capable by now? curContext.moveTo( x + w, y ); curContext.bezierCurveTo( x+w , y-c_y , x+c_x , y-h , x , y-h ); curContext.bezierCurveTo( x-c_x , y-h , x-w , y-c_y , x-w , y ); curContext.bezierCurveTo( x-w , y+c_y , x-c_x , y+h, x, y+h ); curContext.bezierCurveTo( x+c_x , y+h , x+w , y+c_y , x+w , y ); } if( doFill ){ curContext.fill(); } if( doStroke ){ curContext.stroke(); } curContext.closePath(); }; //////////////////////////////////////////////////////////////////////////// // Raster drawing functions //////////////////////////////////////////////////////////////////////////// p.save = function save( file ){}; // Loads an image for display. Type is unused. Callback is fired on load. p.loadImage = function loadImage( file, type, callback ){ var img = document.createElement( 'img' ); img.src = file; img.onload = function(){ var h = this.height, w = this.width; var canvas = document.createElement( "canvas" ); canvas.width = w; canvas.height = h; var context = canvas.getContext( "2d" ); context.drawImage( this, 0, 0 ); this.data = buildImageObject( context.getImageData( 0, 0, w, h ) ); this.data.img = img; callback?callback():0; } return img; }; // Gets a single pixel or block of pixels from the current Canvas Context p.get = function get( x, y ){ if( !arguments.length ){ var c = p.createGraphics( p.width, p.height ); c.image( curContext, 0, 0 ); return c; } if( !getLoaded ){ getLoaded = buildImageObject( curContext.getImageData( 0, 0, p.width, p.height ) ); } return getLoaded.get( x, y ); }; // Creates a new Processing instance and passes it back for... processing p.createGraphics = function createGraphics( w, h ){ var canvas = document.createElement( "canvas" ); var ret = buildProcessing( canvas ); ret.size( w, h ); ret.canvas = canvas; return ret; }; // Paints a pixel array into the canvas p.set = function set( x, y, obj ){ if( obj && obj.img ){ p.image( obj, x, y ); }else{ var oldFill = curContext.fillStyle, color = obj; curContext.fillStyle = color; curContext.fillRect( Math.round( x ), Math.round( y ), 1, 1 ); curContext.fillStyle = oldFill; } }; // Gets a 1-Dimensional pixel array from Canvas p.loadPixels = function(){ p.pixels = buildImageObject( curContext.getImageData(0, 0, p.width, p.height) ).pixels; }; // Draws a 1-Dimensional pixel array to Canvas p.updatePixels = function() { var colors = /(\d+),(\d+),(\d+),(\d+)/, pixels = {}; pixels.width = p.width; pixels.height = p.height; pixels.data = []; if( curContext.createImageData ){ pixels = curContext.createImageData( p.width, p.height ); } var data = pixels.data, pos = 0; for( var i = 0, l = p.pixels.length; i < l; i++ ){ var c = ( p.pixels[i] || "rgba(0,0,0,1)" ).match( colors ); data[ pos + 0 ] = parseInt( c[ 1 ] ); data[ pos + 1 ] = parseInt( c[ 2 ] ); data[ pos + 2 ] = parseInt( c[ 3 ] ); data[ pos + 3 ] = parseFloat( c[ 4 ] ) * 255; pos += 4; } curContext.putImageData( pixels, 0, 0 ); }; // Draw an image or a color to the background p.background = function background( img ) { if( arguments.length ){ if( img.data && img.data.img ){ curBackground = img.data; }else{ curBackground = p.color.apply( this, arguments ); } } if( curBackground.img ){ p.image( img, 0, 0 ); }else{ var oldFill = curContext.fillStyle; curContext.fillStyle = curBackground + ""; curContext.fillRect( 0, 0, p.width, p.height ); curContext.fillStyle = oldFill; } }; p.AniSprite = function( prefix, frames ){ this.images = []; this.pos = 0; for( var i = 0; i < frames; i++ ){ this.images.push( prefix + p.nf( i, ( "" + frames ).length ) + ".gif" ); } this.display = function( x, y ){ p.image_old( this.images[ this.pos ], x, y ); if( ++this.pos >= frames ){ this.pos = 0; } }; this.getWidth = function(){ return getImage_old( this.images[ 0 ] ).width; }; this.getHeight = function(){ return getImage_old( this.images[ 0 ] ).height; }; }; function buildImageObject( obj ){ var pixels = obj.data; var data = p.createImage( obj.width, obj.height ); if( data.__defineGetter__ && data.__lookupGetter__ && !data.__lookupGetter__( "pixels" ) ){ var pixelsDone; data.__defineGetter__( "pixels", function(){ if( pixelsDone ){ return pixelsDone; } pixelsDone = []; for( var i = 0; i < pixels.length; i += 4 ){ pixelsDone.push( p.color( pixels[ i ], pixels[ i + 1 ], pixels[ i + 2 ], pixels[ i + 3 ]) ); } return pixelsDone; }); }else{ data.pixels = []; for ( var i = 0; i < pixels.length; i += 4 ){ data.pixels.push( p.color( pixels[ i ], pixels[ i + 1 ], pixels[ i + 2 ], pixels[ i + 3 ] )); } } return data; } p.createImage = function createImage( w, h, mode ){ var data = {}; data.width = w; data.height = h; data.data = []; if( curContext.createImageData ) { data = curContext.createImageData( w, h ); } data.pixels = new Array( w * h ); data.get = function( x, y ){ return this.pixels[ w * y + x ]; }; data._mask = null; data.mask = function( img ){ this._mask = img; }; data.loadPixels = function(){}; data.updatePixels = function(){}; return data; }; function getImage( img ){ if( typeof img == "string" ){ return document.getElementById( img ); } if( img.img ){ return img.img; }else if( img.getContext || img.canvas ){ img.pixels = img.getContext( '2d' ).createImageData( img.width, img.height ); } for( var i = 0, l = img.pixels.length; i < l; i++ ){ var pos = i * 4; var c = ( img.pixels[ i ] || "rgba(0,0,0,1)" ).slice( 5, - 1 ).split( "," ); img.data[ pos + 0 ] = parseInt( c[ 0 ] ); img.data[ pos + 1 ] = parseInt( c[ 1 ] ); img.data[ pos + 2 ] = parseInt( c[ 2 ] ); img.data[ pos + 3 ] = parseFloat( c[ 3 ] ) * 100; } var canvas = document.createElement( "canvas" ); canvas.width = img.width; canvas.height = img.height; var context = canvas.getContext( "2d" ); context.putImageData( img.pixels, 0, 0 ); img.canvas = canvas; return img; } // Depreciating "getImage_old" from PJS - currently here to support AniSprite function getImage_old( img ){ if( typeof img == "string" ){ return document.getElementById( img ); } if( img.img || img.canvas ){ return img.img || img.canvas; } for( var i = 0, l = img.pixels.length; i < l; i++ ){ var pos = i * 4; var c = ( img.pixels[ i ] || "rgba(0,0,0,1)" ).slice( 5, - 1 ).split( "," ); img.data[ pos + 0 ] = parseInt( c[ 0 ] ); img.data[ pos + 1 ] = parseInt( c[ 1 ] ); img.data[ pos + 2 ] = parseInt( c[ 2 ] ); img.data[ pos + 3 ] = parseFloat( c[ 3 ] ) * 100; } var canvas = document.createElement( "canvas" ); canvas.width = img.width; canvas.height = img.height; var context = canvas.getContext( "2d" ); context.putImageData( img, 0, 0 ); img.canvas = canvas; return canvas; } // Depreciating "getImage_old" from PJS - currently here to support AniSprite p.image_old=function image_old(img,x,y,w,h){ x = x || 0; y = y || 0; var obj = getImage( img ); if( curTint >= 0 ){ var oldAlpha = curContext.globalAlpha; curContext.globalAlpha = curTint / opacityRange; } if( arguments.length == 3 ){ curContext.drawImage( obj, x, y ); }else{ curContext.drawImage( obj, x, y, w, h ); } if( curTint >= 0 ){ curContext.globalAlpha = oldAlpha; } if( img._mask ){ var oldComposite = curContext.globalCompositeOperation; curContext.globalCompositeOperation = "darker"; p.image( img._mask, x, y ); curContext.globalCompositeOperation = oldComposite; } }; // Draws an image to the Canvas p.image = function image( img, x, y, w, h ){ if( img.data || img.canvas ){ x = x || 0; y = y || 0; var obj = getImage( img.data || img.canvas ); if( curTint >= 0 ){ var oldAlpha = curContext.globalAlpha; curContext.globalAlpha = curTint / opacityRange; } if( arguments.length == 3 ){ curContext.drawImage( obj, x, y ); }else{ curContext.drawImage( obj, x, y, w, h ); } if( curTint >= 0 ){ curContext.globalAlpha = oldAlpha; } if( img._mask ){ var oldComposite = curContext.globalCompositeOperation; curContext.globalCompositeOperation = "darker"; p.image( img._mask, x, y ); curContext.globalCompositeOperation = oldComposite; } } if( typeof img == 'string' ){ } }; // Clears hole in the Canvas or the whole Canvas p.clear = function clear ( x, y, width, height ) { if( arguments.length == 0 ){ curContext.clearRect( x, y, width, height ); }else{ curContext.clearRect( 0, 0, p.width, p.height ); } } p.tint = function tint( rgb, a ){ curTint = a; }; //////////////////////////////////////////////////////////////////////////// // Font handling //////////////////////////////////////////////////////////////////////////// // Loads a font from an SVG or Canvas API p.loadFont = function loadFont( name ){ if( name.indexOf( ".svg" ) == - 1 ){ return { name: name, width: function( str ){ if( curContext.mozMeasureText ){ return curContext.mozMeasureText( typeof str == "number" ? String.fromCharCode( str ) : str ) / curTextSize; }else{ return 0; } } }; }else{ // If the font is a glyph, calculate by SVG table var font = p.loadGlyphs( name ); return { name : name, glyph : true, units_per_em : font.units_per_em, horiz_adv_x : 1 / font.units_per_em * font.horiz_adv_x, ascent : font.ascent, descent : font.descent, width : function( str ){ var width = 0; var len = str.length; for( var i = 0; i < len; i++ ){ try{ width += parseFloat( p.glyphLook( p.glyphTable[ name ], str[ i ] ).horiz_adv_x ); } catch( e ){ ; } } return width / p.glyphTable[ name ].units_per_em; } } } }; // Sets a 'current font' for use p.textFont = function textFont( name, size ){ curTextFont = name; p.textSize( size ); }; // Sets the font size p.textSize = function textSize( size ){ //! Was this meant to return textSize value if no arguments were passed? if( size ){ curTextSize = size; } }; p.textAlign = function textAlign(){}; // A lookup table for characters that can not be referenced by Object p.glyphLook = function glyphLook( font, chr ){ try{ switch( chr ){ case "1" : return font[ "one" ]; break; case "2" : return font[ "two" ]; break; case "3" : return font[ "three" ]; break; case "4" : return font[ "four" ]; break; case "5" : return font[ "five" ]; break; case "6" : return font[ "six" ]; break; case "7" : return font[ "seven" ]; break; case "8" : return font[ "eight" ]; break; case "9" : return font[ "nine" ]; break; case "0" : return font[ "zero" ]; break; case " " : return font[ "space" ]; break; case "$" : return font[ "dollar" ]; break; case "!" : return font[ "exclam" ]; break; case '"' : return font[ "quotedbl" ]; break; case "#" : return font[ "numbersign" ]; break; case "%" : return font[ "percent" ]; break; case "&" : return font[ "ampersand" ]; break; case "'" : return font[ "quotesingle" ]; break; case "(" : return font[ "parenleft" ]; break; case ")" : return font[ "parenright" ]; break; case "*" : return font[ "asterisk" ]; break; case "+" : return font[ "plus" ]; break; case "," : return font[ "comma" ]; break; case "-" : return font[ "hyphen" ]; break; case "." : return font[ "period" ]; break; case "/" : return font[ "slash" ]; break; case "_" : return font[ "underscore" ]; break; case ":" : return font[ "colon" ]; break; case ";" : return font[ "semicolon" ]; break; case "<" : return font[ "less" ]; break; case "=" : return font[ "equal" ]; break; case ">" : return font[ "greater" ]; break; case "?" : return font[ "question" ]; break; case "@" : return font[ "at" ]; break; case "[" : return font[ "bracketleft" ]; break; case "\\" : return font[ "backslash" ]; break; case "]" : return font[ "bracketright" ]; break; case "^" : return font[ "asciicircum" ]; break; case "`" : return font[ "grave" ]; break; case "{" : return font[ "braceleft" ]; break; case "|" : return font[ "bar" ]; break; case "}" : return font[ "braceright" ]; break; case "~" : return font[ "asciitilde" ]; break; // If the character is not 'special', access it by object reference default : return font[ chr ]; break; } }catch( e ){ ; } } // Print some text to the Canvas p.text = function text( str, x, y ){ // If the font is a standard Canvas font... if( !curTextFont.glyph ){ if( str && curContext.mozDrawText ){ curContext.save(); curContext.mozTextStyle = curTextSize + "px " + curTextFont.name; curContext.translate( x, y ); curContext.mozDrawText( typeof str == "number" ? String.fromCharCode( str ) : str ) ; curContext.restore(); } }else{ // If the font is a Batik SVG font... var font = p.glyphTable[ curTextFont.name ]; curContext.save(); curContext.translate( x, y + curTextSize ); var upem = font[ "units_per_em" ], newScale = 1 / upem * curTextSize; curContext.scale( newScale, newScale ); var len = str.length; for(var i = 0; i < len; i++ ){ // Test character against glyph table try{ p.glyphLook( font, str[ i ] ).draw(); } catch( e ){ ; } } curContext.restore(); } }; // Load Batik SVG Fonts and parse to pre-def objects for quick rendering p.loadGlyphs = function loadGlyph( url ){ // Load and parse Batik SVG font as XML into a Processing Glyph object var loadXML = function loadXML(){ try{ var xmlDoc = new ActiveXObject( "Microsoft.XMLDOM" ); } catch( e ){ try{ xmlDoc=document.implementation.createDocument( "", "", null ); } catch( e ){ p.println( e.message ); return; } }; try{ xmlDoc.async = false; xmlDoc.load( url ); parse( xmlDoc.getElementsByTagName( "svg" )[ 0 ] ); } catch( e ){ // Google Chrome, Safari etc. try{ p.println( e.message ); var xmlhttp = new window.XMLHttpRequest(); xmlhttp.open( "GET", url, false ); xmlhttp.send( null ); parse( xmlhttp.responseXML.documentElement ); } catch( e ){ ; } } }; // Return arrays of SVG commands and coords var regex = function regex( needle, hay ){ var regexp = new RegExp( needle, "g" ), results = [], i = 0; while( results[ i ] = regexp.exec( hay ) ){ i++; } return results; } // Parse SVG font-file into block of Canvas commands var parse = function parse( svg ){ // Store font attributes var font = svg.getElementsByTagName( "font" ); p.glyphTable[ url ][ "horiz_adv_x" ] = font[ 0 ].getAttribute( "horiz-adv-x" ); var font_face = svg.getElementsByTagName( "font-face" )[ 0 ]; p.glyphTable[ url ][ "units_per_em" ] = parseFloat( font_face.getAttribute( "units-per-em") ); p.glyphTable[ url ][ "ascent" ] = parseFloat( font_face.getAttribute( "ascent" ) ); p.glyphTable[ url ][ "descent" ] = parseFloat( font_face.getAttribute( "descent" ) ); var getXY = "[0-9\-]+", glyph = svg.getElementsByTagName( "glyph" ), len = glyph.length; // Loop through each glyph in the SVG for( var i = 0; i < len; i++ ){ // Store attributes for this glyph var unicode = glyph[ i ].getAttribute( "unicode" ); var name = glyph[ i ].getAttribute( "glyph-name" ); var horiz_adv_x = glyph[ i ].getAttribute( "horiz-adv-x" ); if( horiz_adv_x == null ){ var horiz_adv_x = p.glyphTable[ url ][ 'horiz_adv_x' ]; } var buildPath = function buildPath( d ){ var c = regex( "[A-Za-z][0-9\- ]+|Z", d ); // Begin storing path object var path = "var path={draw:function(){curContext.beginPath();curContext.save();"; var x = 0, y = 0, cx = 0, cy = 0, nx = 0, ny = 0, d = 0, a = 0, lastCom = "", lenC = c.length - 1; // Loop through SVG commands translating to canvas eqivs functions in path object for( var j = 0; j < lenC; j++ ){ var com = c[ j ][ 0 ], xy = regex( getXY, com ); switch( com[ 0 ] ){ case "M": //curContext.moveTo(x,-y); x = parseFloat( xy[ 0 ][ 0 ] ); y = parseFloat( xy[ 1 ][ 0 ] ); //! Brackets needed on (-y)? path += "curContext.moveTo("+ x +","+ (-y) +");"; break; case "L": //curContext.lineTo(x,-y); x = parseFloat( xy[ 0 ][ 0 ] ); y = parseFloat( xy[ 1 ][ 0 ] ); path += "curContext.lineTo("+ x +","+ (-y) +");"; break; case "H"://curContext.lineTo(x,-y) x = parseFloat( xy[ 0 ][ 0 ] ); path += "curContext.lineTo("+ x +","+ (-y) +");"; break; case "V"://curContext.lineTo(x,-y); y = parseFloat( xy[ 0 ][ 0 ] ); path += "curContext.lineTo("+ x +","+ (-y) +");"; break; case "T"://curContext.quadraticCurveTo(cx,-cy,nx,-ny); nx = parseFloat( xy[ 0 ][ 0 ] ); ny = parseFloat( xy[ 1 ][ 0 ] ); if( lastCom == "Q" || lastCom == "T" ){ d = Math.sqrt( Math.pow( x - cx, 2 ) + Math.pow( cy - y, 2 ) ); a = Math.PI+Math.atan2( cx - x, cy - y ); cx = x + ( Math.sin( a ) * ( d ) ); cy = y + ( Math.cos( a ) * ( d ) ); }else{ cx = x; cy = y; } path += "curContext.quadraticCurveTo("+ cx +","+ (-cy) +","+ nx +","+ (-ny) +");"; x = nx; y = ny; break; case "Q"://curContext.quadraticCurveTo(cx,-cy,nx,-ny); cx = parseFloat( xy[ 0 ][ 0 ] ); cy = parseFloat( xy[ 1 ][ 0 ] ); nx = parseFloat( xy[ 2 ][ 0 ] ); ny = parseFloat( xy[ 3 ][ 0 ] ); path += "curContext.quadraticCurveTo("+ cx +","+ (-cy) +","+ nx +","+ (-ny) +");"; x = nx; y = ny; break; case "Z"://curContext.closePath(); path += "curContext.closePath();"; break; } lastCom = com[ 0 ]; } path += "doStroke?curContext.stroke():0;"; path += "doFill?curContext.fill():0;"; path += "curContext.restore();"; path += "curContext.translate("+ horiz_adv_x +",0);"; path += "}}"; return path; } var d = glyph[ i ].getAttribute( "d" ); // Split path commands in glpyh if( d !== undefined ){ var path = buildPath( d ); eval( path ); // Store glyph data to table object p.glyphTable[ url ][ name ] = { name : name, unicode : unicode, horiz_adv_x : horiz_adv_x, draw : path.draw } } } // finished adding glyphs to table } // Create a new object in glyphTable to store this font p.glyphTable[ url ] = {}; // Begin loading the Batik SVG font... loadXML( url ); // Return the loaded font for attribute grabbing return p.glyphTable[ url ]; } //////////////////////////////////////////////////////////////////////////// // Class methods //////////////////////////////////////////////////////////////////////////// p.extendClass = function extendClass( obj, args, fn ){ if( arguments.length == 3 ){ fn.apply( obj, args ); }else{ args.call( obj ); } }; p.addMethod = function addMethod( object, name, fn ){ if( object[ name ] ){ var args = fn.length, oldfn = object[ name ]; object[ name ] = function(){ if( arguments.length == args ){ return fn.apply( this, arguments ); }else{ return oldfn.apply( this, arguments ); } }; }else{ object[ name ] = fn; } }; //////////////////////////////////////////////////////////////////////////// // Set up environment //////////////////////////////////////////////////////////////////////////// p.init = function init(code){ p.stroke( 0 ); p.fill( 255 ); // Canvas has trouble rendering single pixel stuff on whole-pixel // counts, so we slightly offset it (this is super lame). curContext.translate( 0.5, 0.5 ); // The fun bit! if( code ){ (function( Processing ){ with ( p ){ eval(parse(code, p)); } })( p ); } if( p.setup ){ inSetup = true; p.setup(); } inSetup = false; if( p.draw ){ if( !doLoop ){ p.redraw(); } else { p.loop(); } } ////////////////////////////////////////////////////////////////////////// // Event handling ////////////////////////////////////////////////////////////////////////// attach( curElement, "mousemove" , function(e){ var scrollX = window.scrollX != null ? window.scrollX : window.pageXOffset; var scrollY = window.scrollY != null ? window.scrollY : window.pageYOffset; p.pmouseX = p.mouseX; p.pmouseY = p.mouseY; p.mouseX = e.clientX - curElement.offsetLeft + scrollX; p.mouseY = e.clientY - curElement.offsetTop + scrollY; if( p.mouseMoved ){ p.mouseMoved(); } if( mousePressed && p.mouseDragged ){ p.mouseDragged(); } }); attach( curElement, "mouseout" , function( e ){ p.cursor("auto"); }); attach( curElement, "mousedown", function( e ){ mousePressed = true; switch(e.which){ case 1: p.mouseButton = p.LEFT; break; case 2: p.mouseButton = p.CENTER; break; case 3: p.mouseButton = p.RIGHT; break; } p.mouseDown = true; if( typeof p.mousePressed == "function" ){ p.mousePressed(); } else{ p.mousePressed = true; } }); attach( curElement, "contextmenu", function( e ){ e.preventDefault(); e.stopPropagation(); }); attach( curElement, "mouseup", function( e ){ mousePressed = false; if( p.mouseClicked ){ p.mouseClicked(); } if( typeof p.mousePressed != "function" ){ p.mousePressed = false; } if( p.mouseReleased ){ p.mouseReleased(); } }); attach( document, "keydown", function( e ){ keyPressed = true; p.key = e.keyCode + 32; var i, len = p.codedKeys.length; for( i=0; i < len; i++ ){ if( p.key == p.codedKeys[ i ] ){ switch(p.key){ case 70: p.keyCode = p.UP ; break; case 71: p.keyCode = p.RIGHT ; break; case 72: p.keyCode = p.DOWN ; break; case 69: p.keyCode = p.LEFT ; break; } p.key=p.CODED; } } if( e.shiftKey ){ p.key = String.fromCharCode(p.key).toUpperCase().charCodeAt( 0 ); } if( typeof p.keyPressed == "function" ){ p.keyPressed(); } else{ p.keyPressed = true; } }); attach( document, "keyup", function( e ){ keyPressed = false; if( typeof p.keyPressed != "function" ){ p.keyPressed = false; } if( p.keyReleased ){ p.keyReleased(); } }); function attach(elem, type, fn) { if( elem.addEventListener ){ elem.addEventListener( type, fn, false ); } else{ elem.attachEvent( "on" + type, fn ); } } }; return p; } })(); sagenb-1.0.1/sagenb/data/jquery/000077500000000000000000000000001311436262400164415ustar00rootroot00000000000000sagenb-1.0.1/sagenb/data/jquery/plugins/000077500000000000000000000000001311436262400201225ustar00rootroot00000000000000sagenb-1.0.1/sagenb/data/jquery/plugins/achtung/000077500000000000000000000000001311436262400215535ustar00rootroot00000000000000sagenb-1.0.1/sagenb/data/jquery/plugins/achtung/AUTHORS.txt000066400000000000000000000020541311436262400234420ustar00rootroot00000000000000achtung 0.3.0 Josh Varner http://achtung-ui.googlecode.com/ =============================================================================== For portions from jQuery UI: =============================================================================== jQuery UI Authors (http://ui.jquery.com/about) This software consists of voluntary contributions made by many individuals. For exact contribution history, see the revision history and logs, available at http://jquery-ui.googlecode.com/svn/ Brandon Aaron Paul Bakaus (paulbakaus.com) David Bolter Rich Caloggero Chi Cheng (cloudream@gmail.com) Colin Clark (http://colin.atrc.utoronto.ca/) Michelle D'Souza Aaron Eisenberger (aaronchi@gmail.com) Ariel Flesler Bohdan Ganicky Scott González Marc Grabanski (m@marcgrabanski.com) Klaus Hartl (stilbuero.de) Scott Jehl Cody Lindley Eduardo Lundgren (eduardolundgren@gmail.com) Todd Parker John Resig Patty Toland Ca-Phun Ung (yelotofu.com) Keith Wood (kbwood@virginbroadband.com.au) Maggie Costello Wachs Richard D. Worth (rdworth.org) Jörn Zaefferer (bassistance.de) sagenb-1.0.1/sagenb/data/jquery/plugins/achtung/LICENSE.txt000066400000000000000000000021201311436262400233710ustar00rootroot00000000000000achtung 0.3.0 Copyright (c) 2009 Josh Varner, http://achtung-ui.googlecode.com/ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. sagenb-1.0.1/sagenb/data/jquery/plugins/achtung/ui.achtung-min.css000066400000000000000000000254421311436262400251220ustar00rootroot00000000000000* html #achtung-overlay{position:absolute;}* html .achtung{width:280px;}#achtung-overlay{overflow:hidden;position:fixed;top:15px;right:15px;width:280px;z-index:50;}.achtung{display:none;margin-bottom:8px;padding:15px 15px;background-color:#000;color:white;width:250px;font-weight:bold;position:relative;overflow:hidden;-moz-box-shadow:#aaa 1px 1px 2px;-webkit-box-shadow:#aaa 1px 1px 2px;box-shadow:#aaa 1px 1px 2px;-moz-border-radius:4px;-webkit-border-radius:4px;border-radius:4px;opacity:.85;filter:Alpha(Opacity=85);}.ui-icon{display:block;text-indent:-99999px;overflow:hidden;background-repeat:no-repeat;}.ui-icon{width:16px;height:16px;background-image:url(images/ui-icons_222222_256x240.png);}.ui-icon-carat-1-n{background-position:0 0;}.ui-icon-carat-1-ne{background-position:-16px 0;}.ui-icon-carat-1-e{background-position:-32px 0;}.ui-icon-carat-1-se{background-position:-48px 0;}.ui-icon-carat-1-s{background-position:-64px 0;}.ui-icon-carat-1-sw{background-position:-80px 0;}.ui-icon-carat-1-w{background-position:-96px 0;}.ui-icon-carat-1-nw{background-position:-112px 0;}.ui-icon-carat-2-n-s{background-position:-128px 0;}.ui-icon-carat-2-e-w{background-position:-144px 0;}.ui-icon-triangle-1-n{background-position:0 -16px;}.ui-icon-triangle-1-ne{background-position:-16px -16px;}.ui-icon-triangle-1-e{background-position:-32px -16px;}.ui-icon-triangle-1-se{background-position:-48px -16px;}.ui-icon-triangle-1-s{background-position:-64px -16px;}.ui-icon-triangle-1-sw{background-position:-80px -16px;}.ui-icon-triangle-1-w{background-position:-96px -16px;}.ui-icon-triangle-1-nw{background-position:-112px -16px;}.ui-icon-triangle-2-n-s{background-position:-128px -16px;}.ui-icon-triangle-2-e-w{background-position:-144px -16px;}.ui-icon-arrow-1-n{background-position:0 -32px;}.ui-icon-arrow-1-ne{background-position:-16px -32px;}.ui-icon-arrow-1-e{background-position:-32px -32px;}.ui-icon-arrow-1-se{background-position:-48px -32px;}.ui-icon-arrow-1-s{background-position:-64px -32px;}.ui-icon-arrow-1-sw{background-position:-80px -32px;}.ui-icon-arrow-1-w{background-position:-96px -32px;}.ui-icon-arrow-1-nw{background-position:-112px -32px;}.ui-icon-arrow-2-n-s{background-position:-128px -32px;}.ui-icon-arrow-2-ne-sw{background-position:-144px -32px;}.ui-icon-arrow-2-e-w{background-position:-160px -32px;}.ui-icon-arrow-2-se-nw{background-position:-176px -32px;}.ui-icon-arrowstop-1-n{background-position:-192px -32px;}.ui-icon-arrowstop-1-e{background-position:-208px -32px;}.ui-icon-arrowstop-1-s{background-position:-224px -32px;}.ui-icon-arrowstop-1-w{background-position:-240px -32px;}.ui-icon-arrowthick-1-n{background-position:0 -48px;}.ui-icon-arrowthick-1-ne{background-position:-16px -48px;}.ui-icon-arrowthick-1-e{background-position:-32px -48px;}.ui-icon-arrowthick-1-se{background-position:-48px -48px;}.ui-icon-arrowthick-1-s{background-position:-64px -48px;}.ui-icon-arrowthick-1-sw{background-position:-80px -48px;}.ui-icon-arrowthick-1-w{background-position:-96px -48px;}.ui-icon-arrowthick-1-nw{background-position:-112px -48px;}.ui-icon-arrowthick-2-n-s{background-position:-128px -48px;}.ui-icon-arrowthick-2-ne-sw{background-position:-144px -48px;}.ui-icon-arrowthick-2-e-w{background-position:-160px -48px;}.ui-icon-arrowthick-2-se-nw{background-position:-176px -48px;}.ui-icon-arrowthickstop-1-n{background-position:-192px -48px;}.ui-icon-arrowthickstop-1-e{background-position:-208px -48px;}.ui-icon-arrowthickstop-1-s{background-position:-224px -48px;}.ui-icon-arrowthickstop-1-w{background-position:-240px -48px;}.ui-icon-arrowreturnthick-1-w{background-position:0 -64px;}.ui-icon-arrowreturnthick-1-n{background-position:-16px -64px;}.ui-icon-arrowreturnthick-1-e{background-position:-32px -64px;}.ui-icon-arrowreturnthick-1-s{background-position:-48px -64px;}.ui-icon-arrowreturn-1-w{background-position:-64px -64px;}.ui-icon-arrowreturn-1-n{background-position:-80px -64px;}.ui-icon-arrowreturn-1-e{background-position:-96px -64px;}.ui-icon-arrowreturn-1-s{background-position:-112px -64px;}.ui-icon-arrowrefresh-1-w{background-position:-128px -64px;}.ui-icon-arrowrefresh-1-n{background-position:-144px -64px;}.ui-icon-arrowrefresh-1-e{background-position:-160px -64px;}.ui-icon-arrowrefresh-1-s{background-position:-176px -64px;}.ui-icon-arrow-4{background-position:0 -80px;}.ui-icon-arrow-4-diag{background-position:-16px -80px;}.ui-icon-extlink{background-position:-32px -80px;}.ui-icon-newwin{background-position:-48px -80px;}.ui-icon-refresh{background-position:-64px -80px;}.ui-icon-shuffle{background-position:-80px -80px;}.ui-icon-transfer-e-w{background-position:-96px -80px;}.ui-icon-transferthick-e-w{background-position:-112px -80px;}.ui-icon-folder-collapsed{background-position:0 -96px;}.ui-icon-folder-open{background-position:-16px -96px;}.ui-icon-document{background-position:-32px -96px;}.ui-icon-document-b{background-position:-48px -96px;}.ui-icon-note{background-position:-64px -96px;}.ui-icon-mail-closed{background-position:-80px -96px;}.ui-icon-mail-open{background-position:-96px -96px;}.ui-icon-suitcase{background-position:-112px -96px;}.ui-icon-comment{background-position:-128px -96px;}.ui-icon-person{background-position:-144px -96px;}.ui-icon-print{background-position:-160px -96px;}.ui-icon-trash{background-position:-176px -96px;}.ui-icon-locked{background-position:-192px -96px;}.ui-icon-unlocked{background-position:-208px -96px;}.ui-icon-bookmark{background-position:-224px -96px;}.ui-icon-tag{background-position:-240px -96px;}.ui-icon-home{background-position:0 -112px;}.ui-icon-flag{background-position:-16px -112px;}.ui-icon-calendar{background-position:-32px -112px;}.ui-icon-cart{background-position:-48px -112px;}.ui-icon-pencil{background-position:-64px -112px;}.ui-icon-clock{background-position:-80px -112px;}.ui-icon-disk{background-position:-96px -112px;}.ui-icon-calculator{background-position:-112px -112px;}.ui-icon-zoomin{background-position:-128px -112px;}.ui-icon-zoomout{background-position:-144px -112px;}.ui-icon-search{background-position:-160px -112px;}.ui-icon-wrench{background-position:-176px -112px;}.ui-icon-gear{background-position:-192px -112px;}.ui-icon-heart{background-position:-208px -112px;}.ui-icon-star{background-position:-224px -112px;}.ui-icon-link{background-position:-240px -112px;}.ui-icon-cancel{background-position:0 -128px;}.ui-icon-plus{background-position:-16px -128px;}.ui-icon-plusthick{background-position:-32px -128px;}.ui-icon-minus{background-position:-48px -128px;}.ui-icon-minusthick{background-position:-64px -128px;}.ui-icon-close{background-position:-80px -128px;}.ui-icon-closethick{background-position:-96px -128px;}.ui-icon-key{background-position:-112px -128px;}.ui-icon-lightbulb{background-position:-128px -128px;}.ui-icon-scissors{background-position:-144px -128px;}.ui-icon-clipboard{background-position:-160px -128px;}.ui-icon-copy{background-position:-176px -128px;}.ui-icon-contact{background-position:-192px -128px;}.ui-icon-image{background-position:-208px -128px;}.ui-icon-video{background-position:-224px -128px;}.ui-icon-script{background-position:-240px -128px;}.ui-icon-alert{background-position:0 -144px;}.ui-icon-info{background-position:-16px -144px;}.ui-icon-notice{background-position:-32px -144px;}.ui-icon-help{background-position:-48px -144px;}.ui-icon-check{background-position:-64px -144px;}.ui-icon-bullet{background-position:-80px -144px;}.ui-icon-radio-off{background-position:-96px -144px;}.ui-icon-radio-on{background-position:-112px -144px;}.ui-icon-pin-w{background-position:-128px -144px;}.ui-icon-pin-s{background-position:-144px -144px;}.ui-icon-play{background-position:0 -160px;}.ui-icon-pause{background-position:-16px -160px;}.ui-icon-seek-next{background-position:-32px -160px;}.ui-icon-seek-prev{background-position:-48px -160px;}.ui-icon-seek-end{background-position:-64px -160px;}.ui-icon-seek-first{background-position:-80px -160px;}.ui-icon-stop{background-position:-96px -160px;}.ui-icon-eject{background-position:-112px -160px;}.ui-icon-volume-off{background-position:-128px -160px;}.ui-icon-volume-on{background-position:-144px -160px;}.ui-icon-power{background-position:0 -176px;}.ui-icon-signal-diag{background-position:-16px -176px;}.ui-icon-signal{background-position:-32px -176px;}.ui-icon-battery-0{background-position:-48px -176px;}.ui-icon-battery-1{background-position:-64px -176px;}.ui-icon-battery-2{background-position:-80px -176px;}.ui-icon-battery-3{background-position:-96px -176px;}.ui-icon-circle-plus{background-position:0 -192px;}.ui-icon-circle-minus{background-position:-16px -192px;}.ui-icon-circle-close{background-position:-32px -192px;}.ui-icon-circle-triangle-e{background-position:-48px -192px;}.ui-icon-circle-triangle-s{background-position:-64px -192px;}.ui-icon-circle-triangle-w{background-position:-80px -192px;}.ui-icon-circle-triangle-n{background-position:-96px -192px;}.ui-icon-circle-arrow-e{background-position:-112px -192px;}.ui-icon-circle-arrow-s{background-position:-128px -192px;}.ui-icon-circle-arrow-w{background-position:-144px -192px;}.ui-icon-circle-arrow-n{background-position:-160px -192px;}.ui-icon-circle-zoomin{background-position:-176px -192px;}.ui-icon-circle-zoomout{background-position:-192px -192px;}.ui-icon-circle-check{background-position:-208px -192px;}.ui-icon-circlesmall-plus{background-position:0 -208px;}.ui-icon-circlesmall-minus{background-position:-16px -208px;}.ui-icon-circlesmall-close{background-position:-32px -208px;}.ui-icon-squaresmall-plus{background-position:-48px -208px;}.ui-icon-squaresmall-minus{background-position:-64px -208px;}.ui-icon-squaresmall-close{background-position:-80px -208px;}.ui-icon-grip-dotted-vertical{background-position:0 -224px;}.ui-icon-grip-dotted-horizontal{background-position:-16px -224px;}.ui-icon-grip-solid-vertical{background-position:-32px -224px;}.ui-icon-grip-solid-horizontal{background-position:-48px -224px;}.ui-icon-gripsmall-diagonal-se{background-position:-64px -224px;}.ui-icon-grip-diagonal-se{background-position:-80px -224px;}.achtung .achtung-message-icon{margin-top:0;margin-left:-.5em;margin-right:.5em;float:left;zoom:1;}.achtung .ui-icon.achtung-close-button{overflow:hidden;float:right;position:relative;top:-8px;right:-8px;cursor:pointer;background-image:url(images/ui-icons_cccccc_256x240.png);}.achtung .ui-icon.achtung-close-button-hover{background-image:url(images/ui-icons_ffffff_256x240.png);}.achtungSuccess,.achtungFail,.achtungWait{opacity:.93;filter:Alpha(Opacity=93);}.achtungSuccess{background-color:#4DB559;}.achtungFail{background-color:#D64450;}.achtungWait{background-color:#658093;}.achtungSuccess .ui-icon.achtung-close-button,.achtungFail .ui-icon.achtung-close-button{background-image:url(images/ui-icons_444444_256x240.png);}.achtungSuccess .ui-icon.achtung-close-button-hover,.achtungFail .ui-icon.achtung-close-button-hover{background-image:url(images/ui-icons_000000_256x240.png);}.achtung .wait-icon{background-image:url('images/wait.gif');}.achtung .achtung-message{display:inline;}sagenb-1.0.1/sagenb/data/jquery/plugins/achtung/ui.achtung-mod.js000066400000000000000000000212521311436262400247350ustar00rootroot00000000000000// This modified version adds optional callbacks at the end of a // timeout (in lieu of close) and when a user clicks on the close // button (just before close). /** * achtung 0.3.0 * * Growl-like notifications for jQuery * * Copyright (c) 2009 Josh Varner * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. * * @license http://www.opensource.org/licenses/mit-license.php * @author Josh Varner */ /*globals jQuery,clearTimeout,document,navigator,setTimeout */ (function($) { /** * This is based on the jQuery UI $.widget code. I would have just made this * a $.widget but I didn't want the jQuery UI dependency. */ $.fn.achtung = function(options) { var isMethodCall = (typeof options === 'string'), args = Array.prototype.slice.call(arguments, 0), name = 'achtung'; // handle initialization and non-getter methods return this.each(function() { var instance = $.data(this, name); // prevent calls to internal methods if (isMethodCall && options.substring(0, 1) === '_') { return this; } // constructor (!instance && !isMethodCall && $.data(this, name, new $.achtung(this))._init(args)); // method call (instance && isMethodCall && $.isFunction(instance[options]) && instance[options].apply(instance, args.slice(1))); }); }; $.achtung = function(element) { var args = Array.prototype.slice.call(arguments, 0), $el; if (!element || !element.nodeType) { $el = $('
'); return $el.achtung.apply($el, args); } this.$container = $(element); }; /** * Static members **/ $.extend($.achtung, { version: '0.3.0', $overlay: false, defaults: { timeout: 10, // Called at end of a timeout *instead* of close. Inside the // callback, close explicitly with this.close(). onTimeout: null, // Called on clicking the close button but before close. onCloseButton: null, disableClose: false, icon: false, className: '', animateClassSwitch: false, showEffects: {'opacity':'toggle','height':'toggle'}, hideEffects: {'opacity':'toggle','height':'toggle'}, showEffectDuration: 500, hideEffectDuration: 700 } }); /** * Non-static members **/ $.extend($.achtung.prototype, { $container: false, closeTimer: false, options: {}, _init: function(args) { var o, self = this; args = $.isArray(args) ? args : []; args.unshift($.achtung.defaults); args.unshift({}); o = this.options = $.extend.apply($, args); if (!$.achtung.$overlay) { $.achtung.$overlay = $('
').appendTo(document.body); } if (!o.disableClose) { $('') .click(function () { if ($.isFunction(o.onCloseButton)) { o.onCloseButton.call(self); } self.close(); }) .hover(function () { $(this).addClass('achtung-close-button-hover'); }, function () { $(this).removeClass('achtung-close-button-hover'); }) .prependTo(this.$container); } this.changeIcon(o.icon, true); if (o.message) { this.$container.append($('' + o.message + '')); } (o.className && this.$container.addClass(o.className)); (o.css && this.$container.css(o.css)); this.$container .addClass('achtung') .appendTo($.achtung.$overlay); if (o.showEffects) { this.$container.animate(o.showEffects, o.showEffectDuration); } else { this.$container.show(); } if (o.timeout > 0) { this.timeout(o.timeout); } }, timeout: function(timeout) { var self = this; if (this.closeTimer) { clearTimeout(this.closeTimer); } this.closeTimer = setTimeout(function() { if ($.isFunction(self.options.onTimeout)) { self.options.onTimeout.call(self); } else { self.close(); } }, timeout * 1000); this.options.timeout = timeout; }, /** * Change the CSS class associated with this message, using * a transition if available (not availble in Safari/Webkit). * If no transition is available, the switch is immediate. * * #LATER Check if this has been corrected in Webkit or jQuery UI * #TODO Make transition time configurable * @param newClass string Name of new class to associate */ changeClass: function(newClass) { var self = this; if (this.options.className === newClass) { return; } this.$container.queue(function() { if (!self.options.animateClassSwitch || /webkit/.test(navigator.userAgent.toLowerCase()) || !$.isFunction($.fn.switchClass)) { self.$container.removeClass(self.options.className); self.$container.addClass(newClass); } else { self.$container.switchClass(self.options.className, newClass, 500); } self.options.className = newClass; self.$container.dequeue(); }); }, changeIcon: function(newIcon, force) { var self = this; if ((force !== true || newIcon === false) && this.options.icon === newIcon) { return; } if (force || this.options.icon === false) { this.$container.prepend($('')); this.options.icon = newIcon; return; } else if (newIcon === false) { this.$container.find('.achtung-message-icon').remove(); this.options.icon = false; return; } this.$container.queue(function() { var $span = $('.achtung-message-icon', self.$container); if (!self.options.animateClassSwitch || /webkit/.test(navigator.userAgent.toLowerCase()) || !$.isFunction($.fn.switchClass)) { $span.removeClass(self.options.icon); $span.addClass(newIcon); } else { $span.switchClass(self.options.icon, newIcon, 500); } self.options.icon = newIcon; self.$container.dequeue(); }); }, changeMessage: function(newMessage) { this.$container.queue(function() { $('.achtung-message', $(this)).html(newMessage); $(this).dequeue(); }); }, update: function(options) { (options.className && this.changeClass(options.className)); (options.css && this.$container.css(options.css)); (typeof(options.icon) !== 'undefined' && this.changeIcon(options.icon)); (options.message && this.changeMessage(options.message)); (options.timeout && this.timeout(options.timeout)); }, close: function() { var o = this.options, $container = this.$container; if (this.closeTimer) { clearTimeout(this.closeTimer); } if (o.hideEffects) { this.$container.animate(o.hideEffects, o.hideEffectDuration); } else { this.$container.hide(); } $container.queue(function() { $container.removeData('achtung'); $container.remove(); if ($.achtung.$overlay && $.achtung.$overlay.is(':empty')) { $.achtung.$overlay.remove(); $.achtung.$overlay = false; } $container.dequeue(); }); } }); })(jQuery); sagenb-1.0.1/sagenb/data/jquery/plugins/achtung/ui.achtung.css000066400000000000000000000334341311436262400243410ustar00rootroot00000000000000/** * achtung 0.3.0 * * Growl-like notifications for jQuery * * Copyright (c) 2009 Josh Varner * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. * * Portions of this file are from the jQuery UI CSS framework. * * @license http://www.opensource.org/licenses/mit-license.php * @author Josh Varner */ /* IE 6 doesn't support position: fixed */ * html #achtung-overlay { position:absolute; } /* IE6 includes padding in width */ * html .achtung { width: 280px; } #achtung-overlay { overflow: hidden; position: fixed; top: 15px; right: 15px; width: 280px; z-index:50; } .achtung { display:none; margin-bottom: 8px; padding: 15px 15px; background-color: #000; color: white; width: 250px; font-weight: bold; position:relative; overflow: hidden; -moz-box-shadow: #aaa 1px 1px 2px; -webkit-box-shadow: #aaa 1px 1px 2px; box-shadow: #aaa 1px 1px 2px; -moz-border-radius: 4px; -webkit-border-radius: 4px; border-radius: 4px; /* Note that if using show/hide animations, IE will lose this setting */ opacity: .85; filter:Alpha(Opacity=85); } /** * This section from jQuery UI CSS framework * Copyright (c) 2009 AUTHORS.txt (http://jqueryui.com/about) * Can (and should) be removed if you are already loading the jQuery UI CSS * to reduce payload size. */ .ui-icon { display: block; text-indent: -99999px; overflow: hidden; background-repeat: no-repeat; } .ui-icon { width: 16px; height: 16px; background-image: url(images/ui-icons_222222_256x240.png); } .ui-icon-carat-1-n { background-position: 0 0; } .ui-icon-carat-1-ne { background-position: -16px 0; } .ui-icon-carat-1-e { background-position: -32px 0; } .ui-icon-carat-1-se { background-position: -48px 0; } .ui-icon-carat-1-s { background-position: -64px 0; } .ui-icon-carat-1-sw { background-position: -80px 0; } .ui-icon-carat-1-w { background-position: -96px 0; } .ui-icon-carat-1-nw { background-position: -112px 0; } .ui-icon-carat-2-n-s { background-position: -128px 0; } .ui-icon-carat-2-e-w { background-position: -144px 0; } .ui-icon-triangle-1-n { background-position: 0 -16px; } .ui-icon-triangle-1-ne { background-position: -16px -16px; } .ui-icon-triangle-1-e { background-position: -32px -16px; } .ui-icon-triangle-1-se { background-position: -48px -16px; } .ui-icon-triangle-1-s { background-position: -64px -16px; } .ui-icon-triangle-1-sw { background-position: -80px -16px; } .ui-icon-triangle-1-w { background-position: -96px -16px; } .ui-icon-triangle-1-nw { background-position: -112px -16px; } .ui-icon-triangle-2-n-s { background-position: -128px -16px; } .ui-icon-triangle-2-e-w { background-position: -144px -16px; } .ui-icon-arrow-1-n { background-position: 0 -32px; } .ui-icon-arrow-1-ne { background-position: -16px -32px; } .ui-icon-arrow-1-e { background-position: -32px -32px; } .ui-icon-arrow-1-se { background-position: -48px -32px; } .ui-icon-arrow-1-s { background-position: -64px -32px; } .ui-icon-arrow-1-sw { background-position: -80px -32px; } .ui-icon-arrow-1-w { background-position: -96px -32px; } .ui-icon-arrow-1-nw { background-position: -112px -32px; } .ui-icon-arrow-2-n-s { background-position: -128px -32px; } .ui-icon-arrow-2-ne-sw { background-position: -144px -32px; } .ui-icon-arrow-2-e-w { background-position: -160px -32px; } .ui-icon-arrow-2-se-nw { background-position: -176px -32px; } .ui-icon-arrowstop-1-n { background-position: -192px -32px; } .ui-icon-arrowstop-1-e { background-position: -208px -32px; } .ui-icon-arrowstop-1-s { background-position: -224px -32px; } .ui-icon-arrowstop-1-w { background-position: -240px -32px; } .ui-icon-arrowthick-1-n { background-position: 0 -48px; } .ui-icon-arrowthick-1-ne { background-position: -16px -48px; } .ui-icon-arrowthick-1-e { background-position: -32px -48px; } .ui-icon-arrowthick-1-se { background-position: -48px -48px; } .ui-icon-arrowthick-1-s { background-position: -64px -48px; } .ui-icon-arrowthick-1-sw { background-position: -80px -48px; } .ui-icon-arrowthick-1-w { background-position: -96px -48px; } .ui-icon-arrowthick-1-nw { background-position: -112px -48px; } .ui-icon-arrowthick-2-n-s { background-position: -128px -48px; } .ui-icon-arrowthick-2-ne-sw { background-position: -144px -48px; } .ui-icon-arrowthick-2-e-w { background-position: -160px -48px; } .ui-icon-arrowthick-2-se-nw { background-position: -176px -48px; } .ui-icon-arrowthickstop-1-n { background-position: -192px -48px; } .ui-icon-arrowthickstop-1-e { background-position: -208px -48px; } .ui-icon-arrowthickstop-1-s { background-position: -224px -48px; } .ui-icon-arrowthickstop-1-w { background-position: -240px -48px; } .ui-icon-arrowreturnthick-1-w { background-position: 0 -64px; } .ui-icon-arrowreturnthick-1-n { background-position: -16px -64px; } .ui-icon-arrowreturnthick-1-e { background-position: -32px -64px; } .ui-icon-arrowreturnthick-1-s { background-position: -48px -64px; } .ui-icon-arrowreturn-1-w { background-position: -64px -64px; } .ui-icon-arrowreturn-1-n { background-position: -80px -64px; } .ui-icon-arrowreturn-1-e { background-position: -96px -64px; } .ui-icon-arrowreturn-1-s { background-position: -112px -64px; } .ui-icon-arrowrefresh-1-w { background-position: -128px -64px; } .ui-icon-arrowrefresh-1-n { background-position: -144px -64px; } .ui-icon-arrowrefresh-1-e { background-position: -160px -64px; } .ui-icon-arrowrefresh-1-s { background-position: -176px -64px; } .ui-icon-arrow-4 { background-position: 0 -80px; } .ui-icon-arrow-4-diag { background-position: -16px -80px; } .ui-icon-extlink { background-position: -32px -80px; } .ui-icon-newwin { background-position: -48px -80px; } .ui-icon-refresh { background-position: -64px -80px; } .ui-icon-shuffle { background-position: -80px -80px; } .ui-icon-transfer-e-w { background-position: -96px -80px; } .ui-icon-transferthick-e-w { background-position: -112px -80px; } .ui-icon-folder-collapsed { background-position: 0 -96px; } .ui-icon-folder-open { background-position: -16px -96px; } .ui-icon-document { background-position: -32px -96px; } .ui-icon-document-b { background-position: -48px -96px; } .ui-icon-note { background-position: -64px -96px; } .ui-icon-mail-closed { background-position: -80px -96px; } .ui-icon-mail-open { background-position: -96px -96px; } .ui-icon-suitcase { background-position: -112px -96px; } .ui-icon-comment { background-position: -128px -96px; } .ui-icon-person { background-position: -144px -96px; } .ui-icon-print { background-position: -160px -96px; } .ui-icon-trash { background-position: -176px -96px; } .ui-icon-locked { background-position: -192px -96px; } .ui-icon-unlocked { background-position: -208px -96px; } .ui-icon-bookmark { background-position: -224px -96px; } .ui-icon-tag { background-position: -240px -96px; } .ui-icon-home { background-position: 0 -112px; } .ui-icon-flag { background-position: -16px -112px; } .ui-icon-calendar { background-position: -32px -112px; } .ui-icon-cart { background-position: -48px -112px; } .ui-icon-pencil { background-position: -64px -112px; } .ui-icon-clock { background-position: -80px -112px; } .ui-icon-disk { background-position: -96px -112px; } .ui-icon-calculator { background-position: -112px -112px; } .ui-icon-zoomin { background-position: -128px -112px; } .ui-icon-zoomout { background-position: -144px -112px; } .ui-icon-search { background-position: -160px -112px; } .ui-icon-wrench { background-position: -176px -112px; } .ui-icon-gear { background-position: -192px -112px; } .ui-icon-heart { background-position: -208px -112px; } .ui-icon-star { background-position: -224px -112px; } .ui-icon-link { background-position: -240px -112px; } .ui-icon-cancel { background-position: 0 -128px; } .ui-icon-plus { background-position: -16px -128px; } .ui-icon-plusthick { background-position: -32px -128px; } .ui-icon-minus { background-position: -48px -128px; } .ui-icon-minusthick { background-position: -64px -128px; } .ui-icon-close { background-position: -80px -128px; } .ui-icon-closethick { background-position: -96px -128px; } .ui-icon-key { background-position: -112px -128px; } .ui-icon-lightbulb { background-position: -128px -128px; } .ui-icon-scissors { background-position: -144px -128px; } .ui-icon-clipboard { background-position: -160px -128px; } .ui-icon-copy { background-position: -176px -128px; } .ui-icon-contact { background-position: -192px -128px; } .ui-icon-image { background-position: -208px -128px; } .ui-icon-video { background-position: -224px -128px; } .ui-icon-script { background-position: -240px -128px; } .ui-icon-alert { background-position: 0 -144px; } .ui-icon-info { background-position: -16px -144px; } .ui-icon-notice { background-position: -32px -144px; } .ui-icon-help { background-position: -48px -144px; } .ui-icon-check { background-position: -64px -144px; } .ui-icon-bullet { background-position: -80px -144px; } .ui-icon-radio-off { background-position: -96px -144px; } .ui-icon-radio-on { background-position: -112px -144px; } .ui-icon-pin-w { background-position: -128px -144px; } .ui-icon-pin-s { background-position: -144px -144px; } .ui-icon-play { background-position: 0 -160px; } .ui-icon-pause { background-position: -16px -160px; } .ui-icon-seek-next { background-position: -32px -160px; } .ui-icon-seek-prev { background-position: -48px -160px; } .ui-icon-seek-end { background-position: -64px -160px; } .ui-icon-seek-first { background-position: -80px -160px; } .ui-icon-stop { background-position: -96px -160px; } .ui-icon-eject { background-position: -112px -160px; } .ui-icon-volume-off { background-position: -128px -160px; } .ui-icon-volume-on { background-position: -144px -160px; } .ui-icon-power { background-position: 0 -176px; } .ui-icon-signal-diag { background-position: -16px -176px; } .ui-icon-signal { background-position: -32px -176px; } .ui-icon-battery-0 { background-position: -48px -176px; } .ui-icon-battery-1 { background-position: -64px -176px; } .ui-icon-battery-2 { background-position: -80px -176px; } .ui-icon-battery-3 { background-position: -96px -176px; } .ui-icon-circle-plus { background-position: 0 -192px; } .ui-icon-circle-minus { background-position: -16px -192px; } .ui-icon-circle-close { background-position: -32px -192px; } .ui-icon-circle-triangle-e { background-position: -48px -192px; } .ui-icon-circle-triangle-s { background-position: -64px -192px; } .ui-icon-circle-triangle-w { background-position: -80px -192px; } .ui-icon-circle-triangle-n { background-position: -96px -192px; } .ui-icon-circle-arrow-e { background-position: -112px -192px; } .ui-icon-circle-arrow-s { background-position: -128px -192px; } .ui-icon-circle-arrow-w { background-position: -144px -192px; } .ui-icon-circle-arrow-n { background-position: -160px -192px; } .ui-icon-circle-zoomin { background-position: -176px -192px; } .ui-icon-circle-zoomout { background-position: -192px -192px; } .ui-icon-circle-check { background-position: -208px -192px; } .ui-icon-circlesmall-plus { background-position: 0 -208px; } .ui-icon-circlesmall-minus { background-position: -16px -208px; } .ui-icon-circlesmall-close { background-position: -32px -208px; } .ui-icon-squaresmall-plus { background-position: -48px -208px; } .ui-icon-squaresmall-minus { background-position: -64px -208px; } .ui-icon-squaresmall-close { background-position: -80px -208px; } .ui-icon-grip-dotted-vertical { background-position: 0 -224px; } .ui-icon-grip-dotted-horizontal { background-position: -16px -224px; } .ui-icon-grip-solid-vertical { background-position: -32px -224px; } .ui-icon-grip-solid-horizontal { background-position: -48px -224px; } .ui-icon-gripsmall-diagonal-se { background-position: -64px -224px; } .ui-icon-grip-diagonal-se { background-position: -80px -224px; } .achtung .achtung-message-icon { margin-top: 0px; margin-left: -.5em; margin-right: .5em; float: left; zoom: 1; } .achtung .ui-icon.achtung-close-button { overflow: hidden; float: right; position: relative; top: -8px; right: -8px; cursor: pointer; background-image: url(images/ui-icons_cccccc_256x240.png); } .achtung .ui-icon.achtung-close-button-hover { background-image: url(images/ui-icons_ffffff_256x240.png); } /* Slightly darker for these colors (readability) */ .achtungSuccess, .achtungFail, .achtungWait { /* Note that if using show/hide animations, IE will lose this setting */ opacity: .93; filter:Alpha(Opacity=93); } .achtungSuccess { background-color: #4DB559; } .achtungFail { background-color: #D64450; } .achtungWait { background-color: #658093; } .achtungSuccess .ui-icon.achtung-close-button, .achtungFail .ui-icon.achtung-close-button { background-image: url(images/ui-icons_444444_256x240.png); } .achtungSuccess .ui-icon.achtung-close-button-hover, .achtungFail .ui-icon.achtung-close-button-hover { background-image: url(images/ui-icons_000000_256x240.png); } .achtung .wait-icon { background-image: url('images/wait.gif'); } .achtung .achtung-message { display: inline; } sagenb-1.0.1/sagenb/data/jquery/plugins/achtung/ui.achtung.js000066400000000000000000000200111311436262400241500ustar00rootroot00000000000000/** * achtung 0.3.0 * * Growl-like notifications for jQuery * * Copyright (c) 2009 Josh Varner * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. * * @license http://www.opensource.org/licenses/mit-license.php * @author Josh Varner */ /*globals jQuery,clearTimeout,document,navigator,setTimeout */ (function($) { /** * This is based on the jQuery UI $.widget code. I would have just made this * a $.widget but I didn't want the jQuery UI dependency. */ $.fn.achtung = function(options) { var isMethodCall = (typeof options === 'string'), args = Array.prototype.slice.call(arguments, 0), name = 'achtung'; // handle initialization and non-getter methods return this.each(function() { var instance = $.data(this, name); // prevent calls to internal methods if (isMethodCall && options.substring(0, 1) === '_') { return this; } // constructor (!instance && !isMethodCall && $.data(this, name, new $.achtung(this))._init(args)); // method call (instance && isMethodCall && $.isFunction(instance[options]) && instance[options].apply(instance, args.slice(1))); }); }; $.achtung = function(element) { var args = Array.prototype.slice.call(arguments, 0), $el; if (!element || !element.nodeType) { $el = $('
'); return $el.achtung.apply($el, args); } this.$container = $(element); }; /** * Static members **/ $.extend($.achtung, { version: '0.3.0', $overlay: false, defaults: { timeout: 10, disableClose: false, icon: false, className: '', animateClassSwitch: false, showEffects: {'opacity':'toggle','height':'toggle'}, hideEffects: {'opacity':'toggle','height':'toggle'}, showEffectDuration: 500, hideEffectDuration: 700 } }); /** * Non-static members **/ $.extend($.achtung.prototype, { $container: false, closeTimer: false, options: {}, _init: function(args) { var o, self = this; args = $.isArray(args) ? args : []; args.unshift($.achtung.defaults); args.unshift({}); o = this.options = $.extend.apply($, args); if (!$.achtung.$overlay) { $.achtung.$overlay = $('
').appendTo(document.body); } if (!o.disableClose) { $('') .click(function () { self.close(); }) .hover(function () { $(this).addClass('achtung-close-button-hover'); }, function () { $(this).removeClass('achtung-close-button-hover'); }) .prependTo(this.$container); } this.changeIcon(o.icon, true); if (o.message) { this.$container.append($('' + o.message + '')); } (o.className && this.$container.addClass(o.className)); (o.css && this.$container.css(o.css)); this.$container .addClass('achtung') .appendTo($.achtung.$overlay); if (o.showEffects) { this.$container.animate(o.showEffects, o.showEffectDuration); } else { this.$container.show(); } if (o.timeout > 0) { this.timeout(o.timeout); } }, timeout: function(timeout) { var self = this; if (this.closeTimer) { clearTimeout(this.closeTimer); } this.closeTimer = setTimeout(function() { self.close(); }, timeout * 1000); this.options.timeout = timeout; }, /** * Change the CSS class associated with this message, using * a transition if available (not availble in Safari/Webkit). * If no transition is available, the switch is immediate. * * #LATER Check if this has been corrected in Webkit or jQuery UI * #TODO Make transition time configurable * @param newClass string Name of new class to associate */ changeClass: function(newClass) { var self = this; if (this.options.className === newClass) { return; } this.$container.queue(function() { if (!self.options.animateClassSwitch || /webkit/.test(navigator.userAgent.toLowerCase()) || !$.isFunction($.fn.switchClass)) { self.$container.removeClass(self.options.className); self.$container.addClass(newClass); } else { self.$container.switchClass(self.options.className, newClass, 500); } self.options.className = newClass; self.$container.dequeue(); }); }, changeIcon: function(newIcon, force) { var self = this; if ((force !== true || newIcon === false) && this.options.icon === newIcon) { return; } if (force || this.options.icon === false) { this.$container.prepend($('')); this.options.icon = newIcon; return; } else if (newIcon === false) { this.$container.find('.achtung-message-icon').remove(); this.options.icon = false; return; } this.$container.queue(function() { var $span = $('.achtung-message-icon', self.$container); if (!self.options.animateClassSwitch || /webkit/.test(navigator.userAgent.toLowerCase()) || !$.isFunction($.fn.switchClass)) { $span.removeClass(self.options.icon); $span.addClass(newIcon); } else { $span.switchClass(self.options.icon, newIcon, 500); } self.options.icon = newIcon; self.$container.dequeue(); }); }, changeMessage: function(newMessage) { this.$container.queue(function() { $('.achtung-message', $(this)).html(newMessage); $(this).dequeue(); }); }, update: function(options) { (options.className && this.changeClass(options.className)); (options.css && this.$container.css(options.css)); (typeof(options.icon) !== 'undefined' && this.changeIcon(options.icon)); (options.message && this.changeMessage(options.message)); (options.timeout && this.timeout(options.timeout)); }, close: function() { var o = this.options, $container = this.$container; if (o.hideEffects) { this.$container.animate(o.hideEffects, o.hideEffectDuration); } else { this.$container.hide(); } $container.queue(function() { $container.removeData('achtung'); $container.remove(); if ($.achtung.$overlay && $.achtung.$overlay.is(':empty')) { $.achtung.$overlay.remove(); $.achtung.$overlay = false; } $container.dequeue(); }); } }); })(jQuery);sagenb-1.0.1/sagenb/data/jquery/plugins/achtung/version.txt000066400000000000000000000000051311436262400237740ustar00rootroot000000000000000.3.0sagenb-1.0.1/sagenb/data/jquery/plugins/extendedclick/000077500000000000000000000000001311436262400227305ustar00rootroot00000000000000sagenb-1.0.1/sagenb/data/jquery/plugins/extendedclick/jquery.event.extendedclick.js000066400000000000000000000054021311436262400305330ustar00rootroot00000000000000;(function($){ /* * Copyright (c) 2008, Minus Creative (http://minuscreative.com) * Dual licensed under the MIT (MIT-LICENSE.txt) * and GPL (GPL-LICENSE.txt) licenses. * * Created: 2008-10-01 * * Updated from version 1.0 by Jason Grout * Available at https://github.com/jasongrout/jquery-extended-click * */ // According to http://docs.jquery.com/Plugins/Authoring#Plugin_Methods, // having 8 different namespaces for this plugin is discouraged, so we comment this out. //$.fn.plainclick = function(fn) { return this[fn ? "bind" : "trigger"]("plainclick", fn); }; //$.fn.ctrlclick = function(fn) { return this[fn ? "bind" : "trigger"]("ctrlclick", fn); }; //$.fn.shiftclick = function(fn) { return this[fn ? "bind" : "trigger"]("shiftclick", fn); }; //$.fn.altclick = function(fn) { return this[fn ? "bind" : "trigger"]("altclick", fn); }; //$.fn.ctrlaltclick = function(fn) { return this[fn ? "bind" : "trigger"]("ctrlaltclick", fn); }; //$.fn.ctrlshiftclick = function(fn) { return this[fn ? "bind" : "trigger"]("ctrlshiftclick", fn); }; //$.fn.altshiftclick = function(fn) { return this[fn ? "bind" : "trigger"]("altshiftclick", fn); }; //$.fn.ctrlaltshiftclick = function(fn) { return this[fn ? "bind" : "trigger"]("ctrlaltshiftclick", fn); }; // all event clicks share the same config $.event.special.plainclick = $.event.special.ctrlclick = $.event.special.altclick = $.event.special.shiftclick = $.event.special.ctrlaltclick = $.event.special.ctrlshiftclick = $.event.special.altshiftclick = $.event.special.ctrlaltshiftclick = { setup: function() { $.event.add(this, "click", extendedClickHandler, {}); }, teardown: function() { $.event.remove(this, "click", extendedClickHandler); } }; // Big shared event handler function extendedClickHandler(event){ if(event.type==="click") { if (event.ctrlKey) { if (event.shiftKey) { if (event.altKey || event.originalEvent.altKey) { event.type = "ctrlaltshiftclick"; // set to trigger } else event.type = "ctrlshiftclick"; // set to trigger } else if (event.altKey || event.originalEvent.altKey) { event.type = "ctrlaltclick"; // set to trigger } else event.type = "ctrlclick"; // set to trigger } else if (event.altKey || event.originalEvent.altKey) { if (event.shiftKey) { event.type = "altshiftclick"; // set to trigger } else event.type = "altclick"; // set to trigger } else if (event.shiftKey) { event.type = "shiftclick"; // set to trigger } else { event.type = "plainclick"; // set to trigger } return $.event.handle.call(this, event); } } })(jQuery); sagenb-1.0.1/sagenb/data/jquery/plugins/jeditable/000077500000000000000000000000001311436262400220455ustar00rootroot00000000000000sagenb-1.0.1/sagenb/data/jquery/plugins/jeditable/jquery.jeditable.js000066400000000000000000000574371311436262400256640ustar00rootroot00000000000000/* * Jeditable - jQuery in place edit plugin * * Copyright (c) 2006-2009 Mika Tuupola, Dylan Verheul * * Licensed under the MIT license: * http://www.opensource.org/licenses/mit-license.php * * Project home: * http://www.appelsiini.net/projects/jeditable * * Based on editable by Dylan Verheul : * http://www.dyve.net/jquery/?editable * */ /** * Version 1.7.1 * * ** means there is basic unit tests for this parameter. * * @name Jeditable * @type jQuery * @param String target (POST) URL or function to send edited content to ** * @param Hash options additional options * @param String options[method] method to use to send edited content (POST or PUT) ** * @param Function options[callback] Function to run after submitting edited content ** * @param String options[name] POST parameter name of edited content * @param String options[id] POST parameter name of edited div id * @param Hash options[submitdata] Extra parameters to send when submitting edited content. * @param String options[type] text, textarea or select (or any 3rd party input type) ** * @param Integer options[rows] number of rows if using textarea ** * @param Integer options[cols] number of columns if using textarea ** * @param Mixed options[height] 'auto', 'none' or height in pixels ** * @param Mixed options[width] 'auto', 'none' or width in pixels ** * @param String options[loadurl] URL to fetch input content before editing ** * @param String options[loadtype] Request type for load url. Should be GET or POST. * @param String options[loadtext] Text to display while loading external content. * @param Mixed options[loaddata] Extra parameters to pass when fetching content before editing. * @param Mixed options[data] Or content given as paramameter. String or function.** * @param String options[indicator] indicator html to show when saving * @param String options[tooltip] optional tooltip text via title attribute ** * @param String options[event] jQuery event such as 'click' of 'dblclick' ** * @param String options[submit] submit button value, empty means no button ** * @param String options[cancel] cancel button value, empty means no button ** * @param String options[cssclass] CSS class to apply to input form. 'inherit' to copy from parent. ** * @param String options[style] Style to apply to input form 'inherit' to copy from parent. ** * @param String options[select] true or false, when true text is highlighted ?? * @param String options[placeholder] Placeholder text or html to insert when element is empty. ** * @param String options[onblur] 'cancel', 'submit', 'ignore' or function ?? * * @param Function options[onsubmit] function(settings, original) { ... } called before submit * @param Function options[onreset] function(settings, original) { ... } called before reset * @param Function options[onerror] function(settings, original, xhr) { ... } called on error * * @param Hash options[ajaxoptions] jQuery Ajax options. See docs.jquery.com. * */ (function($) { $.fn.editable = function(target, options) { if ('disable' == target) { $(this).data('disabled.editable', true); return; } if ('enable' == target) { $(this).data('disabled.editable', false); return; } if ('destroy' == target) { $(this) .unbind($(this).data('event.editable')) .removeData('disabled.editable') .removeData('event.editable'); return; } var settings = $.extend({}, $.fn.editable.defaults, {target:target}, options); /* setup some functions */ var plugin = $.editable.types[settings.type].plugin || function() { }; var submit = $.editable.types[settings.type].submit || function() { }; var buttons = $.editable.types[settings.type].buttons || $.editable.types['defaults'].buttons; var content = $.editable.types[settings.type].content || $.editable.types['defaults'].content; var element = $.editable.types[settings.type].element || $.editable.types['defaults'].element; var reset = $.editable.types[settings.type].reset || $.editable.types['defaults'].reset; var callback = settings.callback || function() { }; var onedit = settings.onedit || function() { }; var onsubmit = settings.onsubmit || function() { }; var onreset = settings.onreset || function() { }; var onerror = settings.onerror || reset; /* show tooltip */ if (settings.tooltip) { $(this).attr('title', settings.tooltip); } settings.autowidth = 'auto' == settings.width; settings.autoheight = 'auto' == settings.height; return this.each(function() { /* save this to self because this changes when scope changes */ var self = this; /* inlined block elements lose their width and height after first edit */ /* save them for later use as workaround */ var savedwidth = $(self).width(); var savedheight = $(self).height(); /* save so it can be later used by $.editable('destroy') */ $(this).data('event.editable', settings.event); /* if element is empty add something clickable (if requested) */ if (!$.trim($(this).html())) { $(this).html(settings.placeholder); } $(this).bind(settings.event, function(e) { /* abort if disabled for this element */ if (true === $(this).data('disabled.editable')) { return; } /* prevent throwing an exeption if edit field is clicked again */ if (self.editing) { return; } /* abort if onedit hook returns false */ if (false === onedit.apply(this, [settings, self])) { return; } /* prevent default action and bubbling */ e.preventDefault(); e.stopPropagation(); /* remove tooltip */ if (settings.tooltip) { $(self).removeAttr('title'); } /* figure out how wide and tall we are, saved width and height */ /* are workaround for http://dev.jquery.com/ticket/2190 */ if (0 == $(self).width()) { //$(self).css('visibility', 'hidden'); settings.width = savedwidth; settings.height = savedheight; } else { if (settings.width != 'none') { settings.width = settings.autowidth ? $(self).width() : settings.width; } if (settings.height != 'none') { settings.height = settings.autoheight ? $(self).height() : settings.height; } } //$(this).css('visibility', ''); /* remove placeholder text, replace is here because of IE */ if ($(this).html().toLowerCase().replace(/(;|")/g, '') == settings.placeholder.toLowerCase().replace(/(;|")/g, '')) { $(this).html(''); } self.editing = true; self.revert = $(self).html(); $(self).html(''); /* create the form object */ var form = $('
'); /* apply css or style or both */ if (settings.cssclass) { if ('inherit' == settings.cssclass) { form.attr('class', $(self).attr('class')); } else { form.attr('class', settings.cssclass); } } if (settings.style) { if ('inherit' == settings.style) { form.attr('style', $(self).attr('style')); /* IE needs the second line or display wont be inherited */ form.css('display', $(self).css('display')); } else { form.attr('style', settings.style); } } /* add main input element to form and store it in input */ var input = element.apply(form, [settings, self]); /* set input content via POST, GET, given data or existing value */ var input_content; if (settings.loadurl) { var t = setTimeout(function() { input.disabled = true; content.apply(form, [settings.loadtext, settings, self]); }, 100); var loaddata = {}; loaddata[settings.id] = self.id; if ($.isFunction(settings.loaddata)) { $.extend(loaddata, settings.loaddata.apply(self, [self.revert, settings])); } else { $.extend(loaddata, settings.loaddata); } $.ajax({ type : settings.loadtype, url : settings.loadurl, data : loaddata, async : false, success: function(result) { window.clearTimeout(t); input_content = result; input.disabled = false; } }); } else if (settings.data) { input_content = settings.data; if ($.isFunction(settings.data)) { input_content = settings.data.apply(self, [self.revert, settings]); } } else { input_content = self.revert; } content.apply(form, [input_content, settings, self]); input.attr('name', settings.name); /* add buttons to the form */ buttons.apply(form, [settings, self]); /* add created form to self */ $(self).append(form); /* attach 3rd party plugin if requested */ plugin.apply(form, [settings, self]); /* focus to first visible form element */ $(':input:visible:enabled:first', form).focus(); /* highlight input contents when requested */ if (settings.select) { input.select(); } /* discard changes if pressing esc */ input.keydown(function(e) { if (e.keyCode == 27) { e.preventDefault(); //self.reset(); reset.apply(form, [settings, self]); } }); /* discard, submit or nothing with changes when clicking outside */ /* do nothing is usable when navigating with tab */ var t; if ('cancel' == settings.onblur) { input.blur(function(e) { /* prevent canceling if submit was clicked */ t = setTimeout(function() { reset.apply(form, [settings, self]); }, 500); }); } else if ('submit' == settings.onblur) { input.blur(function(e) { /* prevent double submit if submit was clicked */ t = setTimeout(function() { form.submit(); }, 200); }); } else if ($.isFunction(settings.onblur)) { input.blur(function(e) { settings.onblur.apply(self, [input.val(), settings]); }); } else { input.blur(function(e) { /* TODO: maybe something here */ }); } form.submit(function(e) { if (t) { clearTimeout(t); } /* do no submit */ e.preventDefault(); /* call before submit hook. */ /* if it returns false abort submitting */ if (false !== onsubmit.apply(form, [settings, self])) { /* custom inputs call before submit hook. */ /* if it returns false abort submitting */ if (false !== submit.apply(form, [settings, self])) { /* check if given target is function */ if ($.isFunction(settings.target)) { var str = settings.target.apply(self, [input.val(), settings]); $(self).html(str); self.editing = false; callback.apply(self, [self.innerHTML, settings]); /* TODO: this is not dry */ if (!$.trim($(self).html())) { $(self).html(settings.placeholder); } } else { /* add edited content and id of edited element to POST */ var submitdata = {}; submitdata[settings.name] = input.val(); submitdata[settings.id] = self.id; /* add extra data to be POST:ed */ if ($.isFunction(settings.submitdata)) { $.extend(submitdata, settings.submitdata.apply(self, [self.revert, settings])); } else { $.extend(submitdata, settings.submitdata); } /* quick and dirty PUT support */ if ('PUT' == settings.method) { submitdata['_method'] = 'put'; } /* show the saving indicator */ $(self).html(settings.indicator); /* defaults for ajaxoptions */ var ajaxoptions = { type : 'POST', data : submitdata, dataType: 'html', url : settings.target, success : function(result, status) { if (ajaxoptions.dataType == 'html') { $(self).html(result); } self.editing = false; callback.apply(self, [result, settings]); if (!$.trim($(self).html())) { $(self).html(settings.placeholder); } }, error : function(xhr, status, error) { onerror.apply(form, [settings, self, xhr]); } }; /* override with what is given in settings.ajaxoptions */ $.extend(ajaxoptions, settings.ajaxoptions); $.ajax(ajaxoptions); } } } /* show tooltip again */ $(self).attr('title', settings.tooltip); return false; }); }); /* privileged methods */ this.reset = function(form) { /* prevent calling reset twice when blurring */ if (this.editing) { /* before reset hook, if it returns false abort reseting */ if (false !== onreset.apply(form, [settings, self])) { $(self).html(self.revert); self.editing = false; if (!$.trim($(self).html())) { $(self).html(settings.placeholder); } /* show tooltip again */ if (settings.tooltip) { $(self).attr('title', settings.tooltip); } } } }; }); }; $.editable = { types: { defaults: { element : function(settings, original) { var input = $(''); $(this).append(input); return(input); }, content : function(string, settings, original) { $(':input:first', this).val(string); }, reset : function(settings, original) { original.reset(this); }, buttons : function(settings, original) { var form = this; if (settings.submit) { /* if given html string use that */ if (settings.submit.match(/>$/)) { var submit = $(settings.submit).click(function() { if (submit.attr("type") != "submit") { form.submit(); } }); /* otherwise use button with given string as text */ } else { var submit = $('
{% endif %} sagenb-1.0.1/sagenb/data/sage/html/notebook/doc_page.html000066400000000000000000000002571311436262400232600ustar00rootroot00000000000000{% extends "html/notebook/worksheet_page.html" %} {% block pre_main_css %} {% endblock %} sagenb-1.0.1/sagenb/data/sage/html/notebook/download_or_delete_datafile.html000066400000000000000000000057211311436262400272020ustar00rootroot00000000000000{% extends "html/notebook/base_aux.html" %} {# INPUT: - worksheet - an instance of Worksheet - username - a string containing a username - filename_ - the name of the file - file_is_image - a boolean stating whether the file is an image - file_is_text - a boolean stating whether the file is a text file - text_file_content - a string containing the content of a text file #} {% block page_id %}datafile-page{% endblock %} {% block more_css %} {% endblock %} {% block more_javascript %} {% endblock %} {% set path = "/home/%s/data/%s"|format(worksheet.filename(), filename_) %} {% block sharebar_title %} {{ gettext('Data file') }}: {{ filename_ }} {% endblock %} {% block after_sharebar %}

{{ gettext('You may download %(f)s or create a link to this file in worksheet ', p=path, f=filename_) |safe }} {{ gettext('or delete %(f)s.', wf=worksheet.filename(), f=filename_) |safe }}

{{ gettext("Access %(f)s in this worksheet by typing DATA+'%(f)s'. Here DATA is a special variable that gives the exact path to all data files uploaded to this worksheet.", f=filename_) |safe }}


{% if file_is_image %}
{% elif file_is_text %}
{% endif %} {% endblock %} sagenb-1.0.1/sagenb/data/sage/html/notebook/edit_window.html000066400000000000000000000015061311436262400240310ustar00rootroot00000000000000{% extends "html/notebook/base_aux.html" %} {% block page_id %}edit-page{% endblock %} {% block before_sharebar %}
{% endblock %} {% block sharebar_title %} {{ gettext('Edit plain text') }} {% endblock %} {% set select = "edit" %} {% block after_sharebar %}
{% endblock %} sagenb-1.0.1/sagenb/data/sage/html/notebook/guest_worksheet_page.html000066400000000000000000000057651311436262400257460ustar00rootroot00000000000000{% extends "html/notebook/base.html" %} {# INPUT: - worksheet - an instance of Worksheet - notebook - an instance of Notebook which contains worksheet - username - a string containing a username #} {% block javascript %} {{ super() }} {% endblock %} {% block page_id %}guest-worksheet-page{% endblock %} {% block body_classes %}{% if conf['pub_interact'] %}active-worksheet{% endif %}{% endblock %} {% set original_worksheet = worksheet.worksheet_that_was_published() %} {% if original_worksheet.is_collaborator(username) or original_worksheet.is_owner(username) %} {% set edit_text = "Edit this." %} {% set edit_text = gettext('Edit this.') %} {% set url = original_worksheet.worksheet_command('') %} {% elif notebook.user_manager().user_is_guest(username) %} {% set edit_text = gettext('Log in to edit a copy.') %} {% set url = "/" %} {% else %} {% set edit_text = gettext('Edit a copy.') %} {% set url = "edit_published_page" %} {% endif %} {% set download_name = worksheet.download_name() %} {% block published_link_rel %} {% endblock %} {% block body %}

{{ worksheet.name() }}

{{ worksheet.html_time_since_last_edited() | safe }}

{{ worksheet.html(do_print=false, publish=true, username=username) | safe }}
{%- for i in range(10) %}   {%- endfor %} {% endblock %} sagenb-1.0.1/sagenb/data/sage/html/notebook/plain_text_window.html000066400000000000000000000004711311436262400252530ustar00rootroot00000000000000{% extends "html/notebook/base_aux.html" %} {% block sharebar_title %} {{ gettext('View plain text') }} {% endblock %} {% set select = "text" %} {% block after_sharebar %}
{{ worksheet.plain_text(prompts=true, banner=false)|trim }}
{% endblock %} sagenb-1.0.1/sagenb/data/sage/html/notebook/print_worksheet.html000066400000000000000000000004321311436262400247410ustar00rootroot00000000000000{% extends "html/notebook/base.html" %} {% block page_id %}print-page{% endblock %} {% block body %}

{{ worksheet.name() }}

{{ worksheet.html(do_print=true) | safe }} {% endblock %} sagenb-1.0.1/sagenb/data/sage/html/notebook/specific_revision.html000066400000000000000000000024241311436262400252200ustar00rootroot00000000000000{% extends "html/notebook/base_aux.html" %} {% set select = "revisions" %} {% block sharebar_title %} {{ gettext('Revision from %(ta)s ago', ta=time_ago) }}    {{ gettext('Revision List') }} {% endblock %} {% block page_id %}specific-revision-page{% endblock %} {% macro actions() %} {% if prev_rev %} {{ gettext('Older') }} {% else %} {{ gettext('Oldest') }} {% endif %} {% if next_rev %} {{ gettext('Newer') }} {% else %} {{ gettext('Newest') }} {% endif %} {{ gettext('Revert to this one') }} {{ gettext('(note that images are not recorded)') }}   {{ gettext('Publish this one') }} {% endmacro %} {% block after_sharebar %} {{ actions() }}
{{ worksheet.html(do_print=true, publish=true, username=username) | safe }}
{{ actions() }} {% endblock %} sagenb-1.0.1/sagenb/data/sage/html/notebook/text_cell.html000066400000000000000000000055161311436262400235050ustar00rootroot00000000000000{# INPUT: - cell -- Cell instance - wrap -- number of columns to wrap - do_print -- whether to display for printing - editing -- whether user is editing the cell - publish - a boolean; whether this is a published cell #} {% if not do_print and not publish and not cell.worksheet().docbrowser() %}
{% endif %}
{{ cell.plain_text() | safe }}
{% if JEDITABLE_TINYMCE and not cell.worksheet().is_published() and not cell.worksheet().docbrowser() and not do_print and not publish %} {% endif %} {% if editing and not do_print %} {% endif %}
sagenb-1.0.1/sagenb/data/sage/html/notebook/upload_data_window.html000066400000000000000000000023621311436262400253620ustar00rootroot00000000000000{% extends "html/notebook/base_aux.html" %} {% block page_id %}upload-data-page{% endblock %} {% block sharebar_title %} {{ gettext('Upload or Create Data File to attach to worksheet "%(wn)s"', wn=worksheet.name()) }} {% endblock %} {% block after_sharebar %}
{% endblock %} sagenb-1.0.1/sagenb/data/sage/html/notebook/worksheet.html000066400000000000000000000010661311436262400235310ustar00rootroot00000000000000{# INPUT: - worksheet -- Worksheet object - publish -- boolean whether this is for the published version - do_print -- boolean whether this is for a print version #} {% set wrap = conf['word_wrap_cols'] %} {% if not publish %} {% set publish = worksheet.is_published() %} {% endif %}
{% for cell in worksheet.cell_list() %} {{ cell.html(wrap = wrap, div_wrap = true, do_print = do_print, publish = publish) | safe }} {% endfor %}
sagenb-1.0.1/sagenb/data/sage/html/notebook/worksheet_page.html000066400000000000000000000044421311436262400245260ustar00rootroot00000000000000{% extends "html/notebook/base.html" %} {# INPUT: - worksheet - an instance of Worksheet - notebook - an instance of Notebook which contains worksheet - do_print - a boolean stating whether the file is for print mode #} {% block page_id %}user-worksheet-page{% endblock %} {% block body_classes %}active-worksheet{% endblock %} {% set select = "use" %} {% block worksheet_main %} {% set toggle=true %}
{{ worksheet.html(username=username) | safe }}
{% if not worksheet.docbrowser() %}
{% endif %}
{% endblock %} sagenb-1.0.1/sagenb/data/sage/html/notebook/worksheet_revision_list.html000066400000000000000000000014421311436262400265000ustar00rootroot00000000000000{% extends "html/notebook/base_aux.html" %} {% block page_id %}revision-list-page{% endblock %} {% block sharebar_title %} {{ gettext('Revision History -- List of Snapshots') }} {% endblock %} {% set select = "revisions" %} {% block after_sharebar %} {% for desc, key in worksheet.snapshot_data()|reverse %} {% endfor %}
{{ gettext('Revision') }} {{ gettext('Last Edited') }}
{{ gettext('Revision %(lr)s', lr=loop.revindex0) }} {{ desc }}
{% endblock %} sagenb-1.0.1/sagenb/data/sage/html/notebook/worksheet_share.html000066400000000000000000000023761311436262400247200ustar00rootroot00000000000000{% extends "html/notebook/base_aux.html" %} {# INPUT: - worksheet - an instance of Worksheet - username - a string containing a username - other_users - a list of strings containing other users names #} {% block sharebar_title %} {{ gettext('Share this document') }} {% endblock %} {% set select = "share" %} {% block after_sharebar %} {% if not (notebook.user_manager().user_is_admin(username) or username == worksheet.owner()) %} {{ gettext('Only the owner of a worksheet is allowed to share it. You can do whatever you want if you make your own copy.') }} {% else %}

{{ gettext('This Sage Worksheet is currently shared with the people listed in the box below.') }}

{{ gettext('You may add or remove collaborators (separate user names by commas).') }}

{% endif %} {% endblock %} sagenb-1.0.1/sagenb/data/sage/html/recaptcha.html000066400000000000000000000017201311436262400216250ustar00rootroot00000000000000

sagenb-1.0.1/sagenb/data/sage/html/settings/000077500000000000000000000000001311436262400206455ustar00rootroot00000000000000sagenb-1.0.1/sagenb/data/sage/html/settings/account_settings.html000066400000000000000000000044441311436262400251150ustar00rootroot00000000000000{% extends "html/settings/base.html" %} {% block title %}{{ gettext('Account Settings') }}{% endblock %} {% block page_id %}account-settings-page{% endblock %} {% block settings_main %}

{{ gettext('Change Auto-Save Interval') }}

{{ gettext('Minutes') }}:
{% if not external %}

{{ gettext('Change Password') }}

{% if message -%} {%- endif -%}

{{ gettext('Change E-mail Address') }}

{{ email_address }} {{ email_confirmed }}
{% endif %} {%- if auto_table %} {{ auto_table }} {%- endif %}
{% endblock %} sagenb-1.0.1/sagenb/data/sage/html/settings/admin_add_user.html000066400000000000000000000024041311436262400244710ustar00rootroot00000000000000{% extends "html/settings/base.html" %} {% block title %}{{ gettext('Add New User') }}{% endblock %} {% block page_id %}add-user-page{% endblock %} {% block main %}

{{ gettext('Add New User') }}

  1. {{ gettext('Pick a username') }}

    {{ gettext('The username must start with a letter and be between 4 and 32 characters long. It can only consist of letters, numbers, underscores, and one dot (.).') }}

    {% if error %} {% if error == 'username_invalid' %}

    {{ gettext('Error') }}: {{ gettext('Invalid username') }}

    {% elif error == 'username_taken' %}

    {{ gettext('Error') }}: {{ gettext('Username taken') }}

    {% else %}

    {{ gettext('Error') }}: {{ gettext('Username Error') }}

    {% endif %} {% endif %}
{% endblock %} sagenb-1.0.1/sagenb/data/sage/html/settings/base.html000066400000000000000000000010371311436262400224460ustar00rootroot00000000000000{% extends "html/base_authenticated.html" %} {% block body_classes %}settings-page{% endblock %} {% block main %}

{{ render_title() }}

{% block settings_nav %} {% endblock %} {% block settings_main %} {% endblock %} {% endblock %} sagenb-1.0.1/sagenb/data/sage/html/settings/notebook_settings.html000066400000000000000000000020411311436262400252700ustar00rootroot00000000000000{% extends "html/settings/base.html" %} {% block title %}{{ gettext('Notebook Settings') }}{% endblock %} {% block more_css %} {% endblock %} {% block javascript %} {% endblock %} {% block page_id %}notebook-settings-page{% endblock %} {% block settings_main %}
{%- if auto_table %} {{ auto_table | safe }} {%- endif %}
{% endblock %} sagenb-1.0.1/sagenb/data/sage/html/settings/user_management.html000066400000000000000000000030171311436262400247060ustar00rootroot00000000000000{% extends "html/settings/base.html" %} {% block title %}{{ gettext('Users') }}{% endblock %} {% block page_id %}user-management-page{% endblock %} {% block settings_main %}

{{ gettext('User Management') }}

{{ gettext('Add User') }} {% if reset %}

{{ gettext('The password for the user %(u)s has been reset to %(p)s', u=reset[0], p=reset[1]) }}

{% endif %} {% for u in users %} {% if u.username() != 'admin' %} {% endif %} {% endfor %}
{{ gettext('User') }} {{ gettext('Password') }} {{ gettext('Suspension') }} {{ gettext('Admin') }} {{ gettext('Delete') }}
{{ u }} {% if not u.is_external() %} {{ gettext('Reset') }} {% endif %} {% if u.is_suspended() %}{{ gettext('Unsuspend') }}{% else %}{{ gettext('Suspend') }}{% endif %} {% if u.is_admin() %}{{ gettext('Revoke') }}{% else %}{{ gettext('Grant') }}{% endif %} {{ gettext('Delete') }}
{% endblock %} sagenb-1.0.1/sagenb/data/sage/html/source_code.html000066400000000000000000000013531311436262400221670ustar00rootroot00000000000000{% extends "html/base_authenticated.html" %} {% block title %}{{ src_filename }} - {{ gettext('Source Code') }}{% endblock %} {% block css %}main{% endblock %} {% block more_css %}{% endblock %} {% block page_id %}source-code-page{% endblock %} {% block body %}

{{ gettext('Sage Source Browser') }}

{{ src_filename }} ({{ gettext('browse directory') }})

{{ src }} {% endblock %} sagenb-1.0.1/sagenb/data/sage/html/test_report.html000066400000000000000000000114071311436262400222500ustar00rootroot00000000000000 {{ title }} {{ stylesheet }} {{ javascript }}

{{ title }}

{{ description }}

{%- if sagenb_version %} {% endif %} {%- if sage_version %} {% endif %} {%- if environment %} {% endif %}
{{ gettext('Sage Notebook version') }} {{ sagenb_version }}
{{ gettext('Sage version') }} {{ sage_version }}
{{ gettext('Environment') }} {{ environment }}
{{ gettext('Start') }} {{ start_time }}
{{ gettext('Stop') }} {{ stop_time }}
{{ gettext('Elapsed') }} {{ elapsed_time }}
{{ gettext('Status') }} {{ gettext('Pass') }} {{ pass_total }}  {{ gettext('Fail') }} {{ fail_total }}  {{ gettext('Error') }} {{ error_total }}  {{ gettext('Total') }} {{ count_total }}
Output / Tracebacks:  
{{ gettext('Hide') }}
 
{{ gettext('Show') }}
 
{{ gettext('Toggle') }}
{{ test_cases_and_tests }}
{{ gettext('Cases / Tests') }} {{ gettext('Pass') }} {{ gettext('Fail') }} {{ gettext('Error') }} {{ gettext('Count') }} H S T
{{ gettext('Totals') }} {{ pass_total }} {{ fail_total }} {{ error_total }} {{ count_total }} H S T
{%- if ending %}
{{ ending }}
{%- endif %} sagenb-1.0.1/sagenb/data/sage/html/upload.html000066400000000000000000000056561311436262400211730ustar00rootroot00000000000000{% extends "html/base_authenticated.html" %} {% block title %}{{ gettext('Upload File') }}{% endblock %} {% block page_id %}upload-worksheet-page{% endblock %} {% block main %} {% if "url" in request.args: %}

{{ gettext('Upload worksheet to the Sage Notebook') }}

{% else: %}

{{ gettext('Upload worksheet to the Sage Notebook') }}

{{ gettext('Supported file formats:') }}

  • .sws - {{ gettext('a Sage worksheet') }}
  • .html {{ gettext('or .txt - a worksheet text file with html code and cells surrounded by {{{ and }}} that defines a worksheet') }}
  • .html - {{ gettext('the URL of a page of the Sage Documentation, for example the URL of this page') }}
  • .html - {{ gettext('an HTML page generated by docutils from a ReStructuredText file') }}
  • .rst - {{ gettext('a ReStructuredText file (Add ".. escape-backslashes" as a line in the file if you want backslashes to be escaped. Put latex code inside backticks "`" or dollar signs "$" or "$$". Math role is not supported for now.)') }}
  • .zip - {{ gettext('a zip archive of any of the above') }}
{% endif %} {% endblock %} sagenb-1.0.1/sagenb/data/sage/html/worksheet/000077500000000000000000000000001311436262400210205ustar00rootroot00000000000000sagenb-1.0.1/sagenb/data/sage/html/worksheet/attached.html000066400000000000000000000003221311436262400234600ustar00rootroot00000000000000{# INPUT: - attached_files - dictionary of attached files #} {% for file, tm in attached_files %}
{{ file }}
{% endfor %}sagenb-1.0.1/sagenb/data/sage/html/worksheet/completions.html000066400000000000000000000014171311436262400242450ustar00rootroot00000000000000{# INPUT: - cell_id - id for the cell of the completions - completions_enumerated - enumerated (enumerate()) 2D list of completions in column-major order #}
      {%- for row in column %}
    • {{- row }}
    • {%- endfor %}
    {%- endfor %}
sagenb-1.0.1/sagenb/data/sage/html/worksheet/ratings_info.html000066400000000000000000000015301311436262400243670ustar00rootroot00000000000000{% extends "html/base.html" %} {% block title %}{{ gettext('Ratings for %(wn)s', wn=worksheet.name()) }}{% endblock %} {% block body %}

{{ gettext('Ratings for %(wn)s', wn=worksheet.name()) }}

{{ gettext('Go to the worksheet.') }} {% for rating in worksheet.ratings()|sort %} {% endfor %}
{{ gettext('User') }}{{ gettext('Rating') }}{{ gettext('Comment') }}
{{ rating[0] }}{# User #} {{ rating[1] }}{# Rating #} {{'' if rating|length < 3 else rating[2] }}{# Comment #}
{% endblock %} sagenb-1.0.1/sagenb/data/sage/html/worksheet/time_last_edited.html000066400000000000000000000002701311436262400252040ustar00rootroot00000000000000{# INPUT: - time - string of time of last edit - last_editor - string of name of last editor #} {{ gettext('%(t)s by %(le)s', t=time, le=last_editor) }} sagenb-1.0.1/sagenb/data/sage/html/worksheet/time_since_last_edited.html000066400000000000000000000002761311436262400263730ustar00rootroot00000000000000{# INPUT: - time - string of time since last edit - last_editor - string of name of last editor #} {{ gettext('%(t)s ago by %(le)s', t=time, le=last_editor) }} sagenb-1.0.1/sagenb/data/sage/html/worksheet_listing.html000066400000000000000000000241641311436262400234460ustar00rootroot00000000000000{% extends "html/base_authenticated.html" %} {# INPUT: - pub -- a boolean stating whether to show in public mode. - typ -- a string stating what kind of worksheets this listing shows - worksheets -- list of Worksheet objects - readonly -- a boolean stating whether the user is read only #} {% if pub %} {% set worksheet_heading=gettext('Published Worksheets') %} {% elif typ == 'trash' %} {% set worksheet_heading=gettext('Deleted Worksheets') %} {% elif typ == 'active' %} {% set worksheet_heading=gettext('Active Worksheets') %} {% else %} {% set worksheet_heading=gettext('Archived Worksheets') %} {% endif %} {% block title %} {{ worksheet_heading }} {% endblock %} {% block page_id %}worksheet-listing-page{% endblock %} {% block body_classes %}{% if pub %}public{% endif %}{% endblock %} {% block javascript %} {% if not pub %} {% else %} {% endif %} {% endblock %} {% block main %} {% if readonly is defined and readonly %}

{{ gettext('Account is read only. You may download or delete worksheets or data.') }}

{% endif %}
{% if pub is not defined or not pub %} {{ gettext('New Worksheet') }} {{ gettext('Upload') }} {{ gettext('Download All Active') }} {% endif %}
{% if not pub %}
{% if typ == 'archive' %} {% else %} {% endif %} {% if typ != 'trash' %} {% else %} {% endif %}
{{ gettext('Current Folder') }}: {{ gettext('Active') }} {{ gettext('Archived') }} {{ gettext('Trash') }} {% if typ == 'trash' %}
({{ gettext('Empty Trash') }})
{% endif %}
{% endif %}
{% if not pub %} {% else %} {% endif %} {% if not worksheets %} {% if pub %} {% elif typ == 'active' %} {% endif %} {% else %} {% for worksheet in worksheets %} {% set name = worksheet.filename() %} {% endfor %} {% endif %}
{{ gettext('Rating') }} {{ worksheet_heading }} {{ gettext('Owner') }} {{ '' if pub else ' / '+gettext('Collaborators') }} {{ gettext('Last Edited') }}
{{ gettext('There are no published worksheets.') }}
{{ gettext('Welcome to Sage! You can create a new worksheet, view published worksheets, or read the documentation.') }}
{% if pub %} {% if worksheet.rating() < 0 %} ---- {% else %} {{ worksheet.rating() }} {% endif %} {% else %} {# I'm removing this select since it is a massive performance killer and these serve no real purpose at all. Plus google docs got rid of the analogous menu. #} {% endif %} {% if not pub %} {{ worksheet.owner() }} {% else %} {{worksheet.worksheet_that_was_published().owner()}} {% endif %} {% if not pub and typ != 'trash' %} {% set shared = False %} {% if worksheet.collaborator_names() %} / {{ worksheet.collaborator_names(5) }} {% set shared = True %} {% endif %} {% if worksheet.viewer_names() %} / {{ worksheet.viewer_names(5) }} {% set shared = True %} {% endif %} {% if (worksheet.owner() != username) or username == 'admin' %} {% set shared = False %} {% endif %} {% if shared %} {% else %} {% endif %} {% if worksheet.has_published_version() %} ({{ gettext('published') }}) {% endif %} {% endif %} {{ worksheet.html_time_nice_edited(username) | safe }}
{% endblock %} sagenb-1.0.1/sagenb/data/sage/html/yes_no.html000066400000000000000000000005461311436262400211740ustar00rootroot00000000000000{% extends "html/base.html" %} {# This is just used for doctesting template.py. #} {% block title %}Confirm{% endblock %} {% block body %}
{{ message }}

Yes or No?
{% endblock %} sagenb-1.0.1/sagenb/data/sage/images/000077500000000000000000000000001311436262400173065ustar00rootroot00000000000000sagenb-1.0.1/sagenb/data/sage/images/corner.png000066400000000000000000000001361311436262400213040ustar00rootroot00000000000000‰PNG  IHDR 2Ͻ%IDATÓcø40 ¢aQˆ]šBÜŠâWUHXÑKP³åŒãôIEND®B`‚sagenb-1.0.1/sagenb/data/sage/images/evaluate.png000066400000000000000000000003361311436262400216240ustar00rootroot00000000000000‰PNG  IHDR 2ϽbKGDÿÿÿ ½§“ pHYs  šœtIMEÖ TjjtEXtCommentCreated with The GIMPïd%nBIDATÓ¥A ! Ä&þÿÏñ$¬«°sh’¨¨’CFó|6VxÔãØúZÝYUHb7bIP[ÓuL}g† # äðIEND®B`‚sagenb-1.0.1/sagenb/data/sage/images/evaluate_over.png000066400000000000000000000003401311436262400226520ustar00rootroot00000000000000‰PNG  IHDR 2ϽbKGDÿÿÿ ½§“ pHYs  šœtIMEÖ 0S^tEXtCommentCreated with The GIMPïd%nDIDATÓ¥A À0 ÃäþÿÏêa+lf…ùˆQ‚(&D1l28Ì¿bˆÇÄZuù,¼çÛº£^_;‰‰Ú’>eê9\± ”ŸAOIEND®B`‚sagenb-1.0.1/sagenb/data/sage/images/favicon.ico000066400000000000000000000021761311436262400214350ustar00rootroot00000000000000 h(  × × ÿëÿëÿëÿëÿëÿàÿŽÿxÿëÿëÿëÿëÿëÿëÿëÿëÿëÿëÿëÿëÿÜÿbÿÿÿ ÿ$ÿxÿ€ÿëÿëÿëÿëÿëÿëÿëÿâÿAÿÿ ÿÿÎÿJÿ8ÿÿÿÙÿëÿëÿëÿëÿëÿ>ÿ=ÿæÿ’ÿÿëÿëÿâÿ¨ÿÿxÿëÿëÿëÿëÿUÿCÿéÿëÿâÿÿëÿëÿëÿèÿ«ÿ ÿëÿëÿÚÿÿCÿéÿëÿëÿëÿÿâÿëÿëÿëÿÓÿÿ€ÿëÿžÿÿÿÿ0ÿOÿxÿÿÿèÿëÿëÿæÿÿuÿëÿëÿÿ€ÿÚÿÁÿ›ÿ+ÿÿÿ ÿ$ÿÿÊÿÿ=ÿëÿëÿ"ÿæÿëÿëÿëÿ:ÿÿÿèÿÊÿ&ÿÿ ÿÿÜÿëÿ.ÿiÿëÿëÿuÿÿâÿ ÿµÿëÿëÿéÿ+ÿÿéÿëÿ²ÿ@ÿëÿ¥ÿÿÏÿëÿOÿ\ÿëÿëÿƒÿ+ÿëÿëÿëÿâÿ"ÿ¼ÿÿ«ÿëÿëÿ¦ÿÿëÿÇÿÿâÿëÿëÿëÿëÿ ÿÿŒÿëÿëÿëÿæÿÿàÿÿÁÿëÿëÿëÿëÿæÿÿÿ ÿ¢ÿÓÿëÿëÿ ÿ ÿ{ÿëÿëÿëÿëÿëÿëÿÇÿ¨ÿaÿ+ÿÿÿÿÿÿéÿëÿëÿëÿëÿëÿëÿëÿëÿëÿëÿëÿëÿ{ÿžÿ’ÿëÿëÿëÿëÿësagenb-1.0.1/sagenb/data/sage/images/icon128x128.png000066400000000000000000000247271311436262400216360ustar00rootroot00000000000000‰PNG  IHDR€€Ã>aËsRGB®ÎébKGDÿÿÿ ½§“ pHYs × ×B(›xtIMEØ 1 ÒÅUL IDATxÚí}Gp\W–åy?-\Â{€ ‚$H‚EŠ”—J¦ÕŠŠPLTD/fßËé˜å,&0X΢·³›ål:ª«£«:ºZR•JRKt¢h@¤@›ðé‘ÿÍâ¼›ÿg2$ Iüˆ óç»÷Ý{î¹æ)<åêëÓE8`¾vØ  @€Âîµ—°à€»æ«|¯¿_éõþYåýýÊýó§þÀQ~ó˜‡ßüÿ®l¿Ø®ÇªQŠ þ±¿_ ‰|dÉXå~_Ÿîð€ßø€¢ß˱¦/•(ÄbÀÔP_ÿäï¡"hÛ¼^Àã,+û«y(÷s/‚El›¯#σÀ±cÀ½{У£» °i PL·Ë(˜Ÿçî››£Ÿa[VöÃý\¾¿q+†RÎó¹ß{<@s3t áØUQT]ti)ÔêjŒª](ø3€ µµ@KKèD˜›î߇þé'è• i=ÿ/\Ìý;¸(I®Eñù€Ï>ƒÕÙI÷c"tvBÍÎBß½ë¼îNŽ ^ N3ô{ã ¨ÆF¨D˜…¾rúÆ èTŠ~ḜÖ@*ŇG B—• P++@I °oT:MKäŽHv`¤´¶B< ÕÙÉÝ61=6LLÑ(àñ@›8\Èê¬)<±HJÑ2¬¬@_¼G@­®ÂúãaG£t;Õ X;]øJAUT@9ÕÝ B_½Ja‡ÃЋ‹߬ éo…ÔÉ}H´HååP¡ðÎèK— ïÜá}ïßuö,¬’âºÆ;Vd†BÀñãPGrݸ\» AE£@$B`³ïC?]Rtu‘ˆòûQ„BTÈúŸ8}jÿ~Z†ªÞ(x1³ÅÅÀ¾}ÀûïCYõ*cpŸ:ãN _ü}\ÔèS-‚Öôóû÷C}ð¬òrþ.Þ{$Óð0´ÏTWCÕÕo¾ •Jׯ;¹Šìh päÔGÁ²,Æ×W®@ÏÍ1˜™!ù²QßêÞÝn"huÕ~é4}}Upò$Ô§ŸB••9¯áóMMÀGAµµAݽ ýÕW°c1 ¾êÄ ¨ýû w-ÀÓw¤N¥h>OŸ†*)&'¡Ïƒ…®¨€ª®†š™a(!Ÿ{G¯Åû»IËbXY\ A9ÌsÁ Àë**ø»Ì[™DÏìÙÔ×C?|ŒŽBÿõ¯°?üª« *™d¸:?OŒ°SòÞíºÖŒçE0^/Mlo/T}=T8 }þ<ôƒÐÑ(9€ª*`lŒ¬ßêꓨÜç£p}>&jäáz~?)Ü` ÌW¸¿ƒüÿ|·žñ ÊQ.¥€ÒR*U,F³_[ uò$ó‹‹À?«Ø)ü€w›w¼6J‰éO›š€…蟮\öz¹óB!&_îß§? ¼^îh¯—ÿ_\ÌßÓ‚ÈÃ<¯Š‹³É¢õnN5-Ì÷YÏd:íü>.]búúèQ¨Ó§Icß½Kå5‘Ëë«PUõöÛ$PJJ˜Úõz郠ϟ‡ Q€Á ÐÖÕд·û÷eeP¥¥tqñ‹qûëa¿œ¯Èq¹\ZVVÀø8ôÀ￳ê“O ’IØ·n½ÆÀ˜{]Sõ›ß0¿ :ô«üMOÐÕËïw8ø`‹ÛÓÃäæðŸçò öiW4ÊDSi©c r`ï^¨ÉI Þç£2ÿò ‰ªŠ Fo½E2ëÚ5hžx}À¶¡‹‹GïÙC!Jè'»Ë㮪Z{qrNçÙµëîlÛâq 5%™cÛÜ©•• íb1`|œ¬ãâ"ÿ±½êðáÌî×é4͸|†ƒh”þ>‘àߤRÐ##À? ÕÒ;µ¼ <|ȤÑvBïVï|€¡UCw‹Û+Åd-ȳ”ªev¤äêÝaœ„rÞÁ#çë `´,*ÄÂS½óóÐØyýÆFÆöî÷]Z‚^^ª«ŒÑÝ =750{uðz¡b1è7%œ< tuñ8eyyû"ï _Hô㦤+k÷»Mªù%aüÎ ÿ¬>•¢PWVÈF"a±wäÒôÒw» UQÐØÈ“¦&F’m|øÚ5X“LÍÍT\÷51A¸µèé!˜­©zë-è‰ ¨éih“V««Ðß~ ]\ ëèQ*ÊÌ ÔÏ?S‰¶#2ðnõî³gIíVU­ÏÀ¥ÓÜ¥‘ÁUu5}ïkÿ–—A›R¬¬˜ßã!'_]M¡OM1Äko‡:tª¥…;sxøúkèéi’KB ¹Š:´m°VWgïÒXŒ$Õð0­Ck+ÝAEÔgŸø]ˆÏÇûŠFsç¨Ì==Pï¾K‹34ÄÏP`»ý  5HÐç8@^Ï,‰T<]Zš]]“¹9/Ôâ"ôŸÿLüé§äÝÏ£@¤ÖOJ¶äJ¥Z¾÷¬öv*],Fn¡¨ˆ&wnúþ}.þò2‰„c¥$³hv¥¶,bƒ’’l¹´,,ô7ß ´´04mn†:u úÒ%¨‰ h =1AŽ ¬Œnðƒxÿ7oBKéÚVYo!M¼ì·)óxôöï§´¶B%“зnÑ·½½ ãrL ³×Õ33$PÒéÌb>ÁÕ ÁSVÕÜL e†ÊJšùŸ†~øz|œ¯gUå‹Ë5UQ¸è_0 ¼´ÄÏ­5ðày q^/éì¥%è•ZË‚J§¡GF FµµP½½´&÷ï“óÀUi{ é߃A Ìãqü´ðç‡sA˜2½zúñc莨cÇ€xœ<¿I¤Ô••P~URÛç#Hkl„ ²Kº<‡ñ Y¤!—kyú«¯ ÃašdËâë<Í‚)E¬P\œý»©)`qÑ1ÛZ7oÒº½÷KØKK5,/Ji{$=4U[ ý«_1»˜L’*^\d³ËV€Bo¡„ï÷CuvRãKK)èT ª»›qs*Ðtž9k~žæøÍ7¡ 9¤ ³§ý~šùHzy:æ¢QñâqZœtšJæõ>ûâ*Eð—«P33Ä&RûçñKKзoó³õöRˆÍÍd''¡ggé¶|>º¿ï¿*+¡:;wß¾ü’¿ÛŠìá†À¶I¹îßO ·¢‚Bkj¢ÿ  ?f&ïæM~x¿ŸÅuuÀ¾}ÎN9xÂqk¾ì@¿ŸfÜÄ·¹H±Ó©”ã†Òi*JUpècúéi¾2ùÌ4pxmhà=º7= ½°@|àÂ-˜žfjc#Tc#´ÇèçÓOaýþ÷tRtºº üå/|#G¸a¦§¡¯]#þK·c fäØ1"äܬtšÈûÀúeË" “JQ¨UUü€++Г“Ü©·nA77Ó¢TT8%PååT’ÁA,é4_K*…Ýý&$„ßOô½°àdïžUø[èššLbHLíÎÏÓo»­‰„{33Ðß}|ò Tm-y†={€³g¡/^d’Ë€B„ÃÐW®ð>÷ï§µhnÆÆ€GÈ*nV…q!\ü~úm‰åÝ`nzš¾}u•>4™d¸³¼Lä\\Ìš„ÇYM3´{øX]…:qZxu(/g>àþ}è©)§>?×—›,#&&(tƒž akÍÝ[Y™åÿ•m“ŠDø¹=ÞݻР@o/Ùï‡>yjnŽ®.‘àë[Ôð0+Z[ kj˜ï¸u‹ŠoO°aPŠB%JÎ-ÉfRgr’y~·eho‡zë­ ¡¢=b¸¨µþÚ5R¾GŽd̬òûÙ”H@ýðýj>¶P¬ÁF€”(ws3ý»ûÞÇÇù¹ó™g·¼x‘‘Ι3tI pâCÎ7¸Y,‹‡éi µ•Ø!"Y445:J‹Wh+°áŠ c¾qýºS6-Z·oCgL8ü~úÉPˆ•=J±©#çóò¿06ÆBÙÙì8ßãaäpâTm-K±6)g¿Ÿ€×µUVWÉ®ÿi $ 0ñ#ÏíÙuìTcc¶«Y«»¸¼Üé=(ôµa°,úÁáaúp“Õ.@ÿÓ?ÁžœÌX\¨´æÎ®¬än_*?!al›föñcF ¹™¼Þ^*AEMn¡çˆ47g+€mÓB¹+’òYIMN7nÐÂÉ=¶·C½óT0ÈŸ-‹ÅÐP6†ŠÅØù¼ºú|àuËÀJ»’+˜›£Æß»ÇÁ Ó;/EEE€ò÷±X~í÷z þ©)§@ÃÌ P==$’¤ ¤P»DpCQ}²ÁZvõÜð,&Y@áØÝÁÒŸ÷ûö> +$¨L§©³³Ž¢Äb‰éôætL§,ËC++ôÍ&ÔQk„ŽO(@.~0a$êê nÞdEðÌL¦ÑBiÍÁÞ^àÐ!A)+¿ ºÊÂT*EP+¹‡geóÔ­¬P¸ÅÅìtÚ»×qUUÀ/¿dŠ‹ œ³c@|¼[x¹‹ãNÖ‘Ñš¼|4ú¤†[?|I iàsçXèZ|@——³Ò¦¥…Å™î‚ИÿPˆÊ—ëÓ'&œœÁs`%eÛÐß~ {xع·ÒRà­· öìa¥ñÞ½Lv SÉB! ©‰dÖfŒÀ)¨W?)±y¾†K¥¸¸EEüp¶M:5PI ~i)IyÍ;wXr--crAýíßBµ·¦üZ · =!|‘LkºÉóçÉu¸@!Nœ`†²´”¯?2=7ÇbÏr ¶½ƒ-€ø5w¾>ßÈî/-ÍF$\p1sZ±»êê…Á[YîÞÎ#id@¥¶,úê³gÙBf2{/¼cÒi†µ¹ ‹?¿¸ÿöñc‚±1Ðjj‚šågXG D$4æ ë1sn `@›ì]f¡eÜš;––8ÙeJ•e1gpñ"ý©{wPGް¡º:ƒ žYêêØæ¾ææ¸+ ¡’3‰ÅØò¶¼Ìû3£gpê•ad„ëÒÚÊMSèþ wºÖì~½^+´mÓ´––Rfgù÷âÓi`t”àP®p˜¤ÒÒR6÷îñ0.eËÕÌLSˆ`êÄ àða¨òr2ÏbBÓiVéä*Àü¿«®&oŸHÉ»aYħO3¹tçÎóUÄ(\¸ûÂØ–äµkk¡>ûŒ•9ÏÚ<…eqUîЉÉIÖ)*!c”]uu1æ_\¤…ùñGÎ=_/µ-[m­£À; úýÜqk¹ù»êjîòH„>UÀ_"]] õÆÀƒ¬„1ù% o-m—ü»RP‘ 3ÿó?a!+±>ÕÕP}Dß*Cžó™e3„:ëùÉIÞs¡@*¥ººXå,àra–ozÚ…RŠVWÇ^‚2õ Î{< |ŠÈ(€dÔd7””ôijb§ÌÜœ“~Ö{p˜åÙf|\†-TŠiØS§È½P˜5*Ö(@^ ;ƒp»_ƒ™>×!¥ûY]e%Ñ¥KÐÄ*Á«×ËÄÑo@µ¶Bù|ü\ÛÎJoþ³(@UWHYøŽJŒ3¤K¥ž¯r×melj~ÞiÃêèpÊÌöꛪa,-ñ9zç˜÷Ög†Ã¤ž_äžrAf:Í÷hh`¥ ŒðûIùz½ÌLM‘‚3ˆBP°"jq‘‘ÏF”Ò[( Ð] ™ïï Á£"VÔTˆC‡˜ ûçÎŒzUqI¦Øß}Ç×ëêrNÒTŠïgYÀ¿ýLfJÛQUE%[^]e™V"±1öÏý¿¶Mhj††Ø(#‰§†¨†è†¨Üîh‰\”böO?9eîÛº£€\²Bv0èt×Hã¦ÏýÞ{ÆÍ›…3³rŽ—/³6¡£Ãé8¡öí>üøî;ZŒº:ÆÛî÷O¥ˆÂ×c7×Ûí‚5ÜÑNy9‰¶6šücÇXr.år>-ËÏg³jÍfÒµ°Ö–»€§a­;‹Ï‹ÇÚøÆF¨Ž¨_~nß~r üF˜6!¦~ùÊëe¢Éï+¡]{z  ¯\¡™mlÌnYO&Yþõ4z[zÜÂöùØ RQÁÐR¾/)É4š¨Ž¶²­õ9 VO»-¨Û·•l´g `. Wrsû~?ùu“éÂâ"?xo/,GFè =1ÃëåtÑ{÷˜Q{ûí Å«º_ýŠJ™JÑ,»ï=‘`ÜíÎXæN  ÒƒNÊ»²ªªŠ®¥ªŠ­sîK„ojtÏD¨¯gÇðåËOf÷ò qÎGÙæ* ëè•ï¬ ÷éÖüüÚ¨u[L®ŠgJ/ˆ»‹F lggYÒ5=Í×îÀçã$Ó§YÝ43äTQQvR'vú ÿÕU*¬4κû$·]d·Ép1÷îÚ>3W/S\aúõýûD±^ï“Bv)rÓ¼ëP3 Tˤ.ׄP-sJJ¸èyRÕy{ ÊçL§™ŸLMAMN2zÉM>ìSH§É/>Ì))o¨2‘O&Ö—ÐñèQ‡/‰FÙ4»Vâ¶*€m3ÌiksŠ'`qÃíÛŒýS)6|Š9óûYw÷.C©ÜcXÜc­‡Œ•aÎf¦¤J(ç€'å>j-¶VvPÚÔ¾þöð0co×È9N¯_­+UйÃ%L¿ƒ2 á ª« þd§//“I& SŠVPX]¥¯:rÄYܶ6VÍ S{ÛÛ¡Ž'u P“‹‹Éû‡BÙ`J†6û|™)™ïsöz™‚~‘+™¤95¥ßÊ´®e ?Üék­‰Ô‡†H¹-’ ñ«õ,ÔÜÿ÷àAÞ³°‹³³Yц®¨`y¸„ËËtÒI´#c6l**X¶,&ßë%»uö,ýbw7sÞ%%Ž)íîfV«¸øÉéÜ/¢å®“@µ ˆBÊýH¥ÆâqÖâ †în*‚RŽ+..2üZXÈÆ:Ï!©åeŽ‘kl„îê‚nÝʪ.RZs¢Iw·£LSSÊ…BüW¥¸Ë—–²º¶–­ZétÖ%­ÍvGÇÓKØ6Áî¡®1ó™©Ÿæ¡#çg× H‰ðoÝ} PT][ KÊÔ´vÌz4Ê6­Ë—i¹^$(.dvúÒ%FW®@ ›ÈÚ“vQ˜œäD³;#H&k^½Ê„Ž1ÉÊøÆ¼S;$®] }KS‡œ‰°ÈÃ%ج) ùO¹ Ò-rmu•VA”Ukî¼±1àî]è‘àm”ˆ ,çº-Øž=<Mžã(;s<v¤X–ÃPŽB×Ö’\©­e¿þð0§kˆ"È®K$˜¡âqF‰ÍtξÚ}ž¯ùv—‰çšÈ<ß«| Ï²˜ ª¨p,ÕÜðïÿN“/÷#¾· ª,À( Sköÿµ·;¿»wô¸ “Ú‘ ³¹p¼ÙS§ë—–ÒךԦr[€ƒÍð-~Û]è˜;ôÉ}\¬Äþ/º8¶ÍÜCK‹S¤jFÉÁœ.Ũ©–±w¯s¯¬£—+ œ‹9?Oô5ìßÏT±0©7o2ÜHùÙ–+€Äãdúþô'~öv¨}û FFˆ„¥ÏçcÜûñÇ,Òêt+.TUSãp‹‹ÌTnF¶{H4ã÷3d–Ätšï?>þl¨vL60_Ö-å šÁ ÔÙ³ü(ç]»Æñguu¬lÝ·Ï© ¤«p“2…¾„tijrÀßü ´,F !/×íÛ<°j«ŒÚë|>À+W /\ |ò$X_Zþã?8 TÂ¥š¨Ï?‡µo3‰©EÀfö¿(Ø™*Wq1ùˆÏ>ã̾ž¨÷ßç Ù™†ÎÍ÷xê=™JÕÐÀ4:ÀB{÷X¸Ä϶*€‹ý‚éÆÑ?þÈE8~ê½÷ÈüË¿ÐÊߟNL¼Q#Ôîž=ÎYB‰VZÓÚœ> õÁÑ"ÿW\ uö,óôr F2éô?<>‘“ǤÿA„¿¸XøÙ?ÏzyÞÿõmõ›Ê€¤d’±¯eÑ$šcYðË/4Ë>}±R,œ¨­%‚Ÿžf~^^k½OŽ•fí7¨’w9‰£¡Á‰ÇÝQ)òò¸>~êÈ’HPT:ÍÆQŠk L±§jl$í+g"D£À÷ßÓüËa–[-‹m;=\€áÜëã-‹§ƒ<ÈüÿùóÄZ³tÛë傟8ÁŽz•;Gürn‰X޲2¶•–’rW"¼ûƒTÄ¥%'#aš †"4.å˜ze 82Ö sŽ©1åá:¥òÊ ¥%%NÁi8Ì܃;åüÚ(€(eqìåËÜͽ½Ð½½,&½x‘§jstZQ‹Kß~›E'·nQhfx|>§Ã6 ×_YÉÂÕšf'MKX†ýûê+Ø2SŽ• ‡¡;;© òþäÄsËâýÔÖrŒmm-Ake%sfÔ X)µ°@Å“ÉòÞ2>¥ònÜv+à˜”‹Kpæ ,¿úÇa÷ðjzÆÇ\½ÊÝ+­ÝŽ@¢Q–U±î ²xÿ}¾ßÒqF<åóe÷'„Ã|¸0KÖî”Cdh4ØY¤ËËé>êë¡ö()!«™KízÐï§ 6ï@¨—JäHÕ¹9èóç¹x:óúå b­IÐ¥PEEL? 0ž^Z¢ŽD($AífWf`q‘U7¹‹îšÂ‘%pwIšŒ’«®æÁÔUUì‹…¨¥¥ÒÏ%‚Ì=ipNâUP¯­+ ´f-ÜÏ?s:ÖÞ½ÎÑñÁ ‡B†Ã™Æ 9¢ ZxÍÌdƦHg­.)¡ B!§ w~ž¤””Ê%ŒdàƒX§ÒR&nŠ‹)dÁ†TÊKÉxBÿ––:!îßßøàéWJd£Dެ؜³“Iº ¯—>VZÁΜáÎ;>3`9Óš&™ä &'YxáQŸ3›8P}>¾ns3ÃÅÖVÀ|ag:í¸†h”àQS65A<ȹ‡‰Ï<¸uË™úÚc€Ü+&P]ÍÐP 5JJØW',ÉÉ")Ü@¸pÁ),hnv^{b‚ »Ñ]¥ãñм77³^ ¥Å™k tn¾+!wñè;33ÜÝ–Þ¾ }îsá0ï};ÁߎU÷±óÓÓ$J¤ÐT).à¡C<¦ª*ã—3(¾£Ã9IôúuF2‘K®±1gÀž}ÉÎÕÕ1Ö/.¦Ù^«[ii‰Ó<&'Iä,,0´“‡L“, t%E£ü^údæ®ä…É$Ç¥<~ììÔ‰ NôÏFÛnÑÖF…°mþoe¥3TQ|rK QxE_YɾÖÀ¦¥%–¿Kœ??Ï223ïHÇãNj¾cjÅÅ$“Ù§«ìZ€§(,–,d,ƺ¹{÷ `Ûuk+ÏÝä-Jà÷C=xàœû£5Mu[û÷ìÉ/pÛfÄašH±¼ÌQîT(IV¹æ¬;È­Ûí󟸯¾>ÆKv¹gðù|ÜÍføäDî|3Ö¯ÝCff ¤@c|Ü9Ã/ßÜ‚—ýò¾Ì7oòëc:õòev%ïÛ—}ØóÓvæä$wöØ 3"îþuFß¿2×K©îh†*é…… „¹9ŽœwWñ¸wk8LA‡ÃTœ¥%g¦›@’fŽõ&”ì*ÀP÷q3ÃÃÎRÃ!dÌ¿ÖôßׯC?x@E1óŠÝNmöIJ]ØŸXshÃKf ”RFý—¿0] Ô.3ò5V€Œ¬½@áN ÚIüm³ÓGŽb• œfÐâë¾÷™N„x^©OÈœû½w¯ŒÄD,w$^E< àðuBõÏ¡ n[îؽ^¯kÀ Ûì^¯ŸÜXu¡ÃÝëÕFÿ"ãEQ€»Æ¸Ñá®"¼º¡Ÿ ¡)Á÷\~Uàî•%p¹¿_MZýýJøGß»¬À.f~5‘¿\ÿÀïDÐ߯†üÀ€Ë ìºWËü[F þÀŸúûÕ M  À>2Ý>G{v¯—Gè";!ùø?n@_ŸænïëÓ0ñG0!‚ír»Àðå|Úøýßøº¿_E̳A_¿ºàü­]`øÒ>ËX÷ÿàö÷«x^` a¾¯pÀßø-€Ê-–>oh€µþ¨¯Ow8à°yt8 hWv„Ì`7à–yÜîïW“kmn¹þ?Z-àÅ? áIEND®B`‚sagenb-1.0.1/sagenb/data/sage/images/icon16x16.png000066400000000000000000000013401311436262400214500ustar00rootroot00000000000000‰PNG  IHDRóÿasRGB®ÎébKGDÿÿÿ ½§“ pHYs × ×B(›xtIMEØ 5¢¨ÌtEXtCommentCreated with GIMPW;IDAT8Ëm“KK²a†¯yßG;¨a¤FH_‹Š¨MPTÑ2’6µî‡øWúI« Š¢­Á4Òæ©eæ|‹÷Õß7ðÀÀ3sÏ=7÷H"¡Ê¿¡îcbyzc\®óßj'¦ÝÐׇôöÂÐ €Ï‡øýˆmC4 èÞâŽ³Ú À¶‘Ý]BŽ‘j^_ô¨Va|½¹AÜ¡в>?¡XDK%8?w@ÚͶúýpxˆŽC0È•-cÐj’Itm Q—b+AK%ô㎎ÐÕU0¦Ó/@?úü å2’L¢àó9##H>ïäõ:¤R°²ò‹ÁÌ R¯;»‹prñ8b ŒŽB.ס-™ èæ&*‚@=¸¼ü*ºº¢ !Ûۈχ”Ëh ý`ÂaÄãq‡alÌ™ÔÓƒúýˆ× ÃÈeÁÖR¯C6‹‹èò2ÜÝ¡˜h …`i ›C xyû{˜œDs9GÜ–c±mðzáñÑ5R©™ ”ËpzŠ~÷åì,rpÐi «  h6]ßßÑý}h4ÅED\›ƒÔjÐlb¹b‹eA ­¤ÓŽfVÛ÷ ‚Äbˆm#Ñ(¢ÚqÆ@$±ÜÞ~12ߎ‡³3d~‰ÇQËBßÞÀï‡éigï?ÐZ ²Ù/I$ôó›3ÅëE¦¦Ðõu¤RAëu¨T Ÿw,ŸNÿ¸XÌï3n4ÐT ªU´»¹¾æçÞ‰¿ö¶äsÑ¢À7IEND®B`‚sagenb-1.0.1/sagenb/data/sage/images/icon32x32.png000066400000000000000000000033721311436262400214530ustar00rootroot00000000000000‰PNG  IHDR szzôsRGB®ÎébKGDÿÿÿ ½§“ pHYs × ×B(›xtIMEØ 2,+åƒrzIDATXõ—ÝoUÕÅcí}Ρ@OKhŠ"PåëTlIð#"4šh0Dcr_4ñÁâÚ˜ÜgõÅÄ7“|0~01 ½>`1V¡–RR ´å»å´çœ5îÃî‘VKr]ÉÎNÎY{­9ÇœcÌ9ÅÔêìôÛ6ÿ”xˆ€øÿ/ã¶HzcÏ]À[où¿’Û¦î¬þM—M[ÒŽ¤³ÓoK~køû–$,Éà‡Ó ö¹ï´±„b´%ã´gùT2šûÐÿH§b>'ì²ñŠhófÔÕE¬TPŒ`CŒ·ž\ÆÆäéFÞ Ó;K839)·¶Jë×ÃåËVµªš§„í Á´·KûöÙÇ˹Ü_†Séļ\–W®$45¡wßÅ×®%úæÍƒµkÑC) àË—í4;¾é\ƈ%¸ÿ~óè£ÒÑ£X Hù<äó°p!‹¨±Ñ¬Z%Ýw;f?ÿ¼´oËòçž vì <òˆ8u ÚÛÑO úz»XTÈåLµš=6&ƒÉå¤BAþæüÌ3è³Ïp’Ìž¬³`l¹T‚BÚÛ­-[ P@>(_º½½¸\†å˲øãáaxå…“'‰­­¨·—80Û·£¯¾ÊBQcÓ 'gÒMÎçÑsÏ¡]»’üË/¢\ÎÐ8sƱ1»¥EaxwuáÞ^»\FÍÍpè>Œ_ä×_E.‡6mB““XòŸp3cnêëͳϢR _¹bb„> Z*Á¦Mh`÷ôÞy‡êéÓ&I ¥Kqµj†‡{z¢ø¸{·µ¿ãSOI=†Êe<§’(•DWÞ·.]‚›7¡¿ŽÅ Š—_&”Ëfr…EÖ6›7úúä4•B<ˆs9ôôÓÒÐÎç3¦Ìi@MÙnÞ4• ±XD7oÂ’%bÙ2óá‡vs3ìÜI¨T°y$Ak+ôõ™jÂe>ù„øøã¨Z5Å"ª«û]Yo—¦Ù[BÅ"\¸€›š`Ý:éâEûý÷‰ííbÛ6T©d45¡\í²$ A…#G ¥ÅZ»6Ó‰©³o@’Ü’ÕÆFÌ€yï=bŒbdÄÞ»×±£µµ9Ä< &'ahh¦‡Å"\¾L’Htâž?ïÚ%?—/—΃±±Àüù™‡6Ô׋͛ ÙommÒ‰„ññ[tœÕ€JÅ44 º:IÂ##®InšfIY,š7ßTÇÝݸµ­^š›q]JSëçŸåÁA³x±´¿ãø¸˜®ḛ́óyÉ‹A¡`~ûM.¬$ÉPÉçañbXºÕÕÉ,XÙº5hÕ*èîÆ}„s9عS:pwt žÜ×'j92«! +ÐÖ­02õõðÚk„B!Óˆ¡\ׯÛW¯ÊçÏãînÇõëCøòKâ_8Ο/… ¸¿ß¤©üðÃÒ§ŸâMº½KâÐ!¢m=ù¤T©ˆÏ?ÇgÏ*¦)’˜¢Y&Á°q£ôñÇŽ?ý$76*Ô˜R õ÷‹M›ׯ›¡!ÍZÃ4E‡ã#GðÕ«æÕWѺu„$|Þ¤)J”ÑÔ´´ Þ^ÅÙô¤P€-[Ð?Þ¾ Í*D! o¿Å'OÊçÎÁK/Y+W¢Zå«­5k ¿?k¯P¹Lœ.N«WgÂÔÛËŸb[¦Bá$A‡Û££xh^|­_&&ˆóæá… ñ† „¾>ü ¨£µ´-²r9S(à–éØ1b©¤»nH”qYúúk¼m›hh@»w£¦&’³gíjU¬X!öîÅi X²ÛÚ”´¶¢¥K3Æ £ð=5$Nôý÷ÑË–årfûö,£ð™3™Z67›5k¤E‹å2¾pÁtw‹|ÞŒŽâ?fþŒ;:;]ýËi¸RÉø¾qcÐT MMŒâüyÓÓ#ÂÅ‹ÙÞ$ɾ 0WWXkJã_µå¹”JÁß}‡GGÍ®]Ò±cøøq<>‘D’H¹ÜÌöûhz¦ÎNß×ÝÍ@dÛõõÒ޶‚î}–*Ûl…iËLXºv ÛR­ðÜõhlûtô†„ïf.¬iE­¨Ü–H€ÿ„={tâŽÝeûê£pï°Û>üKÒ¿ÿ ¶"U!óªGIEND®B`‚sagenb-1.0.1/sagenb/data/sage/images/icon48x48.png000066400000000000000000000057411311436262400214730ustar00rootroot00000000000000‰PNG  IHDR00Wù‡sRGB®ÎébKGDÿÿÿ ½§“ pHYs × ×B(›xtIMEØ 2sÏc aIDAThÞÍšÙo”çÙÆ×;ãñîqbÀ†xÁ€ ´iÂÒ ÂšVmsPEi¥þŸz†z©ÿ@{’JÝTUJÚÒ(ÔD 4 D€¶± ccÆÆ ãy¯ïà›Õ.8¤b¤G3óÎÌóÞû}]÷38x0TüÊfÄ 0ÇCÀpÒv·¤7ýkèàÁ[/’X[z~é1Q`A›<(égàP4/¼K·YýqþY$J’Z?Ù<‘¿‚yáõ8 ½”2%à)‰ÿKlö„Õ—+¼±ñüúß)aÛÚ-'ì²olã\ÎÊdÄô4NÓÅ÷ºÝD.›L²–­2ð\¶\mÒåļ“mÛ&55Áþ““!ÜÝ+Mo½ÈfáæM˜™‘¥ei`‰ÚìW©6¥¬X!^|žx55Áõëq}~¥i¬Û¯UT@[œ;‡ß{/Þ/#€8»üÐ1¶X±ææàüy|äˆ=5Ù¬Èf!›õÂëL†ò³Éåĺu$ÕÕ¦§G ኊåqÙ ÌÍÉííèß@££ð׿âBAN/„ è¾áÔÖ†ººpo¯Øµ ýýïpíšÍ>¼Z4ÅÅ¢ii‘¾û]40ÓÓ·b;Mµ¤¹TV¢ÊJ¨¬4uu⥗PCC],ŠïýóŸbfg2ç‰ìCƼkkÑ“OÂ7¿‰axg³!ÐO ª*¸}ÕÖBMM\¯« ÐØBnÞ,~ÿ{üê«°s':rĤ©œ$®Döa„ÏçÑöíhÓ¦ˆësç £år$¨ºª«MuµTQµ¡TŠ©¬„B߸ñYmm$ï±cx÷nôüóðÉ'óåõ*P*á4µ6m’¾ým˜w󷾡29‚ݸ—.„¯\‘›šÂò““0>އ‡¡¹­^-_¼Õg÷nôöÛøÄ û…¤‰ 8sæÁ“:»xw•‹Å({MMQë[Z`l̬\ zꞘˆ tõj”ËŽ±e‹•ÉH'Nàb1êýÈHÄwWW¼ÿøcœÉÀÞ½$##øßÿÆù¼ %ÌÅ‹z %²÷/‘r.‡¶lövTQV>yºº¤HFX½ff"9W­ijjkaõj©¯td$<$¦²Rlس³ÐÓ¿miÁ»w“\½ªôÃ#L·m“Þ}× r.·t§Né°äóðƒlÛ†š›abÂTW›LŽUÚÝí´¶ž{‘qò¤xë-Ò>ÂÓÓ&“AI‚$¨©+¬BFGíÙYûƒì+Wð+¯XMMèÈ;“7ÞÖ­Ci*{  “,BÅ¢×.áý öÌΊ©)8Æ_|Öß±ÍÍE˜Œãþ~<;{ú±„Z[ãõà ¶…W¯ÂÑ£¸²R¼ü2ºyS\¾ k×¢5k@Z¦%÷]¢X}}ðù縧'’0“‰ŠR(„ûÏÃ.ÈkÖ ×^C D’Kaõyƒ$ ¬[‡æ÷Íd@ñpo/>v wuY;vÀØ."Ò”‡W`)Ú!l©Â××dž““8Ÿoüío¸§wv¢ýårÖý`µë×G÷õA’,\—m>ýŽ—¿÷=’öv«§ÇÔÔ ÚZ´LOý ‰2W,ÆokjP6‹ …ølÿ~’ýû-0þ3ÂÏ>+íß/%É7•"§Ðؘ÷T’ŠEûØ1§ýýxóf1:Šëê ŸK%Á’ ÌC^€úz‘ɘñqœ¦Ña³ÙabÂþãIÇÆðöíè;ßYð ç­¼vm Ç¾>|w£Š÷Òø8œ= V[êè¯ß×¥€e206­­è³Ïðï~‡GFâ{££æÀ7nØûö‘lÝÞ™u¢X„þþ[ás7ºÍçáúu|ø°¼j•X³55¡ÊÊP~Y ÌΪ¬@$â°bE䯸8¶ƒHbpÿå/òÍ›øµ×”¬[‡"ŸÌúõQ©z{#Ÿî‰òÊ•R6 ‡‘?Å"ìÝkuu…<÷óB²ý›÷€uu4››cãÁÁ`cËBB™ :}¿óNPË_üBIKKžêj†©©²¶wl£¯üüç$Û·£l–2wТ^È.åLÆÌΊš+›•jj"Œ._¾?Ç-SE}ônh0»v‰_þ’äôéà?}}8›½eœææƒÐÚJRSÅ"¾r††ìŽil Ÿ8§§ïϳK‡˜Å Ruu9; ×®… w—·rrª²½÷žüä“ÖóÏ‹_Di --°gêì„5kP.‡gf ýýøÒ%óþûJ'&à‡?TÒÜ o¿ìLæn¿-¢€mCÀå\.À\m-´¶ý»pWW#É$‰ oEE„Y>Ü ¡Ù ØI‚6nmm04Ýݤýý00€ÑOŠªªÄô4¬Yc=ý´øòK<:ÊÂ}̉\Îê씚›aÛ¶`S55"I`çN’|>„­«3uuR]]à}J%;M£â Á¤R á·¿u *wâøMUUxYrô%Èd¬þþ |6ôõáÆFsàjo/)}/hOS³eK„ϵkÐÙ‰òy47‡K¥{ÁUUxÃ3=»û̲˜ç™ :Þ>~'IÜ ¦ˆš(M£û–J¸XŒñK{{„á³Ï¢×_G/¿ŒZ[ѪU(— eææ‚c¬\‰ZZDOO t>ô@S‰ð„tæL(°u«ôå—ÐÞûö¡în|ö,Ô×Ç̨Œý%E鬪ŠÚ?5å ¶ÖÌÍ¡R)Æ+6ÀÄôöFõº^úJs¡rû×éӡĦMÑ]ÛÚÐ+¯Dg4RL3¶n•.^ÄÇGüŸ>DhnÎ46ŠM›”¬[MMtóy48TôaŒ5™ O S§ìº:ؼYI’Qß³G¼û®ÜÝs9T]?øß6¡vWzê)ÔÒ‚WT„W.\€úz|ñ"ܸþk›–•àÔ)˜˜ ml„õë¥ÑŽP(ÄaG&##1‚lmE--aùbQÇgÏâË—ƒGLMZ½yÓLL<Üyti9ÓérÂ’$fÕ*´v­Ø¹3`ÇÜäófdDTUÅHfx8ÊðØ\»£XäH1¿¶º ­*H†Ðuþ<¼ñÉÜ @‚;sagenb-1.0.1/sagenb/data/sage/images/icon_preview.gif000066400000000000000000000015461311436262400224740ustar00rootroot00000000000000GIF89a÷ÌÕÿÿÿ×gÔˆ0ÿÿÿÔˆ*댑2¨]Hëdí¨ë´‘2H¿ØëБ2H¿Ø먑ëíìî‘8ÿÿÿ‘2‘«‘ëî<îhî`ëèÝtuï@îûxÿÿÿûqÝu!`Ýu,¿Ø`î`@î¨îh@î¬î`î``‘p‡Ø‡¸ììîìÀÔº¤©©ìÔÔºF¼^p©ììÔ» ¼^p×=áYáXØí ×M¯áY „×MãáYí‘È]@íà‘Q¨‘mî8í<‘È¿Ðî‘QHíX‘È¿Ðî$‘QH‘mîhæ„D0]HÔ‹Ùýð0ë˜ûl ¿ØíÄ‘È ‚hî‘Qá 8‘m €¨ ‚pûqÕ†ç¼íäçÈîŒîûxÿÿíhîŒî‘pÿÿÿ‘m‘ ¼È¿ØîH‘ ’¿ØîœÝíÝí b¦Èáb¦ÔíÔ ‚pîÈî‘pÿÿÿ‘mÂÂÞáÂÂã €¨ ‚pÝhª ‚p ‚pîÔî¤ÿÿÿï@Ã\”Á pÿÿÿÂÂãD•Õ ‚pc c Eµ €¨GŸøê†Ôê†Ôê†Ôê†Ô"KXã $GŸøGŸøæà£æ‚°,K €€ƒ L¨paC‡F\xp ÁŠ!btH0¡Ã‹мx0䯉ŠÌ¨2!I&QVYðdE‹5%¦ ’ O…!;sagenb-1.0.1/sagenb/data/sage/images/icon_print.gif000066400000000000000000000015431311436262400221440ustar00rootroot00000000000000GIF89a÷ÌUUÌÕÿÿÿÔˆ0ÿÿÿÔˆ*댑2¨]Hëdí¨ë´‘2H ëБ2H 먑ëíìî‘8ÿÿÿ‘2‘«‘ëî<îhî`ëèÝtuï@îûxÿÿÿûqÝu!@Ýu, @î`@î¨îh@î¬î@î`@‘p‡Ø‡¸ì¤ìîìÀÔº¤©©ìÔÔºF¼^ˆ©ììÔ» ¼^ˆ×=áYáXØí ×M¯áY „×MãáYí‘È]@íà‘Q¨‘mî8í<‘È øî‘QHíX‘È øî$‘QH‘mîhæ„D0]HÔ‹Ùýð0ë˜ûl  íÄ‘È ‚hî‘Qá 8‘m €¨ ‚pûqÕ†ç¼íäçÈîŒîûxÿÿíhîŒî‘pÿÿÿ‘m‘ ¼È îH‘ ’ îœÝíÝí b¦Èáb¦ÔíÔ ‚pîÈî‘pÿÿÿ‘mÂÂÞáÂÂã €¨ ‚pÝhª ‚p ‚pîÔî¤ÿÿÿï@Ã\”Á pÿÿÿÂÂãD•Õ ‚pc c Eµ €¨J‹Ðê†Ôê†Ôê†Ôê†ÔKXã $J‹ÐJ‹Ðæà£æ‚°,H @° A \8p¡B† œX°!D†/bTHñ`Ƈ9r @É“d¼H0@Ä’$a‚´ÒaL“2m²ÜHa@;sagenb-1.0.1/sagenb/data/sage/images/sageicon.png000066400000000000000000000010471311436262400216060ustar00rootroot00000000000000‰PNG  IHDRóÿasRGB®ÎébKGDÿÿÿ ½§“ pHYs × ×B(›xtIMEÙ$"´zxtEXtCommentCreated with GIMPW‚IDAT8Ë}ÓKˆÎaðŸÏ7}Ó”A IIš"5²±ùÊB)²S’ÝHb)eÊeaÊecÃBʵÄB¨YYLR’”™QCbEj¦)—Ÿmž½þƼ›szÏyŸ÷9ç9gÎÀÀïÅf?‡ñ-ܬ›…¿«° ›±]h`¦q¿fèÀ“øßq/ð1wð ‡pa&€ézñð³PeaJÔÄpÐG°§6(G°©x =øU40‰õ˜H ¥´“™êÌÅ:üÀÅR8zwbwÕØtf&.Gævöâj%Q¨®ŒÌ‹Ð‡/¸RŸÅô‡E+õG•Ç8â dlOàU6òìl»þ¥.VÅ­;×IEND®B`‚sagenb-1.0.1/sagenb/data/sage/images/sagelogo.png000066400000000000000000000037101311436262400216150ustar00rootroot00000000000000‰PNG  IHDRX†mmtbKGDÿÿÿ ½§“ pHYs  šœtIME×3UÏéUIDATXÃÕXmHSí>÷yÙ9ǽú6Åõ²Ù$É„¬°r$¥Vboô¡ZH_‚¢ (*ÅаìÃ*BR‰(±Æ4’ˆ‚ Q}1!¡làœ¹-O;nn;ç>χ›ÿáüÏ6õ¡žß‡qëî—ë¾~o×= I¦°@ píÚ5dz°° Š"Žã8޾•$ Í$YQQÑÑÑQYY966vîܹP(!Äq€>ÑÃ0yyyv»ýÌ™3k×®%IûK¥RÏž=ëééñù|BAAÐØh42 CDIIÉéÓ§«ªª‰„Ëåá8NE´:T9@c‰$INW[[{áÂ…ââbå5 ?~ŒŒŒŠ¢rsssss5 Q!”Qâ8Îó¼×ë-//ÿòåËû÷ïEQd&??_¯×£³e@±X, z<ž‰‰‰«W¯nݺUÉE*•lkk‹F£ƒaÄ  h‚(г³³sss E±,»råJáÐÐÐøø8˲………999E©®#_UÅD"áóùxžŸ››Û¶mÛÞ½{išÎJD"‘H¥R€ŠŠŠæææššƒÁ€ã8úBˆ¸'IŒ˜ŠD"B–ewîÜÙÜÜl·ÛµZ­’o Ã~ýúÕÛÛëv»;::îÝ»·fÍ™‹'Ož´µµavüøñÚÚZ«ÕJ’¤r¹$Ióóó>|ôè‘(ŠÓÓÓÇiµZ!AUUU(ÐrrrT‡ª‚®««kpp0ÿüùS„ň@á8¾nݺ†††ŠŠ 9/2š\DzìæÍ›ëëë ÒI’dµZÃáð›7oººº®\¹RZZŠaØèèè¥K—R©ÔáÇNç† X–͸Üçó ˆ¢(§³$I8ޝX±¢ººÚf³-ðիWgcJM* †1 £ÕjQ–bË3T P*¥¯”””tvvúýþ§OŸZ­ÖóçÏÏÌÌ´´´p×ÐÐÐÔÔTYY©Õj³mn2™Ta‚“ ¡KBeYV^»†¢(I’’Édúìl&çÎ’K¶lÙÒÝÝ}ôèÑžžÀ«W¯>þ\WWçt:‡^¯_d­N§#IR.2Âeâä8.B5E!½sçŽÅbQ9Ayù’’’}ûöÉu™Qãp8ZZZnܸqëÖ­T*UVVvðàÁšš£Ñ¸ø&ªSdo‰¢è÷û‡‡‡Ãá0„PuU´B8??ÿâÅ‹lÞRQTT´qãÆX, …Ò¯!!™LŠ¢hµZY–Ý¿?MÓËÏ Š¢Nž<ùöíÛçÏŸ †íÛ·744X,9¬²™ªé¢Ê !ŒÇã~¿ßív{½ÞD"!÷øt“$Éh4æçç§—U5‹¥··÷û÷ï¡PHnÎéå×ív Åb±©©)A–¼ƒ ÇãÓh4ñx|||\Žöe& *[×”[Œì¢%ëV 8{öìׯ_ëêêN:e6›[[[N‡‚6™Lr·¸ C¯5š¦u:r ’ÙX,Æó|2™Ì¦Y§§§÷ìÙ‡›šš\.—Ýnð÷yÙ9ǽú6Åõ²Ù$É„¬°r$¥Vboô¡ZH_‚¢ (*ÅаìÃ*BR‰(±Æ4’ˆ‚ Q}1!¡làœ¹-O;nn;ç>χ›ÿáüÏ6õ¡žß‡qëî—ë¾~o×= I¦°@ píÚ5dz°° Š"Žã8޾•$ Í$YQQÑÑÑQYY966vîܹP(!Äq€>ÑÃ0yyyv»ýÌ™3k×®%IûK¥RÏž=ëééñù|BAAÐØh42 CDIIÉéÓ§«ªª‰„Ëåá8NE´:T9@c‰$INW[[{áÂ…ââbå5 ?~ŒŒŒŠ¢rsssss5 Q!”Qâ8Îó¼×ë-//ÿòåËû÷ïEQd&??_¯×£³e@±X, z<ž‰‰‰«W¯nݺUÉE*•lkk‹F£ƒaÄ  h‚(г³³sss E±,»råJáÐÐÐøø8˲………999E©®#_UÅD"áóùxžŸ››Û¶mÛÞ½{išÎJD"‘H¥R€ŠŠŠæææššƒÁ€ã8úBˆ¸'IŒ˜ŠD"B–ewîÜÙÜÜl·ÛµZ­’o Ã~ýúÕÛÛëv»;::îÝ»·fÍ™‹'Ož´µµavüøñÚÚZ«ÕJ’¤r¹$Ióóó>|ôè‘(ŠÓÓÓÇiµZ!AUUU(ÐrrrT‡ª‚®««kpp0ÿüùS„ň@á8¾nݺ†††ŠŠ 9/2š\DzìæÍ›ëëë ÒI’dµZÃáð›7oººº®\¹RZZŠaØèèè¥K—R©ÔáÇNç† X–͸Üçó ˆ¢(§³$I8ޝX±¢ººÚf³-ðիWgcJM* †1 £ÕjQ–bË3T P*¥¯”””tvvúýþ§OŸZ­ÖóçÏÏÌÌ´´´p×ÐÐÐÔÔTYY©Õj³mn2™Ta‚“ ¡KBeYV^»†¢(I’’Édúìl&çÎ’K¶lÙÒÝÝ}ôèÑžžÀ«W¯>þ\WWçt:‡^¯_d­N§#IR.2Âeâä8.B5E!½sçŽÅbQ9Ayù’’’}ûöÉu™Qãp8ZZZnܸqëÖ­T*UVVvðàÁšš£Ñ¸ø&ªSdo‰¢è÷û‡‡‡Ãá0„PuU´B8??ÿâÅ‹lÞRQTT´qãÆX, …Ò¯!!™LŠ¢hµZY–Ý¿?MÓËÏ Š¢Nž<ùöíÛçÏŸ †íÛ·744X,9¬²™ªé¢Ê !ŒÇã~¿ßív{½ÞD"!÷øt“$Éh4æçç§—U5‹¥··÷û÷ï¡PHnÎéå×ív Åb±©©)A–¼ƒ ÇãÓh4ñx|||\Žöe& *[×”[Œì¢%ëV 8{öìׯ_ëêêN:e6›[[[N‡‚6™Lr·¸ C¯5š¦u:r ’ÙX,Æó|2™Ì¦Y§§§÷ìÙ‡›šš\.—Ýnð -1; function viewport_offset_for_element(e) { /* Returns the X and Y coordinates of the element relative to the viewport. */ // This code was adapted from Element.viewportOffset in the Prototype // JavaScript framework (http://www.prototypejs.org/). var value_top = 0, value_left = 0; var element = e; // Traverse up the element heirarchy, keeping track of each element's // relative offset, until we have an absolute offset for the original // element. do { value_top += element.offsetTop || 0; value_left += element.offsetLeft || 0; // Safari fix? if(element.offsetParent == document.body && element.style.position == 'absolute') break; } while(element = element.offsetParent); // Now we must compute the scroll offset, and adjust our result accordingly. element = e; do { if(!browser_opera || (element.tagName && (element.tagName.toUpperCase() == 'BODY'))) { value_top -= element.scrollTop || 0; value_left -= element.scrollLeft || 0; } } while(element = element.parentNode); return { x: value_left, y: value_top }; } function setup(canvas) { /* Setup the provided canvas with event listeners and state (stored in * closures) to be an interactive 3D model viewer. */ var dragging = false; var last_mouse_x = 0, last_mouse_y = 0, initialized = false; var camera_scale = 1; var camera_transform = make_identity_affine(); var trackball = new Trackball(CANVAS_SIZE / 2); var pending_update = null; // A timeout ID which may correspond to some // callback to redraw the canvas. function adapt_mouse_pos_for_trackball(evt) { var canvas_pos = viewport_offset_for_element(canvas); return { x: evt.clientX - canvas_pos.x - CANVAS_SIZE / 2, y: evt.clientY - canvas_pos.y - CANVAS_SIZE / 2 }; } function update() { var t = make_identity_affine(); t = mult_matrix(camera_transform, t); t = mult_matrix(trackball.transform, t); t = mult_matrix(make_dilation_affine(FIGURE_SCALE * camera_scale), t); t = mult_matrix(make_translation_affine(0, 0, -FIGURE_ZOFFSET), t); draw(canvas, t); pending_update = null; } function schedule_update() { if(pending_update != null) clearTimeout(pending_update); pending_update = setTimeout(update, 0); } canvas.addEventListener("mousedown", function(evt) { trackball.begin_drag(adapt_mouse_pos_for_trackball(evt)); dragging = true; }, false); canvas.addEventListener("mouseup", function(evt) { camera_transform = mult_matrix(trackball.end_drag(), camera_transform); dragging = false; }, false); canvas.addEventListener("mousemove", function(evt) { if(initialized) { if(dragging) { if(evt.shiftKey) { camera_scale += SCALING_SENSITIVITY * (evt.clientY - last_mouse_y); if(camera_scale < 0.2) camera_scale = 0.2; } else trackball.drag(adapt_mouse_pos_for_trackball(evt)); schedule_update(); } } else initialized = true; last_mouse_x = evt.clientX; last_mouse_y = evt.clientY; }, false); update(); } function render_model(ctx, transform, model) { if("color" in model) ctx.strokeStyle = model.color; else ctx.strokeStyle = "black"; for(var i = 0; i < model.faces.length; i++) { ctx.beginPath(); var points = new Array(model.faces[i].length); var culled_points_count = 0; for(var j = 0; j < model.faces[i].length; j++) { var transformed_vertex = transform_point(transform, model.vertices[model.faces[i][j]]); points[j] = project_point(transformed_vertex); if(points[j].x < CANVAS_SIZE / -2 || points[j].x > CANVAS_SIZE / 2 || points[j].y < CANVAS_SIZE / -2 || points[j].y > CANVAS_SIZE / 2 || transformed_vertex.z < 0) { culled_points_count++; } } if(culled_points_count < model.faces[i].length) { for(var j = 0; j < model.faces[i].length; j++) { if(j == 0) ctx.moveTo(points[j].x, points[j].y); else ctx.lineTo(points[j].x, points[j].y); } } if("face_colors" in model) ctx.strokeStyle = model.face_colors[i] ctx.closePath(); ctx.stroke(); } } function draw(canvas, transform) { /* Redraw the specified canvas. Vertex and face data are stored as a * property of the canvas object. */ var ctx = canvas.getContext('2d'); ctx.save(); ctx.clearRect(0, 0, CANVAS_SIZE, CANVAS_SIZE); ctx.translate(CANVAS_SIZE / 2, CANVAS_SIZE / 2); for(var i = 0; i < canvas.data.length; i++) render_model(ctx, transform, canvas.data[i]); ctx.restore(); } var viewer_count = 0; function viewer(url) { var canvas_id = "canvas3d-viewer" + (viewer_count++); cell_writer.write(('') + translations["Sorry, but you need a browser that supports the <canvas> tag."] + ''); // Send an XHR to get the JSON model data stored at the URL var xhr = new XMLHttpRequest(); xhr.onreadystatechange = function() { if(xhr.readyState == 4) { if(xhr.status == 200 && xhr.responseText != null) { var canvas = document.getElementById(canvas_id); canvas.data = eval('(' + xhr.responseText + ')'); setup(canvas); } } } xhr.open('GET', url, true); xhr.send(null); } return { viewer: viewer }; })(); sagenb-1.0.1/sagenb/data/sage/js/debug.js000066400000000000000000000257001311436262400201050ustar00rootroot00000000000000/*global $, queue_id_list, cell_id_list, console, document, opera, setTimeout, window */ /*jslint white: true, onevar: true, undef: true, nomen: true, eqeqeq: true, plusplus: true, bitwise: true, regexp: true, strict: true, newcap: true, immed: true */ //"use strict"; // For debugging, diagnostics, etc. var sagenb_debug = (function debugging(options) { var dlg, funcs, i, s, settings; // Defaults, overridden by an optional options argument. settings = { // Whether to wrap functions in proxies for logging. This // takes effect *only* on load. proxify: false, // Turn on/off logging of already proxified functions w/o // reloading. log: true, // Whether to log to a floating jQuery UI dialog. // Experimental. dialog: false }; $.extend(settings, options || {}); if (!window.console) { window.console = {}; if (window.opera) { window.console.log = opera.postError; } else { window.console.log = function () {}; } } // Wrap selected functions in proxies. This allows us to log // their arguments, globals, etc., when they're called. If // proxify is false on load, nothing special happens. if (!settings.proxify) { return {settings: settings}; } // Function names. Make a list with sed, Python, or JS: // sed -nre "s/^function\s+(\w+)\s*\(.*/\1/p" notebook_lib.js /* import re s = r'(?').dialog({ autoOpen: false, minHeight: '', height: 'auto', width: '300', title: 'debug' }); par = dlg.parent(); par.css({ left: $(document).width() - par.width() - 30 + 'px', padding: '1px', top: $(window).scrollTop() + 'px' }); $(window).bind('scroll.pin', function () { setTimeout(function () { par.css({top: $(window).scrollTop() + 'px'}); }, 1000); }); $('.ui-dialog-titlebar', par).css({ paddingTop: 0, paddingBottom: 0 }); } function update_dialog(name, value) { var s = 'Cells: '; $.map(cell_id_list, function (id) { if ($.inArray(id, queue_id_list) !== -1) { s += '' + id + '' + ' '; } else { s += id + ' '; } }); s += '
' + name + ': ' + value.toString(); if (!dlg) { prep_dialog(); } dlg.dialog('open').html(s); } A2.prototype.display = function () { if (settings.log) { if (settings.dialog) { update_dialog(this.name, this.store); } else { console.log(this.name + ' ', this.store); } } }; A2.prototype.push = function (x) { var ret = Array.prototype.push.call(this, x); this.store.push(x); this.display(); return ret; }; A2.prototype.splice = function () { var ret = Array.prototype.splice.apply(this, arguments); this.store.splice.apply(this.store, arguments); this.display(); return ret; }; $(document).ready(function () { var q2, i; if (!$('#worksheet_cell_list').length) { return; } q2 = new A2('Queued'); for (i = 0; i < queue_id_list.length; i += 1) { q2.push(queue_id_list[i]); } queue_id_list = q2; queue_id_list.display(); }); // Example: To turn off logging w/o reloading the page: // sagenb_debug.settings.log = false; return {settings: settings}; // Pass just {} to use the default settings. }({proxify: false})); sagenb-1.0.1/sagenb/data/sage/js/jmol_lib.js000066400000000000000000000142731311436262400206110ustar00rootroot00000000000000 SageJmolManager = function() { this._count = 0; this._applets = {}; this._lru_names = []; // most recently used (uncovered) applet name this._limit = 3; // allow at most this many active jmols. if (typeof(Jmol) !== 'undefined') { this._prepare_jmol(); this._watcher = setInterval(this.activator.bind(this), 500); } }; SageJmolManager.prototype._prepare_jmol = function() { // Turn off the JSmolCore.js: synchronous binary file transfer is // requested but not available" warning Jmol._alertNoBinary = false; }; SageJmolManager.prototype.default_info = function() { // Before adding anything here make sure it is not overwritten in // add_applet() return { // actual size is controlled by the parent
width: "95%", //This allows the jquery resize to work do not set to 100% height: "95%", // debug=true will pop up alert boxes debug: false, color: "white", addSelectionOptions: false, use: "HTML5 WebGL Java", //This should probably only be HTML5 // Tooltip when the mouse is over the static image coverTitle: 'Click on 3-D image to make it live. ' + 'Right-click on live image for a control menu.', deferApplet: true, // wait to load applet until click deferUncover: true, // wait to uncover applet until script completed //The paths below assume your server is set up with standard JSmol directory. If not //they will need modification for the page to work. jarPath: "/jsmol/java", //path to applet .jar files on server. j2sPath: "/jsmol/j2s",//path to javascript version. makeLiveImg:"/jsmol/j2s/img/play_make_live.jpg", //path to activate 3-D image. jarFile: "JmolAppletSigned0.jar", isSigned: true, //disableJ2SLoadMonitor: true, disableInitialConsole: true, script: "", z: 5, zIndexBase: 5, menuFile: "/java/jmol/appletweb/SageMenu.mnu", //special sagemenu //platformSpeed: 6, does not work have to do it in the ready function //or set to 7 or 8 for additional rotation graphics capabilities }; }; SageJmolManager.prototype.ready_callback = function (name, applet) { console.log('Jmol applet has launched ' + name); this._applets[name] = applet; this._lru_names.push(name); Jmol.script(applet, "set platformSpeed 8;"); // 8 for best rotation graphics this.enforce_limit(); jQuery('#'+name).parent().append('
Right-click to get options menu.
'); }; // Get the most recently used applet names /* Remove duplicate and stale applet names from this._lru_names as a * side effect */ SageJmolManager.prototype.most_recently_used = function () { var result = []; for (i = this._lru_names.length-1; i >= 0; i--) { var name = this._lru_names[i]; if (result.indexOf(name) >= 0) continue; if (name in this._applets) result.push(name); } result.reverse(); this._lru_names = result; return result; }; // Make sure that there are not too many active applets SageJmolManager.prototype.enforce_limit = function() { var applet_names = this.most_recently_used(); for (i = 0; i < applet_names.length - this._limit; i++) { var name = applet_names[i]; var applet = this._applets[name]; console.log('Covening applet ' + name); Jmol.coverApplet(applet, true); jQuery('#'+name+'_hint').remove(); } }; SageJmolManager.prototype.add_applet = function (size, image, script, server_url, cell_num) { // The id of the container div holding the applet html, use this // to query the dom later to see if the applet is stil there. var applet_name = 'jmolApplet' + this._count; var info = this.default_info(); info.coverImage = image; info.script = 'script ' + script; info.serverURL = server_url; info.readyFunction = this.ready_callback.bind(this, applet_name); var live_3d = jQuery('#3D_check').prop('checked'); info.deferUncover = !live_3d; info.deferApplet = !live_3d; var use_java=$('#3D_use_java').prop('checked'); if (use_java) {info.use='JAVA';} // append container to dom jQuery('#sage_jmol_' + cell_num).append( '
'); //make resizable $('#'+applet_name).resizable({aspectRatio:true}); $('#'+applet_name).append('
JSmol Here
'); // launching JSmol/Jmol applet Jmol.setDocument(false); // manually insert Jmol.getAppletHtml jQuery('#' + applet_name+'_wrapper').html( Jmol.getAppletHtml(applet_name, info)); // Finished this._count += 1; }; // Callback for Action -> Delete all Output SageJmolManager.prototype.delete_all_callback = function() { // console.log('jmol: delete_all'); this.delete_callback(); }; // Callback for deleting single cell (may not contain jmol) SageJmolManager.prototype.delete_callback = function() { // console.log('jmol: delete_check'); var applet_names = Object.keys(this._applets); for (i = 0; i < applet_names.length; i++) { var name = applet_names[i]; if (jQuery('#' + name).length === 0) delete this._applets[name]; } }; SageJmolManager.prototype.activator = function () { if (document.getElementById("loadJmol")) { var parentdiv = jQuery("#loadJmol").parent(); // This div contains the ID number var cell_num = parentdiv.children("#loadJmol").html(); parentdiv.children("#loadJmol").remove(); var size = parentdiv.children("#sage_jmol_size_"+cell_num).html(); var img = parentdiv.children("#sage_jmol_img_"+cell_num).html(); var script = parentdiv.children("#sage_jmol_script_"+cell_num).html(); var server_url = parentdiv.children("#sage_jmol_server_url_"+cell_num).html(); sage_jmol.add_applet(size, img, script, server_url, cell_num); parentdiv.children("#sage_jmol_status_"+cell_num).html("Activated"); } }; sage_jmol = new SageJmolManager(); sagenb-1.0.1/sagenb/data/sage/js/localization.js000066400000000000000000000061551311436262400215120ustar00rootroot00000000000000/*global $, alert, async_request, clearTimeout, confirm, document, escape, location, navigator, open, prompt, setTimeout, window, worksheet_filenames */ /*jslint maxerr: 10000, white: true, onevar: true, undef: true, nomen: true, eqeqeq: true, plusplus: true, bitwise: true, regexp: true, strict: true, newcap: true, immed: true */ //"use strict"; {# If you add any new strings to this list, please enclose them in the dummy translation function N_ (or nN_ for singular/plural forms). #} translations = { {% for string in [N_('Your browser / OS combination is not supported.\\nPlease use Firefox or Opera under Linux, Windows, or Mac OS X, or Safari.'), N_("Java Applet Hidden"), N_("Click here to pop out"), N_('Error applying function to worksheet(s).'), N_('Title of saved worksheet'), N_('Failed to save worksheet.'), N_("Rename worksheet"), N_("Please enter a name for this worksheet."), N_("Rename"), N_('Possible failure deleting worksheet.'), N_("unprinted"), N_('You requested to evaluate a cell that, for some reason, the server is unaware of.'), N_("Error"), N_('This worksheet is read only. Please make a copy or contact the owner to change it.'), N_("loading..."), N_('Error updating cell output after '), N_('s (canceling further update checks).'), N_('Problem inserting new input cell after current input cell.\\n'), N_('Problem inserting new input cell before current input cell.\\n'), N_('Problem inserting new text cell before current input cell.'), N_('Problem inserting new text cell before current input cell.\\n'), N_('Worksheet is locked. Cannot insert cells.'), N_('Unable to interrupt calculation.'), N_('Close this box to stop trying.'), N_('Interrupt attempt'), N_("Restart, instead?"), N_("Emptying the trash will permanently delete all items in the trash. Continue?"), N_("Get Image"), N_('Jmol Image'), N_("To save this image, you can try right-clicking on the image to copy it or save it to a file, or you may be able to just drag the image to your desktop."), N_("Sorry, but you need a browser that supports the <canvas> tag."), ] %} "{{ string }}" : "{{ gettext(string) }}", {% endfor %} {% for singular, plural in [nN_('Trying again in %(num)d second...', 'Trying again in %(num)d seconds...')] %} "{{ singular }}" : function (n) {return n >1 ? '{{ ngettext(singular, plural, 2) }}'.replace("2", n) : '{{ ngettext(singular, plural, 1) }}'} {% if not loop.last %},{% endif %} {% endfor %} }; sagenb-1.0.1/sagenb/data/sage/js/master.js000066400000000000000000000032541311436262400203120ustar00rootroot00000000000000/*global $, window */ /*jslint white: true, onevar: true, undef: true, nomen: true, eqeqeq: true, plusplus: true, bitwise: true, regexp: true, strict: true, newcap: true, immed: true */ //"use strict"; var replicate_str = function(x, n) { var str = ''; for (var i = 0; i < n; ++i) { str += x; } }; $(function () { var body = $('body'), body_id = body.attr('id'); if (body.hasClass('active-worksheet')) { initialize_the_notebook(); //'#worksheet_cell_list' why was it function (e) below. $(document) .on('click','#worksheet_cell_list .introspection .docstring .click-message', function (e) { var ds_elem = $(this).parent(), style; var id = toint(ds_elem.parent().attr('id').slice(15)); var name = introspect[id].before_replacing_word; if (name.slice(-2) === '??') { // Source code. name = name.slice(0, -2); style = 'source'; } else if (name.slice(-1) === '?' || name.slice(-1) === '(') { // Docstring. name = name.slice(0, -1); style = 'doc'; } halt_introspection(id); ds_elem.dialog({ height: 600, width: '90%', title: name, dialogClass: 'docstring-introspection-dialog-'+style, 'close': function (event, ui) { ds_elem.dialog('destroy').remove(); } }); ds_elem.find('.click-message').remove(); }); } }); sagenb-1.0.1/sagenb/data/sage/js/mathjax_sage.js000066400000000000000000000025331311436262400214510ustar00rootroot00000000000000MathJax.Hub.Config({ // Need jsMath2jax so that worksheets with div/span class "math" elements still render correctly // This is important for backwards compatibility (notably Rob Beezer's books) extensions: ["jsMath2jax.js"], tex2jax: { inlineMath: [['$','$'],['\\(','\\)']], processEscapes: true, // "cell_input_print" because those are input cells in published worksheets // "math" so that the tex2jax plugin leaves the spans/divs with class math alone // (since jsMath2jax will take care of it); if we don't, then tex2jax and jsMath2jax conflict. // See https://groups.google.com/forum/?fromgroups=#!topic/mathjax-users/qzWdxiQvNrw ignoreClass: 'cell_input_print|math' }, styles: { ".MathJax .mo, .MathJax .mi": { color: "inherit ! important" } }, MathMenu: {showFontMenu: true}, "HTML-CSS": { imageFont: null, availableFonts: ["TeX"] }, TeX: { Macros: { {{ theme_mathjax_macros|join(',\n') }} }, // the following makes \color in MathJax compatible with the \color // command from LaTeX extensions: ["color.js"] }, }); // This path is a little funny because we have to load our local // config file as '../../dynamic/mathjax_sage' when we load MathJax MathJax.Ajax.loadComplete("[MathJax]/config/../../dynamic/mathjax_sage.js") sagenb-1.0.1/sagenb/data/sage/js/notebook_dynamic.js000066400000000000000000000041341311436262400223410ustar00rootroot00000000000000/////////////////////////////////////////////////////////////////// // // "External" Javascript // /////////////////////////////////////////////////////////////////// // Key codes (auto-generated in js.py from config.py and user's sage // config). {{ KEY_CODES }} // Other libraries. {% include "js/async_lib.js" %} {% include "js/canvas3d_lib.js" %} {% include "js/jmol_lib.js" %} {%- if debug_mode %} {% include "js/debug.js" %} {% endif %} function interrupt_callback(status, response) { /* Callback called after we send the interrupt signal to the server. If the interrupt succeeds, we change the CSS/DOM to indicate that no cells are currently computing. If it fails, we display/update a alert and repeat after a timeout. If the signal doesn't make it, we just reset any alerts. */ var is = interrupt_state, message; {% set timeout = 5 %} var timeout = {{ timeout }}; if (response === 'failed') { if (!is.count) { is.count = 1; message = translations['Unable to interrupt calculation.'] + " " + translations['Trying again in %(num)d second...'](timeout) + ' ' + translations['Close this box to stop trying.']; is.alert = $.achtung({ className: 'interrupt-fail-notification', message: message, timeout: timeout, hideEffects: false, showEffects: false, onCloseButton: function () { reset_interrupts(); }, onTimeout: function () { interrupt(); } }); return; } is.count += 1; message = translations['Interrupt attempt'] + " " + is.count; if (is.count > 5) { message += ". " + translations["Restart, instead?"]; } is.alert.achtung('update', { message: message, timeout: timeout }); } else if (status === 'success') { halt_queued_cells(); } else { reset_interrupts(); } } sagenb-1.0.1/sagenb/data/sage/js/notebook_lib.js000066400000000000000000004152601311436262400214710ustar00rootroot00000000000000/*global $, alert, async_request, clearTimeout, confirm, document, escape, location, navigator, open, prompt, setTimeout, window, worksheet_filenames */ /*jslint maxerr: 10000, white: true, onevar: true, undef: true, nomen: true, eqeqeq: true, plusplus: true, bitwise: true, regexp: true, strict: true, newcap: true, immed: true */ //"use strict"; // Code and docstring conventions. Please use 4-space indentation // throughout. JSLint (http://www.jslint.com/) on the "The Good // Parts" setting can uncover potential problems. //function foo(arg1, arg2) { /* Description. INPUT: arg1 -- description of arg1 arg2 -- description of arg2 GLOBAL INPUT / OUTPUT: glob1 -- how we use and/or change this glob2 -- how we use and/or change this OUTPUT: Returned variable(s). */ /* // Declare variables at the top, since JS vars don't have block scope. var a, b, X; for (a = 0; a < arg1.length; a++) { // This is a comment. arg1[a] *= glob1; } // Here's another comment. return [arg2, arg1]; */ //} /////////////////////////////////////////////////////////////////// // // GLOBAL VARIABLES // // PLEASE define all global variables up here, and if you want to set // them with anything but simple assignment, 'var' them first, and set // them later. Your code might work in your browser, but it might // break initial setup for other critical pieces in other browsers. // Thanks. (and for the record, I'm guilty of this more than anybody // else here -- I figure a big block comment might help keep me in // check) // // Exception: keyboard globals are defined at the end. // /////////////////////////////////////////////////////////////////// // Cell lists, maps, and cache. var cell_id_list = []; var queue_id_list = []; var onload_id_list = []; var cell_element_cache = {}; // Worksheet information from worksheet.py var worksheet_locked; var original_title = document.title; var state_number = -1; // Current worksheet info, set in notebook.py. var worksheet_filename = ''; var worksheet_name = ''; var user_name = ''; // Ping the server periodically for worksheet updates. var server_ping_time = 10000; // Interact constants. See interact.py and related files. // Present in wrapped output, forces re-evaluation of ambient cell. var INTERACT_RESTART = '__SAGE_INTERACT_RESTART__'; // Delimit updated markup. var INTERACT_START = ''; var INTERACT_END = ''; // Browser & OS identification. var browser_op, browser_saf, browser_konq, browser_moz, browser_ie, browser_iphone; var os_mac, os_lin, os_win; // Functions assigned during keyboard setup. var input_keypress; var input_keydown; // Bug workaround. var skip_keyup = false; // Interrupts. var interrupt_state = {count: 0}; // Focus / blur. var current_cell = -1; var cell_has_changed = false; // Resizing too often significantly affects performance. var keypress_resize_delay = 250; var last_keypress_resize = 0; var will_resize_soon = false; var previous = {}; // Are we're splitting a cell and evaluating it? var doing_split_eval = false; // Whether the the next call to jump_to_cell is ignored. Used to // avoid changing focus. var ignore_next_jump = false; // Set to true for pages with public interacts. var ignore_all_jumps = false; var control_key_pressed = 0; var evaluating_all = false; // Cell update check variables. Times are in milliseconds. var update_timeout = -1; var updating = false; var update_time = -1; var update_count = 0; var update_falloff_threshold = 20; var update_falloff_level = 0; var update_falloff_deltas = [250, 500, 1000, 5000]; var update_error_count = 0; var update_error_threshold = 30; var update_error_delta = 1024; var update_normal_delta = update_falloff_deltas[0]; var cell_output_delta = update_normal_delta; // Introspection data. var introspect = {}; // Regular expressions to parse cell input for introspection. // Characters that don't belong in a variable name. var non_word = "[^a-zA-Z0-9_]"; // The command at the end of a string. var command_pat = "([a-zA-Z_][a-zA-Z._0-9]*)$"; var function_pat = "([a-zA-Z_][a-zA-Z._0-9]*)\\([^()]*$"; var one_word_pat = "([a-zA-Z_][a-zA-Z._0-9]*)"; var unindent_pat = "^\\s{0,4}(.*)$"; // The # doesn't need a slash for now, but let's give it one anyway... var uncomment_pat = "^([^\\#]*)\\#{0,1}(.*)$"; var whitespace_pat = "(\\s*)"; try { non_word = new RegExp(non_word); command_pat = new RegExp(command_pat); function_pat = new RegExp(function_pat); one_word_pat = new RegExp(one_word_pat); whitespace_pat = new RegExp(whitespace_pat); unindent_pat = new RegExp(unindent_pat); uncomment_pat = new RegExp(uncomment_pat); } catch (e) {} // The global cell_writer target. var cell_writer = document; // Slideshow mode? var in_slide_mode = false; // Does the current slide have the hidden input class? var slide_hidden = false; var title_spinner_i = 0; var title_spinner = ['/ ', '\\ ']; //var title_spinner = [' ', '. ', '.. ', '... ']; //var title_spinner = ['[ ] ', '[.] ', '[:] ', '[.] ']; //var title_spinner = ['S ', 'SA ', 'SAG ', 'SAGE ']; //var title_spinner = ['[ ] ', '[. ] ', '[.. ] ', '[...] ']; //var title_spinner = ['[-] ','[/] ','[|] ','[\\] ']; var modal_prompt_element = ''; /////////////////////////////////////////////////////////////////// // Cross-Browser Stuff /////////////////////////////////////////////////////////////////// function toint(x) { /* Convert a object to an integer, if it's possible. We use this to convert a cell id to an integer if it's just a string representation of that integer. Otherwise, we return the original id. This allows us to use alphanumeric ids for special cells. INPUT: x -- any object, e.g., a string, integer, float, etc. OUTPUT: an integer or the object */ if (x === '0') { return 0; } else { return parseInt(x, 10) || x; } } function decode_response(text) { /* Reconstructs a JSON-encoded object from a string. We use this to parse server responses into cell IDs, data, etc. In particular, any key in the reconstructed object that ends in 'id' is filtered through toint. INPUT: text -- string OUTPUT: object */ return JSON.parse(text, function (key, value) { if (typeof(key) === 'string' && key.slice(-2) === 'id') { return toint(value); } return value; }); } function encode_response(obj) { /* JSON-encodes a object to a string. INPUT: obj -- object OUTPUT: string */ return JSON.stringify(obj); } function initialize_the_notebook() { /* Do the following: 1. Determine the browser OS, type e.g., opera, safari, etc.; we set global variables for each type. 2. Figure out which keyboard the user has. */ var i, n, nav, nap, nua; // TODO: Use js-hotkeys (http://code.google.com/p/js-hotkeys/)? // Determine the browser, OS and set global variables. try { n = navigator; nav = n.appVersion; nap = n.appName; nua = n.userAgent; browser_op = (nua.indexOf('Opera') !== -1); browser_saf = (nua.indexOf('Safari') !== -1); browser_iphone = (nua.indexOf('iPhone') !== -1); browser_konq = (!browser_saf && (nua.indexOf('Konqueror') !== -1)) ? true : false; browser_moz = ((!browser_saf && !browser_konq) && (nua.indexOf('Gecko') !== -1)) ? true : false; browser_ie = ((nap.indexOf('Internet Explorer') !== -1) && !browser_op); os_mac = (nav.indexOf('Mac') !== -1); os_win = (((nav.indexOf('Win') !== -1) || (nav.indexOf('NT') !== -1)) && !os_mac) ? true : false; os_lin = (nua.indexOf('Linux') !== -1); } catch (e) { alert(e); } // Get the keyboard codes for our browser/os combination. get_keyboard(); // Parse the cell IDs. cell_id_list = $.map(cell_id_list, function (id) { // Reset each cell's introspection variables. if (is_compute_cell(id)) { halt_introspection(id); } return toint(id); }); //TODO: why do we do the following twice? // Parse active cell IDs and mark these cells as running. We // don't use $.map here, to avoid the possibility of overwriting a // debug version of the list. See debug.js for details. for (i = 0; i < queue_id_list.length; i += 1) { queue_id_list[i] = toint(queue_id_list[i]); cell_set_running(queue_id_list[i]); } if (queue_id_list.length) { start_update_check(); } // Parse active cell IDs and mark these cells as running. We // don't use $.map here, to avoid the possibility of overwriting a // debug version of the list. See debug.js for details. for (i = 0; i < queue_id_list.length; i += 1) { queue_id_list[i] = toint(queue_id_list[i]); cell_set_running(queue_id_list[i]); } if (queue_id_list.length) { start_update_check(); } // Parse "onload" cell IDs and evaluate these cells. Note: The // server fires "%auto" cells, whereas the client fires "onload" // cells. onload_id_list = $.map(onload_id_list, function (id) { id = toint(id); evaluate_cell(id, 0); return id; }); // Resize all cells on window resize. previous.height = $(document.documentElement).height(); previous.width = $(document.documentElement).width(); $(window).resize(function () { var h, w; h = $(document.documentElement).height(); w = $(document.documentElement).width(); // IE fires global resize *far* too often (e.g., on every cell // focus/blur). if ((h !== previous.height) || (w !== previous.width)) { resize_all_cells(); previous.height = h; previous.width = w; } }); // Resize and save on paste. $(document).on('paste','textarea', function () { var id = $(this).attr('id').slice(11); setTimeout(function () { send_cell_input(id); cell_input_resize(id); }, keypress_resize_delay); }); // Quit the sage process on close for doc/pub-browser worksheets. i = worksheet_filename.indexOf('/'); if (i !== -1 && worksheet_filename.slice(0, i) === '_sage_') { $(window).unload(function () { quit_sage(); }); } //bind events to our DOM elements bind_events(); } function bind_events() { /* * Attaches events to DOM elements. */ $('body').on('focus', 'textarea.cell_input', function () { var id = $(this).attr("id"); var cell_id = get_cell_id_from_id(id); cell_focused(this, cell_id); return true; }); $('body').on('focus', 'textarea.cell_input_hide', function () {         var id = $(this).attr("id");         var cell_id = get_cell_id_from_id(id);         cell_focused(this, cell_id);         return true;     }); $('body').on('blur', 'textarea.cell_input_active', function () { var id = $(this).attr("id"); var cell_id = get_cell_id_from_id(id); cell_blur(cell_id); return true; }); $('body').on('keyup', 'textarea.cell_input_active', function (event) { var id = $(this).attr("id"); var cell_id = get_cell_id_from_id(id); return input_keyup(cell_id, event); }); $('body').on('keydown', 'textarea.cell_input_active', function (event) { var id = $(this).attr("id"); var cell_id = get_cell_id_from_id(id); return input_keydown(cell_id, event); }); $('body').on('keypress', 'textarea.cell_input_active', function (event) { var id = $(this).attr("id"); var cell_id = get_cell_id_from_id(id); return input_keypress(cell_id, event); }); $('body').on('click', 'input.eval_button_active', function () { var id = $(this).attr("id"); var cell_id = get_cell_id_from_id(id); evaluate_cell(cell_id, 0); }); } function get_cell_id_from_id(id) { /* * A function to get the cell_id from the button's id attribute */ var num_re = /[0-9]+/; var match_result = num_re.exec(id); var cell_id = toint(match_result[0]); return cell_id; } function true_function() { /* A function that always returns true. */ return true; } input_keypress = true_function; function get_keyboard() { /* Determine which keycodes we want, then make a request back to the server for those keycodes. When the server returns the javascript with exactly those keycodes, we eval that javascript. OUTPUT: set some global variables that record platform specific key codes */ var b, o, warn = false; input_keypress = cell_input_key_event; input_keydown = true_function; if (browser_op) { b = "o"; } else if (browser_ie) { b = "i"; input_keypress = true_function; input_keydown = cell_input_key_event; } else if (browser_saf) { b = "s"; input_keypress = true_function; input_keydown = cell_input_key_event; } else if (browser_konq) { b = "k"; warn = true; } else { b = "m"; } if (os_mac) { o = "m"; } else if (os_lin) { o = "l"; } else { o = "w"; } if (!b || !o || warn) { alert(translations['Your browser / OS combination is not supported.\\nPlease use Firefox or Opera under Linux, Windows, or Mac OS X, or Safari.']); } $.getScript('/javascript/dynamic/keyboard/' + b + o); } function get_element(id) { /* Return the DOM element with the given id. If no element has the id, return null. INPUT: id -- an integer or string OUTPUT: a DOM element or null. */ var elem = $('#' + id); if (elem.length) { return elem[0]; } else { return null; } } function set_class(id, cname) { /* Set the class of the DOM element with given id to cname. INPUT: id -- an integer or string cname -- a string OUTPUT: Sets the class of the DOM element with the given id to be class. */ $('#' + id).attr('class', cname); } function key_event(e) { /* Normalizes the different possible keyboard event structures for different browsers. NOTE: We use key_event as an object. INPUT: e -- a DOM event OUTPUT: Sets properties of the DOM object in a uniform way. TODO: Use jQuery's Event, instead. */ // IE uses the global variable event. e = e || window.event; // Record whether alt, control, and shift were pressed. this.v = 0; if (e.altKey) { this.v += 1; } if (e.ctrlKey) { this.v += 2; } if (e.shiftKey) { this.v += 4; } // We set the specific key that was pressed (no modifier), which // is string as a string pair n,m. See keyboards.py for details. this.m = e.keyCode + "," + e.which; return this; } function time_now() { /* Return the time right now as an integer since Unix epoch in milliseconds. OUTPUT: an integer */ return (new Date()).getTime(); } function current_selection(input) { /* Return the text that is currently selected in a given text area. INPUT: input -- a DOM object (a textarea) OUTPUT: a string */ var range; if (browser_ie) { range = document.selection.createRange(); return range.text; } else { return input.value.substring(input.selectionStart, input.selectionEnd); } } function get_selection_range(input) { /* Return the start and end positions of the currently selected text in the input text area (a DOM object). INPUT: input -- a DOM object (a textarea) OUTPUT: an array of two nonnegative integers */ var end, range, start, tmprange; if (browser_ie) { range = document.selection.createRange(); tmprange = range.duplicate(); tmprange.moveToElementText(input); tmprange.setEndPoint("endToStart", range); start = tmprange.text.length; tmprange = range.duplicate(); tmprange.moveToElementText(input); tmprange.setEndPoint("endToEnd", range); end = tmprange.text.length; return [start, end]; } else { return [input.selectionStart, input.selectionEnd]; } } function set_selection_range(input, start, end) { /* Select a range of text in a given textarea. INPUT: input -- a DOM input text area start -- an integer end -- an integer OUTPUT: changes the state of the input textarea. */ var range; if (browser_ie) { input.value = input.value.replaceAll("\r\n", "\n"); range = document.selection.createRange(); range.moveToElementText(input); range.moveStart('character', start); range.setEndPoint("endToStart", range); range.moveEnd('character', end - start); range.select(); } else { input.selectionStart = start; input.selectionEnd = end; } } function get_cursor_position(cell) { /* Return an integer that gives the position of the text cursor in the cells input field. INPUT: cell -- an input cell (not the id but the actual DOM element) OUTPUT: a single integer */ return get_selection_range(cell)[1]; } function set_cursor_position(cell, n) { /* Move the cursor position in the cell to position n. WARNING: Does nothing when n is 0 on Opera at present. INPUT: cell -- an actual cell in the DOM, returned by get_cell n -- a non-negative integer OUTPUT: changes the position of the cursor. */ // if (browser_op && !n) { // program around a "bug" in opera where using this hack to // position the cursor selects the entire text area (which is // very painful, since then the user accidentally deletes all // their code). // return; // } // TODO: note for explorer: may need to focus cell first. set_selection_range(cell, n, n); } /////////////////////////////////////////////////////////////////// // Misc page functions -- for making the page work nicely /////////////////////////////////////////////////////////////////// function hide_java_applets() { /* Hides all Jmol applets by moving them off the screen and putting a box of the same size in the same place. */ $('.jmol_applet').each(function () { var me = $(this), width = me.width(), height = me.height(); me.css({ marginLeft: '-' + (width + 1000) + 'px' }) me.after( $('
' + translations["Java Applet Hidden"] + '
').css({ marginTop: '-' + height.toString() + 'px', width: width.toString() + 'px', height: height.toString() + 'px', border: '1px solid black', backgroundColor: '#ccc', color: 'black' }) ); }); } function show_java_applets() { /* Shows all the java applets hid with applet_hide(). */ $('.jmol_applet').each(function () { $(this).css({ marginLeft: '0px' }).next().remove(); }); } function modal_prompt(form_options, options, modal_options) { /* Displays a prompt with a modal dialog. Use this instead of prompt(). INPUT: form_options -- options passed to jQuery.Form. All options have the same behavior as jQuery.Form's except success, which is passed the form and prompt as arguments. Please refer to the jQuery.Form documentation (http://jquery.malsup.com/form/#options-object) for more information. success -- function to be called when the form is submitted. It is passed the generated form and prompt as arguments. OR, for convenience: form_options -- function to be called when the form is submitted. It is passed the generated form and prompt as arguments. options -- an object with any of the following attributes: - title -- the title of the modal prompt. - message -- the message to be displayed in the prompt. - default -- the default value of the prompt. - submit -- the value of the submit button. Defaults to "OK". - overlay_close -- whether to close the dialog if the overlay is clicked. Defaults to true. - id -- id for the modal prompt. - form_id -- id for the form. - css -- CSS to be applied to the prompt. Consider editing the stylesheet files instead of using this option. - post_submit_behavior -- any of "close", "destroy", which also removes the dialog code or a custom function to be called after submitting the form. Defaults to "destroy" modal_options -- options passed to jQuery UI Dialog. Refer to the jQuery UI Dialog documentation (http://jqueryui.com/demos/dialog/#default>) for more options. Default options are: - autoOpen: true -- automatically opens the dialog. If set to false, open the dialog with .dialog('open'). - modal: true -- makes the dialog modal, i.e., UI blocking. - bgiframe: true -- a fix for an IE issue regarding """%( textval, self.__height, self.__width, self.interact(), textval) else: return """"""%( self.html_escaped_default_value(), self.__width, self.interact()) class ColorInput(InputBox): def value_js(self, n): """ Return JavaScript that evaluates to value of this control. If ``n`` is 0, return code for evaluation by the actual color control. If ``n`` is 1, return code for the text area that displays the current color. INPUT: - ``n`` - integer, either 0 or 1. OUTPUT: - a string EXAMPLES:: sage: C = sagenb.notebook.interact.ColorInput('c', Color('red')) sage: C.value_js(0) 'color' sage: C.value_js(1) 'this.value' """ if n == 0: return 'color' else: return 'this.value' def render(self): """ Render this color input box to HTML. OUTPUT: - a string - HTML format EXAMPLES:: sage: sagenb.notebook.interact.ColorInput('c', Color('red')).render() '...table...color...' """ return html_color_selector('color-selector-%s-%s' % (self.var(), self.cell_id()), change=self.interact(0), input_change=self.interact(1), default=self.default_value().html_color(), **self._kwargs) class InputGrid(InteractControl): def __init__(self, var, rows, columns, default_value=None, label=None, to_value=lambda x: x, width=4): """ A grid interact control. INPUT: - ``var`` - an object; the variable - ``rows`` - an integer; the number of rows - ``columns`` - an integer; the number of columns - ``default_value`` - an object; if this is a scalar, it is put in every cell; if it is a list, it is filled into the cells row by row; if it is a nested list, then it is filled into the cells according to the nesting structure. - ``label`` - a string; the label for the control - ``to_value`` - a function applied to the nested list from user input when assigning the variable - ``width`` - an integer; the width of the input boxes EXAMPLES:: sage: sagenb.notebook.interact.InputGrid('M', 2,2, default_value = 0, label='M') A 2 x 2 InputGrid interactive control with M=[[0, 0], [0, 0]] and label 'M' sage: sagenb.notebook.interact.InputGrid('M', 2,2, default_value = [[1,2],[3,4]], label='M') A 2 x 2 InputGrid interactive control with M=[[1, 2], [3, 4]] and label 'M' sage: sagenb.notebook.interact.InputGrid('M', 2,2, default_value = [[1,2],[3,4]], label='M', to_value=MatrixSpace(ZZ,2,2)) A 2 x 2 InputGrid interactive control with M=[1 2] [3 4] and label 'M' sage: sagenb.notebook.interact.InputGrid('M', 1, 3, default_value=[1,2,3], to_value=lambda x: vector(flatten(x))) A 1 x 3 InputGrid interactive control with M=(1, 2, 3) and label 'M' """ self.__rows = rows self.__columns = columns self.__to_value = to_value self.__width = width if type(default_value) != list: default_value = [[default_value for _ in range(columns)] for _ in range(rows)] elif not all(type(elt) == list for elt in default_value): default_value = [[default_value[i * columns + j] for j in xrange(columns)] for i in xrange(rows)] self.__default_value_grid = default_value InteractControl.__init__(self, var, self.__to_value(default_value), label) def __repr__(self): """ String representation of an :class:`InputGrid` interactive control. OUTPUT: - a string EXAMPLES:: sage: sagenb.notebook.interact.InputGrid('M', 2,2).__repr__() "A 2 x 2 InputGrid interactive control with M=[[None, None], [None, None]] and label 'M'" """ return 'A %r x %r InputGrid interactive control with %s=%r and label %r' % ( self.__rows, self.__columns, self.var(), self.default_value(), self.label()) def _adaptor(self, value, globs): """ Adapt a user input, which is the text they enter, to be an element selected by this control. INPUT: - ``value`` - text entered by user - ``globs`` - a string:object dictionary; the :func:`globals` interpreter variables (not used here). OUTPUT: - an object EXAMPLES:: sage: sagenb.notebook.interact.InputGrid('M', 1,3, default_value=[[1,2,3]], to_value=lambda x: vector(flatten(x)))._adaptor("[[4,5,6]]", globals()) (4, 5, 6) """ return self.__to_value(sage_eval(value, globs)) def value_js(self): """ Return JavaScript string that will give the value of this control element. OUTPUT: - string - JavaScript EXAMPLES:: sage: sagenb.notebook.interact.InputGrid('M', 2,2).value_js() "...jQuery...table...map...val...join..." """ # Basically, given an input element in a table, it constructs # a python string representation of a list of lists from the # rows in the table. return """ '[[' + jQuery(this).parents('table').eq(0).find('tr').map(function() { return jQuery(this).find('input').map(function() { return jQuery(this).val(); }).get().join(','); }).get().join('],[') + ']]' """ def render(self): """ Render this control as a string. OUTPUT: - string - HTML format EXAMPLES:: sage: sagenb.notebook.interact.InputGrid('M', 1,2).render() '...table...input...M...' """ s = "" for i in range(self.__rows): s += " " for j in range(self.__columns): s += ' \n' s += ' \n' s += '
\n' s += ' \n' % (self.__default_value_grid[i][j], self.__width, self.interact()) s += '
\n' return s class Selector(InteractControl): def __init__(self, var, values, label=None, default=0, nrows=None, ncols=None, width=None, buttons=False): """ A drop down menu or a button bar that when pressed sets a variable to a given value. INPUT: - ``var`` - a string; variable name - ``values`` - a list; button values - ``label`` - a string (default: None); label off to the left for this button group - ``default`` - an integer (default: 0); position of default value in values list. - ``nrows`` - an integer (default: None); number of rows - ``ncols`` - an integer (default: None); number of columns - ``width`` - an integer (default: None); width of all the buttons - ``buttons`` - a bool (default: False); if True use buttons instead of dropdown EXAMPLES:: sage: sagenb.notebook.interact.Selector('x', [1..5], 'alpha', default=2) Selector with 5 options for variable 'x' sage: sagenb.notebook.interact.Selector('x', [1..4], 'alpha', default=2, nrows=2, ncols=2, width=10, buttons=True) Selector with 4 options for variable 'x' """ if (len(values) > 0 and isinstance(values[0], tuple) and len(values[0]) == 2): vals = [z[0] for z in values] lbls = [repr(z[1]) if z[1] is not None else None for z in values] else: vals = values lbls = [None] * len(vals) default = int(default) if default < 0 or default >= len(vals): default = 0 InteractControl.__init__(self, var, vals[default], label) self.__default = default self.__buttons = buttons self.__values = vals self.__labels = lbls if nrows is None: if ncols is not None: nrows = len(values) // ncols if ncols * nrows < len(values): nrows += 1 else: nrows = 1 # temporary else: nrows = int(nrows) if nrows <= 0: nrows = 1 if ncols is None: ncols = len(values) // nrows if ncols * nrows < len(values): ncols += 1 self.__nrows = nrows self.__ncols = ncols if width is not None: self.__width = "width:%sex;" % width else: self.__width = '' self.__selected = 'background-color:orange;' def __repr__(self): """ String representation of a :class:`Selector` interactive control. OUTPUT: - a string EXAMPLES:: sage: sagenb.notebook.interact.Selector('x', [1..5]).__repr__() "Selector with 5 options for variable 'x'" """ return "Selector with %s options for variable '%s'" % ( len(self.__values), self.var()) def _adaptor(self, value, globs): """ Adapt value of button or menu selection. The button value is just an integer, and this function adapts it to be the value that we associate with that button. INPUT: - ``value` - an integer; value sent in via JavaScript - ``globs`` - a string:object dictionary; the :func:`globals` interpreter variables (not used here). OUTPUT: - an object EXAMPLES:: sage: S = sagenb.notebook.interact.Selector('x', ['first',x^3+5]) sage: S._adaptor(0,globals()) 'first' sage: S._adaptor(1,globals()) x^3 + 5 """ return self.__values[int(value)] def use_buttons(self): """ Whether or not to use buttons instead of a drop down menu for this select list. OUTPUT: - a bool EXAMPLES:: sage: sagenb.notebook.interact.Selector('x', [1..5]).use_buttons() False sage: sagenb.notebook.interact.Selector('x', [1..5], buttons=True).use_buttons() True """ return self.__buttons def value_js(self): """ Return JavaScript string that will give the value of this control element. OUTPUT: - a string - JavaScript EXAMPLES:: sage: sagenb.notebook.interact.Selector('x', [1..5]).value_js() 'this.options[this.selectedIndex].value' sage: sagenb.notebook.interact.Selector('x', [1..5], buttons=True).value_js() 'this.value' """ if self.use_buttons(): return 'this.value' else: # Now we have to use a option selector. return 'this.options[this.selectedIndex].value' def render(self): """ Render this control as a string. OUTPUT: - a string - HTML format EXAMPLES:: sage: sagenb.notebook.interact.Selector('x', [1..5]).render() '...select...x...' sage: sagenb.notebook.interact.Selector('x', [1..5], buttons=True).render() '...table...button...x...' """ width = self.__width vals = self.__values lbls = self.__labels default = self.__default label = self.label() use_buttons = self.use_buttons() event = self.interact() if use_buttons: #On selected buttons, border is set to inset, on #unselected boxes - outset. This usually is default #rendering. if len(vals) > 1: event = """$('BUTTON', this.parentNode).css('border-style', 'outset'); $(this).css('border-style', 'inset'); %s""" % event s = """""" else: s = """' if use_buttons: s += '
' for c in range(self.__ncols): if i >= len(vals): i += 1 continue style = width #if i == default: # style += self.__selected if lbls[i] is None: if isinstance(vals[i], str): lbl = vals[i] else: lbl = repr(vals[i]) else: lbl = lbls[i] if use_buttons: s += """\n""" % ('border-style:inset;' if i == default and len(vals) > 1 else 'border-style:outset;', style, i, event, lbl) else: s += '\n' % (i, 'selected' if i == default else '', lbl) i += 1 if use_buttons: s += '
' else: s += '' return s class SliderGeneric(InteractControl): def __init__(self, var, values, default_value, label=None, display_value=True): """ An abstract slider :func:`interact` control that takes on the given list of values. INPUT: - ``var`` - a string; name of variable being interacted - ``values`` - a list; a list of the values that the slider will take on - ``default_value`` - an object; default value of the slider. - ``label`` - a string; alternative label to the left of the slider, instead of the variable. - ``display_value`` - a bool; whether to display the current value on the slider EXAMPLES:: sage: sagenb.notebook.interact.SliderGeneric('x', [1..5], 2, 'alpha') Abstract Slider Interact Control: alpha [1--|2|---5] """ InteractControl.__init__(self, var, default_value, label=label) self.__values = values self.__display_value = display_value def __repr__(self): """ Return string representation of this slider control. OUTPUT: - a string EXAMPLES:: sage: sagenb.notebook.interact.SliderGeneric('x', [1..5], 2, 'alpha').__repr__() 'Abstract Slider Interact Control: alpha [1--|2|---5]' """ return "Abstract Slider Interact Control: %s [%s--|%s|---%s]" % ( self.label(), self.__values[0], self.default_value(), self.__values[-1]) def values(self): """ Return list of values the slider acts on. OUTPUT: - a list EXAMPLES:: sagenb.notebook.interact.Slider('x', [1..5], 2, 'alpha').values() [1, 2, 3, 4, 5] """ return self.__values def display_value(self): """ Returns whether to display the value on the slider. OUTPUT: - a bool EXAMPLES:: sagenb.notebook.interact.Slider('x', [1..5], 2, 'alpha').display_value() True """ return self.__display_value def values_js(self): """ Returns JavaScript array representation of values or 'null' if display_value=False OUTPUT: - a string EXAMPLES:: sage: sagenb.notebook.interact.Slider('x', [1..5], 2, 'alpha').values_js() '["1","2","3","4","5"]' sage: sagenb.notebook.interact.Slider('x', [1..5], 2, 'alpha', False).values_js() 'null' sage: sagenb.notebook.interact.Slider('x', [pi..2*pi], 2, 'alpha').values_js() '["pi","pi + 1","pi + 2","pi + 3"]' """ if self.__display_value == False: return "null" s = "[" for i in self.__values: ie = repr(i).replace("\\", "\\\\").replace("\"", "\\\"").replace("'", "\\'") s += "\"%s\"," % ie s = s[:-1] + ']' return s class Slider(SliderGeneric): def __init__(self, var, values, default_position, label=None, display_value=True): """ A slider :func:`interact` control that takes on the given list of values. INPUT: - ``var`` - a string; name of variable being interacted - ``values`` - a list; a list of the values that the slider will take on - ``default_position`` - an integer; default location that the slider is set to. - ``label`` - a string; alternative label to the left of the slider, instead of the variable. - ``display_value`` - a bool, whether to display the current value right of the slider EXAMPLES:: sage: sagenb.notebook.interact.Slider('x', [1..5], 2, 'alpha') Slider Interact Control: alpha [1--|3|---5] """ SliderGeneric.__init__(self, var, values, values[default_position], label=label, display_value=display_value) self.__default_position = default_position def __repr__(self): """ Return string representation of this slider control. OUTPUT: - a string EXAMPLES:: sage: sagenb.notebook.interact.Slider('x', [1..5], 2, 'alpha').__repr__() 'Slider Interact Control: alpha [1--|3|---5]' """ return "Slider Interact Control: %s [%s--|%s|---%s]" % ( self.label(), self.values()[0], self.default_value(), self.values()[-1]) def default_position(self): """ Return the default position (as an integer) of the slider. OUTPUT: - an integer EXAMPLES:: sage: sagenb.notebook.interact.Slider('x', [1..5], 2, 'alpha').default_position() 2 """ return self.__default_position def value_js(self): """ Return JavaScript string that will give the value of this control element. OUTPUT: - a string - JavaScript EXAMPLES:: sage: sagenb.notebook.interact.Slider('x', [1..5], 2, 'alpha').value_js() 'position' """ return "position" def _adaptor(self, position, globs): """ Adapt a user input, which is the slider position, to be an element selected by this control. INPUT: - ``position`` - an object; position of the slider - ``globs`` - a string:object dictionary; the :func:`globals` interpreter variables (not used here). OUTPUT: - an object EXAMPLES:: sage: sagenb.notebook.interact.Slider('x', [1..5], 2, 'alpha')._adaptor(2,globals()) 3 """ v = self.values() # We have to cast to int, since it comes back as a float that # is too big. return v[int(position)] def render(self): """ Render this control as an HTML string. OUTPUT: - a string - HTML format EXAMPLES:: sage: sagenb.notebook.interact.Slider('x', [1..5], 2, 'alpha').render() '...table...slider...["1","2","3","4","5"]...' sage: sagenb.notebook.interact.Slider('x', [1..5], 2, 'alpha', display_value=False).render() '...table...slider...null...' """ return html_slider('slider-%s-%s'%(self.var(), self.cell_id()), self.values_js(), self.interact(), steps=len(self.values()), default=self.default_position()) class RangeSlider(SliderGeneric): def __init__(self, var, values, default_position, label=None, display_value=True): """ A range slider :func:`interact` control that takes on the given list of values. INPUT: - ``var`` - a string; name of variable being interacted - ``values`` - a list; a list of the values that the slider will take on - ``default_position`` - an integer 2-tuple; default location that the slider is set to. - ``label`` - a string; alternative label to the left of the slider, instead of the variable. - ``display_value`` - a bool, whether to display the current value below the slider EXAMPLES:: sage: sagenb.notebook.interact.RangeSlider('x', [1..5], (2,3), 'alpha') Range Slider Interact Control: alpha [1--|3==4|---5] """ SliderGeneric.__init__(self, var, values, (values[default_position[0]], values[default_position[1]]), label=label, display_value=display_value) self.__default_position = default_position def __repr__(self): """ Return string representation of this slider control. OUTPUT: - a string EXAMPLES:: sage: sagenb.notebook.interact.RangeSlider('x', [1..5], (2,3), 'alpha').__repr__() 'Range Slider Interact Control: alpha [1--|3==4|---5]' """ return "Range Slider Interact Control: %s [%s--|%s==%s|---%s]" % ( self.label(), self.values()[0], self.default_value()[0], self.default_value()[1], self.values()[-1]) def default_position(self): """ Return the default position (as an integer) of the slider. OUTPUT: - an integer 2-tuple EXAMPLES:: sage: sagenb.notebook.interact.RangeSlider('x', [1..5], (2,3), 'alpha').default_position() (2, 3) """ return self.__default_position def value_js(self): """ Return JavaScript string that will give the value of this control element. OUTPUT: - a string - JavaScript EXAMPLES:: sage: sagenb.notebook.interact.RangeSlider('x', [1..5], (2,3), 'alpha').value_js() "pos[0]+' '+pos[1]" """ return "pos[0]+' '+pos[1]" def _adaptor(self, position, globs): """ Adapt a user input, which is the slider position, to be an element selected by this control. INPUT: - ``position`` - an object; position of the slider - ``globs` - a string:object dictionary; the :func:`globals` interpreter variables (not used here). OUTPUT: - an object EXAMPLES:: sage: sagenb.notebook.interact.RangeSlider('x', [1..5], (2,3), 'alpha')._adaptor("2 3",globals()) (3, 4) """ v = self.values() s = position.split(' ') # Use of int() here matches it's use in Slider._adaptor return (v[int(s[0])], v[int(s[1])]) def render(self): """ Render this control as an HTML string. OUTPUT: - string - HTML format EXAMPLES:: sage: sagenb.notebook.interact.RangeSlider('x', [1..5], (2,3), 'alpha').render() '...table...slider...["1","2","3","4","5"]...range...' sage: sagenb.notebook.interact.RangeSlider('x', [1..5], (2,3), 'alpha', display_value=False).render() '...table...slider...null...range... """ return html_rangeslider('slider-%s-%s'%(self.var(), self.cell_id()), self.values_js(), self.interact(), steps=len(self.values()), default_l=self.default_position()[0], default_r=self.default_position()[1]) class TextControl(InteractControl): def __init__(self, var, data): """ A text field :func:`interact` control INPUT: - ``data`` - a string; the HTML value of the text field EXAMPLES:: sage: sagenb.notebook.interact.TextControl('x', 'something') Text Interact Control: something """ InteractControl.__init__(self, var, data, label='') self.__data = data def __repr__(self): """ Return string representation of this control. OUTPUT: - a string EXAMPLES:: sage: sagenb.notebook.interact.TextControl('x', 'something').__repr__() 'Text Interact Control: something' """ return 'Text Interact Control: %s' % self.default_value() def render(self): """ Render this control as an HTML string. OUTPUT: - a string - HTML format EXAMPLES:: sage: sagenb.notebook.interact.TextControl('x', 'something').render() '...div...something...' """ return '
%s
' % self.default_value() class InteractCanvas(object): def __init__(self, controls, id, layout=None, width=None, **options): """ Base class for :func:`interact` canvases. This is where all the controls along with the output of the interacted function are laid out and rendered. INPUT: - ``controls`` - a list of :class:`InteractControl` instances. - ``id`` - an integer or a string; the ID of the cell that contains this InteractCanvas. - ``layout`` - a dictionary with keys 'top','bottom','left','right' and values lists of rows of control variable names. If a dictionary is not passed in, then the value of layout is set to the 'top' value. If ``None``, then all control names are put on separate rows in the 'top' value. - ``width`` - the width of the interact control - ``options`` - any additional keyword arguments (for example, auto_update=False) EXAMPLES:: sage: B = sagenb.notebook.interact.InputBox('x',2) sage: sagenb.notebook.interact.InteractCanvas([B], 3) Interactive canvas in cell 3 with 1 controls """ for control in controls: control.set_canvas(self) self.__controls = controls self.__cell_id = id self.__width = width self.__options = options if layout is None: layout = [[c.var()] for c in self.__controls] if not isinstance(layout, dict): layout={'top': layout} self.__layout = layout def __repr__(self): """ Print representation of an interactive canvas. OUTPUT: - a string EXAMPLES:: sage: B = sagenb.notebook.interact.InputBox('x',2) sage: sagenb.notebook.interact.InteractCanvas([B], 3).__repr__() 'Interactive canvas in cell 3 with 1 controls' """ return "Interactive canvas in cell %s with %s controls" % ( self.__cell_id, len(self.__controls)) def cell_id(self): """ Return the ID of the cell that contains this :func:`interact` control. OUTPUT: - an integer or a string EXAMPLES: The output below should equal the ID of the current cell:: sage: B = sagenb.notebook.interact.InputBox('x',2) sage: C = sagenb.notebook.interact.InteractCanvas([B], 3); C Interactive canvas in cell 3 with 1 controls sage: C.cell_id() 3 """ return self.__cell_id def is_auto_update(self): r""" Returns True if any change of the values for the controls on this canvas should cause an update. If ``auto_update=False`` was not specified in the constructor for this canvas, then this will default to True. OUTPUT: - a bool EXAMPLES:: sage: B = sagenb.notebook.interact.InputBox('x',2) sage: canvas = sagenb.notebook.interact.InteractCanvas([B], 3) sage: canvas.is_auto_update() True sage: canvas = sagenb.notebook.interact.InteractCanvas([B], 3, auto_update=False) sage: canvas.is_auto_update() False """ return self.__options.get('auto_update', True) def controls(self): """ Return a list of controls in this canvas. OUTPUT: - list of controls .. note:: Returns a reference to a mutable list. EXAMPLES:: sage: B = sagenb.notebook.interact.InputBox('x',2) sage: sagenb.notebook.interact.InteractCanvas([B], 3).controls() [An InputBox interactive control with x=2 and label 'x'] """ return self.__controls def render_output(self): """ Render in text (HTML) form the output portion of the :func:`interact` canvas. The output contains two special tags, and , which get replaced at runtime by the text and HTML parts of the output of running the function. OUTPUT: - a string - HTML format EXAMPLES:: sage: B = sagenb.notebook.interact.InputBox('x',2) sage: sagenb.notebook.interact.InteractCanvas([B], 3).render_output() '...div...interact...3...' """ return """
{1}
{2}
{3}
{4}
""".format(self.cell_id(), INTERACT_START, INTERACT_TEXT, INTERACT_HTML, INTERACT_END) def render_controls(self, side='top'): """ Render in text (HTML) form all the input controls. OUTPUT: - a string - HTML format EXAMPLES:: sage: B = sagenb.notebook.interact.InputBox('x',2) sage: sagenb.notebook.interact.InteractCanvas([B], 3).render_controls() '...table...x...input...2...' """ if side not in self.__layout: return '' tbl_body = '' controls = dict([c.var(), c] for c in self.__controls) for row in self.__layout[side]: tbl_body += '' for c_name in row: c = controls[c_name] if c.label() == '': tbl_body += '{0}\n'.format(c.render()) else: tbl_body += '{0} {1}\n'.format(c.label(), c.render()) tbl_body += '' return '' + tbl_body + '
' def wrap_in_outside_frame(self, inside): """ Return the entire HTML for the interactive canvas, obtained by wrapping all the inside HTML of the canvas in a div and a table. INPUT: - ``inside`` - a string; HTML OUTPUT: - a string - HTML format EXAMPLES:: sage: B = sagenb.notebook.interact.InputBox('x',2) sage: sagenb.notebook.interact.InteractCanvas([B], 3).wrap_in_outside_frame('') '...notruncate...div...interact...table...inside...' """ return """
%s
""" % (self.cell_id(), inside) # The following could be used to make the interact frame resizable # and/or draggable. Neither effect is as cool as it sounds! # def render(self): """ Render in text (HTML) the entire :func:`interact` canvas. OUTPUT: - string - HTML format EXAMPLES:: sage: B = sagenb.notebook.interact.InputBox('x',2) sage: sagenb.notebook.interact.InteractCanvas([B], 3).render() '...notruncate...div...interact...table...x...' """ html_controls={} for side in ('top','left','right','bottom'): html_controls[side] = self.render_controls(side=side) s = """
{top}
{left}{output}{right}
{bottom}
""".format(output=self.render_output(), **html_controls) s = self.wrap_in_outside_frame(s) return s class JavascriptCodeButton(InteractElement): def __init__(self, label, code): """ This :func:`interact` element displays a button which when clicked executes JavaScript code in the notebook. EXAMPLES:: sage: b = sagenb.notebook.interact.JavascriptCodeButton('Push me', 'alert("2")') """ self.__label = label self.__code = code InteractElement.__init__(self) def render(self): r""" Returns the HTML to display this button. OUTPUT: - a string - HTML format EXAMPLES:: sage: b = sagenb.notebook.interact.JavascriptCodeButton('Push me', 'alert("2")') sage: b.render() '...input...button...Push me...alert("2")...' """ return """\n""" % ( self.__label, self.__code) class UpdateButton(JavascriptCodeButton): def __init__(self, cell_id, var): r""" Creates an :func:`interact` button element. A click on the button triggers recomputation of the cell with the current values of the variables. INPUT: - ``cell_id`` - an integer or string; the ambient cell's ID - ``var``` - a variable which is used in the layout EXAMPLES:: sage: b = sagenb.notebook.interact.UpdateButton(0, 'auto_update') sage: b.render() '...input...button...Update...0...' """ s = "interact(%r, {}, 1)" % cell_id JavascriptCodeButton.__init__(self, "Update", s) self.__var = var def var(self): """ Return the name of the variable that this control interacts. OUTPUT: - a string - name of a variable as a string. EXAMPLES:: sage: sagenb.notebook.interact.UpdateButton(1, 'auto_update').var() 'auto_update' """ return self.__var from sage.misc.decorators import decorator_defaults @decorator_defaults def interact(f, layout=None, width='800px'): r""" Use interact as a decorator to create interactive Sage notebook cells with sliders, text boxes, radio buttons, check boxes, and color selectors. Simply put ``@interact`` on the line before a function definition in a cell by itself, and choose appropriate defaults for the variable names to determine the types of controls (see tables below). INPUT: - ``f`` - a Python function - ``layout`` (optional) - a dictionary with keys 'top', 'bottom', 'left', 'right' and values lists of rows of control variable names. Controls are laid out according to this pattern. If ``layout`` is not a dictionary, it is assumed to be the 'top' value. If ``layout`` is None, then all controls are assigned separate rows in the ``top`` value. EXAMPLES: In each example below we use a single underscore for the function name. You can use *any* name you want; it does not have to be an underscore. We create an interact control with two inputs, a text input for the variable ``a`` and a ``y`` slider that runs through the range of integers from `0` to `19`. :: sage: @interact ....: def _(a=5, y=(0..20)): print(a + y) ....: ... :: sage: @interact(layout=[['a','b'],['d']]) ....: def _(a=x^2, b=(0..20), c=100, d=x+1): print(a+b+c+d) ....: ... :: sage: @interact(layout={'top': [['a', 'b']], 'left': [['c']], 'bottom': [['d']]}) ....: def _(a=x^2, b=(0..20), c=100, d=x+1): print(a+b+c+d) ....: ... Draw a plot interacting with the "continuous" variable ``a``. By default continuous variables have exactly 50 possibilities. :: sage: @interact ....: def _(a=(0,2)): ....: show(plot(sin(x*(1+a*x)), (x,0,6)), figsize=4) ... Interact a variable in steps of 1 (we also use an unnamed function):: sage: @interact ....: def _(n=(10,100,1)): ....: show(factor(x^n - 1)) ... Interact two variables:: sage: @interact ....: def _(a=(1,4), b=(0,10)): ....: show(plot(sin(a*x+b), (x,0,6)), figsize=3) ... Place a block of text among the controls:: sage: @interact ....: def _(t1=text_control("Factors an integer."), n="1"): ....: print(factor(Integer(n))) ... If your the time to evaluate your function takes awhile, you may not want to have it reevaluated every time the inputs change. In order to prevent this, you can add a keyword ``auto_update=False`` to your function to prevent it from updating whenever the values are changed. This will cause a button labeled 'Update' to appear which you can click on to re-evaluate your function. :: sage: @interact ....: def _(n=(10,100,1), auto_update=False): ....: show(factor(x^n - 1)) ... DEFAULTS: Defaults for the variables of the input function determine interactive controls. The standard controls are ``input_box``, ``slider``, ``range_slider``, ``checkbox``, ``selector``, ``input_grid``, and ``color_selector``. There is also a text control (see the defaults below). * ``u = input_box(default=None, label=None, type=None)`` - input box with given ``default``; use ``type=str`` to get input as an arbitrary string * ``u = slider(vmin, vmax=None, step_size=1, default=None, label=None)`` - slider with given list of possible values; ``vmin`` can be a list * ``u = range_slider(vmin, vmax=None, step_size=1, default=None, label=None)`` - range slider with given list of possible values; ``vmin`` can be a list * ``u = checkbox(default=True, label=None)`` - a checkbox * ``u = selector(values, label=None, nrows=None, ncols=None, buttons=False)`` - a dropdown menu or buttons (get buttons if ``nrows``, ``ncols``, or ``buttons`` is set, otherwise a dropdown menu) * ``u = input_grid(nrows, ncols, default=None, label=None, to_value=lambda x:x, width=4)`` - an editable grid of objects (a matrix or array) * ``u = color_selector(default=(0,0,1), label=None, widget='colorpicker', hide_box=False)`` - a color selector with a possibly hidden input box; the ``widget`` can also be ``'farbtastic'`` or ``'jpicker'`` (currently not working properly) * ``u = text_control(value='')`` - a block of text You can also create a color selector by setting the default value for an ``input_box`` to ``Color(...)``. There are also some convenient defaults that allow you to make controls automatically without having to explicitly specify them. E.g., you can make ``x`` a continuous slider of values between ``u`` and ``v`` by just writing ``x=(u,v)`` in the argument list of your function. These are all just convenient shortcuts for creating the controls listed above. * ``u`` - blank input_box field * ``u = element`` - input_box with ``default=element``, if element not below. * ``u = (umin,umax)`` - continuous slider (really `100` steps) * ``u = (umin,umax,du)`` - slider with step size ``du`` * ``u = list`` - buttons if ``len(list)`` at most `5`; otherwise, drop down * ``u = iterator`` (e.g. a generator) - a slider (up to `10000` steps) * ``u = bool`` - a checkbox * ``u = Color('blue')`` - a color selector; returns ``Color`` object * ``u = (default, v)`` - ``v`` as above, with given ``default`` value * ``u = (label, v)`` - ``v`` as above, with given ``label`` (a string) * ``u = matrix`` - an ``input_grid`` with ``to_value`` set to ``matrix.parent()`` and default values given by the matrix .. note:: Suppose you would like to make an interactive with a default RGB color of ``(1,0,0)``, so the function would have signature ``f(color=(1,0,0))``. Unfortunately, the above shortcuts reinterpret the ``(1,0,0)`` as a discrete slider with step size 0 between 1 and 0. Instead you should do the following:: sage: @interact ....: def _(v = input_box((1,0,0))): ....: show(plot(sin,color=v)) ... An alternative:: sage: @interact ....: def _(c = color_selector((1, 0, 0))): ....: show(plot(sin, color = c)) ... MORE EXAMPLES: We give an input box that allows one to enter completely arbitrary strings:: sage: @interact ....: def _(a=input_box('sage', label="Enter your name", type=str)): ....: print("Hello there %s"%a.capitalize()) ... The scope of variables that you control via :func:`interact` are local to the scope of the function being interacted with. However, by using the ``global`` Python keyword, you can still modify global variables as follows:: sage: xyz = 10 sage: @interact ....: def _(a=('xyz',5)): ....: global xyz ....: xyz = a ... If you enter the above you obtain an :func:`interact` canvas. Entering values in the box changes the global variable ``xyz``. Here's a example with several controls:: sage: @interact ....: def _(title=["A Plot Demo", "Something silly", "something tricky"], a=input_box(sin(x*sin(x*sin(x))), 'function'), ....: clr = Color('red'), thickness=[1..30], zoom=(1,0.95,..,0.1), plot_points=(200..2000)): ....: html('

%s

'%title) ....: print(plot_points) ....: show(plot(a, -zoom*pi,zoom*pi, color=clr, thickness=thickness, plot_points=plot_points)) ... For a more compact color control, use an empty label and hide the input box:: sage: @interact ....: def _(color=color_selector((1,0,1), label='', hide_box=True)): ....: show(plot(x/(8/7+sin(x)), (x,-50,50), fill=True, fillcolor=color)) ... We give defaults and name the variables:: sage: @interact ....: def _(a=('first', (1,4)), b=(0,10)): ....: show(plot(sin(a*x+sin(b*x)), (x,0,6)), figsize=3) ... Another example involving labels, defaults, and the slider command:: sage: @interact ....: def _(a = slider(1, 4, default=2, label='Multiplier'), ....: b = slider(0, 10, default=0, label='Phase Variable')): ....: show(plot(sin(a*x+b), (x,0,6)), figsize=4) ... An example where the range slider control is useful:: sage: @interact ....: def _(b = range_slider(-20, 20, 1, default=(-19,3), label='Range')): ....: plot(sin(x)/x, b[0], b[1]).show(xmin=b[0],xmax=b[1]) ... An example using checkboxes, obtained by making the default values bools:: sage: @interact ....: def _(axes=('Show axes', True), square=False): ....: show(plot(sin, -5,5), axes=axes, aspect_ratio = (1 if square else None)) ... An example generating a random walk that uses a checkbox control to determine whether points are placed at each step:: sage: @interact ....: def foo(pts = checkbox(True, "points"), n = (50,(10..100))): ....: s = 0; v = [(0,0)] ....: for i in range(n): ....: s += random() - 0.5 ....: v.append((i, s)) ....: L = line(v, rgbcolor='#4a8de2') ....: if pts: L += points(v, pointsize=20, rgbcolor='black') ....: show(L) ... You can rotate and zoom into 3-D graphics while interacting with a variable:: sage: @interact ....: def _(a=(0,1)): ....: x,y = var('x,y') ....: show(plot3d(sin(x*cos(y*a)), (x,0,5), (y,0,5)), figsize=4) ... A random polygon:: sage: pts = [(random(), random()) for _ in xrange(20)] sage: @interact ....: def _(n = (4..len(pts)), c=Color('purple') ): ....: G = points(pts[:n],pointsize=60) + polygon(pts[:n], rgbcolor=c) ....: show(G, figsize=5, xmin=0, ymin=0) ... Two "sinks" displayed simultaneously via a contour plot and a 3-D interactive plot:: sage: @interact ....: def _(q1=(-1,(-3,3)), q2=(-2,(-3,3))): ....: x,y = var('x,y') ....: f = q1/sqrt((x+1)^2 + y^2) + q2/sqrt((x-1)^2+(y+0.5)^2) ....: C = contour_plot(f, (-2,2), (-2,2), plot_points=30, contours=15, cmap='cool') ....: show(C, figsize=3, aspect_ratio=1) ....: show(plot3d(f, (x,-2,2), (y,-2,2)), figsize=4) ... This is similar to above, but you can select the color map from a dropdown menu:: sage: @interact ....: def _(q1=(-1,(-3,3)), q2=(-2,(-3,3)), ....: cmap=['autumn', 'bone', 'cool', 'copper', 'gray', 'hot', 'hsv', ....: 'jet', 'pink', 'prism', 'spring', 'summer', 'winter']): ....: x,y = var('x,y') ....: f = q1/sqrt((x+1)^2 + y^2) + q2/sqrt((x-1)^2+(y+0.5)^2) ....: C = contour_plot(f, (x,-2,2), (y,-2,2), plot_points=30, contours=15, cmap=cmap) ....: show(C, figsize=3, aspect_ratio=1) ... A quadratic roots etch-a-sketch:: sage: v = [] sage: html('

Quadratic Root Etch-a-sketch

') ...

Quadratic Root Etch-a-sketch

... sage: @interact ....: def _(a=[-10..10], b=[-10..10], c=[-10..10]): ....: f = a*x^2 + b*x + c == 0; show(f) ....: soln = solve(a*x^2 + b*x + c == 0, x)[0].rhs() ....: show(soln) ....: P = tuple(CDF(soln)) ....: v.append(P) ....: show(line(v, rgbcolor='purple') + point(P, pointsize=200)) ... In the following example, we only generate data for a given ``n`` once, so that as one varies ``p`` the data does not randomly change. We do this by simply caching the results for each ``n`` in a dictionary.:: sage: data = {} sage: @interact ....: def _(n=(500,(100,5000,1)), p=(1,(0.1,10))): ....: n = int(n) ....: if n not in data: ....: data[n] = [(random(), random()) for _ in xrange(n)] ....: show(points([(x^p,y^p) for x,y in data[n]], rgbcolor='black'), xmin=0, ymin=0, axes=False) ... A conchoid:: sage: @interact ....: def _(k=(1.2,(1.1,2)), k_2=(1.2,(1.1,2)), a=(1.5,(1.1,2))): ....: u, v = var('u,v') ....: f = (k^u*(1+cos(v))*cos(u), k^u*(1+cos(v))*sin(u), k^u*sin(v)-a*k_2^u) ....: show(parametric_plot3d(f, (u,0,6*pi), (v,0,2*pi), plot_points=[40,40], texture=(0,0.5,0))) ... An input grid:: sage: @interact ....: def _(A=matrix(QQ,3,3,range(9)), v=matrix(QQ,3,1,range(3))): ....: try: ....: x = A\v ....: html('$$%s %s = %s$$'%(latex(A), latex(x), latex(v))) ....: except: ....: html('There is no solution to $$%s x=%s$$'%(latex(A), latex(v))) ... """ if not isinstance(f, types.FunctionType) and callable(f): f = f.__call__ (args, varargs, varkw, defaults) = inspect.getargspec(f) if defaults is None: defaults = [] n = len(args) - len(defaults) controls = [automatic_control(defaults[i - n] if i >= n else None).render(arg) for i, arg in enumerate(args)] variables = {} adapt = {} state[SAGE_CELL_ID] = {'variables': variables, 'adapt': adapt} for control in controls: variables[control.var()] = control.default_value() adapt[control.adapt_number()] = control._adaptor # Replace the auto_update checkbox with a button that will cause # the cell to recompute itself. # TODO: Should auto_update=True yield a checkbox? auto_update = variables.get('auto_update', True) if auto_update is False: i = args.index('auto_update') controls[i] = UpdateButton(SAGE_CELL_ID, 'auto_update') C = InteractCanvas(controls, SAGE_CELL_ID, auto_update=auto_update, layout=layout, width=width) html(C.render()) def _(): z = f(*[variables[arg] for arg in args]) if z: print(z) state[SAGE_CELL_ID]['function'] = _ return f ###################################################### # Actual control objects that the user passes in ###################################################### class control: def __init__(self, label=None): """ An interactive control object used with the :func:`interact` command. This is the abstract base class. INPUTS: - ``label`` - a string EXAMPLES:: sage: sagenb.notebook.interact.control('a control') Interative control 'a control' (abstract base class) """ self.__label = label def __repr__(self): """ Return string representation of this control. (It just mentions the label and that this is an abstract base class.) OUTPUT: - a string EXAMPLES:: sage: sagenb.notebook.interact.control('a control').__repr__() "Interative control 'a control' (abstract base class)" """ return "Interative control '%s' (abstract base class)" % self.__label def label(self): """ Return the label of this control. OUTPUT: - a string EXAMPLES:: sage: sagenb.notebook.interact.control('a control').label() 'a control' sage: selector([1,2,7], 'alpha').label() 'alpha' """ return self.__label def set_label(self, label): """ Set the label of this control. INPUT: - ``label`` - a string EXAMPLES:: sage: C = sagenb.notebook.interact.control('a control') sage: C.set_label('sage'); C Interative control 'sage' (abstract base class) """ self.__label = label class input_box(control): def __init__(self, default=None, label=None, type=None, width=80, height=1, **kwargs): r""" An input box interactive control. Use this in conjunction with the :func:`interact` command. INPUT: - ``default`` - an object; the default put in this input box - ``label`` - a string; the label rendered to the left of the box. - ``type`` - a type; coerce inputs to this; this doesn't have to be an actual type, since anything callable will do. - ``height`` - an integer (default: 1); the number of rows. If greater than 1 a value won't be returned until something outside the textarea is clicked. - ``width`` - an integer; width of text box in characters - ``kwargs`` - a dictionary; additional keyword options EXAMPLES:: sage: input_box("2+2", 'expression') Interact input box labeled 'expression' with default value '2+2' sage: input_box('sage', label="Enter your name", type=str) Interact input box labeled 'Enter your name' with default value 'sage' sage: input_box('Multiline\nInput',label='Click to change value',type=str,height=5) Interact input box labeled 'Click to change value' with default value 'Multiline\nInput' """ self.__default = default self.__type = type control.__init__(self, label) self.__width = width self.__height = height self.__kwargs = kwargs def __repr__(self): """ Return print representation of this input box. OUTPUT: - a string EXAMPLES:: sage: input_box("2+2", 'expression').__repr__() "Interact input box labeled 'expression' with default value '2+2'" """ return "Interact input box labeled %r with default value %r"%( self.label(), self.__default) def default(self): """ Return the default value of this input box. OUTPUT: - an object EXAMPLES:: sage: input_box('2+2', 'Expression').default() '2+2' sage: input_box(x^2 + 1, 'Expression').default() x^2 + 1 sage: checkbox(True, "Points").default() True """ return self.__default def type(self): """ Return the type that elements of this input box are coerced to or None if they are not coerced (they have whatever type they evaluate to). OUTPUT: - a type EXAMPLES:: sage: input_box("2+2", 'expression', type=int).type() sage: input_box("2+2", 'expression').type() is None True """ return self.__type def render(self, var): r""" Return rendering of this input box as an :class:`InputBox` to be used for an :func:`interact` canvas. Basically this specializes this input to be used for a specific function and variable. INPUT: - ``var`` - a string (variable; one of the variable names input to ``f``) OUTPUT: - an :class:`InputBox` instance EXAMPLES:: sage: input_box("2+2", 'Exp').render('x') An InputBox interactive control with x='2+2' and label 'Exp' """ if self.__type is Color: return ColorInput(var, default_value=self.__default, label=self.label(), type=self.__type, **self.__kwargs) else: return InputBox(var, default_value=self.__default, height=self.__height, label=self.label(), type=self.__type, width=self.__width, **self.__kwargs) class color_selector(input_box): def __init__(self, default=(0, 0, 1), label=None, widget='colorpicker', hide_box=False): r""" A color selector (also called a color chooser, picker, or tool) interactive control. Use this with the :func:`interact` command. INPUT: - ``default`` - an instance of or valid constructor argument to :class:`Color` (default: (0,0,1)); the selector's default color; a string argument must be a valid color name (e.g., 'red') or HTML hex color (e.g., '#abcdef') - ``label`` - a string (default: None); the label rendered to the left of the selector. - ``widget`` - a string (default: 'colorpicker'); the color selector widget to use; choices are 'colorpicker', 'farbtastic', and 'jpicker' (currently broken) - ``hide_box`` - a boolean (default: False); whether to hide the input box associated with the color selector widget EXAMPLES:: sage: color_selector() Interact color selector labeled None, with default RGB color (0.0, 0.0, 1.0), widget 'colorpicker', and visible input box sage: color_selector((0.5, 0.5, 1.0), widget='jpicker') Interact color selector labeled None, with default RGB color (0.5, 0.5, 1.0), widget 'jpicker', and visible input box sage: color_selector(default = Color(0, 0.5, 0.25)) Interact color selector labeled None, with default RGB color (0.0, 0.5, 0.25), widget 'colorpicker', and visible input box sage: color_selector('purple', widget = 'colorpicker') Interact color selector labeled None, with default RGB color (0.50..., 0.0, 0.50...), widget 'colorpicker', and visible input box sage: color_selector('crayon', widget = 'colorpicker') Traceback (most recent call last): ... ValueError: unknown color 'crayon' sage: color_selector('#abcdef', label='height', widget='jpicker') Interact color selector labeled 'height', with default RGB color (0.6..., 0.8..., 0.9...), widget 'jpicker', and visible input box sage: color_selector('abcdef', label='height', widget='jpicker') Traceback (most recent call last): ... ValueError: unknown color 'abcdef' """ input_box.__init__(self, default=Color(default), label=label, type=Color, widget=widget, hide_box=hide_box) self.__widget = widget self.__hide_box = hide_box def __repr__(self): """ Return the print representation of this color selector. OUTPUT: - a string EXAMPLES:: sage: color_selector(Color('red'), 'line color').__repr__() "Interact color selector labeled 'line color', with default RGB color (1.0, 0.0, 0.0), widget 'colorpicker', and visible input box" sage: color_selector(Color((1,0,1)), 'circle color', widget='jpicker', hide_box=True).__repr__() "Interact color selector labeled 'circle color', with default RGB color (1.0, 0.0, 1.0), widget 'jpicker', and hidden input box" """ s = "Interact color selector labeled %r, with default %r, widget %r, and " % (self.label(), self.default(), self.widget()) if self.hide_box(): return s + "hidden input box" else: return s + "visible input box" def widget(self): """ Return the name of the HTML widget for this color selector. OUTPUT: - a string; the widget's name EXAMPLES:: sage: color_selector().widget() 'colorpicker' sage: color_selector('#abcdef', hide_box=True, widget='farbtastic').widget() 'farbtastic' sage: color_selector(widget='jpicker').widget() 'jpicker' sage: color_selector(default=Color(0,0.5,0.25)).widget() 'colorpicker' """ return self.__widget def hide_box(self): """ Return whether to hide the input box associated with this color selector. OUTPUT: - a boolean EXAMPLES:: sage: color_selector().hide_box() False sage: color_selector('green', hide_box=True, widget='jpicker').hide_box() True sage: color_selector((0.75,0.5,0.25)).hide_box() False """ return self.__hide_box class input_grid(control): def __init__(self, nrows, ncols, default=None, label=None, to_value=lambda x: x, width=4): r""" An input grid interactive control. Use this in conjunction with the :func:`interact` command. INPUT: - ``nrows`` - an integer - ``ncols`` - an integer - ``default`` - an object; the default put in this input box - ``label`` - a string; the label rendered to the left of the box. - ``to_value`` - a list; the grid output (list of rows) is sent through this function. This may reformat the data or coerce the type. - ``width`` - an integer; size of each input box in characters NOTEBOOK EXAMPLE:: @interact def _(m = input_grid(2,2, default = [[1,7],[3,4]], label='M=', to_value=matrix), v = input_grid(2,1, default=[1,2], label='v=', to_value=matrix)): try: x = m\v html('$$%s %s = %s$$'%(latex(m), latex(x), latex(v))) except: html('There is no solution to $$%s x=%s$$'%(latex(m), latex(v))) EXAMPLES:: sage: input_grid(2,2, default = 0, label='M') Interact 2 x 2 input grid control labeled M with default value 0 sage: input_grid(2,2, default = [[1,2],[3,4]], label='M') Interact 2 x 2 input grid control labeled M with default value [[1, 2], [3, 4]] sage: input_grid(2,2, default = [[1,2],[3,4]], label='M', to_value=MatrixSpace(ZZ,2,2)) Interact 2 x 2 input grid control labeled M with default value [[1, 2], [3, 4]] sage: input_grid(1, 3, default=[[1,2,3]], to_value=lambda x: vector(flatten(x))) Interact 1 x 3 input grid control labeled None with default value [[1, 2, 3]] """ self.__default = default self.__rows = nrows self.__columns = ncols self.__to_value = to_value self.__width = width control.__init__(self, label) def __repr__(self): """ Return print representation of this input box. OUTPUT: - a string EXAMPLES:: sage: input_grid(2,2, label='M').__repr__() 'Interact 2 x 2 input grid control labeled M with default value None' """ return 'Interact %r x %r input grid control labeled %s with default value %s'%( self.__rows, self.__columns, self.label(), self.default()) def default(self): """ Return the default value of this input grid. OUTPUT: - an object EXAMPLES:: sage: input_grid(2,2, default=1).default() 1 """ return self.__default def render(self, var): r""" Return rendering of this input grid as an :class:`InputGrid` to be used for an :func:`interact` canvas. Basically this specializes this input to be used for a specific function and variable. INPUT: - ``var`` - a string (variable; one of the variable names input to ``f``) OUTPUT: - an :class:`InputGrid` instance. EXAMPLES:: sage: input_grid(2,2).render('x') A 2 x 2 InputGrid interactive control with x=[[None, None], [None, None]] and label 'x' """ return InputGrid(var, rows=self.__rows, columns=self.__columns, default_value=self.__default, label=self.label(), to_value=self.__to_value, width=self.__width) class checkbox(input_box): def __init__(self, default=True, label=None): """ A checkbox interactive control. Use this in conjunction with the :func:`interact` command. INPUT: - ``default`` - a bool (default: True); whether box should be checked or not - ``label`` - a string (default: None) text label rendered to the left of the box EXAMPLES:: sage: checkbox(False, "Points") Interact checkbox labeled 'Points' with default value False sage: checkbox(True, "Points") Interact checkbox labeled 'Points' with default value True sage: checkbox(True) Interact checkbox labeled None with default value True sage: checkbox() Interact checkbox labeled None with default value True """ input_box.__init__(self, bool(default), label=label, type=bool) def __repr__(self): """ Print representation of this checkbox. OUTPUT: - a string EXAMPLES:: sage: checkbox(True, "Points").__repr__() "Interact checkbox labeled 'Points' with default value True" """ return "Interact checkbox labeled %r with default value %r"% ( self.label(), self.default()) class slider_generic(control): def __init__(self, vmin, vmax=None, step_size=None, label=None, display_value=True): control.__init__(self, label=label) self.__display_value = display_value self.__vmin = vmin self.__vmax = vmax self.__step_size = step_size @cached_method def values(self): """ Returns list of values that this slider takes on, in order. OUTPUT: - a list .. note:: This is a reference to a mutable list. EXAMPLES:: sage: sagenb.notebook.interact.slider(1,10,1/2).values() [1, 3/2, 2, 5/2, 3, 7/2, 4, 9/2, 5, 11/2, 6, 13/2, 7, 15/2, 8, 17/2, 9, 19/2, 10] """ if isinstance(self.__vmin, list): vals = self.__vmin else: if self.__vmax is None: self.__vmax = self.__vmin self.__vmin = 0 # Compute step size; vmin and vmax are both defined here # 500 is the length of the slider (in px) if self.__step_size is None: self.__step_size = (self.__vmax-self.__vmin) / 499.0 elif self.__step_size <= 0: raise ValueError("invalid negative step size -- step size must be positive") #Compute list of values num_steps = int(math.ceil((self.__vmax-self.__vmin)/float(self.__step_size))) if num_steps <= 1: vals = [self.__vmin, self.__vmax] else: vals = srange(self.__vmin, self.__vmax, self.__step_size, include_endpoint=True) if vals[-1] != self.__vmax: try: if vals[-1] > self.__vmax: vals[-1] = self.__vmax else: vals.append(self.__vmax) except (ValueError, TypeError): pass # Is the list of values is small (len < =50), use the whole # list. Otherwise, use part of the list. if len(vals) == 0: return [0] elif(len(vals) <= 500): return vals else: vlen = (len(vals)-1) / 499.0 return [vals[(int)(i*vlen)] for i in range(500)] def display_value(self): """ Returns whether to display the value on the slider. OUTPUT: - a bool EXAMPLES:: sagenb.notebook.interact.slider_generic(1,10,1/2).display_value() True """ return self.__display_value class slider(slider_generic): def __init__(self, vmin, vmax=None, step_size=None, default=None, label=None, display_value=True): r""" An interactive slider control, which can be used in conjunction with the :func:`interact` command. INPUT: - ``vmin`` - an object - ``vmax`` - an object (default: None); if None then ``vmin`` must be a list, and the slider then varies over elements of the list. - ``step_size`` - an integer (default: 1) - ``default`` - an object (default: None); default value is "closest" in ``vmin`` or range to this default. - ``label`` - a string - ``display_value`` - a bool, whether to display the current value to the right of the slider EXAMPLES: We specify both ``vmin`` and ``vmax``. We make the default `3`, but since `3` isn't one of `3/17`-th spaced values between `2` and `5`, `52/17` is instead chosen as the default (it is closest):: sage: slider(2, 5, 3/17, 3, 'alpha') Slider: alpha [2--|52/17|---5] Here we give a list:: sage: slider([1..10], None, None, 3, 'alpha') Slider: alpha [1--|3|---10] The elements of the list can be anything:: sage: slider([1, 'x', 'abc', 2/3], None, None, 'x', 'alpha') Slider: alpha [1--|x|---2/3] """ slider_generic.__init__(self, vmin, vmax, step_size, label, display_value) self.__default = default def __repr__(self): """ Return string representation of this slider. OUTPUT: - a string EXAMPLES:: sage: slider(2, 5, 1/5, 3, 'alpha').__repr__() 'Slider: alpha [2--|3|---5]' """ return "Slider: %s [%s--|%s|---%s]" % ( self.label(), self.values()[0], self.values()[self.default_index()], self.values()[-1]) @cached_method def default_index(self): """ Return default index into the list of values. OUTPUT: - an integer EXAMPLES:: sage: slider(2, 5, 1/2, 3, 'alpha').default_index() 2 """ # determine the best choice of index into the list of values # for the user-selected default if self.__default is None: return 0 else: try: i = self.values().index(self.__default) except ValueError: # here no index matches - which is best? try: v = [(abs(self.__default - self.values()[j]), j) for j in range(len(self.values()))] m = min(v) i = m[1] except TypeError: # abs not defined on everything, so give up i = 0 return i def render(self, var): """ Render the :func:`interact` control for the given function and variable. INPUT: - ``var`` - a string; variable name OUTPUT: - a :class:`Slider` instance EXAMPLES:: sage: S = slider(0, 10, 1, default=3, label='theta'); S Slider: theta [0--|3|---10] sage: S.render('x') Slider Interact Control: theta [0--|3|---10] sage: slider(2, 5, 2/7, 3, 'alpha').render('x') Slider Interact Control: alpha [2--|20/7|---5] """ return Slider(var, self.values(), self.default_index(), label=self.label(), display_value=self.display_value()) class range_slider(slider_generic): def __init__(self, vmin, vmax=None, step_size=None, default=None, label=None, display_value=True): r""" An interactive range slider control, which can be used in conjunction with the :func:`interact` command. INPUT: - ``vmin`` - an object - ``vmax`` - object or None; if None then ``vmin`` must be a list, and the slider then varies over elements of the list. - ``step_size`` - integer (default: 1) - ``default`` - a 2-tuple of objects (default: None); default range is "closest" in ``vmin`` or range to this default. - ``label`` - a string - ``display_value`` - a bool, whether to display the current value below the slider EXAMPLES: We specify both ``vmin`` and ``vmax``. We make the default `(3,4)` but since neither is one of `3/17`-th spaced values between `2` and `5`, the closest values: `52/17` and `67/17`, are instead chosen as the default:: sage: range_slider(2, 5, 3/17, (3,4), 'alpha') Range Slider: alpha [2--|52/17==67/17|---5] Here we give a list:: sage: range_slider([1..10], None, None, (3,7), 'alpha') Range Slider: alpha [1--|3==7|---10] """ slider_generic.__init__(self, vmin, vmax, step_size, label, display_value) self.__default = default def __repr__(self): """ Return string representation of this slider. OUTPUT: - a string EXAMPLES:: sage: range_slider(2, 5, 1/5, (3,4), 'alpha').__repr__() 'Range Slider: alpha [2--|3==4|---5]' """ return "Range Slider: %s [%s--|%s==%s|---%s]" % ( self.label(), self.values()[0], self.values()[self.default_index()[0]], self.values()[self.default_index()[1]], self.values()[-1]) @cached_method def default_index(self): """ Return default index into the list of values. OUTPUT: - an integer 2-tuple EXAMPLES:: sage: range_slider(2, 5, 1/2, (3,4), 'alpha').default_index() (2, 4) """ # Determine the best choice of index into the list of values # for the user-selected default. if self.__default is None: return (0,1) elif not isinstance(self.__default, tuple) or len(self.__default) != 2: raise TypeError("default value must be None or a 2-tuple.") else: dlist = [] for i in [0, 1]: try: d = self.values().index(self.__default[i]) except ValueError: # Here no index matches -- which is best? try: v = [(abs(self.__default[i] - self.values()[j]), j) for j in range(len(self.values()))] m = min(v) d = m[1] except TypeError: # abs not defined on everything, so give up d = 0 dlist.append(d) return (dlist[0], dlist[1]) def render(self, var): """ Render the :func:`interact` control for the given function and variable. INPUT: - ``var`` - string; variable name OUTPUT: - a :class:`RangeSlider` instance EXAMPLES:: sage: S = range_slider(0, 10, 1, default=(3,7), label='theta'); S Range Slider: theta [0--|3==7|---10] sage: S.render('x') Range Slider Interact Control: theta [0--|3==7|---10] sage: range_slider(2, 5, 2/7, (3,4), 'alpha').render('x') Range Slider Interact Control: alpha [2--|20/7==4|---5] """ return RangeSlider(var, self.values(), self.default_index(), label=self.label(), display_value=self.display_value()) class selector(control): def __init__(self, values, label=None, default=None, nrows=None, ncols=None, width=None, buttons=False): r""" A drop down menu or a button bar that when pressed sets a variable to a given value. Use this in conjunction with the :func:`interact` command. We use the same command to create either a drop down menu or selector bar of buttons, since conceptually the two controls do exactly the same thing - they only look different. If either ``nrows`` or ``ncols`` is given, then you get a buttons instead of a drop down menu. INPUT: - ``values`` - [val0, val1, val2, ...] or [(val0, lbl0), (val1,lbl1), ...] where all labels must be given or given as None. - ``label`` - a string (default: None); if given, this label is placed to the left of the entire button group - ``default`` - an object (default: 0); default value in values list - ``nrows`` - an integer (default: None); if given determines the number of rows of buttons; if given buttons option below is set to True - ``ncols`` - an integer (default: None); if given determines the number of columns of buttons; if given buttons option below is set to True - ``width`` - an integer (default: None); if given, all buttons are the same width, equal to this in HTML ex units's. - ``buttons`` - a bool (default: False); if True, use buttons EXAMPLES:: sage: selector([1..5]) Drop down menu with 5 options sage: selector([1,2,7], default=2) Drop down menu with 3 options sage: selector([1,2,7], nrows=2) Button bar with 3 buttons sage: selector([1,2,7], ncols=2) Button bar with 3 buttons sage: selector([1,2,7], width=10) Drop down menu with 3 options sage: selector([1,2,7], buttons=True) Button bar with 3 buttons We create an :func:`interact` that involves computing charpolys of matrices over various rings:: sage: @interact ....: def _(R=selector([ZZ,QQ,GF(17),RDF,RR]), n=(1..10)): ....: M = random_matrix(R, n) ....: show(M) ....: show(matrix_plot(M,cmap='Oranges')) ....: f = M.charpoly() ....: print(f) ... Here we create a drop-down:: sage: @interact ....: def _(a=selector([(2,'second'), (3,'third')])): ....: print(a) ... """ if nrows is not None or ncols is not None: buttons = True if default is None: default = 0 else: try: default = values.index(default) except IndexError: default = 0 self.__values = values self.__nrows = nrows self.__ncols = ncols self.__width = width self.__default = default self.__buttons = buttons control.__init__(self, label) def __repr__(self): """ Return print representation of this button. OUTPUT: - a string EXAMPLES:: sage: selector([1,2,7], default=2).__repr__() 'Drop down menu with 3 options' """ if self.__buttons: return "Button bar with %s buttons" % len(self.__values) else: return "Drop down menu with %s options" % len(self.__values) def values(self): """ Return the list of values or (val, lbl) pairs that this selector can take on. OUTPUT: - a list EXAMPLES:: sage: selector([1..5]).values() [1, 2, 3, 4, 5] sage: selector([(5,'fifth'), (8,'eight')]).values() [(5, 'fifth'), (8, 'eight')] """ return self.__values def default(self): """ Return the default choice for this control. OUTPUT: - an integer, with 0 corresponding to the first choice. EXAMPLES:: sage: selector([1,2,7], default=2).default() 1 """ return self.__default def render(self, var): r""" Return rendering of this button as a :class:`Selector` instance to be used for an :func:`interact` canvas. INPUT: - ``var`` - a string (variable; one of the variable names input to ``f``) OUTPUT: - a :class:`Selector` instance EXAMPLES:: sage: selector([1..5]).render('alpha') Selector with 5 options for variable 'alpha' """ return Selector(var, values=self.__values, label=self.label(), default=self.__default, nrows=self.__nrows, ncols=self.__ncols, width=self.__width, buttons=self.__buttons) class text_control(control): def __init__(self, value=''): """ Text that can be inserted among other :func:`interact` controls. INPUT: - ``value`` - HTML for the control EXAMPLES:: sage: text_control('something') Text field: something """ self.__default = value control.__init__(self, '') def __repr__(self): """ Return print representation of this control. OUTPUT: - a string EXAMPLES:: sage: text_control('something') Text field: something """ return "Text field: %s" % self.__default def render(self, var): """ Return rendering of the text field INPUT: - ``var`` - a string (variable; one of the variable names input to ``f``) OUTPUT: - a :class:`TextControl` instance """ return TextControl(var, self.__default) def automatic_control(default): """ Automagically determine the type of control from the default value of the variable. INPUT: - ``default`` - the default value for ``v`` given by the function; see the documentation to :func:`interact` for details. OUTPUT: - an :func:`interact` control EXAMPLES:: sage: sagenb.notebook.interact.automatic_control('') Interact input box labeled None with default value '' sage: sagenb.notebook.interact.automatic_control(15) Interact input box labeled None with default value 15 sage: sagenb.notebook.interact.automatic_control(('start', 15)) Interact input box labeled 'start' with default value 15 sage: sagenb.notebook.interact.automatic_control((1,250)) Slider: None [1.0--|1.0|---250.0] sage: sagenb.notebook.interact.automatic_control(('alpha', (1,250))) Slider: alpha [1.0--|1.0|---250.0] sage: sagenb.notebook.interact.automatic_control((2,(0,250))) Slider: None [0.0--|2.00400801603|---250.0] sage: sagenb.notebook.interact.automatic_control(('alpha label', (2,(0,250)))) Slider: alpha label [0.0--|2.00400801603|---250.0] sage: sagenb.notebook.interact.automatic_control((2, ('alpha label',(0,250)))) Slider: alpha label [0.0--|2.00400801603|---250.0] sage: C = sagenb.notebook.interact.automatic_control((1,52, 5)); C Slider: None [1--|1|---52] sage: C.values() [1, 6, 11, 16, 21, 26, 31, 36, 41, 46, 51, 52] sage: sagenb.notebook.interact.automatic_control((17, (1,100,5))) Slider: None [1--|16|---100] sage: sagenb.notebook.interact.automatic_control([1..4]) Button bar with 4 buttons sage: sagenb.notebook.interact.automatic_control([1..100]) Drop down menu with 100 options sage: sagenb.notebook.interact.automatic_control((1..100)) Slider: None [1--|1|---100] sage: sagenb.notebook.interact.automatic_control((5, (1..100))) Slider: None [1--|5|---100] sage: sagenb.notebook.interact.automatic_control(matrix(2,2)) Interact 2 x 2 input grid control labeled None with default value [0, 0, 0, 0] """ label = None default_value = None for _ in range(2): if isinstance(default, tuple) and len(default) == 2 and isinstance(default[0], str): label, default = default if isinstance(default, tuple) and len(default) == 2 and isinstance(default[1], (tuple, list, collections.Iterator)): default_value, default = default if isinstance(default, control): C = default if label: C.set_label(label) elif isinstance(default, str): C = input_box(default, label=label, type=str) elif isinstance(default, bool): C = input_box(default, label=label, type=bool) elif isinstance(default, list): C = selector(default, default=default_value, label=label, buttons=len(default) <= 5) elif isinstance(default, collections.Iterator): C = slider(list_of_first_n(default, 10000), default=default_value, label=label) elif isinstance(default, Color): C = input_box(default, label=label, type=Color) elif isinstance(default, tuple): if len(default) == 2: C = slider(default[0], default[1], default=default_value, label=label) elif len(default) == 3: C = slider(default[0], default[1], default[2], default=default_value, label=label) else: C = slider(list(default), default=default_value, label=label) elif is_Matrix(default): C = input_grid(default.nrows(), default.ncols(), default=default.list(), to_value=default.parent(), label=label) else: C = input_box(default, label=label) return C def list_of_first_n(v, n): """ Given an iterator v, return first n elements it produces as a list. INPUT: - ``v`` - an iterator - ``n`` - an integer OUTPUT: - a list EXAMPLES:: sage: from itertools import takewhile sage: p100 = takewhile(lambda x: x < 100, Primes()) sage: sagenb.notebook.interact.list_of_first_n(p100, 10) [2, 3, 5, 7, 11, 13, 17, 19, 23, 29] sage: sagenb.notebook.interact.list_of_first_n((1..5), 10) [1, 2, 3, 4, 5] sage: sagenb.notebook.interact.list_of_first_n(QQ, 10) [0, 1, -1, 1/2, -1/2, 2, -2, 1/3, -1/3, 3] """ if not hasattr(v, 'next'): v = v.__iter__() w = [] while n > 0: try: w.append(v.next()) except StopIteration: return w n -= 1 return w def update(cell_id, var, adapt, value, globs): r""" Called when updating the positions of an interactive control. Note that this just causes the values of the variables to be updated; it does not reevaluate the function with the new values. INPUT: - ``cell_id`` - an integer or string; the ID of an :func:`interact` cell - ``var`` - an object; a variable associated to that cell - ``adapt`` - in integer; the number of the adapt function - ``value`` - an object; new value of the control - ``globs`` - global variables. EXAMPLES: The following outputs __SAGE_INTERACT_RESTART__ to indicate that not all the state of the :func:`interact` canvas has been set up yet (this setup happens when JavaScript calls certain functions):: sage: sagenb.notebook.interact.update(0, 'a', 0, '5', globals()) __SAGE_INTERACT_RESTART__ """ # We cast the id to an integer, if it's an integer. try: cell_id = int(cell_id) except ValueError: pass try: S = state[cell_id] # Look up the function that adapts inputs to have the right # type adapt_function = S["adapt"][adapt] # Apply that function and save the result in the appropriate # variables dictionary. S["variables"][var] = adapt_function(value, globs) except KeyError: # If you change this, make sure to change notebook_lib.js as # well. print(INTERACT_RESTART) def recompute(cell_id): """ Evaluates the :func:`interact` function associated to the cell ``cell_id``. This typically gets called after a call to :func:`update`. INPUT: - ``cell_id`` - a string or an integer; the ID of an :func:`interact` cell EXAMPLES: The following outputs __SAGE_INTERACT_RESTART__ to indicate that not all the state of the :func:`interact` canvas has been set up yet (this setup happens when JavaScript calls certain functions):: sage: sagenb.notebook.interact.recompute(10) __SAGE_INTERACT_RESTART__ """ # We cast the id to an integer, if it's an integer. try: cell_id = int(cell_id) except ValueError: pass try: S = state[cell_id] # Finally call the interactive function, which will use the # above variables. S['function']() except KeyError: # If you change this, make sure to change notebook_lib.js as # well. print(INTERACT_RESTART) sagenb-1.0.1/sagenb/notebook/jquery.py000066400000000000000000000011661311436262400177260ustar00rootroot00000000000000# -*- coding: utf-8 -* from . import interact def javascript(s): print('' % s) def cell_id(): return interact.SAGE_CELL_ID def draggable(option=''): """ INPUT: option -- string "" (default) -- Creates new draggables on the current cell. "enable" -- Enable the draggable functionality. "disable" -- Temporarily disable the draggable functionality. """ s = '$("#cell_outer_%s").draggable("%s")' % (cell_id(), option) javascript(s) def resizable(): s = '$("#cell_outer_%s").resizable()' % cell_id() javascript(s) sagenb-1.0.1/sagenb/notebook/js.py000066400000000000000000000124661311436262400170300ustar00rootroot00000000000000# -*- coding: utf-8 -* r"""nodoctest JavaScript (AJAX) Components of the Notebook AUTHORS: - William Stein - Tom Boothby - Alex Clemesha This file contains some minimal code to generate the Javascript code which is inserted to the head of the notebook web page. All of the interesting Javascript code is contained under ``data/sage/js/notebook_lib.js``. """ ########################################################################### # Copyright (C) 2006 William Stein # 2006 Tom Boothby # # Released under the *modified* BSD license. # Tom wrote in email to me at wstein@gmail.com on March 2, 2008: # "You have my permission to change the license on anything I've # contributed to the notebook, to whatever suits you." # ########################################################################### import os from . import keyboards from .template import template from sagenb.misc.misc import SAGE_URL from .compress.JavaScriptCompressor import JavaScriptCompressor from hashlib import sha1 # Debug mode? If sagenb lives under SAGE_ROOT/, we minify/pack and cache # the Notebook JS library. debug_mode = False try: from sage.env import SAGE_ROOT from pkg_resources import Requirement, working_set sagenb_path = working_set.find(Requirement.parse('sagenb')).location debug_mode = SAGE_ROOT not in os.path.realpath(sagenb_path) except Exception: pass _cache_javascript = None def javascript(): """ Return javascript library for the Sage Notebook. This is done by reading the template ``notebook_lib.js`` where all of the javascript code is contained and replacing a few of the values specific to the running session. Before the code is returned (as a string), it is run through a JavascriptCompressor to minimize the amount of data needed to be sent to the browser. The code and a hash of the code is returned. .. note:: This the output of this function is cached so that it only needs to be generated once. EXAMPLES:: sage: from sagenb.notebook.js import javascript sage: s = javascript() sage: s[0][:30] '/* JavaScriptCompressor 0.1 [w' """ global _cache_javascript, debug_mode if _cache_javascript is not None: return _cache_javascript s = template(os.path.join('js', 'notebook_dynamic.js'), SAGE_URL=SAGE_URL, KEY_CODES=keyhandler.all_tests(), debug_mode=debug_mode) if debug_mode: # TODO: maybe we should return a random hash so that the code # is reloaded on every refresh return s, sha1(s).hexdigest() # TODO: use minify here, which is more standard (and usually safer # and with gzip compression, smaller); But first inquire about the # propriety of the "This software shall be used for Good, not # Evil" clause in the license. Does that prevent us from # distributing it (i.e., it adds an extra condition to the # software)? See http://www.crockford.com/javascript/jsmin.py.txt s = JavaScriptCompressor().getPacked(s.encode('utf-8')) _cache_javascript = (s, sha1(s).hexdigest()) return _cache_javascript class JSKeyHandler: """ This class is used to make javascript functions to check for specific keyevents. """ def __init__(self): self.key_codes = {}; def set(self, name, key='', alt=False, ctrl=False, shift=False): """ Add a named keycode to the handler. When built by ``all_tests()``, it can be called in javascript by ``key_(event_object)``. The function returns true if the keycode numbered by the ``key`` parameter was pressed with the appropriate modifier keys, false otherwise. """ self.key_codes.setdefault(name,[]) self.key_codes[name] = [JSKeyCode(key, alt, ctrl, shift)] def add(self, name, key='', alt=False, ctrl=False, shift=False): """ Similar to ``set_key(...)``, but this instead checks if there is an existing keycode by the specified name, and associates the specified key combination to that name in addition. This way, if different browsers don't catch one keycode, multiple keycodes can be assigned to the same test. """ try: self.key_codes[name] except KeyError: self.key_codes.setdefault(name,[]) self.key_codes[name].append(JSKeyCode(key,alt,ctrl,shift)) def all_tests(self): """ Builds all tests currently in the handler. Returns a string of javascript code which defines all functions. """ tests = '' for name, keys in self.key_codes.items(): value = "\n||".join([k.js_test() for k in keys]) tests += " function key_%s(e) {\n return %s;\n}"%(name, value) return tests class JSKeyCode: def __init__(self, key, alt, ctrl, shift): global key_codes self.key = key self.alt = alt self.ctrl = ctrl self.shift = shift def js_test(self): v = 0 if self.alt: v+=1 if self.ctrl: v+=2 if self.shift: v+=4 t = "((e.m==%s)&&(e.v==%s))"%(self.key,v) return t keyhandler = JSKeyHandler() sagenb-1.0.1/sagenb/notebook/keyboards.py000066400000000000000000000776111311436262400204020ustar00rootroot00000000000000# -*- coding: utf-8 -* """ Keyboard maps for the Sage Notebook AUTHORS: -- Tom Boothby -- William Stein """ ############################################################################# # Copyright (C) 2007 William Stein # Distributed under the terms of the GNU General Public License (GPL) # The full text of the GPL is available at: # http://www.gnu.org/licenses/ ############################################################################# """ The functions below return a block of javascript code that defines global variables for every key that we could think of that works in (almost) all systems. Keys intentionally not captured are escape, insert, delete, and F1-F12. Support for the capture of ctrl, alt, and shift is spotty; however, checking for this is necessary for proper behavior in IE. This file contains keyboard layouts for the following systems: Firefox 1.5 windows, mac, linux Opera 9 windows, mac, linux (linux only tested on opera 8) IE 6 windows Safari Konqueror We are deaf to the complaints of users of the following systems: AOL IE mac LYNX / other command line browsers (Sage has a command line interface!) the browser your cousin wrote for your sister's birthday If you think that your browser deserves support, go to the following page: http://sage.math.washington.edu/home/boothby/modular.old/www/keys_capture.html and follow the directions you see there. Copy the output, and email it to boothby@u.washington.edu """ from six import iteritems def get_keyboard(s): # keyboard_map is a dictionary defined at the bottom of this # file that maps os/browser codes to functions that give the # corresponding keymaps. if s in keyboard_map: codes = keyboard_map[s]() else: # Default in case something goes wrong. This should # never get called. codes = keyboard_map['mm']() defaults = {'KEY_CTRLENTER':'KEY_ENTER'} # We now add in each default keycode if it isn't already present. # The point of this is that it allows us to easily alias keys to # predefined keys, but doesn't overwrite anything. for key, val in iteritems(defaults): if '%s =' % key not in codes: codes += '\nvar %s = %s;' % (key, val) return codes.strip() def keyboard_moz_win(): return """ var KEY_SHIFT = "16,16!"; var KEY_CTRL = "20,20"; var KEY_ALT = "18,18"; var KEY_ESC = "27,0"; var KEY_HOME = "36,0"; var KEY_END = "35,0"; var KEY_PGUP = "33,0"; var KEY_PGDN = "34,0"; var KEY_BKSPC = "8,8"; var KEY_SPC = "0,32"; var KEY_ENTER = "13,13"; var KEY_RETURN = "13,13"; var KEY_TAB = "9,0"; var KEY_Q = "0,113"; var KEY_W = "0,119"; var KEY_E = "0,101"; var KEY_R = "0,114"; var KEY_T = "0,116"; var KEY_Y = "0,121"; var KEY_U = "0,117"; var KEY_I = "0,105"; var KEY_O = "0,111"; var KEY_P = "0,112"; var KEY_QQ = "0,81!"; var KEY_WW = "0,87!"; var KEY_EE = "0,69!"; var KEY_RR = "0,82!"; var KEY_TT = "0,84!"; var KEY_YY = "0,89!"; var KEY_UU = "0,85!"; var KEY_II = "0,73!"; var KEY_OO = "0,79!"; var KEY_PP = "0,80!"; var KEY_A = "0,97"; var KEY_S = "0,115"; var KEY_D = "0,100"; var KEY_F = "0,102"; var KEY_G = "0,103"; var KEY_H = "0,104"; var KEY_J = "0,106"; var KEY_K = "0,107"; var KEY_L = "0,108"; var KEY_AA = "0,65!"; var KEY_SS = "0,68!"; var KEY_DD = "0,70!"; var KEY_FF = "0,70!"; var KEY_GG = "0,71!"; var KEY_HH = "0,72!"; var KEY_JJ = "0,74!"; var KEY_KK = "0,75!"; var KEY_LL = "0,76!"; var KEY_Z = "0,122"; var KEY_X = "0,120"; var KEY_C = "0,99"; var KEY_V = "0,118"; var KEY_B = "0,98"; var KEY_N = "0,110"; var KEY_M = "0,109"; var KEY_ZZ = "0,90!"; var KEY_XX = "0,88!"; var KEY_CC = "0,67!"; var KEY_VV = "0,86!"; var KEY_BB = "0,66!"; var KEY_NN = "0,78!"; var KEY_MM = "0,77!"; var KEY_1 = "0,49"; var KEY_2 = "0,50"; var KEY_3 = "0,51"; var KEY_4 = "0,52"; var KEY_5 = "0,53"; var KEY_6 = "0,54"; var KEY_7 = "0,55"; var KEY_8 = "0,56"; var KEY_9 = "0,57"; var KEY_0 = "0,48"; var KEY_BANG = "0,33!"; var KEY_AT = "0,64!"; var KEY_HASH = "0,35!"; var KEY_DOLLAR = "0,36!"; var KEY_MOD = "0,37!"; var KEY_CARET = "0,94!"; var KEY_AMP = "0,38!"; var KEY_AST = "0,42!"; var KEY_LPAR = "0,40!"; var KEY_RPAR = "0,41!"; var KEY_MINUS = "0,45"; var KEY_UNDER = "0,95!"; var KEY_PLUS = "0,43!"; var KEY_EQ = "0,61"; var KEY_LBRACE = "0,123!"; var KEY_RBRACE = "0,125!"; var KEY_LBRACK = "0,91"; var KEY_RBRACK = "0,93"; var KEY_PIPE = "0,124!"; var KEY_SLASH = "0,92"; var KEY_COLON = "0,58!"; var KEY_SEMI = "0,59"; var KEY_QUOTE = "0,34!"; var KEY_APOS = "0,39"; var KEY_BSLASH = "191,0"; var KEY_QUEST = "191,0!"; var KEY_COMMA = "0,44"; var KEY_DOT = "0,46"; var KEY_TILDE = "0,126!"; var KEY_TICK = "0,96"; var KEY_LT = "0,60!"; var KEY_GT = "0,62!"; var KEY_LEFT = "37,0"; var KEY_UP = "38,0"; var KEY_RIGHT = "39,0"; var KEY_DOWN = "40,0"; """ def keyboard_moz_lin(): return """ var KEY_SHIFT = "16,16"; var KEY_CTRL = "17,17"; var KEY_ALT = "18,18"; var KEY_ESC = "27,0"; var KEY_HOME = "36,0"; var KEY_END = "35,0"; var KEY_PGUP = "33,0"; var KEY_PGDN = "34,0"; var KEY_BKSPC = "8,8"; var KEY_SPC = "0,32"; var KEY_ENTER = "13,13"; var KEY_RETURN = "13,13"; var KEY_TAB = "9,0"; var KEY_Q = "0,113"; var KEY_W = "0,119"; var KEY_E = "0,101"; var KEY_R = "0,114"; var KEY_T = "0,116"; var KEY_Y = "0,121"; var KEY_U = "0,117"; var KEY_I = "0,105"; var KEY_O = "0,111"; var KEY_P = "0,112"; var KEY_QQ = "0,81!"; var KEY_WW = "0,87!"; var KEY_EE = "0,69!"; var KEY_RR = "0,82!"; var KEY_TT = "0,84!"; var KEY_YY = "0,89!"; var KEY_UU = "0,85!"; var KEY_II = "0,73!"; var KEY_OO = "0,79!"; var KEY_PP = "0,80!"; var KEY_A = "0,97"; var KEY_S = "0,115"; var KEY_D = "0,100"; var KEY_F = "0,102"; var KEY_G = "0,103"; var KEY_H = "0,104"; var KEY_J = "0,106"; var KEY_K = "0,107"; var KEY_L = "0,108"; var KEY_AA = "0,65!"; var KEY_SS = "0,83!"; var KEY_DD = "0,68!"; var KEY_FF = "0,70!"; var KEY_GG = "0,71!"; var KEY_HH = "0,72!"; var KEY_JJ = "0,74!"; var KEY_KK = "0,75!"; var KEY_LL = "0,76!"; var KEY_Z = "0,122"; var KEY_X = "0,120"; var KEY_C = "0,99"; var KEY_V = "0,118"; var KEY_B = "0,98"; var KEY_N = "0,110"; var KEY_M = "0,109"; var KEY_ZZ = "0,90!"; var KEY_XX = "0,88!"; var KEY_CC = "0,67!"; var KEY_VV = "0,86!"; var KEY_BB = "0,66!"; var KEY_NN = "0,78!"; var KEY_MM = "0,77!"; var KEY_1 = "0,49"; var KEY_2 = "0,50"; var KEY_3 = "0,51"; var KEY_4 = "0,52"; var KEY_5 = "0,53"; var KEY_6 = "0,54"; var KEY_7 = "0,55"; var KEY_8 = "0,56"; var KEY_9 = "0,57"; var KEY_0 = "0,48"; var KEY_BANG = "0,33!"; var KEY_AT = "0,64!"; var KEY_HASH = "0,35!"; var KEY_DOLLAR = "0,36!"; var KEY_MOD = "0,37!"; var KEY_CARET = "0,94!"; var KEY_AMP = "0,38!"; var KEY_AST = "0,42!"; var KEY_LPAR = "0,40!"; var KEY_RPAR = "0,41!"; var KEY_MINUS = "0,45"; var KEY_UNDER = "0,95!"; var KEY_PLUS = "0,43!"; var KEY_EQ = "0,61"; var KEY_LBRACE = "0,123!"; var KEY_RBRACE = "0,125!"; var KEY_LBRACK = "0,91"; var KEY_RBRACK = "0,93"; var KEY_PIPE = "0,124!"; var KEY_SLASH = "0,92"; var KEY_COLON = "0,58!"; var KEY_SEMI = "0,59"; var KEY_QUOTE = "0,34!"; var KEY_APOS = "0,39"; var KEY_BSLASH = "0,47"; var KEY_QUEST = "0,63!"; var KEY_COMMA = "0,44"; var KEY_DOT = "0,46"; var KEY_TILDE = "0,126!"; var KEY_TICK = "0,96"; var KEY_LT = "0,60!"; var KEY_GT = "0,62!"; var KEY_LEFT = "37,0"; var KEY_UP = "38,0"; var KEY_RIGHT = "39,0"; var KEY_DOWN = "40,0"; """ def keyboard_moz_mac(): return """ var KEY_SHIFT = ""; var KEY_CTRL = ""; var KEY_ALT = ""; var KEY_ESC = "27,0"; var KEY_HOME = "36,0"; var KEY_END = "35,0"; var KEY_PGUP = "33,0"; var KEY_PGDN = "34,0"; var KEY_BKSPC = "8,8"; var KEY_SPC = "0,32"; var KEY_ENTER = "13,13"; var KEY_RETURN = "13,13"; var KEY_CTRLENTER = "77,0"; var KEY_TAB = "9,0"; var KEY_Q = "0,113"; var KEY_W = "0,119"; var KEY_E = "0,101"; var KEY_R = "0,114"; var KEY_T = "0,116"; var KEY_Y = "0,121"; var KEY_U = "0,117"; var KEY_I = "0,105"; var KEY_O = "0,111"; var KEY_P = "0,112"; var KEY_QQ = "0,81!"; var KEY_WW = "0,87!"; var KEY_EE = "0,69!"; var KEY_RR = "0,82!"; var KEY_TT = "0,84!"; var KEY_YY = "0,89!"; var KEY_UU = "0,85!"; var KEY_II = "0,73!"; var KEY_OO = "0,79!"; var KEY_PP = "0,80!"; var KEY_A = "0,97"; var KEY_S = "0,115"; var KEY_D = "0,100"; var KEY_F = "0,102"; var KEY_G = "0,103"; var KEY_H = "0,104"; var KEY_J = "0,106"; var KEY_K = "0,107"; var KEY_L = "0,108"; var KEY_AA = "0,65!"; var KEY_SS = "0,83!"; var KEY_DD = "0,68!"; var KEY_FF = "0,70!"; var KEY_GG = "0,71!"; var KEY_HH = "0,72!"; var KEY_JJ = "0,74!"; var KEY_KK = "0,75!"; var KEY_LL = "0,76!"; var KEY_Z = "0,122"; var KEY_X = "0,120"; var KEY_C = "0,99"; var KEY_V = "0,118"; var KEY_B = "0,98"; var KEY_N = "0,110"; var KEY_M = "0,109"; var KEY_ZZ = "0,90!"; var KEY_XX = "0,88!"; var KEY_CC = "0,67!"; var KEY_VV = "0,86!"; var KEY_BB = "0,66!"; var KEY_NN = "0,78!"; var KEY_MM = "0,77!"; var KEY_1 = "0,49"; var KEY_2 = "0,50"; var KEY_3 = "0,51"; var KEY_4 = "0,52"; var KEY_5 = "0,53"; var KEY_6 = "0,54"; var KEY_7 = "0,55"; var KEY_8 = "0,56"; var KEY_9 = "0,57"; var KEY_0 = "0,48"; var KEY_BANG = "0,33!"; var KEY_AT = "0,64!"; var KEY_HASH = "0,35!"; var KEY_DOLLAR = "0,36!"; var KEY_MOD = "0,37!"; var KEY_CARET = "0,94!"; var KEY_AMP = "0,38!"; var KEY_AST = "0,42!"; var KEY_LPAR = "0,40!"; var KEY_RPAR = "0,41!"; var KEY_MINUS = "0,45"; var KEY_UNDER = "0,95!"; var KEY_PLUS = "0,43!"; var KEY_EQ = "0,61"; var KEY_LBRACE = "0,123!"; var KEY_RBRACE = "0,125!"; var KEY_LBRACK = "0,91"; var KEY_RBRACK = "0,93"; var KEY_PIPE = "0,124!"; var KEY_SLASH = "0,92"; var KEY_COLON = "0,58!"; var KEY_SEMI = "0,59"; var KEY_QUOTE = "0,34!"; var KEY_APOS = "0,39"; var KEY_BSLASH = "0,47"; var KEY_QUEST = "0,63!"; var KEY_COMMA = "0,44"; var KEY_DOT = "0,46"; var KEY_TILDE = "0,126!"; var KEY_TICK = "0,96"; var KEY_LT = "0,60!"; var KEY_GT = "0,62!"; var KEY_LEFT = "37,0"; var KEY_UP = "38,0"; var KEY_RIGHT = "39,0"; var KEY_DOWN = "40,0"; """ def keyboard_op_win(): return """ var KEY_SHIFT = "16,16!"; var KEY_CTRL = "20,20"; var KEY_ALT = ""; var KEY_ESC = "27,27"; var KEY_HOME = "36,36"; var KEY_END = "35,35"; var KEY_PGUP = "33,0"; var KEY_PGDN = "34,0"; var KEY_BKSPC = "8,8"; var KEY_SPC = "32,32"; var KEY_ENTER = "13,13"; var KEY_RETURN = "13,13"; var KEY_TAB = "9,9"; var KEY_Q = "81,81"; var KEY_W = "87,87"; var KEY_E = "69,69"; var KEY_R = "82,82"; var KEY_T = "84,84"; var KEY_Y = "89,89"; var KEY_U = "85,85"; var KEY_I = "73,73"; var KEY_O = "79,79"; var KEY_P = "80,80"; var KEY_QQ = "113,113!"; var KEY_WW = "119,119!"; var KEY_EE = "101,101!"; var KEY_RR = "114,114!"; var KEY_TT = "116,116!"; var KEY_YY = "121,121!"; var KEY_UU = "117,117!"; var KEY_II = "105,105!"; var KEY_OO = "111,111!"; var KEY_PP = "112,112!"; var KEY_A = "65,65"; var KEY_S = "83,83"; var KEY_D = "68,68"; var KEY_F = "70,70"; var KEY_G = "71,71"; var KEY_H = "72,72"; var KEY_J = "74,74"; var KEY_K = "75,75"; var KEY_L = "76,76"; var KEY_AA = "97,97!"; var KEY_SS = "115,115!"; var KEY_DD = "100,100!"; var KEY_FF = "102,102!"; var KEY_GG = "103,103!"; var KEY_HH = "104,104!"; var KEY_JJ = "106,106!"; var KEY_KK = "107,107!"; var KEY_LL = "108,108!"; var KEY_Z = "90,90"; var KEY_X = "88,88"; var KEY_C = "67,67"; var KEY_V = "86,86"; var KEY_B = "66,66"; var KEY_N = "78,78"; var KEY_M = "77,77"; var KEY_ZZ = "122,122!"; var KEY_XX = "120,120!"; var KEY_CC = "99,99!"; var KEY_VV = "118,118!"; var KEY_BB = "98,98!"; var KEY_NN = "110,110!"; var KEY_MM = "109,109!"; var KEY_1 = "49,49"; var KEY_2 = "50,50"; var KEY_3 = "51,51"; var KEY_4 = "52,52"; var KEY_5 = "53,53"; var KEY_6 = "54,54"; var KEY_7 = "55,55"; var KEY_8 = "56,56"; var KEY_9 = "57,57"; var KEY_0 = "48,48"; var KEY_BANG = "33,33!"; var KEY_AT = "64,64!"; var KEY_HASH = "35,35!"; var KEY_DOLLAR = "36,36!"; var KEY_MOD = "37,37!"; var KEY_CARET = "94,94!"; var KEY_AMP = "38,38!"; var KEY_AST = "42,42!"; var KEY_LPAR = "40,40!"; var KEY_RPAR = "41,41!"; var KEY_MINUS = "45,45"; var KEY_UNDER = "95,95!"; var KEY_PLUS = "43,43!"; var KEY_EQ = "61,61"; var KEY_LBRACE = "123,123!"; var KEY_RBRACE = "125,125!"; var KEY_LBRACK = "91,91"; var KEY_RBRACK = "93,93"; var KEY_PIPE = "124,124!"; var KEY_SLASH = "92,92"; var KEY_COLON = "58,58!"; var KEY_SEMI = "59,59"; var KEY_QUOTE = "34,34!"; var KEY_APOS = "39,39"; var KEY_BSLASH = "47,47"; var KEY_QUEST = "63,63!"; var KEY_COMMA = "44,44"; var KEY_DOT = "46,46"; var KEY_TILDE = "126,126!"; var KEY_TICK = "96,96"; var KEY_LT = "60,60!"; var KEY_GT = "62,62!"; var KEY_LEFT = "37,0"; var KEY_UP = "38,0"; var KEY_RIGHT = "39,0"; var KEY_DOWN = "40,0"; """ def keyboard_op_lin(): return """ var KEY_SHIFT = "0,0"; var KEY_CTRL = "0,0"; var KEY_ALT = "0,0"; var KEY_ESC = "27,27"; var KEY_HOME = ""; var KEY_END = ""; var KEY_PGUP = "33,0"; var KEY_PGDN = "34,0"; var KEY_BKSPC = "8,8"; var KEY_SPC = "32,32"; var KEY_ENTER = "13,13"; var KEY_RETURN = "13,13"; var KEY_TAB = "9,9"; var KEY_Q = "113,113"; var KEY_W = "119,119"; var KEY_E = "101,101"; var KEY_R = "114,114"; var KEY_T = "116,116"; var KEY_Y = "121,121"; var KEY_U = "117,117"; var KEY_I = "105,105"; var KEY_O = "111,111"; var KEY_P = "112,112"; var KEY_QQ = "81,81!"; var KEY_WW = "87,87!"; var KEY_EE = "69,69!"; var KEY_RR = "82,82!"; var KEY_TT = "84,84!"; var KEY_YY = "89,89!"; var KEY_UU = "85,85!"; var KEY_II = "73,73!"; var KEY_OO = "79,79!"; var KEY_PP = "80,80!"; var KEY_A = "97,97"; var KEY_S = "115,115"; var KEY_D = "100,100"; var KEY_F = "102,102"; var KEY_G = "103,103"; var KEY_H = "104,104"; var KEY_J = "106,106"; var KEY_K = "107,107"; var KEY_L = "108,108"; var KEY_AA = "65,65!"; var KEY_SS = "83,83!"; var KEY_DD = "68,68!"; var KEY_FF = "70,70!"; var KEY_GG = "71,71!"; var KEY_HH = "72,72!"; var KEY_JJ = "74,74!"; var KEY_KK = "75,75!"; var KEY_LL = "76,76!"; var KEY_Z = "122,122"; var KEY_X = "120,120"; var KEY_C = "99,99"; var KEY_V = "118,118"; var KEY_B = "98,98"; var KEY_N = "110,110"; var KEY_M = "109,109"; var KEY_ZZ = "90,90!"; var KEY_XX = "88,88!"; var KEY_CC = "67,67!"; var KEY_VV = "86,86!"; var KEY_BB = "66,66!"; var KEY_NN = "78,78!"; var KEY_MM = "77,77!"; var KEY_1 = "49,49"; var KEY_2 = "50,50"; var KEY_3 = "51,51"; var KEY_4 = "52,52"; var KEY_5 = "53,53"; var KEY_6 = "54,54"; var KEY_7 = "55,55"; var KEY_8 = "56,56"; var KEY_9 = "57,57"; var KEY_0 = "48,48"; var KEY_BANG = "33,33!"; var KEY_AT = "64,64!"; var KEY_HASH = "35,35!"; var KEY_DOLLAR = "36,36!"; var KEY_MOD = "37,37!"; var KEY_CARET = "94,94!"; var KEY_AMP = "38,38!"; var KEY_AST = "42,42!"; var KEY_LPAR = "40,40!"; var KEY_RPAR = "41,41!"; var KEY_MINUS = "45,45"; var KEY_UNDER = "95,95!"; var KEY_PLUS = "43,43!"; var KEY_EQ = "61,61"; var KEY_LBRACE = "123,123!"; var KEY_RBRACE = "125,125!"; var KEY_LBRACK = "91,91"; var KEY_RBRACK = "93,93"; var KEY_PIPE = "124,124!"; var KEY_SLASH = "92,92"; var KEY_COLON = "58,58!"; var KEY_SEMI = "59,59"; var KEY_QUOTE = "34,34!"; var KEY_APOS = "39,39"; var KEY_BSLASH = "47,47"; var KEY_QUEST = "63,63!"; var KEY_COMMA = "44,44"; var KEY_DOT = "46,46"; var KEY_TILDE = "126,126!"; var KEY_TICK = "96,96"; var KEY_LT = "60,60!"; var KEY_GT = "62,62!"; var KEY_LEFT = "37,0"; var KEY_UP = "38,0"; var KEY_RIGHT = "39,0"; var KEY_DOWN = "40,0"; """ # You had var KEY_CTRL = "20,20";, but it"s ";0,0"; def keyboard_op_mac(): return """ var KEY_SHIFT = "16,16"; var KEY_CTRL = "0,0"; var KEY_ALT = "18,18"; var KEY_ESC = "27,27"; var KEY_HOME = "36,36"; var KEY_END = "35,35"; var KEY_PGUP = "33,0"; var KEY_PGDN = "34,0"; var KEY_BKSPC = "8,8"; var KEY_SPC = "32,32"; var KEY_ENTER = "13,13"; var KEY_RETURN = "13,13"; var KEY_TAB = "9,9"; var KEY_Q = "113,113"; var KEY_W = "119,119"; var KEY_E = "101,101"; var KEY_R = "114,114"; var KEY_T = "116,116"; var KEY_Y = "121,121"; var KEY_U = "117,117"; var KEY_I = "105,105"; var KEY_O = "111,111"; var KEY_P = "112,112"; var KEY_QQ = "81,81!"; var KEY_WW = "87,87!"; var KEY_EE = "69,69!"; var KEY_RR = "82,82!"; var KEY_TT = "84,84!"; var KEY_YY = "89,89!"; var KEY_UU = "85,85!"; var KEY_II = "73,73!"; var KEY_OO = "79,79!"; var KEY_PP = "80,80!"; var KEY_A = "97,97"; var KEY_S = "115,115"; var KEY_D = "100,100"; var KEY_F = "102,102"; var KEY_G = "103,103"; var KEY_H = "104,104"; var KEY_J = "106,106"; var KEY_K = "107,107"; var KEY_L = "108,108"; var KEY_AA = "65,65!"; var KEY_SS = "83,83!"; var KEY_DD = "68,68!"; var KEY_FF = "70,70!"; var KEY_GG = "71,71!"; var KEY_HH = "72,72!"; var KEY_JJ = "74,74!"; var KEY_KK = "75,75!"; var KEY_LL = "76,76!"; var KEY_Z = "122,122"; var KEY_X = "120,120"; var KEY_C = "99,99"; var KEY_V = "118,118"; var KEY_B = "98,98"; var KEY_N = "110,110"; var KEY_M = "109,109"; var KEY_ZZ = "90,90!"; var KEY_XX = "88,88!"; var KEY_CC = "67,67!"; var KEY_VV = "86,86!"; var KEY_BB = "66,66!"; var KEY_NN = "78,78!"; var KEY_MM = "77,77!"; var KEY_1 = "49,49"; var KEY_2 = "50,50"; var KEY_3 = "51,51"; var KEY_4 = "52,52"; var KEY_5 = "53,53"; var KEY_6 = "54,54"; var KEY_7 = "55,55"; var KEY_8 = "56,56"; var KEY_9 = "57,57"; var KEY_0 = "48,48"; var KEY_BANG = "33,33!"; var KEY_AT = "64,64!"; var KEY_HASH = "35,35!"; var KEY_DOLLAR = "36,36!"; var KEY_MOD = "37,37!"; var KEY_CARET = "94,94!"; var KEY_AMP = "38,38!"; var KEY_AST = "42,42!"; var KEY_LPAR = "40,40!"; var KEY_RPAR = "41,41!"; var KEY_MINUS = "45,45"; var KEY_UNDER = "95,95!"; var KEY_PLUS = "43,43!"; var KEY_EQ = "61,61"; var KEY_LBRACE = "123,123!"; var KEY_RBRACE = "125,125!"; var KEY_LBRACK = "91,91"; var KEY_RBRACK = "93,93"; var KEY_PIPE = "124,124!"; var KEY_SLASH = "92,92"; var KEY_COLON = "58,58!"; var KEY_SEMI = "59,59"; var KEY_QUOTE = "34,34!"; var KEY_APOS = "39,39"; var KEY_BSLASH = "47,47"; var KEY_QUEST = "63,63!"; var KEY_COMMA = "44,44"; var KEY_DOT = "46,46"; var KEY_TILDE = "126,126!"; var KEY_TICK = "96,96"; var KEY_LT = "60,60!"; var KEY_GT = "62,62!"; var KEY_LEFT = "37,0"; var KEY_UP = "38,0"; var KEY_RIGHT = "39,0"; var KEY_DOWN = "40,0"; """ def keyboard_saf_mac(): return """ var KEY_SHIFT = ""; var KEY_CTRL = ""; var KEY_ALT = ""; var KEY_ESC = "27,27"; var KEY_HOME = "63273,63273"; var KEY_END = "63275,63275"; var KEY_PGUP = "63276,63276"; var KEY_PGDN = "63277,63277"; var KEY_BKSPC = "8,8"; var KEY_SPC = "32,32"; var KEY_ENTER = "3,3"; var KEY_RETURN = "13,13"; var KEY_TAB = "9,9"; var KEY_Q = "113,113"; var KEY_W = "119,119"; var KEY_E = "101,101"; var KEY_R = "114,114"; var KEY_T = "116,116"; var KEY_Y = "121,121"; var KEY_U = "117,117"; var KEY_I = "105,105"; var KEY_O = "111,111"; var KEY_P = "112,112"; var KEY_QQ = "81,81!"; var KEY_WW = "87,87!"; var KEY_EE = "69,69!"; var KEY_RR = "82,82!"; var KEY_TT = "84,84!"; var KEY_YY = "89,89!"; var KEY_UU = "85,85!"; var KEY_II = "73,73!"; var KEY_OO = "79,79!"; var KEY_PP = "80,80!"; var KEY_A = "97,97"; var KEY_S = "115,115"; var KEY_D = "100,100"; var KEY_F = "102,102"; var KEY_G = "103,103"; var KEY_H = "104,104"; var KEY_J = "106,106"; var KEY_K = "107,107"; var KEY_L = "108,108"; var KEY_AA = "65,65!"; var KEY_SS = "83,83!"; var KEY_DD = "68,68!"; var KEY_FF = "70,70!"; var KEY_GG = "71,71!"; var KEY_HH = "72,72!"; var KEY_JJ = "74,74!"; var KEY_KK = "75,75!"; var KEY_LL = "76,76!"; var KEY_Z = "122,122"; var KEY_X = "120,120"; var KEY_C = "99,99"; var KEY_V = "118,118"; var KEY_B = "98,98"; var KEY_N = "110,110"; var KEY_M = "109,109"; var KEY_ZZ = "90,90!"; var KEY_XX = "88,88!"; var KEY_CC = "67,67!"; var KEY_VV = "86,86!"; var KEY_BB = "66,66!"; var KEY_NN = "78,78!"; var KEY_MM = "77,77!"; var KEY_1 = "49,49"; var KEY_2 = "50,50"; var KEY_3 = "51,51"; var KEY_4 = "52,52"; var KEY_5 = "53,53"; var KEY_6 = "54,54"; var KEY_7 = "55,55"; var KEY_8 = "56,56"; var KEY_9 = "57,57"; var KEY_0 = "48,48"; var KEY_BANG = "33,33!"; var KEY_AT = "64,64!"; var KEY_HASH = "35,35!"; var KEY_DOLLAR = "36,36!"; var KEY_MOD = "37,37!"; var KEY_CARET = "94,94!"; var KEY_AMP = "38,38!"; var KEY_AST = "42,42!"; var KEY_LPAR = "40,40!"; var KEY_RPAR = "41,41!"; var KEY_MINUS = "45,45"; var KEY_UNDER = "95,95!"; var KEY_PLUS = "43,43!"; var KEY_EQ = "61,61"; var KEY_LBRACE = "123,123!"; var KEY_RBRACE = "125,125!"; var KEY_LBRACK = "91,91"; var KEY_RBRACK = "93,93"; var KEY_PIPE = "124,124!"; var KEY_SLASH = "92,92"; var KEY_COLON = "186,186!"; var KEY_SEMI = "186,186"; var KEY_QUOTE = "34,34!"; var KEY_APOS = "39,39"; var KEY_BSLASH = "47,47"; var KEY_QUEST = "63,63!"; var KEY_COMMA = "44,44"; var KEY_DOT = "46,46"; var KEY_TILDE = "126,126!"; var KEY_TICK = "96,96"; var KEY_LT = "60,60!"; var KEY_GT = "62,62!"; var KEY_LEFT = "37,37"; var KEY_UP = "38,38"; var KEY_RIGHT = "39,39"; var KEY_DOWN = "40,40"; """ def keyboard_saf_win(): return """ var KEY_SHIFT = "16,16!"; var KEY_CTRL = "17,17"; var KEY_ALT = "18,18"; var KEY_ESC = "27,27"; var KEY_HOME = "36,36"; var KEY_END = "35,35"; var KEY_PGUP = "33,33"; var KEY_PGDN = "34,34"; var KEY_BKSPC = "8,8"; var KEY_SPC = "32,32"; var KEY_ENTER = "13,13"; var KEY_RETURN = "13,13"; var KEY_TAB = "9,9"; var KEY_Q = "113,113"; var KEY_W = "119,119"; var KEY_E = "101,101"; var KEY_R = "114,114"; var KEY_T = "116,116"; var KEY_Y = "121,121"; var KEY_U = "117,117"; var KEY_I = "105,105"; var KEY_O = "111,111"; var KEY_P = "112,112"; var KEY_QQ = "81,81!"; var KEY_WW = "87,87!"; var KEY_EE = "69,69!"; var KEY_RR = "82,82!"; var KEY_TT = "84,84!"; var KEY_YY = "89,89!"; var KEY_UU = "85,85!"; var KEY_II = "73,73!"; var KEY_OO = "79,79!"; var KEY_PP = "80,80!"; var KEY_A = "97,97"; var KEY_S = "115,115"; var KEY_D = "100,100"; var KEY_F = "102,102"; var KEY_G = "103,103"; var KEY_H = "104,104"; var KEY_J = "106,106"; var KEY_K = "107,107"; var KEY_L = "108,108"; var KEY_AA = "65,65!"; var KEY_SS = "83,83!"; var KEY_DD = "68,68!"; var KEY_DD = "68,68!"; var KEY_GG = "71,71!"; var KEY_HH = "72,72!"; var KEY_JJ = "74,74!"; var KEY_KK = "75,75!"; var KEY_LL = "76,76!"; var KEY_Z = "122,122"; var KEY_X = "120,120"; var KEY_C = "99,99"; var KEY_V = "118,118"; var KEY_B = "98,98"; var KEY_N = "110,110"; var KEY_M = "109,109"; var KEY_ZZ = "90,90!"; var KEY_XX = "88,88!"; var KEY_CC = "67,67!"; var KEY_VV = "86,86!"; var KEY_BB = "66,66!"; var KEY_NN = "78,78!"; var KEY_MM = "77,77!"; var KEY_1 = "49,49"; var KEY_2 = "50,50"; var KEY_3 = "51,51"; var KEY_4 = "52,52"; var KEY_5 = "53,53"; var KEY_6 = "54,54"; var KEY_7 = "55,55"; var KEY_8 = "56,56"; var KEY_9 = "57,57"; var KEY_0 = "48,48"; var KEY_BANG = "33,33!"; var KEY_AT = "64,64!"; var KEY_HASH = "35,35!"; var KEY_DOLLAR = "36,36!"; var KEY_MOD = "37,37!"; var KEY_CARET = "94,94!"; var KEY_AMP = "38,38!"; var KEY_AST = "42,42!"; var KEY_LPAR = "40,40!"; var KEY_RPAR = "41,41!"; var KEY_MINUS = "45,45"; var KEY_UNDER = "95,95!"; var KEY_PLUS = "43,43!"; var KEY_EQ = "61,61"; var KEY_LBRACE = "123,123!"; var KEY_RBRACE = "125,125!"; var KEY_LBRACK = "91,91"; var KEY_RBRACK = "93,93"; var KEY_PIPE = "124,124!"; var KEY_SLASH = "92,92"; var KEY_COLON = "58,58!"; var KEY_SEMI = "59,59"; var KEY_QUOTE = "34,34!"; var KEY_APOS = "39,39"; var KEY_BSLASH = "47,47"; var KEY_QUEST = "63,63!"; var KEY_COMMA = "44,44"; var KEY_DOT = "46,46"; var KEY_TILDE = "126,126!"; var KEY_TICK = "96,96"; var KEY_LT = "60,60!"; var KEY_GT = "62,62!"; var KEY_LEFT = "37,37"; var KEY_UP = "38,38"; var KEY_RIGHT = "39,39"; var KEY_DOWN = "40,40"; """ # These are the same as of 12 August 2009. def keyboard_chr_win(): return keyboard_saf_win() def keyboard_chr_lin(): return """ var KEY_SHIFT = "16,16"; var KEY_CTRL = "17,17"; var KEY_ALT = "18,18"; var KEY_ESC = "27,27"; var KEY_HOME = "36,36"; var KEY_END = "35,35"; var KEY_PGUP = "33,33"; var KEY_PGDN = "34,34"; var KEY_BKSPC = "8,8"; var KEY_SPC = "32,32"; var KEY_ENTER = "13,13"; var KEY_RETURN = "13,13"; var KEY_TAB = "9,9"; var KEY_Q = "113,113"; var KEY_W = "119,119"; var KEY_E = "101,101"; var KEY_R = "114,114"; var KEY_T = "116,116"; var KEY_Y = "121,121"; var KEY_U = "117,117"; var KEY_I = "105,105"; var KEY_O = "111,111"; var KEY_P = "112,112"; var KEY_QQ = "81,81!"; var KEY_WW = "87,87!"; var KEY_EE = "69,69!"; var KEY_RR = "82,82!"; var KEY_TT = "84,84!"; var KEY_YY = "89,89!"; var KEY_UU = "85,85!"; var KEY_II = "73,73!"; var KEY_OO = "79,79!"; var KEY_PP = "80,80!"; var KEY_A = "97,97"; var KEY_S = "115,115"; var KEY_D = "100,100"; var KEY_F = "102,102"; var KEY_G = "103,103"; var KEY_H = "104,104"; var KEY_J = "106,106"; var KEY_K = "107,107"; var KEY_L = "108,108"; var KEY_AA = "65,65!"; var KEY_SS = "83,83!"; var KEY_DD = "68,68!"; var KEY_DD = "68,68!"; var KEY_GG = "71,71!"; var KEY_HH = "72,72!"; var KEY_JJ = "74,74!"; var KEY_KK = "75,75!"; var KEY_LL = "76,76!"; var KEY_Z = "122,122"; var KEY_X = "120,120"; var KEY_C = "99,99"; var KEY_V = "118,118"; var KEY_B = "98,98"; var KEY_N = "110,110"; var KEY_M = "109,109"; var KEY_ZZ = "90,90!"; var KEY_XX = "88,88!"; var KEY_CC = "67,67!"; var KEY_VV = "86,86!"; var KEY_BB = "66,66!"; var KEY_NN = "78,78!"; var KEY_MM = "77,77!"; var KEY_1 = "49,49"; var KEY_2 = "50,50"; var KEY_3 = "51,51"; var KEY_4 = "52,52"; var KEY_5 = "53,53"; var KEY_6 = "54,54"; var KEY_7 = "55,55"; var KEY_8 = "56,56"; var KEY_9 = "57,57"; var KEY_0 = "48,48"; var KEY_BANG = "33,33!"; var KEY_AT = "64,64!"; var KEY_HASH = "35,35!"; var KEY_DOLLAR = "36,36!"; var KEY_MOD = "37,37!"; var KEY_CARET = "94,94!"; var KEY_AMP = "38,38!"; var KEY_AST = "42,42!"; var KEY_LPAR = "40,40!"; var KEY_RPAR = "41,41!"; var KEY_MINUS = "45,45"; var KEY_UNDER = "95,95!"; var KEY_PLUS = "43,43!"; var KEY_EQ = "61,61"; var KEY_LBRACE = "123,123!"; var KEY_RBRACE = "125,125!"; var KEY_LBRACK = "91,91"; var KEY_RBRACK = "93,93"; var KEY_PIPE = "124,124!"; var KEY_SLASH = "92,92"; var KEY_COLON = "58,58!"; var KEY_SEMI = "59,59"; var KEY_QUOTE = "34,34!"; var KEY_APOS = "39,39"; var KEY_BSLASH = "47,47"; var KEY_QUEST = "63,63!"; var KEY_COMMA = "44,44"; var KEY_DOT = "46,46"; var KEY_TILDE = "126,126!"; var KEY_TICK = "96,96"; var KEY_LT = "60,60!"; var KEY_GT = "62,62!"; var KEY_LEFT = "37,37"; var KEY_UP = "38,38"; var KEY_RIGHT = "39,39"; var KEY_DOWN = "40,40"; """ def keyboard_konq(): return """ var KEY_SHIFT = "16,16"; var KEY_CTRL = "20,20"; var KEY_ALT = "18,18"; var KEY_ESC = "27,27"; var KEY_HOME = "36,36"; var KEY_END = "35,35"; var KEY_PGUP = "33,33"; var KEY_PGDN = "34,34"; var KEY_BKSPC = "8,8"; var KEY_SPC = "32,32"; var KEY_ENTER = "13,13"; var KEY_RETURN = "13,13"; var KEY_TAB = "9,9"; var KEY_Q = "113,113"; var KEY_W = "119,119"; var KEY_E = "101,101"; var KEY_R = "114,114"; var KEY_T = "116,116"; var KEY_Y = "121,121"; var KEY_U = "117,117"; var KEY_I = "105,105"; var KEY_O = "111,111"; var KEY_P = "112,112"; var KEY_QQ = "81,81!"; var KEY_WW = "87,87!"; var KEY_EE = "69,69!"; var KEY_RR = "82,82!"; var KEY_TT = "84,84!"; var KEY_YY = "89,89!"; var KEY_UU = "85,85!"; var KEY_II = "73,73!"; var KEY_OO = "79,79!"; var KEY_PP = "80,80!"; var KEY_A = "97,97"; var KEY_S = "115,115"; var KEY_D = "100,100"; var KEY_F = "102,102"; var KEY_G = "103,103"; var KEY_H = "104,104"; var KEY_J = "106,106"; var KEY_K = "107,107"; var KEY_L = "108,108"; var KEY_AA = "65,65!"; var KEY_SS = "83,83!"; var KEY_DD = "68,68!"; var KEY_FF = "70,70!"; var KEY_GG = "71,71!"; var KEY_HH = "72,72!"; var KEY_JJ = "74,74!"; var KEY_KK = "75,75!"; var KEY_LL = "76,76!"; var KEY_Z = "122,122"; var KEY_X = "120,120"; var KEY_C = "99,99"; var KEY_V = "118,118"; var KEY_B = "98,98"; var KEY_N = "110,110"; var KEY_M = "109,109"; var KEY_ZZ = "90,90!"; var KEY_XX = "88,88!"; var KEY_CC = "67,67!"; var KEY_VV = "86,86!"; var KEY_BB = "66,66!"; var KEY_NN = "78,78!"; var KEY_MM = "77,77!"; var KEY_1 = "49,49"; var KEY_2 = "50,50"; var KEY_3 = "51,51"; var KEY_4 = "52,52"; var KEY_5 = "53,53"; var KEY_6 = "54,54"; var KEY_7 = "55,55"; var KEY_8 = "56,56"; var KEY_9 = "57,57"; var KEY_0 = "48,48"; var KEY_BANG = "33,33!"; var KEY_AT = "64,64!"; var KEY_HASH = "35,35!"; var KEY_DOLLAR = "36,36!"; var KEY_MOD = "37,37!"; var KEY_CARET = "94,94!"; var KEY_AMP = "38,38!"; var KEY_AST = "42,42!"; var KEY_LPAR = "40,40!"; var KEY_RPAR = "41,41!"; var KEY_MINUS = "45,45"; var KEY_UNDER = "95,95!"; var KEY_PLUS = "43,43!"; var KEY_EQ = "61,61"; var KEY_LBRACE = "123,123!"; var KEY_RBRACE = "125,125!"; var KEY_LBRACK = "91,91"; var KEY_RBRACK = "93,93"; var KEY_PIPE = "124,124!"; var KEY_SLASH = "92,92"; var KEY_COLON = "58,58!"; var KEY_SEMI = "59,59"; var KEY_QUOTE = "34,34!"; var KEY_APOS = "39,39"; var KEY_BSLASH = "47,47"; var KEY_QUEST = "63,63!"; var KEY_COMMA = "44,44"; var KEY_DOT = "46,46"; var KEY_TILDE = "126,126!"; var KEY_TICK = "96,96"; var KEY_LT = "60,60!"; var KEY_GT = "62,62!"; var KEY_LEFT = "37,37"; var KEY_UP = "38,38"; var KEY_RIGHT = "39,39"; var KEY_DOWN = "40,40"; """ def keyboard_ie(): return """ var KEY_SHIFT = "16,undefined!"; var KEY_CTRL = "20,undefined"; var KEY_ALT = "18,undefined"; var KEY_ESC = "27,undefined"; var KEY_HOME = "36,undefined"; var KEY_END = "35,undefined"; var KEY_PGUP = "33,undefined"; var KEY_PGDN = "34,undefined"; var KEY_BKSPC = "8,undefined"; var KEY_SPC = "32,undefined"; var KEY_ENTER = "13,undefined"; var KEY_RETURN = "13,undefined"; var KEY_TAB = "9,undefined"; var KEY_Q = "81,undefined"; var KEY_W = "87,undefined"; var KEY_E = "69,undefined"; var KEY_R = "82,undefined"; var KEY_T = "84,undefined"; var KEY_Y = "89,undefined"; var KEY_U = "85,undefined"; var KEY_I = "73,undefined"; var KEY_O = "79,undefined"; var KEY_P = "80,undefined"; var KEY_QQ = "81,undefined!"; var KEY_WW = "87,undefined!"; var KEY_EE = "69,undefined!"; var KEY_RR = "82,undefined!"; var KEY_TT = "84,undefined!"; var KEY_YY = "89,undefined!"; var KEY_UU = "85,undefined!"; var KEY_II = "73,undefined!"; var KEY_OO = "79,undefined!"; var KEY_PP = "80,undefined!"; var KEY_A = "65,undefined"; var KEY_S = "83,undefined"; var KEY_D = "68,undefined"; var KEY_F = "70,undefined"; var KEY_G = "71,undefined"; var KEY_H = "72,undefined"; var KEY_J = "74,undefined"; var KEY_K = "75,undefined"; var KEY_L = "76,undefined"; var KEY_AA = "65,undefined!"; var KEY_SS = "83,undefined!"; var KEY_DD = "68,undefined!"; var KEY_FF = "70,undefined!"; var KEY_GG = "71,undefined!"; var KEY_HH = "72,undefined!"; var KEY_JJ = "74,undefined!"; var KEY_KK = "75,undefined!"; var KEY_LL = "76,undefined!"; var KEY_Z = "90,undefined"; var KEY_X = "88,undefined"; var KEY_C = "67,undefined"; var KEY_V = "86,undefined"; var KEY_B = "66,undefined"; var KEY_N = "78,undefined"; var KEY_M = "77,undefined"; var KEY_ZZ = "90,undefined!"; var KEY_XX = "88,undefined!"; var KEY_CC = "67,undefined!"; var KEY_VV = "86,undefined!"; var KEY_BB = "66,undefined!"; var KEY_NN = "78,undefined!"; var KEY_MM = "77,undefined!"; var KEY_1 = "49,undefined"; var KEY_2 = "50,undefined"; var KEY_3 = "51,undefined"; var KEY_4 = "52,undefined"; var KEY_5 = "53,undefined"; var KEY_6 = "54,undefined"; var KEY_7 = "55,undefined"; var KEY_8 = "56,undefined"; var KEY_9 = "57,undefined"; var KEY_0 = "48,undefined"; var KEY_BANG = "49,undefined!"; var KEY_AT = "50,undefined!"; var KEY_HASH = "51,undefined!"; var KEY_DOLLAR = "52,undefined!"; var KEY_MOD = "53,undefined!"; var KEY_CARET = "54,undefined!"; var KEY_AMP = "55,undefined!"; var KEY_AST = "56,undefined!"; var KEY_LPAR = "57,undefined!"; var KEY_RPAR = "48,undefined!"; var KEY_MINUS = "189,undefined"; var KEY_UNDER = "189,undefined!"; var KEY_PLUS = "187,undefined!"; var KEY_EQ = "187,undefined"; var KEY_LBRACE = "219,undefined!"; var KEY_RBRACE = "221,undefined!"; var KEY_LBRACK = "219,undefined"; var KEY_RBRACK = "221,undefined"; var KEY_PIPE = "220,undefined!"; var KEY_SLASH = "220,undefined"; var KEY_COLON = "186,undefined!"; var KEY_SEMI = "186,undefined"; var KEY_QUOTE = "222,undefined!"; var KEY_APOS = "222,undefined"; var KEY_BSLASH = "191,undefined"; var KEY_QUEST = "191,undefined!"; var KEY_COMMA = "188,undefined"; var KEY_DOT = "190,undefined"; var KEY_TILDE = "192,undefined!"; var KEY_TICK = "192,undefined"; var KEY_LT = "188,undefined!"; var KEY_GT = "190,undefined!"; var KEY_LEFT = "37,undefined"; var KEY_UP = "38,undefined"; var KEY_RIGHT = "39,undefined"; var KEY_DOWN = "40,undefined"; """ # Define mapping from 2-letter OS/Browser codes to the # functions defined above. # Note: The notebook identifies Chrome on Windows and Chromium on # Linux as Safari, so we use 's' instead of 'c'. keyboard_map = {'mw':keyboard_moz_win, 'ml':keyboard_moz_lin, 'mm':keyboard_moz_mac, 'ow':keyboard_op_win, 'ol':keyboard_op_lin, 'om':keyboard_op_mac, 'sw':keyboard_saf_win, 'sm':keyboard_saf_mac, 'sl':keyboard_chr_lin, 'kl':keyboard_konq, 'iw':keyboard_ie} sagenb-1.0.1/sagenb/notebook/mailsender.py000066400000000000000000000101341311436262400205250ustar00rootroot00000000000000# -*- coding: utf-8 -* """nodoctest """ ############################################################################# # Copyright (C) 2007 William Stein # Distributed under the terms of the GNU General Public License (GPL) # The full text of the GPL is available at: # http://www.gnu.org/licenses/ ############################################################################# from twisted.application import service from twisted.application import internet from twisted.internet import protocol from twisted.mail import smtp, relaymanager from six import StringIO from email.MIMEBase import MIMEBase from email.MIMEMultipart import MIMEMultipart from email import Encoders import mimetypes class MailMessage(MIMEMultipart): """ Represents an email's data. """ def __init__(self, fromaddr, toaddr, subject, body): MIMEMultipart.__init__(self) self['From'] = fromaddr self['To'] = toaddr self['Subject'] = subject text_part = MIMEBase('text', 'plain') text_part.set_payload(body) self.attach(text_part) # Make an instance of this class if you need to send an email class SMTPInput: """ A message to be sent off to an SMTP server. INPUT: mail_from -- the SMTP MAIL FROM: ... rcpt -- the SMTP RCPT TO: ... data -- the entire message. This should be a StringIO object. identity -- the SMTP HELO identity. For some SMTP servers, the Sage email sender's IP must resolve to this address. secret -- Dunno? """ def __init__(self, mail_from, rcpt, data, identity, secret=None): self._mail_from = mail_from self._rcpt = rcpt self._id = identity self._data = data self._secret = secret self._factory = SMTPClientFactory(self) # the server that we will deliver the mail to try: self._rcpt_domain = [(r.split('@'))[1] for r in rcpt] except ValueError: raise ValueError("mal-formed recipient email address") print(self._rcpt_domain) def exchange_mail(self, exchange): smtp_client = internet.TCPClient(exchange, 25, self._factory) smtp_client.setServiceParent(self._app) def get_mx(self, host): on_found_record = lambda rec: str(rec.name) # return a deffered that will call on_found_record when it's done. # on_found_record's return value gets passed to exchange_mail return relaymanager.MXCalculator().getMX(host).addCallback(on_found_record) def run_from(self, app): self._app = app self.get_mx(self._rcpt_domain[0]).addCallback(self.exchange_mail) class MailClient(smtp.ESMTPClient): def __init__(self, mesg, **kwds): smtp.ESMTPClient.__init__(self,**kwds) self._mesg = mesg # these are all overridden from the super class, and called by Twisted to do # the real work getMailFrom = lambda self: self._mesg._mail_from getMailTo = lambda self: self._mesg._rcpt def getMailData(self): return StringIO(self._mesg._data) def sentMail(self, code, resp, numOk, addresses, log): print('<< dest SMTP server >> %s: %s' % (code, resp)) print('Sent %s messages.' % numOk) from twisted.internet import reactor reactor.stop() class SMTPClientFactory(protocol.ClientFactory): def __init__(self, mesg): self._mesg = mesg self._protocol = MailClient def buildProtocol(self, addr): mesg = self._mesg return self._protocol(mesg, secret=mesg._secret, identity=mesg._id) application = service.Application("SAGE SMTP Client") _from = "moretti@u.math.washington.edu" _to = ["wstein@gmail.com"] _id = "sage.math.washington.edu" subject = "Progress" body = \ """ William, I'm sending this to you from Twisted. I think I'm ready to try to plug this in from SAGE, as soon as Yi has the login stuff working (which he almost does.) ~Bobby """ data = MailMessage(_from, _to[0], subject, body) m = SMTPInput(_from, _to, data.as_string(unixfrom=False), _id) m.run_from(application) sagenb-1.0.1/sagenb/notebook/misc.py000066400000000000000000000167101311436262400173430ustar00rootroot00000000000000# -*- coding: utf-8 -* """ Miscellaneus functions used by the Sage Notebook """ ##################################################### ## Global variables across the application ##################################################### notebook = None DIR = None ##################################################### ## Utility functions ##################################################### import re valid_username_chars = 'a-z|A-Z|0-9|_|.|@' re_valid_username = re.compile('[%s]*' % valid_username_chars) def is_valid_username(username): r""" Returns whether a candidate username is valid. It must contain between 3 and 65 of these characters: letters, numbers, underscores, @, and/or dots ('.'). INPUT: - ``username`` - a string; the candidate username OUTPUT: - a boolean EXAMPLES:: sage: from sagenb.notebook.misc import is_valid_username sage: is_valid_username('mark10') True sage: is_valid_username('10mark') False sage: is_valid_username('me') False sage: is_valid_username('abcde' * 13) False sage: is_valid_username('David Andrews') False sage: is_valid_username('David M. Andrews') False sage: is_valid_username('sarah_andrews') True sage: is_valid_username('TA-1') False sage: is_valid_username('math125-TA') False sage: is_valid_username('dandrews@sagemath.org') True """ import string if not (len(username) > 2 and len(username) < 65): return False if not username[0] in string.letters: return False m = re_valid_username.match(username) return m.start() == 0 and m.end() == len(username) def is_valid_password(password, username): r""" Return True if and only if ``password`` is valid, i.e., is between 4 and 32 characters long, doesn't contain space(s), and doesn't contain ``username``. EXAMPLES:: sage: from sagenb.notebook.misc import is_valid_password sage: is_valid_password('uip@un7!', None) True sage: is_valid_password('markusup89', None) True sage: is_valid_password('8u7', None) False sage: is_valid_password('fUmDagaz8LmtonAowjSe0Pvu9C5Gvr6eKcC6wsAT', None) True sage: is_valid_password('rrcF !u78!', None) False sage: is_valid_password('markusup89', 'markus') False """ import string if len(password) < 4 or ' ' in password: return False if username: if string.lower(username) in string.lower(password): return False return True def do_passwords_match(pass1, pass2): """ EXAMPLES:: sage: from sagenb.notebook.misc import do_passwords_match sage: do_passwords_match('momcat', 'mothercat') False sage: do_passwords_match('mothercat', 'mothercat') True """ return pass1 == pass2 re_valid_email = re.compile(r""" ^%(unquoted)s+(\.%(unquoted)s+)* # unquoted local-part @ # at ([a-z0-9]([a-z0-9-]*[a-z0-9])?\.)+ # subdomains can't start or end with - [a-z]+$ # top-level domain is at least 1 char """ % {'unquoted': r"[a-z0-9!#$%&'*+\-/=?^_`{|}~]"}, re.IGNORECASE | re.VERBOSE) def is_valid_email(email): """ Validates an email address. The implemention here is short, but it should cover the more common forms. In particular, it allows "plus addresses," e.g., first.last+label@gmail.com But it rejects several other classes, including those with comments, quoted local-parts, and/or IP address domains. For more information, please see `RFC 3696`_, `RFC 5322`_, and their errata. .. _RFC 3696: http://tools.ietf.org/html/rfc3696#section-3 .. _RFC 5322: http://tools.ietf.org/html/rfc5322#section-3.4.1 INPUT: - ``email`` - string; the address to validate OUTPUT: - a boolean; whether the address is valid, according to simplistic but widely used criteria EXAMPLES:: sage: from sagenb.notebook.misc import is_valid_email sage: is_valid_email('joe@washinton.gov') True sage: is_valid_email('joe.washington.gov') # missing @ False sage: is_valid_email('foo+plus@gmail.com') True sage: is_valid_email('foo++@gmail.com') True sage: is_valid_email('foo+bar+baz@gmail.com') True sage: is_valid_email('+plus@something.org') True sage: is_valid_email('hyphens-are-okay@example.ab.cd') True sage: is_valid_email('onlytld@com') # missing subdomain False sage: is_valid_email("we..are@the.borg") # consecutive dots not allowed False sage: is_valid_email("abcd@[12.34.56.78]") # legal, really False sage: is_valid_email("x@y.z") # legal but too short False sage: is_valid_email('"i c@nt"@do.it') # legal, really False sage: is_valid_email(65 * 'a' + '@lim.sup') # username too long False sage: is_valid_email(32 * '@..@.][.' + '!') # too long, ... False """ if 7 < len(email) < 257: if re_valid_email.match(email) is None: return False # TODO: If/when we permit *quoted* local-parts, account for # legal additional @'s, e.g., "foo@bar"@bar.foo if len(email.split('@')[0]) > 64: return False return True return False try: # simplejson is faster, so try to import it first import simplejson as json except ImportError: import json def encode_response(obj, separators=(',', ':'), **kwargs): """ Encodes response data to send to a client. The current implementation uses JSON. See :mod:`json` for details. INPUT: - ``obj`` - an object comprised of basic Python types - ``separators`` - a string 2-tuple (default: (',', ':')); dictionary separators to use - ``kwargs`` - additional keyword arguments to pass to the encoding function OUTPUT: - a string EXAMPLES:: sage: from sagenb.notebook.misc import encode_response sage: o = [int(3), float(2), {'foo': 'bar'}, None] sage: encode_response(o) '[3,2.0,{"foo":"bar"},null]' sage: d = {'AR': 'MA', int(11): 'foo', 'bar': float(1.0), None: 'blah'} sage: encode_response(d, sort_keys = True) '{"null":"blah","11":"foo","AR":"MA","bar":1.0}' sage: d['archies'] = ['an', 'mon', 'hier'] sage: d['sub'] = {'shape': 'triangle', 'color': 'blue', 'sides': [int(3), int(4), int(5)]} sage: encode_response(d, sort_keys = True) '{"null":"blah","11":"foo","AR":"MA","archies":["an","mon","hier"],"bar":1.0,"sub":{"color":"blue","shape":"triangle","sides":[3,4,5]}}' sage: print(encode_response(d, separators = (', ', ': '), indent = 4)) { "...": ... } """ # TODO: Serialize class attributes, so we can do, e.g., r_dict.foo # = 'bar' instead of r_dict['foo'] = 'bar' below. # TODO: Use cjson, simplejson instead? Serialize Sage types, # e.g., Integer, RealLiteral? return json.dumps(obj, separators = separators, **kwargs) def extract_title(html_page, username=None): h = html_page.lower() i = h.find('') if i == -1: return _("Untitled", username) j = h.find('') return html_page[i + len('') : j] ��������������������������������������������������������sagenb-1.0.1/sagenb/notebook/notebook.py������������������������������������������������������������0000664�0000000�0000000�00000221330�13114362624�0020224�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# -*- coding: utf-8 -* """ The Sage Notebook AUTHORS: - William Stein """ ############################################################################# # # Copyright (C) 2006-2009 William Stein <wstein@gmail.com> # Distributed under the terms of the GNU General Public License (GPL) # The full text of the GPL is available at: # http://www.gnu.org/licenses/ # ############################################################################# from __future__ import print_function, absolute_import # For debugging sometimes it is handy to use only the reference implementation. USE_REFERENCE_WORKSHEET_PROCESSES = False # System libraries import os import random import re import shutil import socket import time import bz2 from cgi import escape try: import cPickle as pickle except ImportError: import pickle from six import iteritems # Sage libraries from sagenb.misc.misc import (pad_zeros, cputime, tmp_dir, load, save, ignore_nonexistent_files, unicode_str) # Sage Notebook from . import css # style from . import js # javascript from . import worksheet # individual worksheets (which make up a notebook) from . import config # internal configuration stuff (currently, just keycodes) from . import keyboards # keyboard layouts from . import server_conf # server configuration from . import user_conf # user configuration from . import user # users from .template import template, prettify_time_ago from flask.ext.babel import gettext, lazy_gettext try: # sage is installed import sage # [(string: name, bool: optional)] SYSTEMS = [('sage', False), ('gap', False), ('gp', False), ('html', False), ('latex', False), ('maxima', False), ('python', False), ('r', False), ('sh', False), ('singular', False), ('axiom', True), ('fricas', True), ('kash', True), ('macaulay2', True), ('magma', True), ('maple', True,), ('mathematica', True), ('matlab', True), ('mupad', True), ('octave', True), ('scilab', True)] except ImportError: # sage is not installed SYSTEMS = [('sage', True)] # but gracefully degenerated version of sage mode, e.g., preparsing is trivial # We also record the system names without (optional) since they are # used in some of the html menus, etc. SYSTEM_NAMES = [v[0] for v in SYSTEMS] MATHJAX = True JEDITABLE_TINYMCE = True class WorksheetDict(dict): def __init__(self, notebook, *args, **kwds): self.notebook = notebook self.storage = notebook._Notebook__storage dict.__init__(self, *args, **kwds) def __getitem__(self, item): if item in self: return dict.__getitem__(self, item) try: if '/' not in item: raise KeyError(item) except TypeError: raise KeyError(item) username, id = item.split('/') try: id=int(id) except ValueError: raise KeyError(item) try: worksheet = self.storage.load_worksheet(username, id) except ValueError: raise KeyError(item) dict.__setitem__(self, item, worksheet) return worksheet class Notebook(object): HISTORY_MAX_OUTPUT = 92*5 HISTORY_NCOLS = 90 def __init__(self, dir, user_manager = None): if isinstance(dir, basestring) and len(dir) > 0 and dir[-1] == "/": dir = dir[:-1] if not dir.endswith('.sagenb'): raise ValueError("dir (=%s) must end with '.sagenb'" % dir) self._dir = dir # For now we only support the FilesystemDatastore storage # backend. from sagenb.storage import FilesystemDatastore S = FilesystemDatastore(dir) self.__storage = S # Now set the configuration, loaded from the datastore. try: self.__conf = S.load_server_conf() except IOError: # Worksheet has never been saved before, so the server conf doesn't exist. self.__worksheets = WorksheetDict(self) from sagenb.notebook.user_manager import SimpleUserManager, OpenIDUserManager self._user_manager = OpenIDUserManager(conf=self.conf()) if user_manager is None else user_manager # Set up email notification logger import logging from sagenb.notebook.notification import logger, TwistedEmailHandler logger.addHandler(TwistedEmailHandler(self.conf(), logging.ERROR)) # also log to stderr logger.addHandler(logging.StreamHandler()) # Set the list of users try: S.load_users(self._user_manager) except IOError: pass # Set the list of worksheets W = WorksheetDict(self) self.__worksheets = W # Store / Refresh public worksheets for id_number in os.listdir(self.__storage._abspath(self.__storage._user_path("pub"))): if id_number.isdigit(): a = "pub/"+str(id_number) if a not in self.__worksheets: try: self.__worksheets[a] = self.__storage.load_worksheet("pub",int(id_number)) except Exception: import traceback print("Warning: problem loading %s/%s: %s" % ("pub", int(id_number), traceback.format_exc())) # Set the openid-user dict try: self._user_manager.load(S) except IOError: pass def delete(self): """ Delete all files related to this notebook. This is used for doctesting mainly. This command is obviously *VERY* dangerous to use on a notebook you actually care about. You could easily lose all data. EXAMPLES:: sage: tmp = tmp_dir(ext='.sagenb') sage: nb = sagenb.notebook.notebook.Notebook(tmp) sage: sorted(os.listdir(tmp)) ['home'] sage: nb.delete() Now the directory is gone.:: sage: os.listdir(tmp) Traceback (most recent call last): ... OSError: [Errno 2] No such file or directory: '... """ self.__storage.delete() def systems(self, username=None): systems = [] for system in SYSTEMS: if system[1]: systems.append(system[0] + ' (' + lazy_gettext('optional') + ')') else: systems.append(system[0]) return systems def system_names(self): return SYSTEM_NAMES def user_manager(self): """ Returns self's UserManager object. EXAMPLES:: sage: n = sagenb.notebook.notebook.Notebook(tmp_dir(ext='.sagenb')) sage: n.user_manager() <sagenb.notebook.user_manager.OpenIDUserManager object at 0x...> """ return self._user_manager ########################################################## # Users ########################################################## def create_default_users(self, passwd): """ Create the default users for a notebook. INPUT: - ``passwd`` - a string EXAMPLES:: sage: from six import iteritems sage: nb = sagenb.notebook.notebook.Notebook(tmp_dir(ext='.sagenb')) sage: nb.create_default_users('password') sage: sorted(list(iteritems(nb.user_manager().users()))) [('_sage_', _sage_), ('admin', admin), ('guest', guest), ('pub', pub)] sage: sorted(list(iteritems(nb.user_manager().passwords()))) #random [('_sage_', ''), ('admin', ''), ('guest', ''), ('pub', '')] sage: nb.create_default_users('newpassword') WARNING: User 'pub' already exists -- and is now being replaced. WARNING: User '_sage_' already exists -- and is now being replaced. WARNING: User 'guest' already exists -- and is now being replaced. WARNING: User 'admin' already exists -- and is now being replaced. sage: sorted(list(iteritems(nb.user_manager().passwords()))) #random [('_sage_', ''), ('admin', ''), ('guest', ''), ('pub', '')] sage: len(list(iteritems(nb.user_manager().passwords()))) 4 """ self.user_manager().create_default_users(passwd) def user(self, username): """ Return an instance of the User class given the ``username`` of a user in a notebook. INPUT: - ``username`` - a string OUTPUT: - an instance of User EXAMPLES:: sage: nb = sagenb.notebook.notebook.Notebook(tmp_dir(ext='.sagenb')) sage: nb.user_manager().create_default_users('password') sage: nb.user('admin') admin sage: nb.user('admin').get_email() '' sage: nb.user('admin').password() #random '256$7998210096323979f76e9fedaf1f85bda1561c479ae732f9c1f1abab1291b0b9$373f16b9d5fab80b9a9012af26a6b2d52d92b6d4b64c1836562cbd4264a6e704' """ return self.user_manager().user(username) def valid_login_names(self): """ Return a list of users that can log in. OUTPUT: - a list of strings EXAMPLES:: sage: nb = sagenb.notebook.notebook.Notebook(tmp_dir(ext='.sagenb')) sage: nb.create_default_users('password') sage: nb.valid_login_names() ['admin'] sage: nb.user_manager().add_user('Mark', 'password', '', force=True) sage: nb.user_manager().add_user('Sarah', 'password', '', force=True) sage: nb.user_manager().add_user('David', 'password', '', force=True) sage: sorted(nb.valid_login_names()) ['David', 'Mark', 'Sarah', 'admin'] """ return self.user_manager().valid_login_names() def readonly_user(self, username): """ Returns True if the user is supposed to only be a read-only user. """ return self.__storage.readonly_user(username) ########################################################## # Publishing worksheets ########################################################## def _initialize_worksheet(self, src, W): r""" Initialize a new worksheet from a source worksheet. INPUT: - ``src`` - a Worksheet instance; the source - ``W`` - a new Worksheet instance; the target """ # Note: Each Worksheet method *_directory actually creates a # directory, if it doesn't already exist. # More compact, but significantly less efficient? # shutil.rmtree(W.cells_directory(), ignore_errors=True) # shutil.rmtree(W.data_directory(), ignore_errors=True) # shutil.rmtree(W.snapshots_directory(), ignore_errors=True) # shutil.copytree(src.cells_directory(), W.cells_directory()) # shutil.copytree(src.data_directory(), W.data_directory()) for sub in ['cells', 'data', 'snapshots']: target_dir = os.path.join(W.directory(), sub) if os.path.exists(target_dir): shutil.rmtree(target_dir, ignore_errors=True) # Copy images, data files, etc. for sub in ['cells', 'data']: source_dir = os.path.join(src.directory(), sub) if os.path.exists(source_dir): target_dir = os.path.join(W.directory(), sub) shutil.copytree(source_dir, target_dir) W.edit_save(src.edit_text()) W.save() def pub_worksheets(self): path = self.__storage._abspath(self.__storage._user_path("pub")) v = [] a = "" for id_number in os.listdir(path): if id_number.isdigit(): a = "pub"+"/"+id_number if a in self.__worksheets: v.append(self.__worksheets[a]) else: try: self.__worksheets[a] = self.__storage.load_worksheet("pub", int(id_number)) v.append(self.__worksheets[a]) except Exception: import traceback print("Warning: problem loading %s/%s: %s" % ("pub", id_number, traceback.format_exc())) return v def users_worksheets(self, username): r""" Returns all worksheets owned by `username` """ if username == "pub": return self.pub_worksheets() worksheets = self.__storage.worksheets(username) # if a worksheet has already been loaded in self.__worksheets, return # that instead since worksheets that are already running should be # noted as such return [self.__worksheets[w.filename()] if w.filename() in self.__worksheets else w for w in worksheets] def users_worksheets_view(self, username): r""" Returns all worksheets viewable by `username` """ # Should return worksheets from self.__worksheets if possible worksheets = self.users_worksheets(username) user=self.user_manager().user(username) viewable_worksheets=[self.__storage.load_worksheet(owner, id) for owner,id in user.viewable_worksheets()] # we double-check that we can actually view these worksheets # just in case someone forgets to update the map worksheets.extend([w for w in viewable_worksheets if w.is_viewer(username)]) # if a worksheet has already been loaded in self.__worksheets, return that instead # since worksheets that are already running should be noted as such return [self.__worksheets[w.filename()] if w.filename() in self.__worksheets else w for w in worksheets] def publish_worksheet(self, worksheet, username): r""" Publish a user's worksheet. This creates a new worksheet in the 'pub' directory with the same contents as ``worksheet``. INPUT: - ``worksheet`` - an instance of Worksheet - ``username`` - a string OUTPUT: - a new or existing published instance of Worksheet EXAMPLES:: sage: nb = sagenb.notebook.notebook.load_notebook(tmp_dir(ext='.sagenb')) sage: nb.user_manager().add_user('Mark','password','',force=True) sage: W = nb.new_worksheet_with_title_from_text('First steps', owner='Mark') sage: nb.worksheet_names() ['Mark/0'] sage: nb.create_default_users('password') sage: nb.publish_worksheet(nb.get_worksheet_with_filename('Mark/0'), 'Mark') pub/0: [Cell 1: in=, out=] sage: sorted(nb.worksheet_names()) ['Mark/0', 'pub/0'] """ W = None # Reuse an existing published version for X in self.get_worksheets_with_owner('pub'): if (X.worksheet_that_was_published() == worksheet): W = X # Or create a new one. if W is None: W = self.create_new_worksheet(worksheet.name(), 'pub') # Copy cells, output, data, etc. self._initialize_worksheet(worksheet, W) # Update metadata. W.set_worksheet_that_was_published(worksheet) W.move_to_archive(username) worksheet.set_published_version(W.filename()) W.record_edit(username) W.set_name(worksheet.name()) self.__worksheets[W.filename()] = W W.save() return W ########################################################## # Moving, copying, creating, renaming, and listing worksheets ########################################################## def scratch_worksheet(self): try: return self.__scratch_worksheet except AttributeError: W = self.create_new_worksheet('scratch', '_sage_') self.__scratch_worksheet = W return W def create_new_worksheet(self, worksheet_name, username): if username!='pub' and self.user_manager().user_is_guest(username): raise ValueError("guests cannot create new worksheets") W = self.worksheet(username) W.set_system(self.system(username)) W.set_name(worksheet_name) self.save_worksheet(W) self.__worksheets[W.filename()] = W return W def copy_worksheet(self, ws, owner): W = self.create_new_worksheet('default', owner) self._initialize_worksheet(ws, W) name = "Copy of %s" % ws.name() W.set_name(name) return W def delete_worksheet(self, filename): """ Delete the given worksheet and remove its name from the worksheet list. Raise a KeyError, if it is missing. INPUT: - ``filename`` - a string """ try: W = self.__worksheets[filename] except KeyError: raise KeyError("Attempt to delete missing worksheet '%s'" % filename) W.quit() shutil.rmtree(W.directory(), ignore_errors=False) self.deleted_worksheets()[filename] = W def deleted_worksheets(self): try: return self.__deleted_worksheets except AttributeError: self.__deleted_worksheets = {} return self.__deleted_worksheets def empty_trash(self, username): """ Empty the trash for the given user. INPUT: - ``username`` - a string This empties the trash for the given user and cleans up all files associated with the worksheets that are in the trash. EXAMPLES:: sage: nb = sagenb.notebook.notebook.Notebook(tmp_dir(ext='.sagenb')) sage: nb.user_manager().add_user('sage','sage','sage@sagemath.org',force=True) sage: W = nb.new_worksheet_with_title_from_text('Sage', owner='sage') sage: W._notebook = nb sage: W.move_to_trash('sage') sage: nb.worksheet_names() ['sage/0'] sage: nb.empty_trash('sage') sage: nb.worksheet_names() [] """ X = self.get_worksheets_with_viewer(username) X = [W for W in X if W.is_trashed(username)] for W in X: W.delete_user(username) if W.owner() is None: self.delete_worksheet(W.filename()) def worksheet_names(self): """ Return a list of all the names of worksheets in this notebook. OUTPUT: - a list of strings. EXAMPLES: We make a new notebook with two users and two worksheets, then list their names:: sage: nb = sagenb.notebook.notebook.Notebook(tmp_dir(ext='.sagenb')) sage: nb.user_manager().add_user('sage','sage','sage@sagemath.org',force=True) sage: W = nb.new_worksheet_with_title_from_text('Sage', owner='sage') sage: nb.user_manager().add_user('wstein','sage','wstein@sagemath.org',force=True) sage: W2 = nb.new_worksheet_with_title_from_text('Elliptic Curves', owner='wstein') sage: nb.worksheet_names() ['sage/0', 'wstein/0'] """ W = self.__worksheets.keys() W.sort() return W ########################################################## # Information about the pool of worksheet compute servers ########################################################## def server_pool(self): return self.conf()['server_pool'] def set_server_pool(self, servers): self.conf()['server_pool'] = servers def get_ulimit(self): try: return self.__ulimit except AttributeError: self.__ulimit = '' return '' def set_ulimit(self, ulimit): self.__ulimit = ulimit def get_server(self): P = self.server_pool() if P is None or len(P) == 0: return None try: self.__server_number = (self.__server_number + 1) % len(P) i = self.__server_number except AttributeError: self.__server_number = 0 i = 0 return P[i] def new_worksheet_process(self): """ Return a new worksheet process object with parameters determined by configuration of this notebook server. """ from sagenb.interfaces import (WorksheetProcess_ExpectImplementation, WorksheetProcess_ReferenceImplementation, WorksheetProcess_RemoteExpectImplementation) if USE_REFERENCE_WORKSHEET_PROCESSES: return WorksheetProcess_ReferenceImplementation() ulimit = self.get_ulimit() from sagenb.interfaces import ProcessLimits # We have to parse the ulimit format to our ProcessLimits. # The typical format is. # '-u 400 -v 1000000 -t 3600' # Despite -t being cputime for ulimit, we map it to walltime, # since that is the only thing that really makes sense for a # notebook server. # -u --> max_processes # -v --> max_vmem (but we divide by 1000) # -t -- > max_walltime max_vmem = max_cputime = max_walltime = None tbl = {'v': None, 'u': None, 't': None} for x in ulimit.split('-'): for k in tbl.keys(): if x.startswith(k): tbl[k] = int(x.split()[1].strip()) if tbl['v'] is not None: tbl['v'] = tbl['v'] / 1000.0 process_limits = ProcessLimits(max_vmem=tbl['v'], max_walltime=tbl['t'], max_processes=tbl['u']) server_pool = self.server_pool() if not server_pool or len(server_pool) == 0: return WorksheetProcess_ExpectImplementation(process_limits=process_limits) else: import random user_at_host = random.choice(server_pool) python_command = os.path.join(os.environ['SAGE_ROOT'], 'sage -python') return WorksheetProcess_RemoteExpectImplementation(user_at_host=user_at_host, process_limits=process_limits, remote_python=python_command) def _python_command(self): """ """ try: return self.__python_command except AttributeError: pass ########################################################## # Configuration settings. ########################################################## def system(self, username=None): """ The default math software system for new worksheets for a given user or the whole notebook (if username is None). """ return self.user(username).conf()['default_system'] def pretty_print(self, username=None): """ The default typeset setting for new worksheets for a given user or the whole notebook (if username is None). TODO -- only implemented for the notebook right now """ return self.user(username).conf()['default_pretty_print'] def set_pretty_print(self, pretty_print): self.__pretty_print = pretty_print def color(self): """ The default color scheme for the notebook. """ try: return self.__color except AttributeError: self.__color = 'default' return self.__color def set_color(self, color): self.__color = color ########################################################## # The notebook history. ########################################################## def user_history(self, username): if not hasattr(self, '_user_history'): self._user_history = {} if username in self._user_history: return self._user_history[username] history = [] for hunk in self.__storage.load_user_history(username): hunk = unicode_str(hunk) history.append(hunk) self._user_history[username] = history return history def create_new_worksheet_from_history(self, name, username, maxlen=None): W = self.create_new_worksheet(name, username) W.edit_save('Log Worksheet\n' + self.user_history_text(username, maxlen=None)) return W def user_history_text(self, username, maxlen=None): history = self.user_history(username) if maxlen: history = history[-maxlen:] return '\n\n'.join([hunk.strip() for hunk in history]) def add_to_user_history(self, entry, username): history = self.user_history(username) history.append(entry) maxlen = self.user_manager().user_conf(username)['max_history_length'] while len(history) > maxlen: del history[0] ########################################################## # Importing and exporting worksheets to files ########################################################## def export_worksheet(self, worksheet_filename, output_filename, title=None): """ Export a worksheet, creating a sws file on the file system. INPUT: - ``worksheet_filename`` - a string e.g., 'username/id_number' - ``output_filename`` - a string, e.g., 'worksheet.sws' - ``title`` - title to use for the exported worksheet (if None, just use current title) """ S = self.__storage W = self.get_worksheet_with_filename(worksheet_filename) S.save_worksheet(W) username = W.owner() id_number = W.id_number() S.export_worksheet(username, id_number, output_filename, title=title) def worksheet(self, username, id_number=None): """ Create a new worksheet with given id_number belonging to the user with given username, or return an already existing worksheet. If id_number is None, creates a new worksheet using the next available new id_number for the given user. INPUT: - ``username`` -- string - ``id_number`` - nonnegative integer or None (default) """ S = self.__storage if id_number is None: id_number = self.new_id_number(username) try: W = S.load_worksheet(username, id_number) except ValueError: W = S.create_worksheet(username, id_number) self.__worksheets[W.filename()] = W return W def new_id_number(self, username): """ Find the next worksheet id for the given user. """ u = self.user(username).conf() id_number = u['next_worksheet_id_number'] if id_number == -1: # need to initialize id_number = max([w.id_number() for w in self.worksheet_list_for_user(username)] + [-1]) + 1 u['next_worksheet_id_number'] = id_number + 1 return id_number def new_worksheet_with_title_from_text(self, text, owner): name, _ = worksheet.extract_name(text) W = self.create_new_worksheet(name, owner) return W def change_worksheet_key(self, old_key, new_key): ws = self.__worksheets W = ws[old_key] ws[new_key] = W del ws[old_key] def import_worksheet(self, filename, owner): r""" Import a worksheet with the given ``filename`` and set its ``owner``. If the file extension is not recognized, raise a ValueError. INPUT: - ``filename`` - a string - ``owner`` - a string OUTPUT: - ``worksheet`` - a newly created Worksheet instance EXAMPLES: We create a notebook and import a plain text worksheet into it. :: sage: nb = sagenb.notebook.notebook.Notebook(tmp_dir(ext='.sagenb')) sage: nb.create_default_users('password') sage: name = tmp_filename() + '.txt' sage: open(name,'w').write('foo\n{{{\n2+3\n}}}') sage: W = nb.import_worksheet(name, 'admin') W is our newly-created worksheet, with the 2+3 cell in it:: sage: W.name() u'foo' sage: W.cell_list() [TextCell 0: foo, Cell 1: in=2+3, out=] """ if not os.path.exists(filename): raise ValueError("no file %s" % filename) # Figure out the file extension ext = os.path.splitext(filename)[1] if ext.lower() == '.txt': # A plain text file with {{{'s that defines a worksheet (no graphics). W = self._import_worksheet_txt(filename, owner) elif ext.lower() == '.sws': # An sws file (really a tar.bz2) which defines a worksheet with graphics, etc. W = self._import_worksheet_sws(filename, owner) elif ext.lower() == '.html': # An html file, which should contain the static version of # a sage help page, as generated by Sphinx html = open(filename).read() cell_pattern = r"""{{{id=.*?///.*?}}}""" docutils_pattern = r"""<meta name="generator" content="Docutils \S+: http://docutils\.sourceforge\.net/" />""" sphinx_pattern = r"""Created using <a href="http://sphinx\.pocoo\.org/">Sphinx</a>""" if re.search(cell_pattern, html, re.DOTALL) is not None: W = self._import_worksheet_txt(filename, owner) elif re.search(docutils_pattern, html) is not None: W = self._import_worksheet_docutils_html(filename, owner) elif re.search(sphinx_pattern, html) is not None: W = self._import_worksheet_html(filename, owner) else: # Unrecognized html file # We do the default behavior, i.e. we import as if it was generated # by Sphinx web page W = self._import_worksheet_html(filename, owner) elif ext.lower() == '.rst': # A ReStructuredText file W = self._import_worksheet_rst(filename, owner) else: # We only support txt, sws, html and rst files raise ValueError("unknown extension '%s'" % ext) self.__worksheets[W.filename()] = W return W def _import_worksheet_txt(self, filename, owner): r""" Import a plain text file as a new worksheet. INPUT: - ``filename`` - a string; a filename that ends in .txt - ``owner`` - a string; the imported worksheet's owner OUTPUT: - a new instance of Worksheet EXAMPLES: We write a plain text worksheet to a file and import it using this function.:: sage: nb = sagenb.notebook.notebook.Notebook(tmp_dir(ext='.sagenb')) sage: nb.create_default_users('password') sage: name = tmp_filename() + '.txt' sage: open(name,'w').write('foo\n{{{\na = 10\n}}}') sage: W = nb._import_worksheet_txt(name, 'admin'); W admin/0: [TextCell 0: foo, Cell 1: in=a = 10, out=] """ # Open the worksheet txt file and load it in. worksheet_txt = open(filename).read() # Create a new worksheet with the right title and owner. worksheet = self.new_worksheet_with_title_from_text(worksheet_txt, owner) # Set the new worksheet to have the contents specified by that file. worksheet.edit_save(worksheet_txt) return worksheet def _import_worksheet_sws(self, filename, username): r""" Import an sws format worksheet into this notebook as a new worksheet. INPUT: - ``filename`` - a string; a filename that ends in .sws; internally it must be a tar'd bz2'd file. - ``username`` - a string OUTPUT: - a new Worksheet instance EXAMPLES: We create a notebook, then make a worksheet from a plain text file first.:: sage: nb = sagenb.notebook.notebook.load_notebook(tmp_dir(ext='.sagenb')) sage: nb.create_default_users('password') sage: name = tmp_filename() + '.txt' sage: open(name,'w').write('{{{id=0\n2+3\n}}}') sage: W = nb.import_worksheet(name, 'admin') sage: W.filename() 'admin/0' sage: sorted([w.filename() for w in nb.get_all_worksheets()]) ['admin/0'] We then export the worksheet to an sws file.:: sage: sws = os.path.join(tmp_dir(), 'tmp.sws') sage: nb.export_worksheet(W.filename(), sws) Now we import the sws.:: sage: W = nb._import_worksheet_sws(sws, 'admin') sage: nb._Notebook__worksheets[W.filename()] = W Yes, it's there now (as a new worksheet):: sage: sorted([w.filename() for w in nb.get_all_worksheets()]) ['admin/0', 'admin/1'] """ id_number = self.new_id_number(username) worksheet = self.__storage.import_worksheet(username, id_number, filename) # I'm not at all convinced this is a good idea, since we # support multiple worksheets with the same title very well # already. So it's commented out. # self.change_worksheet_name_to_avoid_collision(worksheet) return worksheet def _import_worksheet_html(self, filename, owner): r""" Import a static html help page generated by Sphinx as a new worksheet. INPUT: - ``filename`` - a string; a filename that ends in .html - ``owner`` - a string; the imported worksheet's owner OUTPUT: - a new instance of Worksheet EXAMPLES: We write a plain text worksheet to a file and import it using this function.:: sage: nb = sagenb.notebook.notebook.Notebook(tmp_dir(ext='.sagenb')) sage: nb.create_default_users('password') sage: name = tmp_filename() + '.html' sage: fd = open(name,'w') sage: fd.write(''.join([ ....: '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"\n', ....: ' "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">\n', ....: '\n', ....: '<html xmlns="http://www.w3.org/1999/xhtml">\n', ....: ' <head>\n', ....: ' <title>Test notebook — test\n', ....: ' \n', ....: ' \n', ....: '
\n', ....: '
\n', ....: '
\n', ....: '
\n', ....: '

Here are some computations:

\n', ....: '\n', ....: '
\n',
            ....: 'sage',
            ....: ': 1+1\n',
            ....: '2\n',
            ....: '
\n', ....: '\n', ....: '
\n', ....: ''])) sage: fd.close() sage: W = nb._import_worksheet_html(name, 'admin') sage: W.name() u'Test notebook -- test' sage: W.owner() 'admin' sage: W.cell_list() [TextCell 1:

Here are some computations:

, Cell 0: in=1+1, out= 2, TextCell 2:
] sage: cell = W.cell_list()[1] sage: cell.input_text() u'1+1' sage: cell.output_text() u'
2
' """ # Inspired from sagenb.notebook.twist.WorksheetFile.render doc_page_html = open(filename).read() from .docHTMLProcessor import SphinxHTMLProcessor # FIXME: does SphinxHTMLProcessor raise an appropriate message # if the html file does not contain a Sphinx HTML page? doc_page = SphinxHTMLProcessor().process_doc_html(doc_page_html) from .misc import extract_title title = extract_title(doc_page_html).replace('—','--') worksheet = self.create_new_worksheet(title, owner) worksheet.edit_save(doc_page) # FIXME: An extra compute cell is always added to the end. # Pop it off. cells = worksheet.cell_list() cells.pop() return worksheet def _import_worksheet_rst(self, filename, owner): r""" Import a ReStructuredText file as a new worksheet. INPUT: - ``filename`` - a string; a filename that ends in .rst - ``owner`` - a string; the imported worksheet's owner OUTPUT: - a new instance of Worksheet EXAMPLES: sage: sprompt = 'sage' + ':' sage: rst = '\n'.join(['=============', ....: 'Test Notebook', ....: '=============', ....: '', ....: 'Let\'s do some computations::', ....: '', ....: ' %s 2+2' % sprompt, ....: ' 4', ....: '', ....: '::', ....: '', ....: ' %s x^2' % sprompt, ....: ' x^2']) sage: name = tmp_filename() + '.rst' sage: fd = open(name,'w') sage: fd.write(rst) sage: fd.close() sage: nb = sagenb.notebook.notebook.Notebook(tmp_dir(ext='.sagenb')) sage: nb.create_default_users('password') sage: W = nb._import_worksheet_rst(name, 'admin') sage: W.name() u'Test Notebook' sage: W.owner() 'admin' sage: W.cell_list() [TextCell 2:

Test Notebook

Let's do some computations:

, Cell 0: in=2+2, out= 4, Cell 1: in=x^2, out= x^2] sage: cell = W.cell_list()[1] sage: cell.input_text() u'2+2' sage: cell.output_text() u'
4
' """ rst = open(filename).read() # docutils removes the backslashes if they are not escaped This is # not practical because backslashes are almost never escaped in # Sage docstrings written in ReST. So if the user wants the # backslashes to be escaped automatically, he adds the comment # ".. escape-backslashes" in the input file if re.search(r'^\.\.[ \t]+escape-backslashes', rst, re.MULTILINE) is not None: rst = rst.replace('\\','\\\\') # Do the translation rst -> html (using docutils) from docutils.core import publish_parts D = publish_parts(rst, writer_name='html') title = D['title'] html = D['whole'] # Do the translation html -> txt from .docHTMLProcessor import docutilsHTMLProcessor translator = docutilsHTMLProcessor() worksheet_txt = translator.process_doc_html(html) # Create worksheet worksheet = self.create_new_worksheet(title, owner) worksheet.edit_save(worksheet_txt) return worksheet def _import_worksheet_docutils_html(self, filename, owner): r""" Import a static html help page generated by docutils as a new worksheet. INPUT: - ``filename`` - a string; a filename that ends in .html - ``owner`` - a string; the imported worksheet's owner OUTPUT: - a new instance of Worksheet EXAMPLES: sage: sprompt = 'sage' + ':' sage: rst = '\n'.join(['=============', ....: 'Test Notebook', ....: '=============', ....: '', ....: 'Let\'s do some computations::', ....: '', ....: ' %s 2+2' % sprompt, ....: ' 4', ....: '', ....: '::', ....: '', ....: ' %s x^2' % sprompt, ....: ' x^2']) sage: from docutils.core import publish_string sage: html = publish_string(rst, writer_name='html') sage: name = tmp_filename() + '.html' sage: fd = open(name,'w') sage: fd.write(html) sage: fd.close() sage: nb = sagenb.notebook.notebook.Notebook(tmp_dir(ext='.sagenb')) sage: nb.create_default_users('password') sage: W = nb._import_worksheet_docutils_html(name, 'admin') sage: W.name() u'Test Notebook' sage: W.owner() 'admin' sage: W.cell_list() [TextCell 2:

Test Notebook

Let's do some computations:

, Cell 0: in=2+2, out= 4, Cell 1: in=x^2, out= x^2] sage: cell = W.cell_list()[1] sage: cell.input_text() u'2+2' sage: cell.output_text() u'
4
' """ html = open(filename).read() # Do the translation html -> txt from .docHTMLProcessor import docutilsHTMLProcessor translator = docutilsHTMLProcessor() worksheet_txt = translator.process_doc_html(html) # Extract title from .worksheet import extract_name title, _ = extract_name(worksheet_txt) if title.startswith('

'): title = title[18:] if title.endswith('

'): title = title[:-5] # Create worksheet worksheet = self.create_new_worksheet(title, owner) worksheet.edit_save(worksheet_txt) return worksheet def change_worksheet_name_to_avoid_collision(self, worksheet): """ Change the display name of the worksheet if there is already a worksheet with the same name as this one. """ name = worksheet.name() display_names = [w.name() for w in self.get_worksheets_with_owner(worksheet.owner())] if name in display_names: j = name.rfind('(') if j != -1: name = name[:j].rstrip() i = 2 while name + " (%s)" % i in display_names: i += 1 name = name + " (%s)" % i worksheet.set_name(name) ########################################################## # Server configuration ########################################################## def conf(self): try: return self.__conf except AttributeError: C = server_conf.ServerConfiguration() # if we are newly creating a notebook, then we want to # have a default model version of 1, currently # we can't just set the default value in server_conf.py # to 1 since it would then be 1 for notebooks without the # model_version property # TODO: distinguish between a new server config default values # and default values for missing properties C['model_version']=1 self.__conf = C return C ########################################################## # Computing control ########################################################## def set_not_computing(self): # unpickled, no worksheets will think they are # being computed, since they clearly aren't (since # the server just started). for W in self.__worksheets.values(): W.set_not_computing() def quit(self): for W in self.__worksheets.values(): W.quit() def update_worksheet_processes(self): worksheet.update_worksheets() def quit_idle_worksheet_processes(self): timeout = self.conf()['idle_timeout'] doc_timeout = self.conf()['doc_timeout'] for W in self.__worksheets.values(): if W.compute_process_has_been_started(): if W.docbrowser(): W.quit_if_idle(doc_timeout) else: W.quit_if_idle(timeout) def quit_worksheet(self, W): try: del self.__worksheets[W.filename()] except KeyError: pass ########################################################## # Worksheet HTML generation ########################################################## def worksheet_list_for_public(self, username, sort='last_edited', reverse=False, search=None): W = self.users_worksheets('pub') if search: W = [x for x in W if x.satisfies_search(search)] sort_worksheet_list(W, sort, reverse) # changed W in place return W def worksheet_list_for_user(self, user, typ="active", sort='last_edited', reverse=False, search=None): X = self.get_worksheets_with_viewer(user) if typ == "trash": W = [x for x in X if x.is_trashed(user)] elif typ == "active": W = [x for x in X if x.is_active(user)] else: # typ must be archived W = [x for x in X if not (x.is_trashed(user) or x.is_active(user))] if search: W = [x for x in W if x.satisfies_search(search)] sort_worksheet_list(W, sort, reverse) # changed W in place return W ########################################################## # Revision history for a worksheet ########################################################## def html_worksheet_revision_list(self, username, worksheet): r""" Return HTML for the revision list of a worksheet. INPUT: - ``username`` - a string - ``worksheet`` - an instance of Worksheet OUTPUT: - a string - the HTML for the revision list EXAMPLES:: sage: from sagenb.flask_version import base # random output -- depends on warnings issued by other sage packages sage: app = base.create_app(tmp_dir(ext='.sagenb')) sage: ctx = app.app_context() sage: ctx.push() sage: nb = base.notebook sage: nb.create_default_users('password') sage: W = nb.create_new_worksheet('Test', 'admin') sage: W.body() u'\n\n{{{id=1|\n\n///\n}}}' sage: W.save_snapshot('admin') sage: nb.html_worksheet_revision_list('admin', W) u'...Revision...Last Edited...ago...' """ data = worksheet.snapshot_data() # pairs ('how long ago', key) return template(os.path.join("html", "notebook", "worksheet_revision_list.html"), data = data, worksheet = worksheet, notebook = self, username = username) def html_specific_revision(self, username, ws, rev): r""" Return the HTML for a specific revision of a worksheet. INPUT: - ``username`` - a string - ``ws`` - an instance of Worksheet - ``rev`` - a string containing the key of the revision OUTPUT: - a string - the revision rendered as HTML """ t = time.time() - float(rev[:-4]) time_ago = prettify_time_ago(t) filename = ws.get_snapshot_text_filename(rev) txt = bz2.decompress(open(filename).read()) W = self.scratch_worksheet() W.set_name('Revision of ' + ws.name()) W.delete_cells_directory() W.edit_save(txt) data = ws.snapshot_data() # pairs ('how long ago', key) prev_rev = None next_rev = None for i in range(len(data)): if data[i][1] == rev: if i > 0: prev_rev = data[i - 1][1] if i < len(data)-1: next_rev = data[i + 1][1] break return template(os.path.join("html", "notebook", "specific_revision.html"), worksheet = W, # the revision, not the original! username = username, rev = rev, prev_rev = prev_rev, next_rev = next_rev, time_ago = time_ago) def html_share(self, worksheet, username): r""" Return the HTML for the "share" page of a worksheet. INPUT: - ``username`` - a string - ``worksheet`` - an instance of Worksheet OUTPUT: - string - the share page's HTML representation EXAMPLES:: sage: nb = sagenb.notebook.notebook.Notebook(tmp_dir(ext='.sagenb')) sage: nb.create_default_users('password') sage: W = nb.create_new_worksheet('Test', 'admin') sage: nb.html_share(W, 'admin') u'...currently shared...add or remove collaborators...' """ return template(os.path.join("html", "notebook", "worksheet_share.html"), worksheet = worksheet, notebook = self, username = username) def html_download_or_delete_datafile(self, ws, username, filename): r""" Return the HTML for the download or delete datafile page. INPUT: - ``username`` - a string - ``ws`` - an instance of Worksheet - ``filename`` - a string; the name of the file OUTPUT: - a string - the page rendered as HTML EXAMPLES:: sage: nb = sagenb.notebook.notebook.Notebook(tmp_dir(ext='.sagenb')) sage: nb.create_default_users('password') sage: W = nb.create_new_worksheet('Test', 'admin') sage: nb.html_download_or_delete_datafile(W, 'admin', 'bar') u'...Data file: bar...DATA is a special variable...uploaded...' """ ext = os.path.splitext(filename)[1].lower() file_is_image, file_is_text = False, False text_file_content = "" if ext in ['.png', '.jpg', '.gif']: file_is_image = True if ext in ['.txt', '.tex', '.sage', '.spyx', '.py', '.f', '.f90', '.c']: file_is_text = True text_file_content = open(os.path.join(ws.data_directory(), filename)).read() # Detect the character encoding from BeautifulSoup import UnicodeDammit text_file_content = UnicodeDammit(text_file_content).unicode return template(os.path.join("html", "notebook", "download_or_delete_datafile.html"), worksheet = ws, notebook = self, username = username, filename_ = filename, file_is_image = file_is_image, file_is_text = file_is_text, text_file_content = text_file_content) ########################################################## # Accessing all worksheets with certain properties. ########################################################## def active_worksheets_for(self, username): # TODO: check if the worksheets are active #return [ws for ws in self.get_worksheets_with_viewer(username) if ws.is_active(username)] return self.users_worksheets_view(username) def get_all_worksheets(self): """ We should only call this if the user is admin! """ all_worksheets = [] for username in self._user_manager.users(): if username in ['_sage_', 'pub']: continue for w in self.users_worksheets(username): all_worksheets.append(w) return all_worksheets def get_worksheets_with_viewer(self, username): if self._user_manager.user_is_admin(username): return self.get_all_worksheets() return self.users_worksheets_view(username) def get_worksheets_with_owner(self, owner): return self.users_worksheets(owner) def get_worksheet_with_filename(self, filename): """ Get the worksheet with the given filename. If there is no such worksheet, raise a ``KeyError``. INPUT: - ``filename`` - a string OUTPUT: - a Worksheet instance """ try: return self.__worksheets[filename] except KeyError: raise KeyError("No worksheet with filename '%s'" % filename) ########################################################### # Saving the whole notebook ########################################################### def save(self): """ Save this notebook server to disk. """ S = self.__storage S.save_users(self.user_manager().users()) S.save_server_conf(self.conf()) self._user_manager.save(S) # Save the non-doc-browser worksheets. for n, W in self.__worksheets.items(): if not n.startswith('doc_browser'): S.save_worksheet(W) if hasattr(self, '_user_history'): for username, H in iteritems(self._user_history): S.save_user_history(username, H) def save_worksheet(self, W, conf_only=False): self.__storage.save_worksheet(W, conf_only=conf_only) def logout(self, username): r""" Do not do anything on logout (so far). In particular, do **NOT** stop all ``username``'s worksheets! """ pass def delete_doc_browser_worksheets(self): for w in self.users_worksheets('_sage_'): if w.name().startswith('doc_browser'): self.delete_worksheet(w.filename()) ########################################################### # HTML -- generate most html related to the whole notebook page ########################################################### def html_plain_text_window(self, worksheet, username): r""" Return HTML for the window that displays a plain text version of the worksheet. INPUT: - ``worksheet`` - a Worksheet instance - ``username`` - a string OUTPUT: - a string - the plain text window rendered as HTML EXAMPLES:: sage: nb = sagenb.notebook.notebook.Notebook(tmp_dir(ext='.sagenb')) sage: nb.create_default_users('password') sage: W = nb.create_new_worksheet('Test', 'admin') sage: nb.html_plain_text_window(W, 'admin') u'...pre class="plaintext"...cell_intext...textfield...' """ plain_text = worksheet.plain_text(prompts=True, banner=False) plain_text = escape(plain_text).strip() return template(os.path.join("html", "notebook", "plain_text_window.html"), worksheet = worksheet, notebook = self, username = username, plain_text = plain_text, MATHJAX = MATHJAX, JEDITABLE_TINYMCE = JEDITABLE_TINYMCE) def html_edit_window(self, worksheet, username): r""" Return HTML for a window for editing ``worksheet``. INPUT: - ``username`` - a string containing the username - ``worksheet`` - a Worksheet instance OUTPUT: - a string - the editing window's HTML representation EXAMPLES:: sage: nb = sagenb.notebook.notebook.Notebook(tmp_dir(ext='.sagenb')) sage: nb.create_default_users('password') sage: W = nb.create_new_worksheet('Test', 'admin') sage: nb.html_edit_window(W, 'admin') u'...textarea class="plaintextedit"...{{{id=1|...//...}}}...' """ return template(os.path.join("html", "notebook", "edit_window.html"), worksheet = worksheet, notebook = self, username = username) def html_beforepublish_window(self, worksheet, username): r""" Return HTML for the warning and decision page displayed prior to publishing the given worksheet. INPUT: - ``worksheet`` - an instance of Worksheet - ``username`` - a string OUTPUT: - a string - the pre-publication page rendered as HTML EXAMPLES:: sage: nb = sagenb.notebook.notebook.Notebook(tmp_dir(ext='.sagenb')) sage: nb.create_default_users('password') sage: W = nb.create_new_worksheet('Test', 'admin') sage: nb.html_beforepublish_window(W, 'admin') u'...want to publish this worksheet?...re-publish when changes...' """ msg = """You can publish your worksheet to the Internet, where anyone will be able to access and view it online. Your worksheet will be assigned a unique address (URL) that you can send to your friends and colleagues.

Do you want to publish this worksheet?



Automatically re-publish when changes are made and saved
""" return template(os.path.join("html", "notebook", "beforepublish_window.html"), worksheet = worksheet, notebook = self, username = username) def html_afterpublish_window(self, worksheet, username, url, dtime): r""" Return HTML for a given worksheet's post-publication page. INPUT: - ``worksheet`` - an instance of Worksheet - ``username`` - a string - ``url`` - a string representing the URL of the published worksheet - ``dtime`` - an instance of time.struct_time representing the publishing time OUTPUT: - a string - the post-publication page rendered as HTML """ from time import strftime time = strftime("%B %d, %Y %I:%M %p", dtime) return template(os.path.join("html", "notebook", "afterpublish_window.html"), worksheet = worksheet, notebook = self, username = username, url = url, time = time) def html_upload_data_window(self, ws, username): r""" Return HTML for the "Upload Data" window. INPUT: - ``worksheet`` - an instance of Worksheet - ``username`` - a string OUTPUT: - a string - the HTML representation of the data upload window EXAMPLES:: sage: nb = sagenb.notebook.notebook.Notebook(tmp_dir(ext='.sagenb')) sage: nb.create_default_users('password') sage: W = nb.create_new_worksheet('Test', 'admin') sage: nb.html_upload_data_window(W, 'admin') u'...Upload or Create Data File...Browse...url...name of a new...' """ return template(os.path.join("html", "notebook", "upload_data_window.html"), worksheet = ws, username = username) def html(self, worksheet_filename=None, username='guest', admin=False, do_print=False): r""" Return the HTML for a worksheet's index page. INPUT: - ``worksheet_filename`` - a string (default: None) - ``username`` - a string (default: 'guest') - ``admin`` - a bool (default: False) OUTPUT: - a string - the worksheet rendered as HTML EXAMPLES:: sage: nb = sagenb.notebook.notebook.Notebook(tmp_dir(ext='.sagenb')) sage: nb.create_default_users('password') sage: W = nb.create_new_worksheet('Test', 'admin') sage: nb.html(W.filename(), 'admin') u'...Test...cell_input...if (e.shiftKey)...state_number...' """ if worksheet_filename is None or worksheet_filename == '': worksheet_filename = None W = None else: try: W = self.get_worksheet_with_filename(worksheet_filename) except KeyError: W = None from flask import current_app if W is None: return current_app.message(gettext("The worksheet does not exist"), username=username) if W.docbrowser() or W.is_published(): if W.is_published() or self.user_manager().user_is_guest(username): template_page = os.path.join('html', 'notebook', 'guest_worksheet_page.html') else: template_page = os.path.join("html", "notebook", "doc_page.html") elif do_print: template_page = os.path.join('html', 'notebook', 'print_worksheet.html') else: template_page = os.path.join("html", "notebook", "worksheet_page.html") return template(template_page, worksheet = W, notebook = self, do_print=do_print, username = username) def upgrade_model(self): """ Upgrade the model, if needed. - Version 0 (or non-existent model version, which defaults to 0): Original flask notebook - Version 1: shared worksheet data cached in the User object """ model_version=self.conf()['model_version'] if model_version is None or model_version<1: print("Upgrading model version to version 1") # this uses code from get_all_worksheets() user_manager = self.user_manager() num_users=0 for username in self._user_manager.users(): num_users+=1 if num_users%1000==0: print('Upgraded %d users' % num_users) if username in ['_sage_', 'pub']: continue try: for w in self.users_worksheets(username): owner = w.owner() id_number = w.id_number() collaborators = w.collaborators() for u in collaborators: try: user_manager.user(u).viewable_worksheets().add((owner, id_number)) except KeyError: # user doesn't exist pass except (UnicodeEncodeError, OSError): # Catch UnicodeEncodeError because sometimes a username has a non-ascii character # Catch OSError since sometimes when moving user directories (which happens # automatically when getting user's worksheets), OSError: [Errno 39] Directory not empty # is thrown (we should be using shutil.move instead, probably) # users with these problems won't have their sharing cached, but they will probably have # problems logging in anyway, so they probably won't notice not having shared worksheets import sys import traceback print('Error on username %s' % username.encode('utf8'), file=sys.stderr) print(traceback.format_exc(), file=sys.stderr) pass print('Done upgrading to model version 1') self.conf()['model_version'] = 1 #################################################################### def load_notebook(dir, interface=None, port=None, secure=None, user_manager=None): """ Load and return a notebook from a given directory. Create a new one in that directory, if one isn't already there. INPUT: - ``dir`` - a string that defines a directory name - ``interface`` - the address of the interface the server listens at - ``port`` - the port the server listens on - ``secure`` - whether the notebook is secure OUTPUT: - a Notebook instance """ if not dir.endswith('.sagenb'): if not os.path.exists(dir + '.sagenb') and os.path.exists(os.path.join(dir, 'nb.sobj')): try: nb = migrate_old_notebook_v1(dir) except KeyboardInterrupt: raise KeyboardInterrupt("Interrupted notebook migration. Delete the directory '%s' and try again." % (os.path.abspath(dir+'.sagenb'))) return nb dir += '.sagenb' dir = make_path_relative(dir) nb = Notebook(dir) nb.interface = interface nb.port = port nb.secure = secure # Install this copy of the notebook in misc.py as *the* # global notebook object used for computations. This is # mainly to avoid circular references, etc. This also means # only one notebook can actually be used at any point. import sagenb.notebook.misc sagenb.notebook.misc.notebook = nb return nb def migrate_old_notebook_v1(dir): """ Back up and migrates an old saved version of notebook to the new one (`sagenb`) """ nb_sobj = os.path.join(dir, 'nb.sobj') old_nb = pickle.loads(open(nb_sobj).read()) ###################################################################### # Tell user what is going on and make a backup ###################################################################### print("") print("*" * 80) print("*") print("* The Sage notebook at") print("*") print("* '%s'" % os.path.abspath(dir)) print("*") print("* will be upgraded to a new format and stored in") print("*") print("* '%s.sagenb'." % os.path.abspath(dir)) print("*") print("* Your existing notebook will not be modified in any way.") print("*") print("*" * 80) print("") ans = raw_input("Would like to continue? [YES or no] ").lower() if ans not in ['', 'y', 'yes']: raise RuntimeError("User aborted upgrade.") # Create new notebook new_nb = Notebook(dir + '.sagenb') # Define a function for transfering the attributes of one object to another. def transfer_attributes(old, new, attributes): for attr_old, attr_new in attributes: if hasattr(old, attr_old): setattr(new, attr_new, getattr(old, attr_old)) # Transfer all the notebook attributes to our new notebook object new_nb.conf().confs = old_nb.conf().confs for t in ['pretty_print', 'server_pool', 'ulimit', 'system']: if hasattr(old_nb, '_Notebook__' + t): new_nb.conf().confs[t] = getattr(old_nb, '_Notebook__' + t) # Now update the user data from the old notebook to the new one: print("Migrating %s user accounts..." % len(old_nb.user_manager().users())) users = new_nb.user_manager().users() for username, old_user in iteritems(old_nb.user_manager().users()): new_user = user.User(old_user.username(), '', old_user.get_email(), old_user.account_type()) new_user.set_hashed_password(old_user.password()) transfer_attributes(old_user, new_user, [('_User__email_confirmed', '_email_confirmed'), ('_User__temporary_password', '_temporary_password'), ('_User__is_suspended', '_is_suspended')]) # Fix the __conf field, which is also an instance of a class new_user.conf().confs = old_user.conf().confs users[new_user.username()] = new_user ###################################################################### # Set the worksheets of the new notebook equal to the ones from # the old one. ###################################################################### def migrate_old_worksheet(old_worksheet): """ Migrates an old worksheet to the new format. """ old_ws_dirname = old_ws._Worksheet__filename.partition(os.path.sep)[-1] new_ws = new_nb.worksheet(old_ws.owner(), old_ws_dirname) # some ugly creation of new attributes from what used to be stored tags = {} try: for user, val in iteritems(old_ws._Worksheet__user_view): if isinstance(user, str): # There was a bug in the old notebook where sometimes the # user was the *module* "user", so we don't include that # invalid data. tags[user] = [val] except AttributeError: pass import time last_change = (old_ws.last_to_edit(), old_ws.last_edited()) try: published_id_number = int(os.path.split(old_ws._Worksheet__published_version)[1]) except AttributeError: published_id_number = None ws_pub = old_ws.worksheet_that_was_published().filename().split('/') ws_pub = (ws_pub[0], int(ws_pub[1])) obj = {'name': old_ws.name(), 'system': old_ws.system(), 'viewers': old_ws.viewers(), 'collaborators' :old_ws.collaborators(), 'pretty_print': old_ws.pretty_print(), 'ratings': old_ws.ratings(), 'auto_publish': old_ws.is_auto_publish(), 'tags': tags, 'last_change': last_change, 'published_id_number': published_id_number, 'worksheet_that_was_published': ws_pub } new_ws.reconstruct_from_basic(obj) base = os.path.join(dir, 'worksheets', old_ws.filename()) worksheet_file = os.path.join(base, 'worksheet.txt') if os.path.exists(worksheet_file): text = open(worksheet_file).read() # delete first two lines -- we don't embed the title or # system in the worksheet text anymore. i = text.find('\n') text=text[i+1:] i = text.find('\n') text=text[i+1:] new_ws.edit_save(text) # copy over the DATA directory and cells directories try: dest = new_ws.data_directory() if os.path.exists(dest): shutil.rmtree(dest) shutil.copytree(old_ws.data_directory(), dest) except Exception as msg: print(msg) try: if os.path.exists(old_ws.cells_directory()): dest = new_ws.cells_directory() if os.path.exists(dest): shutil.rmtree(dest) shutil.copytree(old_ws.cells_directory(), dest) except Exception as msg: print(msg) return new_ws worksheets = WorksheetDict(new_nb) num_worksheets = len(old_nb._Notebook__worksheets) print("Migrating (at most) %s worksheets..." % num_worksheets) from sage.misc.all import walltime tm = walltime() i = 0 for ws_name, old_ws in iteritems(old_nb._Notebook__worksheets): if old_ws.docbrowser(): continue i += 1 if i % 25==0: percent = i / float(num_worksheets) # total_time * percent = time_so_far, so # remaining_time = total_time - time_so_far = time_so_far*(1/percent - 1) print(" Migrated %s (of %s) worksheets (about %.0f seconds remaining)" % ( i, num_worksheets, walltime(tm) * (1 / percent - 1))) new_ws = migrate_old_worksheet(old_ws) worksheets[new_ws.filename()] = new_ws new_nb._Notebook__worksheets = worksheets # Migrating history new_nb._user_history = {} for username in old_nb.user_manager().users().keys(): history_file = os.path.join(dir, 'worksheets', username, 'history.sobj') if os.path.exists(history_file): new_nb._user_history[username] = pickle.loads(open(history_file).read()) # Save our newly migrated notebook to disk new_nb.save() print("Worksheet migration completed.") return new_nb def make_path_relative(dir): r""" Replace an absolute path with a relative path, if possible. Otherwise, return the given path. INPUT: - ``dir`` - a string containing, e.g., a directory name OUTPUT: - a string """ base, file = os.path.split(dir) if os.path.exists(file): return file return dir ########################################################## # Misc ########################################################## def sort_worksheet_list(v, sort, reverse): """ Sort a given list on a given key, in a given order. INPUT: - ``sort`` - a string; 'last_edited', 'owner', 'rating', or 'name' - ``reverse`` - a bool; if True, reverse the order of the sort. OUTPUT: - the sorted list """ f = None if sort == 'last_edited': def c(a): return a.last_edited() reverse = not reverse f = c elif sort == 'name': def c(a): return (a.name().lower(), -a.last_edited()) f = c elif sort == 'owner': def c(a): return (a.owner().lower(), -a.last_edited()) f = c elif sort == "rating": def c(a): return (a.rating(), -a.last_edited()) reverse = not reverse f = c else: raise ValueError("invalid sort key '%s'" % sort) v.sort(key=f, reverse=reverse) sagenb-1.0.1/sagenb/notebook/notebook_object.py000066400000000000000000000272171311436262400215620ustar00rootroot00000000000000# -*- coding: utf-8 -* """nodoctest Configure and Start a Notebook Server The :class:`NotebookObject` is used to configure and launch a Sage Notebook server. """ ############################################################################# # Copyright (C) 2007 William Stein # Distributed under the terms of the GNU General Public License (GPL) # The full text of the GPL is available at: # http://www.gnu.org/licenses/ ############################################################################# import time import os import shutil import signal import tempfile from . import notebook as _notebook from . import run_notebook class NotebookObject: r""" Start the Sage Notebook server. More details about using these options, as well as tips and tricks, may be available at `this Sage wiki page`_. If a notebook server is already running in the directory, this will open a browser to the running notebook. INPUT: - ``directory`` -- string; directory that contains the Sage notebook files; the default is ``.sage/sage_notebook.sagenb``, in your home directory. - ``port`` -- integer (default: ``8080``), port to serve the notebook on. - ``interface`` -- string (default: ``'localhost'``), address of network interface to listen on; give ``''`` to listen on all interfaces. - ``port_tries`` -- integer (default: ``0``), number of additional ports to try if the first one doesn't work (*not* implemented). - ``secure`` -- boolean (default: ``False``) if True use https so all communication, e.g., logins and passwords, between web browsers and the Sage notebook is encrypted via SSL. You must have OpenSSL installed to use this feature, or if you compile Sage yourself, have the OpenSSL development libraries installed. *Highly recommended!* When ``notebook()`` is run for first time with ``secure=True``, it will generate new keys and store them to ``.sage/notebook/``. Remove this when you want to generate new keys, for example if an older version of Sage has generated keys that are too short for current browsers. - ``reset`` -- boolean (default: ``False``) if True allows you to set the admin password. Use this if you forget your admin password. - ``accounts`` -- boolean (default: ``False``) if True, any visitor to the website will be able to create a new account. If False, only the admin can create accounts (currently, this can only be done by running with ``accounts=True`` and shutting down the server properly (``SIG_INT`` or ``SIG_TERM``), or on the command line with, e.g., :: from sagenb.notebook.notebook import load_notebook nb = load_notebook("directory_to_run_sage_in") user_manager = nb.user_manager() user_manager.set_accounts(True) user_manager.add_user("username", "password", "email@place", "user") nb.save() - ``automatic_login`` -- boolean (default: True) whether to pop up a web browser and automatically log into the server as admin. You can override the default browser by setting the ``SAGE_BROWSER`` environment variable, e.g., by putting :: export SAGE_BROWSER="firefox" in the file .bashrc in your home directory. - ``upload`` -- string (default: None) Full path to a local file (sws, txt, zip) to be uploaded and turned into a worksheet(s). This is equivalent to manually uploading a file via ``http://localhost:8080/upload`` or to fetching ``http://localhost:8080/upload_worksheet?url=file:///...`` in a script except that (hopefully) you will already be logged in. .. warning:: If you are running a server for others to log into, set ``automatic_login=False``. Otherwise, all of the worksheets on the entire server will be loaded when the server automatically logs into the admin account. - ``timeout`` -- integer (default: 0) seconds until idle worksheet sessions automatically timeout, i.e., the corresponding Sage session terminates. 0 means "never timeout". If your server is running out of memory, setting a timeout can be useful as this will free the memory used by idle sessions. - ``doc_timeout`` -- integer (default: 600) seconds until idle live documentation worksheet sessions automatically timeout, i.e., the corresponding Sage session terminates. 0 means "never timeout". - ``server_pool`` -- list of strings (default: None) list; this option specifies that worksheet processes run as a separate user (chosen from the list in the ``server_pool`` -- see below). .. note:: If you have problems with the server certificate hostname not matching, do ``notebook.setup()``. .. note:: The ``require_login`` option has been removed. Use ``automatic_login`` to control automatic logins instead---``automatic_login=False`` corresponds to ``require_login=True``. EXAMPLES: 1. I just want to run the Sage notebook. Type:: notebook() 2. I want to run the Sage notebook server on a remote machine and be the only person allowed to log in. Type:: notebook(interface='', secure=True) the first time you do this you'll be prompted to set an administrator password. Use this to login. NOTE: You may have to run ``notebook.setup()`` again and change the hostname. ANOTHER NOTE: You must have installed pyOpenSSL in order to use secure mode; see the top-level Sage README file or the "Install from Source Code" section in the Sage manual for more information. 3. I want to create a Sage notebook server that is open to anybody in the world to create new accounts. To run the Sage notebook publicly (1) at a minimum run it from a chroot jail or inside a virtual machine (see `this Sage wiki page`_) and (2) use a command like:: notebook(interface='', server_pool=['sage1@localhost'], ulimit='-v 500000', accounts=True, automatic_login=False) The server_pool option specifies that worksheet processes run as a separate user. The ulimit option restricts the memory available to each worksheet processes to 500 MB. See help on the ``accounts`` option above. Be sure that ``sage_notebook.sagenb/users.pickle`` and the contents of ``sage_notebook.sagenb/backups`` are chmod ``og-rwx``, i.e., only readable by the notebook process, since otherwise any user can read ``users.pickle``, which contains user email addresses and account information (passwords are stored hashed, so fewer worries there). You will need to use the ``directory`` option to accomplish this. INPUT: (more advanced) - ``server_pool`` -- list of strings (initial default: None), if given, should be a list like \['sage1@localhost', 'sage2@localhost'\], where you have setup ssh keys so that typing:: ssh sage1@localhost logs in without requiring a password, e.g., by typing ``ssh-keygen`` as the notebook server user, then putting ``~/.ssh/id_rsa.pub`` as the file ``.ssh/authorized_keys``. Note: you have to get the permissions of files and directories just right -- see `this Sage wiki page`_ for more details. Files between the main Sage process and the ``server_pool`` workers are transferred through ``/tmp`` by default. If the environment variable :envvar:`SAGENB_TMPDIR` or :envvar:`TMPDIR` exists, that directory is used instead. This directory must be shared, so if the machines are separate the server machine must NFS-export ``/tmp`` or :envvar:`SAGENB_TMPDIR`. - ``server`` -- string ("twistd" (default) or "flask"). The server to use to server content. - ``profile`` -- True, False, or file prefix (default: False - no profiling), If True, profiling is saved to a randomly-named file like `sagenb-*-profile*.stats` in the $DOT_SAGE directory. If a string, that string is used as a prefix for the pstats data file. - ``ulimit`` -- string (initial default: None -- leave as is), if given and ``server_pool`` is also given, the worksheet processes are run with these constraints. See the ulimit documentation. Common options include: - ``-t`` The maximum amount of cpu time in seconds. NOTE: For Sage, ``-t`` is the wall time, not cpu time. - ``-u`` The maximum number of processes available to a single user. - ``-v`` The maximum amount of virtual memory available to the process. Values are in 1024-byte increments, except for ``-t``, which is in seconds, and ``-u`` which is a positive integer. Example: ulimit="-v 400000 -t 30" .. note:: The values of ``server_pool`` and ``ulimit`` default to what they were last time the notebook command was called. OTHER NOTES: - If you create a file ``\\$DOT_SAGE/notebook.css`` then it will get applied when rendering the notebook HTML. This allows notebook administrators to customize the look of the notebook. Note that by default ``\\$DOT_SAGE`` is ``\\$HOME/.sage``. .. _this Sage wiki page: http://wiki.sagemath.org/StartingTheNotebook """ def __call__(self, *args, **kwds): return self.notebook(*args, **kwds) notebook = run_notebook.notebook_run setup = run_notebook.notebook_setup notebook = NotebookObject() def inotebook(*args, **kwds): """ Exactly the same as ``notebook(...)`` but with ``secure=False``. """ kwds['secure'] = False notebook(*args, **kwds) def test_notebook(admin_passwd, secure=False, directory=None, port=8050, interface='localhost', verbose=False): """ This function is used to test notebook server functions. EXAMPLES:: sage: from sagenb.notebook.notebook_object import test_notebook sage: passwd = str(randint(1,1<<128)) sage: nb = test_notebook(passwd, interface='localhost', port=8060) sage: import urllib sage: h = urllib.urlopen('http://localhost:8060') sage: homepage = h.read() sage: h.close() sage: 'html' in homepage True sage: nb.dispose() """ import socket, pexpect if directory is None: directory = tmp_dir = tempfile.mkdtemp() else: tmp_dir = None if not os.path.exists(directory): os.makedirs(directory) nb = _notebook.load_notebook(directory) nb.set_accounts(True) nb.add_user('admin', admin_passwd, '') nb.set_accounts(False) nb.save() p = notebook(directory=directory, accounts=True, secure=secure, port=port, interface=interface, automatic_login=False, fork=True, quiet=True) p.expect("Starting factory") def dispose(): try: p.send('\x03') # control-C except pexpect.EOF: pass p.close(force=True) shutil.rmtree(nb._dir) p.dispose = dispose if verbose: print("Notebook started.") return p sagenb-1.0.1/sagenb/notebook/notification.py000066400000000000000000000022231311436262400210700ustar00rootroot00000000000000# -*- coding: utf-8 -* import logging from .sage_email import default_email_address from .smtpsend import send_mail from socket import getfqdn logger = logging.getLogger('notification') class TwistedEmailHandler(logging.Handler): """Sends log messages via SMTP using a running twisted reactor.""" def __init__(self, conf, level=logging.NOTSET): logging.Handler.__init__(self, level) self.conf = conf self.setFormatter( logging.Formatter(''' Host: %(fqdn)s Message type: %(levelname)s Location: %(pathname)s:%(lineno)d Module: %(module)s Function: %(funcName)s Time: %(asctime)s Message: %(message)s ''')) def emit(self, record): fqdn = getfqdn() from_address = default_email_address() subject = '[sage-notebook] %s' % fqdn record.fqdn = fqdn message = self.format(record) recipients = self.conf['notification_recipients'] if recipients is None: recipients = [] for rcpt in recipients: to = rcpt.strip() send_mail(from_address, to, subject, message) sagenb-1.0.1/sagenb/notebook/register.py000066400000000000000000000031661311436262400202350ustar00rootroot00000000000000# -*- coding: utf-8 -* """nodoctest """ ############################################################################# # Copyright (C) 2007 William Stein # Distributed under the terms of the GNU General Public License (GPL) # The full text of the GPL is available at: # http://www.gnu.org/licenses/ ############################################################################# """ Helper functions dealing with the verification of user """ from flask.ext.babel import gettext as _ def build_msg(key, username, addr, port, secure): url_prefix = "https" if secure else "http" s = _("Hi %(username)s!\n\n", username=username) s += _('Thank you for registering for the Sage notebook. To complete your registration, copy and paste' ' the following link into your browser:\n\n' '%(url_prefix)s://%(addr)s:%(port)s/confirm?key=%(key)s\n\n' 'You will be taken to a page which will confirm that you have indeed registered.', url_prefix=url_prefix, addr=addr, port=port, key=key) return s.encode('utf-8') def build_password_msg(key, username, addr, port, secure): url_prefix = "https" if secure else "http" s = _("Hi %(username)s!\n\n", username=username) s += _('Your new password is %(key)s\n\n' 'Sign in at %(url_prefix)s://%(addr)s:%(port)s/\n\n' 'Make sure to reset your password by going to Settings in the upper right bar.', key=key, url_prefix=url_prefix, addr=addr, port=port) return s.encode('utf-8') def make_key(): from random import randint key = randint(0,2**128-1) return key sagenb-1.0.1/sagenb/notebook/run_notebook.py000066400000000000000000000570701311436262400211200ustar00rootroot00000000000000# -*- coding: utf-8 -* """nodoctest Serve the Sage Notebook. """ from __future__ import absolute_import ############################################################################# # Copyright (C) 2009 William Stein # Distributed under the terms of the GNU General Public License (GPL) # The full text of the GPL is available at: # http://www.gnu.org/licenses/ ############################################################################# # System libraries import getpass import os import shutil import socket import sys import hashlib from exceptions import SystemExit from twisted.python.runtime import platformType from six import iteritems from sagenb.misc.misc import (DOT_SAGENB, find_next_available_port, print_open_msg) from . import notebook conf_path = os.path.join(DOT_SAGENB, 'notebook') private_pem = os.path.join(conf_path, 'private.pem') public_pem = os.path.join(conf_path, 'public.pem') template_file = os.path.join(conf_path, 'cert.cfg') class NotebookRun(object): config_stub=""" #################################################################### # WARNING -- Do not edit this file! It is autogenerated each time # the notebook(...) command is executed. #################################################################### import sagenb.notebook.misc sagenb.notebook.misc.DIR = %(cwd)r #We should really get rid of this! ######### # Flask # ######### import os, sys, random import sagenb.flask_version.base as flask_base opts={} startup_token = '{0:x}'.format(random.randint(0, 2**128)) if %(automatic_login)s: opts['startup_token'] = startup_token flask_app = flask_base.create_app(%(notebook_opts)s, **opts) def save_notebook(notebook): print("Quitting all running worksheets...") notebook.quit() print("Saving notebook...") notebook.save() print("Notebook cleanly saved.") """ def prepare_kwds(self, kw): import os kw['absdirectory']=os.path.abspath(kw['directory']) kw['notebook_opts'] = '"%(absdirectory)s",interface="%(interface)s",port=%(port)s,secure=%(secure)s'%kw kw['hostname'] = kw['interface'] if kw['interface'] else 'localhost' if kw['automatic_login']: kw['start_path'] = "'/?startup_token=%s' % startup_token" kw['open_page'] = "from sagenb.misc.misc import open_page; open_page('%(hostname)s', %(port)s, %(secure)s, %(start_path)s)" % kw if kw['upload']: import urllib # If we have to login and upload a file, then we do them # in that order and hope that the login is fast enough. kw['start_path'] = "'/upload_worksheet?url=file://%s'" % (urllib.quote(kw['upload'])) kw['open_page'] = kw['open_page']+ "; open_page('%(hostname)s', %(port)s, %(secure)s, %(start_path)s)" % kw elif kw['upload']: import urllib kw['start_path'] = "'/upload_worksheet?url=file://%s'" % (urllib.quote(kw['upload'])) kw['open_page'] = "from sagenb.misc.misc import open_page; open_page('%(hostname)s', %(port)s, %(secure)s, %(start_path)s)" % kw else: kw['open_page'] = '' def profile_file(self, profile): import random _id=random.random() if isinstance(profile, basestring): profilefile = profile+'%s.stats'%_id else: profilefile = 'sagenb-%s-profile-%s.stats'%(self.name,_id) return profilefile def run_command(self, kw): raise NotImplementedError class NotebookRunTornado(NotebookRun): name="tornado" TORNADO_NOTEBOOK_CONFIG = """ from tornado import web from tornado.wsgi import WSGIContainer from tornado.httpserver import HTTPServer from tornado.ioloop import IOLoop %(open_page)s wsgi_app = WSGIContainer(flask_app) http_server = HTTPServer(wsgi_app) http_server.listen(%(port)s) IOLoop.instance().start() """ def run_command(self, kw): """Run a tornado webserver.""" self.prepare_kwds(kw) run_file = os.path.join(kw['directory'], 'run_tornado') with open(run_file, 'w') as script: script.write((self.config_stub+self.TORNADO_NOTEBOOK_CONFIG)%kw) cmd = 'python %s' % (run_file) return cmd class NotebookRunuWSGI(NotebookRun): name="uWSGI" uWSGI_NOTEBOOK_CONFIG = """ import atexit from functools import partial atexit.register(partial(save_notebook,flask_base.notebook)) %(open_page)s """ def run_command(self, kw): """Run a uWSGI webserver.""" # TODO: Check to see if server is running already (PID file?) self.prepare_kwds(kw) run_file = os.path.join(kw['directory'], 'run_uwsgi') with open(run_file, 'w') as script: script.write((self.config_stub+self.uWSGI_NOTEBOOK_CONFIG)%kw) port=kw['port'] pidfile=kw['pidfile'] cmd = 'uwsgi --single-interpreter --socket-timeout 30 --http-timeout 30 --listen 300 --http-socket :%s --file %s --callable flask_app --pidfile %s' % (port, run_file, pidfile) # Comment out the line below to turn on request logging cmd += ' --disable-logging' cmd += ' --threads 4 --enable-threads' return cmd class NotebookRunFlask(NotebookRun): name="flask" FLASK_NOTEBOOK_CONFIG = """ import os with open(%(pidfile)r, 'w') as pidfile: pidfile.write(str(os.getpid())) if %(secure)s: try: from OpenSSL import SSL ssl_context = SSL.Context(SSL.SSLv23_METHOD) ssl_context.use_privatekey_file(%(private_pem)r) ssl_context.use_certificate_file(%(public_pem)r) except ImportError: raise RuntimeError("HTTPS cannot be used without pyOpenSSL" " installed. See the Sage README for more information.") else: ssl_context = None import logging logger=logging.getLogger('werkzeug') logger.setLevel(logging.WARNING) #logger.setLevel(logging.INFO) # to see page requests #logger.setLevel(logging.DEBUG) logger.addHandler(logging.StreamHandler()) if %(secure)s: # Monkey-patch werkzeug so that it works with pyOpenSSL and Python 2.7 # otherwise, we constantly get TypeError: shutdown() takes exactly 0 arguments (1 given) # Monkey patching idiom: http://mail.python.org/pipermail/python-dev/2008-January/076194.html def monkeypatch_method(cls): def decorator(func): setattr(cls, func.__name__, func) return func return decorator from werkzeug import serving @monkeypatch_method(serving.BaseWSGIServer) def shutdown_request(self, request): request.shutdown() %(open_page)s try: flask_app.run(host=%(interface)r, port=%(port)s, threaded=True, ssl_context=ssl_context, debug=False) finally: save_notebook(flask_base.notebook) os.unlink(%(pidfile)r) """ def run_command(self, kw): """Run a flask (werkzeug) webserver.""" # TODO: Check to see if server is running already (PID file?) self.prepare_kwds(kw) run_file = os.path.join(kw['directory'], 'run_flask') with open(run_file, 'w') as script: script.write((self.config_stub+self.FLASK_NOTEBOOK_CONFIG)%kw) if kw['profile']: profilecmd = '-m cProfile -o %s'%self.profile_file(kw['profile']) else: profilecmd='' cmd = 'python %s %s' % (profilecmd, run_file) return cmd class NotebookRunTwisted(NotebookRun): name="twistd" TWISTD_NOTEBOOK_CONFIG = """ ######################################################################## # See http://twistedmatrix.com/documents/current/web/howto/using-twistedweb.html # (Serving WSGI Applications) for the basic ideas of the below code #################################################################### ##### START EPOLL # Take this out when Twisted 12.1 is released, since epoll will then # be the default reactor when needed. See http://twistedmatrix.com/trac/ticket/5478 import sys, platform if (platform.system()=='Linux' and (platform.release().startswith('2.6') or platform.release().startswith('3'))): try: from twisted.internet import epollreactor epollreactor.install() except: pass #### END EPOLL def save_notebook2(notebook): from twisted.internet.error import ReactorNotRunning save_notebook(notebook) import signal from twisted.internet import reactor def my_sigint(x, n): try: reactor.stop() except ReactorNotRunning: pass signal.signal(signal.SIGINT, signal.SIG_DFL) signal.signal(signal.SIGINT, my_sigint) from twisted.web import server from twisted.web.wsgi import WSGIResource resource = WSGIResource(reactor, reactor.getThreadPool(), flask_app) class QuietSite(server.Site): def log(*args, **kwargs): "Override the logging so that requests are not logged" pass # Log only errors, not every page hit site = QuietSite(resource) # To log every single page hit, uncomment the following line #site = server.Site(resource) from twisted.application import service, strports application = service.Application("Sage Notebook") s = strports.service(%(strport)r, site) %(open_page)s s.setServiceParent(application) #This has to be done after flask_base.create_app is run from functools import partial reactor.addSystemEventTrigger('before', 'shutdown', partial(save_notebook2, flask_base.notebook)) """ def run_command(self, kw): """Run a twistd webserver.""" # Is a server already running? Check if a Twistd PID exists in # the given directory. self.prepare_kwds(kw) conf = os.path.join(kw['directory'], 'twistedconf.tac') if platformType != 'win32': from twisted.scripts._twistd_unix import checkPID try: checkPID(kw['pidfile']) except SystemExit as e: pid = int(open(kw['pidfile']).read()) if str(e).startswith('Another twistd server is running,'): print('Another Sage Notebook server is running, PID %d.' % pid) old_interface, old_port, old_secure = self.get_old_settings(conf) if (kw['automatic_login'] or kw['upload']) and old_port: old_interface = old_interface or 'localhost' if kw['upload']: import urllib startpath = '/upload_worksheet?url=file://%s' % (urllib.quote(kw['upload'])) else: startpath = '/' print('Opening web browser at http%s://%s:%s%s ...' % ( 's' if old_secure else '', old_interface, old_port, startpath)) from sagenb.misc.misc import open_page as browse_to browse_to(old_interface, old_port, old_secure, startpath) return None print('\nPlease either stop the old server or run the new server in a different directory.') return None ## Create the config file if kw['secure']: kw['strport'] = 'ssl:%(port)s:interface=%(interface)s:privateKey=%(private_pem)s:certKey=%(public_pem)s'%kw else: kw['strport'] = 'tcp:%(port)s:interface=%(interface)s'%kw with open(conf, 'w') as config: config.write((self.config_stub+self.TWISTD_NOTEBOOK_CONFIG)%kw) if kw['profile']: profilecmd = '--profile=%s --profiler=cprofile --savestats'%self.profile_file(kw['profile']) else: profilecmd='' cmd = 'twistd %s --pidfile="%s" -ny "%s"' % (profilecmd, kw['pidfile'], conf) return cmd def get_old_settings(self, conf): """ Returns three settings from the Twisted configuration file conf: the interface, port number, and whether the server is secure. If there are any errors, this returns (None, None, None). """ import re # This should match the format written to twistedconf.tac below. p = re.compile(r'interface="(.*)",port=(\d*),secure=(True|False)') try: interface, port, secure = p.search(open(conf, 'r').read()).groups() if secure == 'True': secure = True else: secure = False return interface, port, secure except (IOError, AttributeError): return None, None, None def cmd_exists(cmd): """ Return True if the given cmd exists. """ return os.system('which %s 2>/dev/null >/dev/null' % cmd) == 0 def notebook_setup(self=None): if not os.path.exists(conf_path): os.makedirs(conf_path) if not cmd_exists('certtool'): raise RuntimeError("You must install certtool to use the secure notebook server.") dn = raw_input("Domain name [localhost]: ").strip() if dn == '': print("Using default localhost") dn = 'localhost' import random template_dict = {'organization': 'SAGE (at %s)' % (dn), 'unit': '389', 'locality': None, 'state': 'Washington', 'country': 'US', 'cn': dn, 'uid': 'sage_user', 'dn_oid': None, 'serial': str(random.randint(1, 2 ** 31)), 'dns_name': None, 'crl_dist_points': None, 'ip_address': None, 'expiration_days': 8999, 'email': 'sage@sagemath.org', 'ca': None, 'tls_www_client': None, 'tls_www_server': True, 'signing_key': True, 'encryption_key': True, } s = "" for key, val in iteritems(template_dict): if val is None: continue if val is True: w = '' elif isinstance(val, list): w = ' '.join(['"%s"' % x for x in val]) else: w = '"%s"' % val s += '%s = %s \n' % (key, w) with open(template_file, 'w') as f: f.write(s) import subprocess if cmd_exists('openssl'): # We use openssl by default if it exists, since it is open # *vastly* faster on Linux, for some weird reason. cmd = ['openssl genrsa 1024 > %s' % private_pem] print("Using openssl to generate key") print(cmd[0]) subprocess.call(cmd, shell=True) else: # We checked above that certtool is available. cmd = ['certtool --generate-privkey --outfile %s' % private_pem] print("Using certtool to generate key") print(cmd[0]) subprocess.call(cmd, shell=True) cmd = ['certtool --generate-self-signed --template %s --load-privkey %s ' '--outfile %s' % (template_file, private_pem, public_pem)] print(cmd[0]) subprocess.call(cmd, shell=True) # Set permissions on private cert os.chmod(private_pem, 0o600) print("Successfully configured notebook.") command={'flask': NotebookRunFlask, 'twistd': NotebookRunTwisted, 'uwsgi': NotebookRunuWSGI, 'tornado': NotebookRunTornado} def notebook_run(self, directory = None, port = 8080, interface = 'localhost', port_tries = 50, secure = False, reset = False, accounts = None, openid = None, server_pool = None, ulimit = '', timeout = None, # timeout for normal worksheets. This is the # same as idle_timeout in server_conf.py doc_timeout = None, # timeout for documentation worksheets upload = None, automatic_login = True, start_path = "", fork = False, quiet = False, server = "twistd", profile = False, subnets = None, require_login = None, open_viewer = None, address = None, ): # Check whether pyOpenSSL is installed or not (see Sage trac #13385) if secure: try: import OpenSSL except ImportError: raise RuntimeError("HTTPS cannot be used without pyOpenSSL" " installed. See the Sage README for more information.") # Turn it into a full path for later conversion to a file URL if upload: upload_abs = os.path.abspath(upload) if os.path.exists(upload_abs): upload = upload_abs else: # They might have expected ~ to be expanded to their user directory upload = os.path.expanduser(upload) if not os.path.exists(upload): raise ValueError("Unable to find the file %s to upload" % upload) if subnets is not None: raise ValueError("""The subnets parameter is no longer supported. Please use a firewall to block subnets, or even better, volunteer to write the code to implement subnets again.""") if require_login is not None or open_viewer is not None: raise ValueError("The require_login and open_viewer parameters are no longer supported. " "Please use automatic_login=True to automatically log in as admin, " "or use automatic_login=False to not automatically log in.") if address is not None: raise ValueError("Use 'interface' instead of 'address' when calling notebook(...).") cwd = os.getcwd() if directory is None: directory = '%s/sage_notebook.sagenb' % DOT_SAGENB else: directory = directory.rstrip('/') if not directory.endswith('.sagenb'): directory += '.sagenb' # First change to the directory that contains the notebook directory wd = os.path.split(directory) if wd[0]: os.chdir(wd[0]) directory = wd[1] pidfile = os.path.join(directory, 'sagenb.pid') port = int(port) if not secure and interface != 'localhost': print('*' * 70) print("WARNING: Running the notebook insecurely not on localhost is dangerous") print("because its possible for people to sniff passwords and gain access to") print("your account. Make sure you know what you are doing.") print('*' * 70) # first use provided values, if none, use loaded values, # if none use defaults nb = notebook.load_notebook(directory) directory = nb._dir if not quiet: print("The notebook files are stored in:", nb._dir) if timeout is not None: nb.conf()['idle_timeout'] = int(timeout) if doc_timeout is not None: nb.conf()['doc_timeout'] = int(doc_timeout) if openid is not None: nb.conf()['openid'] = openid elif not nb.conf()['openid']: # What is the purpose behind this elif? It seems rather pointless. # all it appears to do is set the config to False if bool(config) is False nb.conf()['openid'] = False if accounts is not None: nb.user_manager().set_accounts(accounts) else: nb.user_manager().set_accounts(nb.conf()['accounts']) if nb.user_manager().user_exists('root') and not nb.user_manager().user_exists('admin'): # This is here only for backward compatibility with one # version of the notebook. s = nb.create_user_with_same_password('admin', 'root') # It would be a security risk to leave an escalated account around. if not nb.user_manager().user_exists('admin'): reset = True if reset: passwd = get_admin_passwd() if nb.user_manager().user_exists('admin'): admin = nb.user_manager().user('admin') admin.set_password(passwd) print("Password changed for user 'admin'.") else: nb.user_manager().create_default_users(passwd) print("User admin created with the password you specified.") print("\n\n") print("*" * 70) print("\n") if secure: print("Login to the Sage notebook as admin with the password you specified above.") #nb.del_user('root') # For old notebooks, make sure that default users are always created. # This fixes issue #175 (https://github.com/sagemath/sagenb/issues/175) um = nb.user_manager() for user in ('_sage_', 'pub'): if not um.user_exists(user): um.add_user(user, '', '', account_type='user', force=True) if not um.user_exists('guest'): um.add_user('guest', '', '', account_type='guest', force=True) nb.set_server_pool(server_pool) nb.set_ulimit(ulimit) if os.path.exists('%s/nb-older-backup.sobj' % directory): nb._migrate_worksheets() os.unlink('%s/nb-older-backup.sobj' % directory) print("Updating to new format complete.") nb.upgrade_model() nb.save() del nb if interface != 'localhost' and not secure: print("*" * 70) print("WARNING: Insecure notebook server listening on external interface.") print("Unless you are running this via ssh port forwarding, you are") print("**crazy**! You should run the notebook with the option secure=True.") print("*" * 70) port = find_next_available_port(interface, port, port_tries) if automatic_login: "Automatic login isn't fully implemented. You have to manually open your web browser to the above URL." if secure: if (not os.path.exists(private_pem) or not os.path.exists(public_pem)): print("In order to use an SECURE encrypted notebook, you must first run notebook.setup().") print("Now running notebook.setup()") notebook_setup() if (not os.path.exists(private_pem) or not os.path.exists(public_pem)): print("Failed to setup notebook. Please try notebook.setup() again manually.") kw = dict(port=port, automatic_login=automatic_login, secure=secure, private_pem=private_pem, public_pem=public_pem, interface=interface, directory=directory, pidfile=pidfile, cwd=cwd, profile=profile, upload = upload ) cmd = command[server]().run_command(kw) if cmd is None: return if not quiet: print_open_msg('localhost' if not interface else interface, port, secure=secure) if secure and not quiet: print("There is an admin account. If you do not remember the password,") print("quit the notebook and type notebook(reset=True).") print("Executing {}".format(cmd)) if fork: import pexpect return pexpect.spawn(cmd) else: e = os.system(cmd) os.chdir(cwd) if e == 256: raise socket.error def get_admin_passwd(): print("\n" * 2) print("Please choose a new password for the Sage Notebook 'admin' user.") print("Do _not_ choose a stupid password, since anybody who could guess your password") print("and connect to your machine could access or delete your files.") print("NOTE: Only the hash of the password you type is stored by Sage.") print("You can change your password by typing notebook(reset=True).") print("\n" * 2) while True: passwd = getpass.getpass("Enter new password: ") from sagenb.misc.misc import min_password_length if len(passwd) < min_password_length: print("That password is way too short. Enter a password with at least %d characters."%min_password_length) continue passwd2 = getpass.getpass("Retype new password: ") if passwd != passwd2: print("Sorry, passwords do not match.") else: break print("Please login to the notebook with the username 'admin' and the above password.") return passwd sagenb-1.0.1/sagenb/notebook/sage_email.py000066400000000000000000000154631311436262400205020ustar00rootroot00000000000000# -*- coding: utf-8 -* """ Send an Email Sage supports very easily sending an email from Sage to notify yourself when some event occurs. This does not require configuring an email server or anything else, since Sage already includes by default a sophisticated email server (which is part of Twisted). EXAMPLES:: sage: email('xxxsageuser@gmail.com', 'The calculation finished!') # not tested Child process ... is sending email to xxxsageuser@gmail.com AUTHOR: -- William Stein (2008-12-13) """ from __future__ import absolute_import ############################################################################# # Copyright (C) 2008 William Stein # Distributed under the terms of the GNU General Public License (GPL) # The full text of the GPL is available at: # http://www.gnu.org/licenses/ ############################################################################# import os def default_email_address(): """ Get the hostname and username of the user running this program. This provides a default email from address. OUTPUT: string EXAMPLES:: sage: sagenb.notebook.sage_email.default_email_address() '...@...' """ import socket import getpass hostname = socket.gethostname() username = getpass.getuser() return '%s@%s'%(username, hostname) def email(to, subject, body = '', from_address = None, verbose = True, block = False, kill_on_exit = False): """ Send an email message. INPUT: to -- string; address of recipient subject -- string; subject of the email body -- string (default: ''); body of the email from_address -- string (default: username@hostname); address email will appear to be from verbose -- whether to print status information when the email is sent block -- bool (default: False); if True this function doesn't return until the email is actually sent. if False, the email gets sent in a background thread. kill_on_exit -- bool (default: False): if True, guarantee that the sending mail subprocess is killed when you exit sage, even if it failed to send the message. If False, then the subprocess might keep running for a while. This should never be a problem, but might be useful for certain users. EXAMPLES:: sage: email('xxxsageuser@gmail.com', 'The calculation finished!') # not tested Child process ... is sending email to xxxsageuser@gmail.com NOTE: This function does not require configuring an email server or anything else at all, since Sage already includes by default a sophisticated email server (which is part of Twisted). """ # We use Fork to make this work, because we have to start the # Twisted reactor in order to use it's powerful sendmail # capabilities. Unfortunately, Twisted is purposely designed so # that its reactors cannot be restarted. Thus if we don't fork, # one could send at most one email. Of course, forking means this # won't work on native Windows. It might be possible to get this # to work using threads instead, but I did not do so, since Python # threading with Twisted is not fun, and would likely have many # of the same problems. Plus the below works extremely well. try: pid = os.fork() except: print("Fork not possible -- the email command is not supported on this platform.") return if from_address is None: # Use a default email address as the from: line. from_address = default_email_address() if pid: # We're the parent process if kill_on_exit: # Tell the Sage cleaner about this subprocess, just in case somehow it fails # to properly quit (e.g., smtp is taking a long time), so it will get killed # no matter what when sage exits. Zombies are bad bad bad, no matter what! from sagenb.misc.misc import register_with_cleaner register_with_cleaner(pid) # register pid of forked process with cleaner if verbose: print("Child process %s is sending email to %s..." % (pid, to)) # Now wait for the fake subprocess to finish. os.waitpid(pid,0) return if not block: # Do a non-block sendmail, which is typically what a user wants, since it can take # a while to send an email. # Use the old "double fork" trick -- otherwise there would *definitely* be a zombie # every time. Here's a description from the web of this trick: # "If you can't stand zombies, you can get rid of them with a double fork(). # The forked child immediately forks again while its parent calls waitpid(). # The first forked process exits, and the parent's waitpid() returns, right # away. That leaves an orphaned process whose parent reverts to 1 ("init")." pid = os.fork() if pid: # OK, we're in the subprocess of the subprocess -- we # again register the subprocess we just spawned with the # zombie cleaner just in case, then we kill ourself, as # explained above. if kill_on_exit: from sagenb.misc.misc import register_with_cleaner register_with_cleaner(pid) # register pid of forked process with cleaner os.kill(os.getpid(),9) # suicide # Now we're the child process. Let's do stuff with Twisetd! from .smtpsend import send_mail, reactor # First define two callback functions. Each one optionally prints # some information, then kills the subprocess dead. def on_success(result): """ Callback in case of a successfully sent email. """ if verbose: print("Successfully sent an email to %s." % to) reactor.stop() os.kill(os.getpid(),9) # suicide def on_failure(error): """ Callback in case of a failure sending an email. """ if verbose: print("Failed to send email to %s." % to) print("-" * 70) print(error.getErrorMessage()) print("-" * 70) reactor.stop() os.kill(os.getpid(),9) # suicide # Finally, call the send_mail function. This is code that sets up # a twisted deferred, which actually happens when we run the # reactor. send_mail(from_address, to, subject, body, on_success, on_failure) # Start the twisted reactor. reactor.run() sagenb-1.0.1/sagenb/notebook/sagetex.py000066400000000000000000000024401311436262400200430ustar00rootroot00000000000000# -*- coding: utf-8 -* import os from .notebook_object import notebook def sagetex(filename, gen=True, **kwds): """ Turn a latex document into an interactive notebook server. THIS IS ONLY A PROOF-of-CONCEPT. EXAMPLES:: sage: sagetex('foo.tex') # not tested [pops up web browser with live version of foo.tex.] """ if not os.path.exists(filename): raise IOError("No such file: '%s'" % filename) if not filename.endswith('.tex'): raise ValueError("File must be a latex file (end in .tex): '%s'" % filename) if not '\\document' in open(filename).read(): raise ValueError("File must be a latex file (contain \\document...): '%s'" % filename) if gen: os.system('latex2html -no_images %s'%filename) base = os.path.splitext(os.path.split(filename)[1])[0] absp = os.path.abspath(filename) path = os.path.splitext(absp)[0] for F in os.listdir(base): fn = os.path.join(base, F) if not fn.endswith('.html'): continue r = open(fn).read() r = r.replace('
', '
')
        r = r.replace('
', '
') open(fn,'w').write(r) notebook(sagetex_path=path, start_path="/sagetex/index.html", **kwds) sagenb-1.0.1/sagenb/notebook/server_conf.py000066400000000000000000000143721311436262400207250ustar00rootroot00000000000000# -*- coding: utf-8 -*- """nodoctest """ #from template import language import copy from . import conf from .conf import (POS, DESC, GROUP, TYPE, CHOICES, T_BOOL, T_INTEGER, T_CHOICE, T_REAL, T_COLOR, T_STRING, T_LIST, T_INFO) from sagenb.misc.misc import get_languages, N_ from flask.ext.babel import gettext, lazy_gettext _ = lazy_gettext defaults = {'word_wrap_cols':72, 'max_history_length':250, 'idle_timeout': 0, # timeout in seconds for worksheets 'doc_timeout': 600, # timeout in seconds for live docs 'idle_check_interval':360, 'save_interval':360, # seconds 'doc_pool_size':128, 'pub_interact':False, 'server_pool':[], 'system':'sage', 'pretty_print':False, 'ulimit':'', 'notification_recipients': None, 'email':False, 'accounts':False, 'openid':False, 'challenge':False, 'challenge_type':'simple', 'recaptcha_public_key':'', 'recaptcha_private_key':'', 'default_language': 'en_US', 'model_version': 0, 'auth_ldap':False, 'ldap_uri':'ldap://example.net:389/', 'ldap_basedn':'ou=users,dc=example,dc=net', 'ldap_binddn':'cn=manager,dc=example,dc=net', 'ldap_bindpw': 'secret', 'ldap_gssapi': False, 'ldap_username_attrib': 'cn', 'ldap_timeout': 5, } G_APPEARANCE = _('Appearance') G_AUTH = _('Authentication') G_SERVER = _('Server') G_LDAP = _('LDAP') defaults_descriptions = { 'max_history_length': { DESC : _('Maximum history length'), GROUP : G_SERVER, TYPE : T_INTEGER, }, 'idle_timeout': { POS : 1, DESC : _('Idle timeout for normal worksheets (seconds)'), GROUP : G_SERVER, TYPE : T_INTEGER, }, 'doc_timeout': { POS : 3, DESC : _('Idle timeout for live documentation (seconds)'), GROUP : G_SERVER, TYPE : T_INTEGER, }, 'idle_check_interval': { DESC : _('Idle check interval (seconds)'), GROUP : G_SERVER, TYPE : T_INTEGER, }, 'save_interval': { DESC : _('Save interval (seconds)'), GROUP : G_SERVER, TYPE : T_INTEGER, }, 'doc_pool_size': { DESC : _('Doc worksheet pool size'), GROUP : G_SERVER, TYPE : T_INTEGER, }, 'pub_interact': { DESC : _('Enable published interacts (EXPERIMENTAL; USE AT YOUR OWN RISK)'), GROUP : G_SERVER, TYPE : T_BOOL, }, 'server_pool': { DESC : _('Worksheet process users (comma-separated list)'), GROUP : G_SERVER, TYPE : T_LIST, }, 'system': { DESC : _('Default system'), GROUP : G_SERVER, TYPE : T_STRING, }, 'ulimit': { DESC : _('Worksheet process limits'), GROUP : G_SERVER, TYPE : T_STRING, }, 'model_version': { DESC : _('Model Version'), GROUP : G_SERVER, TYPE : T_INFO, }, 'notification_recipients': { DESC : _('Send notification e-mails to (comma-separated list)'), GROUP : G_SERVER, TYPE : T_LIST, }, 'word_wrap_cols': { DESC : _('Number of word-wrap columns'), GROUP : G_APPEARANCE, TYPE : T_INTEGER, }, 'pretty_print': { DESC : _('Pretty print (typeset) output'), GROUP : G_APPEARANCE, TYPE : T_BOOL, }, 'default_language': { DESC : _('Default Language'), GROUP : G_APPEARANCE, TYPE : T_CHOICE, CHOICES : get_languages(), }, 'openid': { POS: 1, DESC : _('Allow OpenID authentication (requires python ssl module)'), GROUP : G_AUTH, TYPE : T_BOOL, }, 'accounts': { POS : 2, DESC : _('Enable user registration'), GROUP : G_AUTH, TYPE : T_BOOL, }, 'email': { POS : 3, DESC : _('Require e-mail for account registration'), GROUP : G_AUTH, TYPE : T_BOOL, }, 'challenge': { POS : 4, DESC : _('Use a challenge for account registration'), GROUP : G_AUTH, TYPE : T_BOOL, }, 'challenge_type': { POS : 4, DESC : _('Type of challenge'), GROUP : G_AUTH, TYPE : T_CHOICE, CHOICES : [N_('simple'), N_('recaptcha')], }, 'recaptcha_public_key': { DESC : _('reCAPTCHA public key'), GROUP : G_AUTH, TYPE : T_STRING, }, 'recaptcha_private_key': { DESC : _('reCAPTCHA private key'), GROUP : G_AUTH, TYPE : T_STRING, }, 'auth_ldap': { POS : 1, DESC : _('Enable LDAP Authentication'), GROUP : G_LDAP, TYPE : T_BOOL, }, 'ldap_uri': { POS : 2, DESC : _('LDAP URI'), GROUP : G_LDAP, TYPE : T_STRING, }, 'ldap_binddn': { POS : 3, DESC : _('Bind DN'), GROUP : G_LDAP, TYPE : T_STRING, }, 'ldap_bindpw': { POS : 4, DESC : _('Bind Password'), GROUP : G_LDAP, TYPE : T_STRING, }, 'ldap_gssapi': { POS : 5, DESC : _('Use GSSAPI instead of Bind DN/Password'), GROUP : G_LDAP, TYPE : T_BOOL, }, 'ldap_basedn': { POS : 6, DESC : _('Base DN'), GROUP : G_LDAP, TYPE : T_STRING, }, 'ldap_username_attrib': { POS : 7, DESC: _('Username Attribute (i.e. cn, uid or userPrincipalName)'), GROUP : G_LDAP, TYPE : T_STRING, }, 'ldap_timeout': { POS : 8, DESC: _('Query timeout (seconds)'), GROUP : G_LDAP, TYPE : T_INTEGER, }, } def ServerConfiguration_from_basic(basic): c = ServerConfiguration() c.confs = copy.copy(basic) return c class ServerConfiguration(conf.Configuration): def defaults(self): return defaults def defaults_descriptions(self): return defaults_descriptions sagenb-1.0.1/sagenb/notebook/smtpsend.py000066400000000000000000000036041311436262400202430ustar00rootroot00000000000000# -*- coding: utf-8 -* """nodoctest """ ############################################################################# # Copyright (C) 2007 William Stein # Distributed under the terms of the GNU General Public License (GPL) # The full text of the GPL is available at: # http://www.gnu.org/licenses/ ############################################################################# from __future__ import print_function # must be here ! """ Sending mail using Twisted AUTHOR: -- Bobby Moretti """ from twisted.mail import smtp, relaymanager from twisted.internet import reactor, defer from email.MIMEBase import MIMEBase from email.MIMEMultipart import MIMEMultipart from email import Encoders import sys import mimetypes import os def buildMessage(fromaddr, toaddr, subject, body): message = MIMEMultipart() message['From'] = fromaddr message['To'] = toaddr message['Subject'] = subject textPart = MIMEBase('text', 'plain') textPart.set_payload(body) message.attach(textPart) return message def sendComplete(result): print("Message sent.") def handleError(error): print("Error {}".format(error.getErrorMessage()), file=sys.stderr) def send_mail(fromaddr, toaddr, subject, body, on_success=sendComplete, on_failure=handleError): try: recpt_domain = toaddr.split('@')[1].encode("ascii") except (ValueError, IndexError, UnicodeDecodeError): raise ValueError("mal-formed destination address") message = buildMessage(fromaddr, toaddr, subject, body) messageData = message.as_string(unixfrom=False) def on_found_record(mx_rec): smtp_server = str(mx_rec.name) sending = smtp.sendmail(smtp_server, fromaddr, [toaddr], messageData) sending.addCallback(on_success).addErrback(on_failure) relaymanager.MXCalculator().getMX(recpt_domain).addCallback(on_found_record) sagenb-1.0.1/sagenb/notebook/template.py000066400000000000000000000107511311436262400202220ustar00rootroot00000000000000# -*- coding: utf-8 -*- """ HTML Templating for the Notebook AUTHORS: - Bobby Moretti (2007-07-18): initial version - Timothy Clemans and Mike Hansen (2008-10-27): major update """ from __future__ import absolute_import ############################################################################# # Copyright (C) 2007 William Stein # Distributed under the terms of the GNU General Public License (GPL) # The full text of the GPL is available at: # http://www.gnu.org/licenses/ ############################################################################# import jinja2 import os, re, sys from sagenb.misc.misc import SAGE_VERSION, DATA from flask.ext.babel import gettext, ngettext, lazy_gettext from flask import current_app as app if 'SAGENB_TEMPLATE_PATH' in os.environ: if not os.path.isdir(os.environ['SAGENB_TEMPLATE_PATH']): raise ValueError("Enviromental variable SAGENB_TEMPLATE_PATH points to\ a non-existant directory") TEMPLATE_PATH = os.environ['SAGENB_TEMPLATE_PATH'] else: TEMPLATE_PATH = os.path.join(DATA, 'sage') css_illegal_re = re.compile(r'[^-A-Za-z_0-9]') def css_escape(string): r""" Returns a string with all characters not legal in a css name replaced with hyphens (-). INPUT: - ``string`` -- the string to be escaped. EXAMPLES:: sage: from sagenb.notebook.template import css_escape sage: css_escape('abcd') 'abcd' sage: css_escape('12abcd') '12abcd' sage: css_escape(r'\'"abcd\'"') '---abcd---' sage: css_escape('my-invalid/identifier') 'my-invalid-identifier' sage: css_escape(r'quotes"mustbe!escaped') 'quotes-mustbe-escaped' """ return css_illegal_re.sub('-', string) def prettify_time_ago(t): """ Converts seconds to a meaningful string. INPUT - t -- time in seconds """ if t < 60: s = int(t) return ngettext('%(num)d second', '%(num)d seconds', s) if t < 3600: m = int(t/60) return ngettext('%(num)d minute', '%(num)d minutes', m) if t < 3600*24: h = int(t/3600) return ngettext('%(num)d hour', '%(num)d hours', h) d = int(t/(3600*24)) return ngettext('%(num)d day', '%(num)d days', d) def clean_name(name): """ Converts a string to a safe/clean name by converting non-alphanumeric characters to underscores. INPUT: - name -- a string EXAMPLES:: sage: from sagenb.notebook.template import clean_name sage: print(clean_name('this!is@bad+string')) this_is_bad_string """ return ''.join([x if x.isalnum() else '_' for x in name]) def template(filename, **user_context): """ Returns HTML, CSS, etc., for a template file rendered in the given context. INPUT: - ``filename`` - a string; the filename of the template relative to ``sagenb/data/templates`` - ``user_context`` - a dictionary; the context in which to evaluate the file's template variables OUTPUT: - a string - the rendered HTML, CSS, etc. EXAMPLES:: sage: from sagenb.flask_version import base # random output -- depends on warnings issued by other sage packages sage: app = base.create_app(tmp_dir(ext='.sagenb')) sage: ctx = app.app_context() sage: ctx.push() sage: from sagenb.notebook.template import template sage: s = template(os.path.join('html', 'yes_no.html')); type(s) sage: 'Yes' in s True sage: u = unicode('Are Gröbner bases awesome?','utf-8') sage: s = template(os.path.join('html', 'yes_no.html'), message=u) sage: 'Gr\xc3\xb6bner' in s.encode('utf-8') True """ from sagenb.notebook.notebook import MATHJAX, JEDITABLE_TINYMCE from .misc import notebook #A dictionary containing the default context default_context = {'sitename': gettext('Sage Notebook'), 'sage_version': SAGE_VERSION, 'MATHJAX': MATHJAX, 'gettext': gettext, 'JEDITABLE_TINYMCE': JEDITABLE_TINYMCE, 'conf': notebook.conf() if notebook else None} try: tmpl = app.jinja_env.get_template(filename) except jinja2.exceptions.TemplateNotFound: return "Notebook Bug -- missing template %s"%filename context = dict(default_context) context.update(user_context) r = tmpl.render(**context) return r sagenb-1.0.1/sagenb/notebook/tutorial.py000066400000000000000000000555031311436262400202560ustar00rootroot00000000000000# -*- coding: utf-8 -* r"""nodoctest """ ############################################################################# # Copyright (C) 2006, 2007 William Stein # Distributed under the terms of the GNU General Public License (GPL) # The full text of the GPL is available at: # http://www.gnu.org/licenses/ ############################################################################# r""" Sage Notebook Interface AUTHORS: -- William Stein (2006-05-06): initial version -- Alex Clemesha -- Tom Boothby: support for a wide range of web browsers; refactoring of javascript code; systematic keyboard controls -- Dorian Raymer -- Yi Qiang -- Bobby Moretti The Sage graphical user interface is unusual in that it operates via your web browser. It provides you with Sage worksheets that you can edit and evaluate, which contain scalable typeset mathematics and beautiful antialised images. To try it out immediately, do this: sage: notebook() # not tested the sage notebook starts... \subsection{Supported Browsers} The Sage notebook should fully work with Firefox (and Mozilla). It may work to some extent with Safari and Opera. Internet Explorer is not supported. \subsection{Tutorial} Here are some things to try in the the notebook to get a feeling for it. Type "2+2" in the blank box and press "shift-enter". The line below"2+2" will turn a different color for a moment while a Sage kernel fires up and computes the answer. Your cursor should now be in the next box down. Type \code{a = 2\^1000} and press return, then "a" alone on the second line, then shift-return. You'll see a big number. Also, "a" will appear in the variable browser in the left of the screen. Next, click just to the left of the big number in the blue-ish area. The number will shrink a little and change to occupy only one line. You can see the whole number using your browser's horizontal scroll bar. Click again and the number vanishes, to be replaced by a horizontal bar. Click on the bar and the number is back. If you click "Hide Output" in the upper right, all output disappears. Next try graphics! Type "show(plot(sin,0,10))" into an empty box and hit shift-enter. You'll get a graph of sin. Try another function, e.g., \begin{verbatim} show(plot(lambda x: sin(x)^2 - cos(2*x)^3, -5,5)) \end{verbatim} Click on the left side of the figure (twice) to make it disappear. One important feature of the Sage notebook is that you can "queue up" a bunch of calculations in a row, *while* still editing the notebook! As an example, consider computing factorials, which takes a while (but not forever). First, enter the following in a blank box and press"shift-return": \begin{verbatim} def f(n): return len(str(factorial(10^n))) \end{verbatim} This defines a function that takes a while to compute. For example, time the execution of "f(5)", by typing (in a new box), "time f(5)". It should take a few seconds. Next try "f(6)", which takes quite a while (about 21 seconds on sage.math). While f(6) is being computed, note that the output line for f(6) is a different color, indicating that it is being computed While f(6) is computing (if it finishes first, restart it by just hitting shift-enter in the box where "f(6)" is), try typing "f(4)" in the next box. You're allowed to give input, but the result doesn't get computed immediately. You can enter several more lines as well, etc.; when the f(6) finally finishes, Sage goes on to compute "f(4)". You can queue up dozens of calculations. For example, if you hit the "Evaluate" link in the upper right, the whole worksheet is queued up for computation. Try it. When the computation gets stuck on "f(6)", hit the interrupt button (or press escape) and the queued up calculations are cancelled. Click "Hide Output" in the upper right. You'll see just your input and some little boxes; clicking on the boxes reveals output. You can also embed nicely typeset math. Try this: \begin{verbatim} f = maxima('sin(x^2)') g = f.integrate('x') view(g) \end{verbatim} If this silently fails, type "view(g, debug=True)" instead. You need latex and the "convert" and "gs" commands, (use an "apt-get install imagemagick gs"). Anyways, you get a nicely typeset formula. Try a matrix next: \begin{verbatim} A = MatrixSpace(QQ, 5).random_element() view(A) \end{verbatim} Try typing this into a new box: \begin{verbatim} %latex Consider the matrix $$A = \sage{A},$$ which has square $$A^2 = \sage{A^2}.$$ \end{verbatim} If you would like to typeset a slide (suitable for presentation), use \%slide instead. Here is another example: \begin{verbatim} %latex The first ten squares are $$ \sage{', '.join([str(sq(i)) for i in range(1,11)])} $$ The primes up to 100 are $$ \sage{', '.join(str(p) for p in prime_range(100))} $$ \end{verbatim} \subsubsection{Using Gap, Magma, GP/PARI} Make the first line of the input block \code{\%gap} \code{\%magma}, or \code{\%gp}, etc. The rest of the block is fed directly to the corresponding interpreter. In this way you can make a single session that has input blocks that work with a range of different systems. (Note -- there is currently no support for pulling in objects and evaluating code in Sage by typing "sage(...)" inside the input block. This is planned.) \subsubsection{Typesetting Mathematics} SAGE \emph{includes} MathJax, which is an implementation of the TeX math layout engine in javascript. If you use the show or view commands, they display a given Sage object typeset using MathJax. Moreover, if you put \code{\%mathjax} at the beginning of an input cell, the whole cell will be typeset using MathJax. Also, you can type \code{mathjax(obj)} to typeset a given object obj using MathJax. \subsubsection{Adding and Removing Cells} To add a new cell, click on a little black line that appears when you hover between any two cells, or above the top one. To delete a cell delete all its contents, then press ctrl-backspace one more time. The cell vanishes forever. You can also move back and forth between cells using the up and down arrow. In particular, when you are at the top of a cell and press the up arrow the cursor jumps to the previous cell. Press control-enter in a cell to create a new cell after the current cell. There is no direct support for moving and reorganizing cells, though you can copy and paste any individual cell into another one. However, the "Text" buttons provide the full text of the worksheet in a very convenient format for copy and paste. \subsubsection{History} Click the history button near the top to pop up a history of the last 1000 (or so) input cells. After a huge amount of design discussion about how to design a history system, a simple popup with the text of previous commands seems like the best choice. It's incredibly simple, yet provides an incredible amount of functionality, especially because that popup window can be easily searched (at least in Firefox), pasted from, etc., and refreshed (use F5 or Ctrl-R). \subsubsection{Introspection} To find all completions for an identifier you are typing press the tab key. This should work exactly like IPython, and even respects the \code{trait_names()} method. To find help for any object in a line, put ? after it and press the tab key. The cursor must be somewhere in the identifier with the question mark after it. For source code, put ?? after the identifier and press tab. You can also put an identifier by itself on a line with ? (or ??) after it and press shift-enter. Note that only help retrieved by shift-enter appears in printed output. It also overwrites all current output, while using TAB does not. To get extensive help on an object, type "help(object)" and press return. This works, since I set the PAGER to "cat", and I strip out control codes that appear in the output. And this isn't annoying, since web browsers are very good for scrolling through long output. \subsubsection{Saving and Loading Individual Objects} When you start a notebook you give a name argument to it, and it creates a directory. Inside that directory there will be many worksheets (which you can use all at once and easily flip through -- not implemented yet), and an object store. You can save and load individual objects (using save and load), and they'll be listed in the box on the bottom let, e.g., try a = 5 save a and you'll see the "a" appear there. You can load and save objects from any worksheet in any other one. (Currently the only way to delete objects from the list of saved objects is to remove the object from the objects subdirectory.) \subsubsection{Pasting in Examples} Code is evaluated by exec'ing (after preparsing). Only the output of the last line of the cell is implicitly printed. If any line starts with "sage:" or ">>>" the \emph{entire block} is assumed to contain text and examples, and only lines that begin with a prompt are executed. Thus you can paste in *complete examples* from the docs without any editing, and you can write input cells that contains non-evaluated plain text mixed with examples by starting the block with ">>>" or including an example. (NOTE: Lines beginning with ">>>" are still preparsed.) \subsubsection{Saving and Loading Notebooks and Worksheets} The Sage notebook is very persistent. Every time you submit a cell for computation, the state of the notebook is saved (a few kb's file). If you quit the notebook and reload, it will have everything you typed from the previous session, along with all output. Firefox has an excellent undo function for text input cells. Just hit control-z to have ``infinite undo'' for the input you've entered in that particular cell. You can save all variables in a current session using the \code{save_session} command, and you can then load those session variables using the \code{load_session} command. \subsubsection{Architecture} The Sage Notebook is an ``AJAX application'' that can run either entirely locally on your desktop machine, or partly on a server and via a web browser that could be located somewhere else. If you run the server and allow remote access (by setting address when starting the notebook), you should also set the username and password, so not just anybody can access the notebook. Anywhere, here are the components of the Sage Notebook: \begin{enumerate} \item Web Server: A Python process that uses the Python standard library's BaseHTTPServer.HTTPServer to create a web server. This process also handles all requests from the web browser, e.g., organizing computation of cells, etc. It only imports a small subset of the Sage library. In particular, if you do "sage -notebook" at the command line, only some of Sage is imported. \item Sage Server: A Python process with all the Sage libraries loaded; this is started by (1) when a web browser first requests that a cell be evaluated. There's (up to) one of these for each worksheet. \item WEB Browser: The web browser runs a 1000-line javascript (plus 800 lines of css) program that Alex, Tom and I wrote from scratch, which implements much of the browser-side part of the Sage notebook functionality. \end{enumerate} When you use the Sage Notebook, you are mainly interacting with a javascript program. When you do something serious, e.g., request computation of some input, create a new cell, etc., a request is made from your web browser to the web server telling it what is going on. If it's a calculation, the web server tells the Sage server to get started on the calculation, and tells the web browser to check several times a second whether there is anything new with the calculation. When something new appears it fills that in. This continues until all calculations are done. During this time, you can edit cells, create new cells, submit more computations, etc. Note that output is updated as the computation proceeds, so you can verbosely watch a computation progress. For example, try the following from the Sage Notebook: \begin{verbatim} import time for i in range(10): print(i) time.sleep(0.5) \end{verbatim} You get to watch as the integers from 1 to 10 are "computed". Actually, getting this output to be reported as the computation proceeds is, I think, \emph{crucial} to making a really usable Sage GUI--users (i.e., me) want to run huge computations and watch the output progress. The architecture is also good from the point of view of being able to interrupt running computations. What happens when you request an interrupt is that the web browser sends a message to the web server, which in turn tells the Sage server to stop computing by sending it many interrupt signals (for several seconds) until it either stops, or if it's really frozen (due to a bug, or calling into a C function that isn't properly wrapped in signal handling, or maybe you run an interactive program, e.g., via "os.system('...')"), it'll just kill that Sage server and start a new one. The result is that the user doesn't get a frozen web browser or browser interface at any point, and even if the whole Sage process went down and froze, at least all your input and output from your session is still there in your browser. The only thing you've lost is the definition of all your variables. Hit "shift-enter" a few times or "evaluate all" and you're back in shape. This is much better than having to restart the command prompt (e.g., with a terminal interface), then paste back in all your setup code, etc., Also, you can save variables as you go easily (via the "save" command), and get back to where you were quickly. """ ## This is commented out, since it's not recommended. I really ## don't like crap that is both potentially insecure and will ## break on some setups. ## \subsubsection{Typesetting with Latex} ## If you have latex, gv, and the imagemagick programs (e.g., convert) ## installed on your system, you can do nice latex typesetting from ## within SAGE. ## \begin{enumerate} ## \item As usual the command \code{latex(obj)} outputs latex code ## to typeset obj. ## \item The command \code{view(obj)} creates an image representing ## the object, which you can copy and paste into other documents. ## \item If you preface a block with \code{\%latex} the rest of the ## block is typeset and the corresponding image appears. ## The input is also (mostly) hidden. Use {\%latex_debug} to debug ## latex problems. ## \item If you preface a block with \code{\%slide} the rest of the ## block is typeset as a slide (bigger san serif font) ## and the corresponding image appears. The input is again hidden. ## Use {\%slide_debug} for debugging. ## \end{enumerate} ##################################### from flask.ext.babel import lazy_gettext as _ notebook_help = [ (_('Find Help and Documentation'), [(_('Get Started with Sage'), _('Work through the tutorial (if you have trouble with it, view the static version).')), (_('Help About'), _('Type ? immediately after the object or function and press tab or shift-enter (shift-enter overwrites output and saves to worksheet). Doing this twice or more toggles with formatted source code.')), (_('Source Code'), _('Put ?? after the object and press tab or shift-enter (shift-enter overwrites output and saves to worksheet). Doing this twice or more toggles with just the documentation.')), (_('Full Text Search of Docs and Source'), _('Search the SAGE documentation by typing
search_doc("my query")
in an input cell and press shift-enter. Search the source code of SAGE by typing
search_src("my query")
and pressing shift-enter. Arbitrary regular expressions are allowed as queries.')), (_('Live Documentation'), _('Use live documentation to try out the full Sage documentation "live". (Only new compute cells allowed, click the icon.)')), # ('More Help', # 'Type "help(sagenb.notebook.notebook)" for a detailed discussion of the architecture of the SAGE notebook and a tutorial (or see the SAGE reference manual).'), ]), (_('Key and Mouse Bindings'), [(_('Evaluate Input'), _('Press shift-enter or click the "evaluate" button. You can start several calculations at once. If you press alt-enter instead, then a new cell is created after the current one. If you press ctrl-enter then the cell is split and both pieces are evaluated separately.')), (_('Tab Completion'), _('Press tab while the cursor is on an identifier. On some web browsers (e.g., Opera) you must use control-space instead of tab.')), (_('Insert New Cell'), _('Put the mouse between an output and input until the blue horizontal line appears and click, or click the "plus" icon. If you press Alt-Enter in a cell, the cell is evaluated and a new cell is inserted after it.')), (_('Delete Cell'), _('Delete all cell contents, then press backspace.')), (_('Split and Join Cells'), _('Press ctrl-; in a cell to split it into two cells, and ctrl-backspace to join them. Press ctrl-enter to split a cell and evaluate both pieces.')), (_('Insert New Text Cell'), _('Move the mouse between cells until a blue bar appears. Shift-click on the blue bar, or click on the text bubble icon, to create a new text cell. Use $...$ and $$...$$ to include typeset math in the text block. Click the button to save changes, or press shift-enter.')), (_('Edit Text Cell'), _('Double click on existing text to edit it.')), (_('Hide/Show Output'), _('Click on the left side of output to toggle between hidden, shown with word wrap, and shown without word wrap.')), (_('Indenting Blocks'), _('Highlight text and press > to indent it all and < to unindent it all (works in Safari and Firefox). In Firefox you can also press tab and shift-tab.')), (_('Comment/Uncomment Blocks'), _('Highlight text and press ctrl-. to comment it and ctrl-, to uncomment it. As an alternative (necessary in some browsers), use ctrl-3 and ctrl-4.')), (_('Paren matching'), _('To fix unmatched or mis-matched parentheses, braces or brackets, press ctrl-0. Parentheses before the cursor will be matched, minding strings and (Python) comments.')), # ('Emacs Keybindings', # 'If you are using GNU/Linux, you can change (or create) a .gtkrc-2.0 file. Add the line gtk-key-theme-name = "Emacs" to it. See this page [mozillazine.org] for more details.'), ]), (_('Interrupt and Restart Sessions'), [(_('Interrupt Running Calculations'), _('Click Interrupt or press escape in any input cell. This will (attempt) to interrupt SAGE by sending many interrupt signals.')), (_('Restart'), _('Type "restart" to restart the SAGE interpreter for a given worksheet. (You have to interrupt first.)')), ]), (_('Special Cell Blocks'), [(_('Evaluate Cell using GAP, Singular, etc.'), _('Put "%%gap", "%%singular", etc. as the first input line of a cell; the rest of the cell is evaluated in that system.')), (_('Shell Scripts'), _('Begin a block with %%sh to have the rest of the block evaluated as a shell script. The current working directory is maintained.')), (_('Interactive Dynamic Widgets'), _('Put @interact on the line before a function definition. Type interact? for more details.')), (_('Autoevaluate Cells on Load'), _('Any cells with "#auto" in the input is automatically evaluated when the worksheet is first opened.')), (_('Time'), _('Type "%%time" at the beginning of the cell.')), ]), (_('Useful Tips'), [(_('Input Rules'), _("Code is evaluated by exec'ing (after preparsing). Only the output of the last line of the cell is implicitly printed. If any line starts with \"sage:\" or \">>>\" the entire block is assumed to contain text and examples, so only lines that begin with a prompt are executed. Thus you can paste in complete examples from the docs without any editing, and you can write input cells that contains non-evaluated plain text mixed with examples by starting the block with \">>>\" or including an example.")), (_('History'), _('Click log commands you have entered in any worksheet of this notebook.')), (_('Typesetting All Output'), _('Type pretty_print_default() in an input cell and press shift-enter. All future output will be typeset automatically.')), ]), (_('Files and Scripts'), [(_('Loading SAGE/Python Scripts'), _('Use "load filename.sage" and "load filename.py". Load is relative to the path you started the notebook in. The .sage files are preparsed and .py files are not. You may omit the .sage or .py extension. Files may load other files.')), (_('Attaching Scripts'), _('(Currently no different from "load", see bug report) Use "attach filename.sage" or "attach filename.py". Attached files are automatically reloaded when the file changes. The file $HOME/.sage/init.sage is attached on startup if it exists.')), (_('Working Directory'), _('Each block of code is run from its own directory. If any images are created as a side effect, they will automatically be displayed.')), (_('DIR Variable'), _('The variable DIR contains the directory from which you started the SAGE notebook. For example, to open a file in that directory, do "open(DIR+\'filename\')".')), (_('DATA Variable'), _('Use the Data menu to upload images and other files, and create new files that can be shared between worksheets. The DATA variable contains the path to the data files. For example, to open a file in that directory, do "open(DATA+\'filename\')". If foo.sage is a Sage file that you uploaded, type "load foo.sage"; if foo.py is a Python file, you can import it by typing "import foo".')), (_('Loading and Saving Objects'), _('Use "save(obj1,DATA+\'foo\')" to save an object to the data directory of a worksheet, and "obj1 = load(DATA+\'foo\')" to load it again. To use such objects between worksheets, you may save to any filename (given as a string) Sage can write to on your system.')), (_('Loading and Saving Sessions'), _('Use "save_session(\'name\')" to save all variables to an object. Use "load_session(\'name\')" to merge in all variables from a saved session.')), (_('Customizing the Notebook CSS'), _('If you create a file $HOME/.sage/notebook.css then it will get applied when rendering the notebook. See ')) ]) ] sagenb-1.0.1/sagenb/notebook/user.py000066400000000000000000000252421311436262400173660ustar00rootroot00000000000000# -*- coding: utf-8 -* from __future__ import absolute_import import copy import crypt import random import hashlib import os try: import cPickle as pickle except ImportError: import pickle from six import iteritems SALT = 'aa' from . import user_conf from sage.misc.temporary_file import atomic_write def User_from_basic(basic): """ Create a user from a basic data structure. """ user = User(basic['username']) user.__dict__.update(dict([('_' + x, y) for x, y in iteritems(basic)])) user._conf = user_conf.UserConfiguration_from_basic(user._conf) return user def generate_salt(): """ Returns a salt for use in hashing. """ return hex(random.getrandbits(256))[2:-1] class User(object): def __init__(self, username, password='', email='', account_type='admin', external_auth=None): self._username = username self.set_password(password) self._email = email self._email_confirmed = False if not account_type in ['admin', 'user', 'guest']: raise ValueError("account type must be one of admin, user, or guest") self._account_type = account_type self._external_auth = external_auth self._conf = user_conf.UserConfiguration() self._temporary_password = '' self._is_suspended = False self._viewable_worksheets = set() def __eq__(self, other): if self.__class__ is not other.__class__: return False elif self.username() != other.username(): return False elif self.get_email() != other.get_email(): return False elif self.conf() != other.conf(): return False elif self.account_type() != other.account_type(): return False else: return True def __getstate__(self): d = copy.copy(self.__dict__) # Some old worksheets have this attribute, which we do *not* want to save. if 'history' in d: try: self.save_history() del d['history'] except Exception as msg: print(msg) print("Unable to dump history of user %s to disk yet." % self._username) return d def basic(self): """ Return a basic Python data structure from which self can be reconstructed. """ d = {x[1:]: y for x, y in iteritems(self.__dict__) if x[0] == '_'} d['conf'] = self._conf.basic() return d def history_list(self): try: return self.history except AttributeError: from . import misc # late import if misc.notebook is None: return [] history_file = "%s/worksheets/%s/history.sobj"%(misc.notebook.directory(), self._username) if os.path.exists(history_file): try: self.history = pickle.load(open(history_file)) except: print("Error loading history for user %s" % self._username) self.history = [] else: self.history = [] return self.history def save_history(self): if not hasattr(self, 'history'): return from . import misc # late import if misc.notebook is None: return history_file = "%s/worksheets/%s/history.sobj"%(misc.notebook.directory(), self._username) try: his = pickle.dumps(self.history) except AttributeError: his = pickle.dumps([]) with atomic_write(history_file) as f: f.write(his) def username(self): """ EXAMPLES:: sage: from sagenb.notebook.user import User sage: User('andrew', 'tEir&tiwk!', 'andrew@matrixstuff.com', 'user').username() 'andrew' sage: User('sarah', 'Miaasc!', 'sarah@ellipticcurves.org', 'user').username() 'sarah' sage: User('bob', 'Aisfa!!', 'bob@sagemath.net', 'admin').username() 'bob' """ return self._username def password(self): """ Deprecated. Use user_manager object instead. EXAMPLES:: sage: from sagenb.notebook.user import User sage: User('andrew', 'tEir&tiwk!', 'andrew@matrixstuff.com', 'user').password() #random """ return self._password def __repr__(self): return self._username def conf(self): """ EXAMPLES:: sage: from sagenb.notebook.user import User sage: config = User('bob', 'Aisfa!!', 'bob@sagemath.net', 'admin').conf(); config Configuration: {} sage: config['max_history_length'] 1000 sage: config['default_system'] 'sage' sage: config['autosave_interval'] 3600 sage: config['default_pretty_print'] False """ return self._conf def __getitem__(self, *args): return self._conf.__getitem__(*args) def __setitem__(self, *args): self._conf.__setitem__(*args) def set_password(self, password, encrypt=True): """ EXAMPLES:: sage: from sagenb.notebook.user import User sage: user = User('bob', 'Aisfa!!', 'bob@sagemath.net', 'admin') sage: old = user.password() sage: user.set_password('Crrc!') sage: old != user.password() True """ if password == '': self._password = 'x' # won't get as a password -- i.e., this account is closed. else: if encrypt: salt = generate_salt() self._password = 'sha256${0}${1}'.format(salt, hashlib.sha256(salt + password).hexdigest()) else: self._password = password self._temporary_password = '' def set_hashed_password(self, password): """ EXAMPLES:: sage: from sagenb.notebook.user import User sage: user = User('bob', 'Aisfa!!', 'bob@sagemath.net', 'admin') sage: user.set_hashed_password('Crrc!') sage: user.password() 'Crrc!' """ self._password = password self._temporary_password = '' def get_email(self): """ EXAMPLES:: sage: from sagenb.notebook.user import User sage: user = User('bob', 'Aisfa!!', 'bob@sagemath.net', 'admin') sage: user.get_email() 'bob@sagemath.net' """ return self._email def set_email(self, email): """ EXAMPLES:: sage: from sagenb.notebook.user import User sage: user = User('bob', 'Aisfa!!', 'bob@sagemath.net', 'admin') sage: user.get_email() 'bob@sagemath.net' sage: user.set_email('bob@gmail.gov') sage: user.get_email() 'bob@gmail.gov' """ self._email = email def set_email_confirmation(self, value): """ EXAMPLES:: sage: from sagenb.notebook.user import User sage: user = User('bob', 'Aisfa!!', 'bob@sagemath.net', 'admin') sage: user.is_email_confirmed() False sage: user.set_email_confirmation(True) sage: user.is_email_confirmed() True sage: user.set_email_confirmation(False) sage: user.is_email_confirmed() False """ value = bool(value) self._email_confirmed = value def is_email_confirmed(self): """ EXAMPLES:: sage: from sagenb.notebook.user import User sage: user = User('bob', 'Aisfa!!', 'bob@sagemath.net', 'admin') sage: user.is_email_confirmed() False """ try: return self._email_confirmed except AttributeError: self._email_confirmed = False return False def account_type(self): """ EXAMPLES:: sage: from sagenb.notebook.user import User sage: User('A', account_type='admin').account_type() 'admin' sage: User('B', account_type='user').account_type() 'user' sage: User('C', account_type='guest').account_type() 'guest' """ if self._username == 'admin': return 'admin' return self._account_type def is_admin(self): """ EXAMPLES:: sage: from sagenb.notebook.user import User sage: User('A', account_type='admin').is_admin() True sage: User('B', account_type='user').is_admin() False """ return self.account_type() == 'admin' def grant_admin(self): if not self.is_guest(): self._account_type = 'admin' def revoke_admin(self): if not self.is_guest(): self._account_type = 'user' def is_guest(self): """ EXAMPLES:: sage: from sagenb.notebook.user import User sage: User('A', account_type='guest').is_guest() True sage: User('B', account_type='user').is_guest() False """ return self.account_type() == 'guest' def is_external(self): return self.external_auth() is not None def external_auth(self): return self._external_auth def is_suspended(self): """ EXAMPLES:: sage: from sagenb.notebook.user import User sage: user = User('bob', 'Aisfa!!', 'bob@sagemath.net', 'admin') sage: user.is_suspended() False """ try: return self._is_suspended except AttributeError: return False def set_suspension(self): """ EXAMPLES:: sage: from sagenb.notebook.user import User sage: user = User('bob', 'Aisfa!!', 'bob@sagemath.net', 'admin') sage: user.is_suspended() False sage: user.set_suspension() sage: user.is_suspended() True sage: user.set_suspension() sage: user.is_suspended() False """ try: self._is_suspended = False if self._is_suspended else True except AttributeError: self._is_suspended = True def viewable_worksheets(self): """ Returns the (mutable) set of viewable worksheets. The elements of the set are of the form ('owner',id), identifying worksheets the user is able to view. """ return self._viewable_worksheets sagenb-1.0.1/sagenb/notebook/user_conf.py000066400000000000000000000021541311436262400203700ustar00rootroot00000000000000# -*- coding: utf-8 -* """nodoctest """ import os import copy from . import server_conf from .conf import (Configuration, POS, DESC, GROUP, TYPE, CHOICES, T_BOOL, T_INTEGER, T_CHOICE, T_REAL, T_COLOR, T_STRING, T_LIST) from sagenb.misc.misc import SAGENB_ROOT, get_languages from flask.ext.babel import lazy_gettext defaults = {'max_history_length':1000, 'default_system':'sage', 'autosave_interval':60*60, # 1 hour in seconds 'default_pretty_print': False, 'next_worksheet_id_number': -1, # not yet initialized 'language': 'default' } defaults_descriptions = { 'language': { DESC : lazy_gettext('Language'), GROUP : lazy_gettext('Appearance'), TYPE : T_CHOICE, CHOICES : ['default'] + get_languages(), }, } def UserConfiguration_from_basic(basic): c = UserConfiguration() c.confs = copy.copy(basic) return c class UserConfiguration(Configuration): def defaults(self): return defaults def defaults_descriptions(self): return defaults_descriptions sagenb-1.0.1/sagenb/notebook/user_db.py000066400000000000000000000013641311436262400200320ustar00rootroot00000000000000# -*- coding: utf-8 -* """nodoctest """ ############################################################################# # Copyright (C) 2007 William Stein # Distributed under the terms of the GNU General Public License (GPL) # The full text of the GPL is available at: # http://www.gnu.org/licenses/ ############################################################################# class UserDatabase(): def add_user(self, user, passwd, email): self[user] = UserRecord(user, passwd, email) def remove_user(self, user): del self[user] class UserRecord: def __init__(self, username, passwd, email): self.username = username self.passwd = passwd self.email = email sagenb-1.0.1/sagenb/notebook/user_manager.py000066400000000000000000000533531311436262400210640ustar00rootroot00000000000000from __future__ import absolute_import from . import user import crypt import hashlib SALT = 'aa' class UserManager(object): def __init__(self, accounts=False): """ EXAMPLES: sage: from sagenb.notebook.user_manager import SimpleUserManager sage: U = SimpleUserManager() sage: U == loads(dumps(U)) True """ self._users = {} self._accounts = accounts def __eq__(self, other): """ EXAMPLES: sage: from sagenb.notebook.user_manager import SimpleUserManager sage: U1 = SimpleUserManager() sage: U2 = SimpleUserManager(accounts=False) sage: U1 == U2 False sage: U2.set_accounts(True) sage: U1 == U2 True sage: U1.create_default_users('password') sage: U1 == U2 False sage: U2.create_default_users('password') sage: U1 == U2 True """ if other.__class__ is not self.__class__: return False if self._users != other._users: return False if self._accounts != other._accounts: return False return True def user_list(self): """ Returns a sorted list of the users that have logged into the notebook. EXAMPLES: sage: from sagenb.notebook.user_manager import SimpleUserManager sage: U = SimpleUserManager() sage: U.create_default_users('password') sage: U.user_list() [_sage_, admin, guest, pub] """ user_list = list(self.users().itervalues()) user_list.sort(key=lambda x: str(x)) return user_list def users(self): """ Returns a dictionary whose keys are the usernames and whose values are the corresponding users. Note that these are just the users that have logged into the notebook and are note necessarily all of the valid users. EXAMPLES: sage: from sagenb.notebook.user_manager import SimpleUserManager sage: U = SimpleUserManager() sage: U.create_default_users('password') sage: list(sorted(U.users().items())) [('_sage_', _sage_), ('admin', admin), ('guest', guest), ('pub', pub)] """ return self._users def user(self, username): """ Returns a user object for the user username. This first checks to see if a user with username has been seen before and is in the users dictionary. If such a user is found, then that object is returned. Otherwise, the underscore _user method is tried. This is the method that subclasses should override to provide custom user functionality. EXAMPLES:: sage: from sagenb.notebook.user_manager import SimpleUserManager sage: U = SimpleUserManager() sage: U.create_default_users('password') sage: U.user('pub') pub TESTS:: sage: U.user('william') Traceback (most recent call last): ... LookupError: no user 'william' sage: U.user('hello/') Traceback (most recent call last): ... ValueError: no user 'hello/' """ if not isinstance(username, (str, unicode)) or '/' in username: raise ValueError("no user '%s'" % username) if username in self.users(): return self.users()[username] try: return self._user(username) except AttributeError: pass raise LookupError("no user '{}'".format(username)) def valid_login_names(self): """ Return a list of users that can log in. """ return [x for x in self.usernames() if not x in ['guest', '_sage_', 'pub']] def user_exists(self, username): """ Returns True if and only if the user \emph{username} has signed in before. Note that this should not be used to check to see if a username is valid since there are UserManager backends (such as LDAP) where we could have many valid usernames, but not all of them will have actually logged into the notebook. EXAMPLES: sage: from sagenb.notebook.user_manager import SimpleUserManager sage: U = SimpleUserManager() sage: U.create_default_users('password') sage: U.user_exists('admin') True """ return username in self.users() def usernames(self): """ EXAMPLES: sage: from sagenb.notebook.user_manager import SimpleUserManager sage: U = SimpleUserManager() sage: U.create_default_users('password') sage: u = U.usernames(); u.sort(); u ['_sage_', 'admin', 'guest', 'pub'] """ return self.users().keys() def user_is_admin(self, username): """ Returns True if the user username is an admin user. EXAMPLES: sage: from sagenb.notebook.user_manager import SimpleUserManager sage: U = SimpleUserManager() sage: U.create_default_users('password') sage: U.user_is_admin('admin') True sage: U.user_is_admin('pub') False """ try: return self.user(username).is_admin() except KeyError: return False def user_is_guest(self, username): """ Returns True if the user username is an gues user. EXAMPLES: sage: from sagenb.notebook.user_manager import SimpleUserManager sage: U = SimpleUserManager() sage: U.create_default_users('password') sage: U.user_is_guest('guest') True sage: U.user_is_guest('admin') False """ try: return self.user(username).is_guest() except KeyError: return False def create_default_users(self, passwd, verbose=False): """ Creates the default users (pub, _sage_, guest, and admin) in the current notebook. EXAMPLES: sage: from sagenb.notebook.user_manager import SimpleUserManager sage: U = SimpleUserManager() sage: U.create_default_users('password') sage: U.user_list() [_sage_, admin, guest, pub] """ if verbose: print("Creating default users.") self.add_user('pub', '', '', account_type='user', force=True) self.add_user('_sage_', '', '', account_type='user', force=True) self.add_user('guest', '', '', account_type='guest', force=True) self.add_user('admin', passwd, '', account_type='admin', force=True) def delete_user(self, username): """ Deletes the user username from the users dictionary. EXAMPLES: sage: from sagenb.notebook.user_manager import SimpleUserManager sage: U = SimpleUserManager() sage: U.create_default_users('password') sage: U.user_list() [_sage_, admin, guest, pub] sage: U.delete_user('pub') sage: U.user_list() [_sage_, admin, guest] """ us = self.users() if username in us: del us[username] def user_conf(self, username): """ Returns the configuration dictionary for the user username. EXAMPLES: sage: from sagenb.notebook.user_manager import SimpleUserManager sage: U = SimpleUserManager() sage: U.create_default_users('password') sage: U.user('admin').conf() Configuration: {} """ return self.user(username).conf() def set_accounts(self, value): """ Set whether or not accounts can be created for this notebook. EXAMPLES: sage: from sagenb.notebook.user_manager import SimpleUserManager sage: U = SimpleUserManager() sage: U.create_default_users('password') sage: U.get_accounts() True sage: U.set_accounts(False) sage: U.get_accounts() False """ if value not in [True, False]: raise ValueError("accounts must be True or False") self._accounts = value def get_accounts(self): """ Get whether or not accounts can be created for this notebook. EXAMPLES: sage: from sagenb.notebook.user_manager import SimpleUserManager sage: U = SimpleUserManager() sage: U.create_default_users('password') sage: U.get_accounts() True sage: U.set_accounts(False) sage: U.get_accounts() False """ return self._accounts def add_user(self, username, password, email, account_type="user", external_auth=None, force=False): """ Adds a new user to the user dictionary. INPUT: username -- the username password -- the password email -- the email address account_type -- one of 'user', 'admin', or 'guest' EXAMPLES: sage: from sagenb.notebook.user_manager import SimpleUserManager sage: U = SimpleUserManager() sage: U.add_user('william', 'password', 'email@address.com', account_type='admin') sage: U.set_accounts(True) sage: U.add_user('william', 'password', 'email@address.com', account_type='admin') WARNING: User 'william' already exists -- and is now being replaced. sage: U.user('william') william """ if not self.get_accounts() and not force: raise ValueError("creating new accounts disabled.") us = self.users() if username in us: print("WARNING: User '%s' already exists -- and is now being replaced." % username) U = user.User(username, password, email, account_type, external_auth) us[username] = U self.set_password(username, password) def add_user_object(self, user, force=False): """ Adds a new user to the user dictionary. INPUT: user -- a User object EXAMPLES: sage: from sagenb.notebook.user_manager import SimpleUserManager sage: from sagenb.notebook.user import User sage: U = SimpleUserManager() sage: user = User('william', 'password', 'email@address.com', account_type='admin') sage: U.add_user_object(user) sage: U.set_accounts(True) sage: U.add_user_object(user) WARNING: User 'william' already exists -- and is now being replaced. sage: U.user('william') william """ if not self.get_accounts() and not force: raise ValueError("creating new accounts disabled.") us = self.users() if user.username() in us: print("WARNING: User '%s' already exists -- and is now being replaced." % user.username()) self._users[user.username()] = user class SimpleUserManager(UserManager): def __init__(self, accounts=True, conf=None): """ EXAMPLES: sage: from sagenb.notebook.user_manager import SimpleUserManager sage: U = SimpleUserManager() sage: U == loads(dumps(U)) True """ self._passwords = {} UserManager.__init__(self, accounts=accounts) self._conf = {'accounts': accounts} if conf is None else conf def copy_password(self, username, other_username): """ Sets the password of user to be the password of other_user. EXAMPLES: sage: from sagenb.notebook.user_manager import SimpleUserManager sage: UM = SimpleUserManager(accounts=True) sage: UM.create_default_users('passpass') sage: UM.add_user('william', 'password', 'email@address.com') sage: UM.check_password('admin','passpass') True sage: UM.check_password('william','password') True sage: UM.copy_password('william', 'admin') sage: UM.check_password('william','passpass') True """ O = self.user(other_username) passwd = O.password() self.set_password(username, passwd, encrypt=False) def _user(self, username): """ Returns a User object with username username. This method is called by UserManager.user if it did not find a user with username username in the user dictionary. This method will automatically create users for the usernames 'pub', '_sage_', 'admin', and 'guest'. EXAMPLES: sage: from sagenb.notebook.user_manager import SimpleUserManager sage: U = SimpleUserManager() sage: U.user('guest') guest sage: U.user('pub') pub sage: U.user('admin') admin TESTS:: sage: U.user('william') Traceback (most recent call last): ... LookupError: no user 'william' sage: U._user('william') Traceback (most recent call last): ... LookupError: no user 'william' sage: U.user('hello/') Traceback (most recent call last): ... ValueError: no user 'hello/' sage: U._user('hello/') Traceback (most recent call last): ... LookupError: no user 'hello/' """ if username in ['pub', '_sage_']: self.add_user(username, '', '', account_type='user', force=True) return self.users()[username] elif username == 'admin': self.add_user(username, '', '', account_type='admin', force=True) return self.users()[username] elif username == 'guest': self.add_user('guest', '', '', account_type='guest', force=True) return self.users()[username] raise LookupError("no user '{}'".format(username)) def set_password(self, username, new_password, encrypt = True): """ EXAMPLES: sage: from sagenb.notebook.user_manager import SimpleUserManager sage: U = SimpleUserManager() sage: U.create_default_users('passpass') sage: U.check_password('admin','passpass') True sage: U.set_password('admin', 'password') sage: U.check_password('admin','password') True sage: U.set_password('admin', 'test'); U.check_password('admin','test') True sage: U.set_password('admin', 'test', encrypt=False); U.password('admin') 'test' """ if encrypt: salt = user.generate_salt() new_password = 'sha256${0}${1}'.format(salt, hashlib.sha256(salt + new_password).hexdigest()) self._passwords[username] = new_password # need to make sure password in the user object is synced # for compatibility only the user object data is stored in the 'users.pickle' self.user(username).set_password(new_password, encrypt = False) def passwords(self): """ Return a dictionary whose keys are the usernames and whose values are the encrypted passwords associated to the user. EXAMPLES: sage: from sagenb.notebook.user_manager import SimpleUserManager sage: U = SimpleUserManager() sage: U.create_default_users('passpass') sage: list(sorted(U.passwords().items())) #random [('_sage_', ''), ('admin', ''), ('guest', ''), ('pub', '')] sage: len(list(sorted(U.passwords().items()))) 4 """ return dict([(user.username(), self.password(user.username())) for user in self.user_list()]) def password(self, username): """ Return the stored password for username. Might be encrypted. EXAMPLES: sage: from sagenb.notebook.user_manager import SimpleUserManager sage: U = SimpleUserManager() sage: U.create_default_users('passpass') sage: U.check_password('admin','passpass') True """ return self._passwords.get(username, None) def check_password(self, username, password): # the empty password is always false if username == "pub" or password == '': return False user_password = self.password(username) if user_password is None and not self.user(username).is_external(): print("User %s has None password" % username) return False if user_password.find('$') == -1: if user_password == crypt.crypt(password, user.SALT): self.set_password(username, password) return True else: return False else: salt, user_password = user_password.split('$')[1:] if hashlib.sha256(salt + password).hexdigest() == user_password: return True try: return self._check_password(username, password) except AttributeError: return False def get_accounts(self): # need to use notebook's conf because those are already serialized # fix when user_manager is serialized return self._conf['accounts'] def set_accounts(self, value): if value not in [True, False]: raise ValueError("accounts must be True or False") self._accounts = value self._conf['accounts'] = value class ExtAuthUserManager(SimpleUserManager): def __init__(self, accounts=None, conf=None): SimpleUserManager.__init__(self, accounts=accounts, conf=conf) from .auth import LdapAuth # keys must match to a T_BOOL option in server_config.py # so we can turn this auth method on/off self._auth_methods = { 'auth_ldap': LdapAuth(self._conf), } def _user(self, username): """ Check all auth methods that are enabled in the notebook's config. If a valid username is found, a new User object will be created. """ for a in self._auth_methods: if self._conf[a]: u = self._auth_methods[a].check_user(username) if u: try: email = self._auth_methods[a].get_attrib(username, 'email') except KeyError: email = None self.add_user(username, password='', email=email, account_type='user', external_auth=a, force=True) return self.users()[username] raise LookupError("no user '{}'".format(username)) def _check_password(self, username, password): """ Find auth method for user 'username' and use that auth method to check username/password combination. """ u = self.users()[username] if u.is_external(): a = u.external_auth() else: return False if self._conf[a]: return self._auth_methods[a].check_password(username, password) return False class OpenIDUserManager(ExtAuthUserManager): def __init__(self, accounts=True, conf=None): """ Creates an user_manager that supports OpenID identities EXAMPLES: sage: from sagenb.notebook.user_manager import OpenIDUserManager sage: UM = OpenIDUserManager() sage: UM.create_default_users('passpass') sage: UM.check_password('admin','passpass') True """ ExtAuthUserManager.__init__(self, accounts=accounts, conf=conf) self._openid = {} def load(self, datastore): """ Loads required data from a given datastore. """ self._openid = datastore.load_openid() def save(self, datastore): """ Saves persistent data to a given datastore. """ datastore.save_openid(self._openid) def get_username_from_openid(self, identity_url): """ Return the username corresponding ot a given identity_url EXAMPLES: sage: from sagenb.notebook.user_manager import OpenIDUserManager sage: UM = OpenIDUserManager() sage: UM.create_default_users('passpass') sage: UM.create_new_openid('https://www.google.com/accounts/o8/id?id=AItdaWgzjV1HJTa552549o1csTDdfeH6_bPxF14', 'thedude') sage: UM.get_username_from_openid('https://www.google.com/accounts/o8/id?id=AItdaWgzjV1HJTa552549o1csTDdfeH6_bPxF14') 'thedude' """ try: return self._openid[identity_url] except KeyError: raise LookupError("no openID identity '{}'".format(identity_url)) def create_new_openid(self, identity_url, username): """ Create a new identity_url -- username pairing EXAMPLES: sage: from sagenb.notebook.user_manager import OpenIDUserManager sage: UM = OpenIDUserManager() sage: UM.create_default_users('passpass') sage: UM.create_new_openid('https://www.google.com/accounts/o8/id?id=AItdaWgzjV1HJTa552549o1csTDdfeH6_bPxF14', 'thedude') sage: UM.get_username_from_openid('https://www.google.com/accounts/o8/id?id=AItdaWgzjV1HJTa552549o1csTDdfeH6_bPxF14') 'thedude' """ self._openid[identity_url] = username def get_user_from_openid(self, identity_url): """ Return the user object corresponding ot a given identity_url """ return self.user(self.get_username_from_openid(identity_url)) sagenb-1.0.1/sagenb/notebook/wiki2html.py000066400000000000000000001254711311436262400203270ustar00rootroot00000000000000# -*- coding: utf-8 -* """nodoctest """ ############################################################################# # Copyright (C) 2007 William Stein # Distributed under the terms of the GNU General Public License (GPL) # The full text of the GPL is available at: # http://www.gnu.org/licenses/ ############################################################################# """ Wiki to HTML converter Adopted from the Moin Moin Markup Parser (which is GPL'd) and @copyright: 2000, 2001, 2002 by Jurgen Hermann @license: GNU GPL, see COPYING for details. AUTHOR: -- Jurgen Hermann: Moin Moin version -- William Stein: adoption for Sage """ import os, re from MoinMoin import config, wikimacro, wikiutil from MoinMoin.Page import Page from MoinMoin.util import web Dependencies = [] class Parser: """ Object that turns Wiki markup into HTML. All formatting commands can be parsed one line at a time, though some state is carried over between lines. Methods named like _*_repl() are responsible to handle the named regex patterns defined in print_html(). """ # allow caching caching = 1 Dependencies = [] # some common strings PARENT_PREFIX = wikiutil.PARENT_PREFIX attachment_schemas = ["attachment", "inline", "drawing"] punct_pattern = re.escape(u'''"\'}]|:,.)?!''') url_pattern = (u'http|https|ftp|nntp|news|mailto|telnet|wiki|file|irc|' + u'|'.join(attachment_schemas) + (config.url_schemas and u'|' + u'|'.join(config.url_schemas) or '')) # some common rules word_rule = r'(?:(?&#(\d{1,5}|x[0-9a-fA-F]+);) (?:(?P'''''(?=[^']+''')) (?P'''''(?=[^']+'')) (?P'{5}(?=[^'])) (?P'{2,3}) (?P__) (?P\^.*?\^) (?P,,[^,]{1,40},,) (?P\{\{\{.*?\}\}\}) (?P(\{\{\{(#!.*|\s*$))) (?P
(\{\{\{ ?|\}\}\}))
(?P(\~- ?|-\~))
(?P(\~\+ ?|\+\~))
(?P(--\(|\)--))
(?P-{4,})
(?P^\#\#.*$)
(?P\[\[(%%(macronames)s)(?:\(.*?\))?\]\]))
(?P
    %(ol_rule)s) (?P
    %(dl_rule)s) (?P
  1. ^\s+\*\s*) (?P^\s+\.\s*) (?P^\s+) (?P\|\| $) (?P(?:\|\|)+(?:<[^>]*?>)?(?!\|? $)) (?P^\s*(?P=+)\s.*\s(?P=hmarker) $) (?P[A-Z][a-zA-Z]+\:[^\s'\"\:\<\|]([^\s%(punct)s]|([%(punct)s][^\s%(punct)s]))+) (?P%(word_rule)s) (?P\[((%(url)s)\:|#|\:)[^\s\]]+(\s[^\]]+)?\]) (?P%(url_rule)s) (?P[-\w._+]+\@[\w-]+(\.[\w-]+)+) (?P(?<=\s)(%(smiley)s)(?=\s)) (?P^(%(smiley)s)(?=\s)) (?P&[a-zA-Z]+;) (?P[<>&]) (?P\[".*?"\]) (?P`.*?`)""" % { 'url': url_pattern, 'punct': punct_pattern, 'ol_rule': ol_rule, 'dl_rule': dl_rule, 'url_rule': url_rule, 'word_rule': word_rule, 'smiley': u'|'.join(map(re.escape, config.smileys.keys()))} # Don't start p before these no_new_p_before = ("heading rule table tableZ tr td " "ul ol dl dt dd li li_none indent " "macro processor pre") no_new_p_before = no_new_p_before.split() no_new_p_before = dict(zip(no_new_p_before, [1] * len(no_new_p_before))) def __init__(self, raw, request, **kw): self.raw = raw self.request = request self.form = request.form self._ = request.getText self.cfg = request.cfg self.line_anchors = kw.get('line_anchors', True) self.macro = None self.start_line = kw.get('start_line', 0) self.is_em = 0 self.is_b = 0 self.is_u = 0 self.is_strike = 0 self.lineno = 0 self.in_list = 0 # between
      and
    self.in_li = 0 # between
  2. and
  3. self.in_dd = 0 # between
    and
    self.in_pre = 0 self.in_table = 0 self.is_big = False self.is_small = False self.inhibit_p = 0 # if set, do not auto-create a

    aragraph self.titles = request._page_headings # holds the nesting level (in chars) of open lists self.list_indents = [] self.list_types = [] self.formatting_rules = self.formatting_rules % {'macronames': u'|'.join(wikimacro.getNames(self.cfg))} def _close_item(self, result): #result.append("\n") if self.in_table: result.append(self.formatter.table(0)) self.in_table = 0 if self.in_li: self.in_li = 0 if self.formatter.in_p: result.append(self.formatter.paragraph(0)) result.append(self.formatter.listitem(0)) if self.in_dd: self.in_dd = 0 if self.formatter.in_p: result.append(self.formatter.paragraph(0)) result.append(self.formatter.definition_desc(0)) #result.append("\n") def interwiki(self, url_and_text, **kw): # TODO: maybe support [wiki:Page http://wherever/image.png] ? if len(url_and_text) == 1: url = url_and_text[0] text = None else: url, text = url_and_text # keep track of whether this is a self-reference, so links # are always shown even the page doesn't exist. is_self_reference = 0 url2 = url.lower() if url2.startswith('wiki:self:'): url = url[10:] # remove "wiki:self:" is_self_reference = 1 elif url2.startswith('wiki:'): url = url[5:] # remove "wiki:" tag, tail = wikiutil.split_wiki(url) if text is None: if tag: text = tail else: text = url url = "" elif (url.startswith(wikiutil.CHILD_PREFIX) or # fancy link to subpage [wiki:/SubPage text] is_self_reference or # [wiki:Self:LocalPage text] or [:LocalPage:text] Page(self.request, url).exists()): # fancy link to local page [wiki:LocalPage text] return self._word_repl(url, text) wikitag, wikiurl, wikitail, wikitag_bad = wikiutil.resolve_wiki(self.request, url) href = wikiutil.join_wiki(wikiurl, wikitail) # check for image URL, and possibly return IMG tag if not kw.get('pretty_url', 0) and wikiutil.isPicture(wikitail): return self.formatter.image(src=href) # link to self? if wikitag is None: return self._word_repl(wikitail) return (self.formatter.interwikilink(1, tag, tail) + self.formatter.text(text) + self.formatter.interwikilink(0, tag, tail)) def attachment(self, url_and_text, **kw): """ This gets called on attachment URLs. """ _ = self._ if len(url_and_text) == 1: url = url_and_text[0] text = None else: url, text = url_and_text inline = url[0] == 'i' drawing = url[0] == 'd' url = url.split(":", 1)[1] url = wikiutil.url_unquote(url, want_unicode=True) text = text or url from MoinMoin.action import AttachFile if drawing: return self.formatter.attachment_drawing(url, text) # check for image URL, and possibly return IMG tag # (images are always inlined, just like for other URLs) if not kw.get('pretty_url', 0) and wikiutil.isPicture(url): return self.formatter.attachment_image(url) # inline the attachment if inline: return self.formatter.attachment_inlined(url, text) return self.formatter.attachment_link(url, text) def _u_repl(self, word): """Handle underline.""" self.is_u = not self.is_u return self.formatter.underline(self.is_u) def _strike_repl(self, word): """Handle strikethrough.""" # XXX we don't really enforce the correct sequence --( ... )-- here self.is_strike = not self.is_strike return self.formatter.strike(self.is_strike) def _small_repl(self, word): """Handle small.""" if word.strip() == '~-' and self.is_small: return self.formatter.text(word) if word.strip() == '-~' and not self.is_small: return self.formatter.text(word) self.is_small = not self.is_small return self.formatter.small(self.is_small) def _big_repl(self, word): """Handle big.""" if word.strip() == '~+' and self.is_big: return self.formatter.text(word) if word.strip() == '+~' and not self.is_big: return self.formatter.text(word) self.is_big = not self.is_big return self.formatter.big(self.is_big) def _emph_repl(self, word): """Handle emphasis, i.e. '' and '''.""" if len(word) == 3: self.is_b = not self.is_b if self.is_em and self.is_b: self.is_b = 2 return self.formatter.strong(self.is_b) else: self.is_em = not self.is_em if self.is_em and self.is_b: self.is_em = 2 return self.formatter.emphasis(self.is_em) def _emph_ibb_repl(self, word): """Handle mixed emphasis, i.e. ''''' followed by '''.""" self.is_b = not self.is_b self.is_em = not self.is_em if self.is_em and self.is_b: self.is_b = 2 return self.formatter.emphasis(self.is_em) + self.formatter.strong(self.is_b) def _emph_ibi_repl(self, word): """Handle mixed emphasis, i.e. ''''' followed by ''.""" self.is_b = not self.is_b self.is_em = not self.is_em if self.is_em and self.is_b: self.is_em = 2 return self.formatter.strong(self.is_b) + self.formatter.emphasis(self.is_em) def _emph_ib_or_bi_repl(self, word): """Handle mixed emphasis, exactly five '''''.""" b_before_em = self.is_b > self.is_em > 0 self.is_b = not self.is_b self.is_em = not self.is_em if b_before_em: return self.formatter.strong(self.is_b) + self.formatter.emphasis(self.is_em) else: return self.formatter.emphasis(self.is_em) + self.formatter.strong(self.is_b) def _sup_repl(self, word): """Handle superscript.""" return self.formatter.sup(1) + \ self.formatter.text(word[1:-1]) + \ self.formatter.sup(0) def _sub_repl(self, word): """Handle subscript.""" return self.formatter.sub(1) + \ self.formatter.text(word[2:-2]) + \ self.formatter.sub(0) def _rule_repl(self, word): """Handle sequences of dashes.""" result = self._undent() + self._closeP() if len(word) <= 4: result = result + self.formatter.rule() else: # Create variable rule size 1 - 6. Actual size defined in css. size = min(len(word), 10) - 4 result = result + self.formatter.rule(size) return result def _word_repl(self, word, text=None): """Handle WikiNames.""" # check for parent links # !!! should use wikiutil.AbsPageName here, but setting `text` # correctly prevents us from doing this for now if word.startswith(wikiutil.PARENT_PREFIX): if not text: text = word word = '/'.join(filter(None, self.formatter.page.page_name.split('/')[:-1] + [word[wikiutil.PARENT_PREFIX_LEN:]])) if not text: # if a simple, self-referencing link, emit it as plain text if word == self.formatter.page.page_name: return self.formatter.text(word) text = word if word.startswith(wikiutil.CHILD_PREFIX): word = self.formatter.page.page_name + '/' + word[wikiutil.CHILD_PREFIX_LEN:] # handle anchors parts = word.split("#", 1) anchor = "" if len(parts)==2: word, anchor = parts return (self.formatter.pagelink(1, word, anchor=anchor) + self.formatter.text(text) + self.formatter.pagelink(0, word)) def _notword_repl(self, word): """Handle !NotWikiNames.""" return self.formatter.nowikiword(word[1:]) def _interwiki_repl(self, word): """Handle InterWiki links.""" wikitag, wikiurl, wikitail, wikitag_bad = wikiutil.resolve_wiki(self.request, word) if wikitag_bad: return self.formatter.text(word) else: return self.interwiki(["wiki:" + word]) def _url_repl(self, word): """Handle literal URLs including inline images.""" scheme = word.split(":", 1)[0] if scheme == "wiki": return self.interwiki([word]) if scheme in self.attachment_schemas: return self.attachment([word]) if wikiutil.isPicture(word): word = wikiutil.mapURL(self.request, word) # Get image name http://here.com/dir/image.gif -> image name = word.split('/')[-1] name = ''.join(name.split('.')[:-1]) return self.formatter.image(src=word, alt=name) else: return (self.formatter.url(1, word, css=scheme) + self.formatter.text(word) + self.formatter.url(0)) def _wikiname_bracket_repl(self, word): """Handle special-char wikinames.""" wikiname = word[2:-2] if wikiname: return self._word_repl(wikiname) else: return self.formatter.text(word) def _url_bracket_repl(self, word): """Handle bracketed URLs.""" # Local extended link? if word[1] == ':': words = word[2:-1].split(':', 1) if len(words) == 1: words = words * 2 words[0] = 'wiki:Self:%s' % words[0] return self.interwiki(words, pretty_url=1) #return self._word_repl(words[0], words[1]) # Traditional split on space words = word[1:-1].split(None, 1) if len(words) == 1: words = words * 2 if words[0][0] == '#': # anchor link return (self.formatter.url(1, words[0]) + self.formatter.text(words[1]) + self.formatter.url(0)) scheme = words[0].split(":", 1)[0] if scheme == "wiki": return self.interwiki(words, pretty_url=1) if scheme in self.attachment_schemas: return self.attachment(words, pretty_url=1) if wikiutil.isPicture(words[1]) and re.match(self.url_rule, words[1]): return (self.formatter.url(1, words[0], css='external', do_escape=0) + self.formatter.image(title=words[0], alt=words[0], src=words[1]) + self.formatter.url(0)) else: return (self.formatter.url(1, words[0], css=scheme, do_escape=0) + self.formatter.text(words[1]) + self.formatter.url(0)) def _email_repl(self, word): """Handle email addresses (without a leading mailto:).""" return (self.formatter.url(1, "mailto:" + word, css='mailto') + self.formatter.text(word) + self.formatter.url(0)) def _ent_repl(self, word): """Handle SGML entities.""" return self.formatter.text(word) #return {'&': '&', # '<': '<', # '>': '>'}[word] def _ent_numeric_repl(self, word): """Handle numeric (decimal and hexadecimal) SGML entities.""" return self.formatter.rawHTML(word) def _ent_symbolic_repl(self, word): """Handle symbolic SGML entities.""" return self.formatter.rawHTML(word) def _indent_repl(self, match): """Handle pure indentation (no - * 1. markup).""" result = [] if not (self.in_li or self.in_dd): self._close_item(result) self.in_li = 1 css_class = None if self.line_was_empty and not self.first_list_item: css_class = 'gap' result.append(self.formatter.listitem(1, css_class=css_class, style="list-style-type:none")) return ''.join(result) def _li_none_repl(self, match): """Handle type=none (" .") lists.""" result = [] self._close_item(result) self.in_li = 1 css_class = None if self.line_was_empty and not self.first_list_item: css_class = 'gap' result.append(self.formatter.listitem(1, css_class=css_class, style="list-style-type:none")) return ''.join(result) def _li_repl(self, match): """Handle bullet (" *") lists.""" result = [] self._close_item(result) self.in_li = 1 css_class = None if self.line_was_empty and not self.first_list_item: css_class = 'gap' result.append(self.formatter.listitem(1, css_class=css_class)) return ''.join(result) def _ol_repl(self, match): """Handle numbered lists.""" return self._li_repl(match) def _dl_repl(self, match): """Handle definition lists.""" result = [] self._close_item(result) self.in_dd = 1 result.extend([ self.formatter.definition_term(1), self.formatter.text(match[1:-3].lstrip(' ')), self.formatter.definition_term(0), self.formatter.definition_desc(1), ]) return ''.join(result) def _indent_level(self): """Return current char-wise indent level.""" return len(self.list_indents) and self.list_indents[-1] def _indent_to(self, new_level, list_type, numtype, numstart): """Close and open lists.""" open = [] # don't make one out of these two statements! close = [] if self._indent_level() != new_level and self.in_table: close.append(self.formatter.table(0)) self.in_table = 0 while self._indent_level() > new_level: self._close_item(close) if self.list_types[-1] == 'ol': tag = self.formatter.number_list(0) elif self.list_types[-1] == 'dl': tag = self.formatter.definition_list(0) else: tag = self.formatter.bullet_list(0) close.append(tag) del self.list_indents[-1] del self.list_types[-1] if self.list_types: # we are still in a list if self.list_types[-1] == 'dl': self.in_dd = 1 else: self.in_li = 1 # Open new list, if necessary if self._indent_level() < new_level: self.list_indents.append(new_level) self.list_types.append(list_type) if self.formatter.in_p: close.append(self.formatter.paragraph(0)) if list_type == 'ol': tag = self.formatter.number_list(1, numtype, numstart) elif list_type == 'dl': tag = self.formatter.definition_list(1) else: tag = self.formatter.bullet_list(1) open.append(tag) self.first_list_item = 1 self.in_li = 0 self.in_dd = 0 # If list level changes, close an open table if self.in_table and (open or close): close[0:0] = [self.formatter.table(0)] self.in_table = 0 self.in_list = self.list_types != [] return ''.join(close) + ''.join(open) def _undent(self): """Close all open lists.""" result = [] #result.append("\n") self._close_item(result) for type in self.list_types[::-1]: if type == 'ol': result.append(self.formatter.number_list(0)) elif type == 'dl': result.append(self.formatter.definition_list(0)) else: result.append(self.formatter.bullet_list(0)) #result.append("\n") self.list_indents = [] self.list_types = [] return ''.join(result) def _tt_repl(self, word): """Handle inline code.""" return self.formatter.code(1) + \ self.formatter.text(word[3:-3]) + \ self.formatter.code(0) def _tt_bt_repl(self, word): """Handle backticked inline code.""" # if len(word) == 2: return "" // removed for FCK editor return self.formatter.code(1, css="backtick") + \ self.formatter.text(word[1:-1]) + \ self.formatter.code(0) def _getTableAttrs(self, attrdef): # skip "|" and initial "<" while attrdef and attrdef[0] == "|": attrdef = attrdef[1:] if not attrdef or attrdef[0] != "<": return {}, '' attrdef = attrdef[1:] # extension for special table markup def table_extension(key, parser, attrs, wiki_parser=self): """ returns: tuple (found_flag, msg) found_flag: whether we found something and were able to process it here true for special stuff like 100% or - or #AABBCC false for style xxx="yyy" attributes msg: "" or an error msg """ _ = wiki_parser._ found = False msg = '' if key[0] in "0123456789": token = parser.get_token() if token != '%': wanted = '%' msg = _('Expected "%(wanted)s" after "%(key)s", got "%(token)s"') % { 'wanted': wanted, 'key': key, 'token': token} else: try: dummy = int(key) except ValueError: msg = _('Expected an integer "%(key)s" before "%(token)s"') % { 'key': key, 'token': token} else: found = True attrs['width'] = '"%s%%"' % key elif key == '-': arg = parser.get_token() try: dummy = int(arg) except ValueError: msg = _('Expected an integer "%(arg)s" after "%(key)s"') % { 'arg': arg, 'key': key} else: found = True attrs['colspan'] = '"%s"' % arg elif key == '|': arg = parser.get_token() try: dummy = int(arg) except ValueError: msg = _('Expected an integer "%(arg)s" after "%(key)s"') % { 'arg': arg, 'key': key} else: found = True attrs['rowspan'] = '"%s"' % arg elif key == '(': found = True attrs['align'] = '"left"' elif key == ':': found = True attrs['align'] = '"center"' elif key == ')': found = True attrs['align'] = '"right"' elif key == '^': found = True attrs['valign'] = '"top"' elif key == 'v': found = True attrs['valign'] = '"bottom"' elif key == '#': arg = parser.get_token() try: if len(arg) != 6: raise ValueError dummy = int(arg, 16) except ValueError: msg = _('Expected a color value "%(arg)s" after "%(key)s"') % { 'arg': arg, 'key': key} else: found = True attrs['bgcolor'] = '"#%s"' % arg return found, self.formatter.rawHTML(msg) # scan attributes attr, msg = wikiutil.parseAttributes(self.request, attrdef, '>', table_extension) if msg: msg = '%s' % msg #self.request.log("parseAttributes returned %r" % attr) return attr, msg def _tableZ_repl(self, word): """Handle table row end.""" if self.in_table: result = '' # REMOVED: check for self.in_li, p should always close if self.formatter.in_p: result = self.formatter.paragraph(0) result += self.formatter.table_cell(0) + self.formatter.table_row(0) return result else: return self.formatter.text(word) def _table_repl(self, word): """Handle table cell separator.""" if self.in_table: result = [] # check for attributes attrs, attrerr = self._getTableAttrs(word) # start the table row? if self.table_rowstart: self.table_rowstart = 0 result.append(self.formatter.table_row(1, attrs)) else: # Close table cell, first closing open p # REMOVED check for self.in_li, paragraph should close always! if self.formatter.in_p: result.append(self.formatter.paragraph(0)) result.append(self.formatter.table_cell(0)) # check for adjacent cell markers if word.count("|") > 2: if not 'align' in attrs and \ not ('style' in attrs and 'text-align' in attrs['style'].lower()): # add center alignment if we don't have some alignment already attrs['align'] = '"center"' if not 'colspan' in attrs: attrs['colspan'] = '"%d"' % (word.count("|")/2) # return the complete cell markup result.append(self.formatter.table_cell(1, attrs) + attrerr) result.append(self._line_anchordef()) return ''.join(result) else: return self.formatter.text(word) def _heading_repl(self, word): """Handle section headings.""" from hashlib import sha1 h = word.strip() level = 1 while h[level:level+1] == '=': level += 1 depth = min(5,level) # this is needed for Included pages # TODO but it might still result in unpredictable results # when included the same page multiple times title_text = h[level:-level].strip() pntt = self.formatter.page.page_name + title_text self.titles.setdefault(pntt, 0) self.titles[pntt] += 1 unique_id = '' if self.titles[pntt] > 1: unique_id = '-%d' % self.titles[pntt] result = self._closeP() result += self.formatter.heading(1, depth, id="head-"+sha1.new(pntt.encode(config.charset)).hexdigest()+unique_id) return (result + self.formatter.text(title_text) + self.formatter.heading(0, depth)) def _processor_repl(self, word): """Handle processed code displays.""" if word[:3] == '{{{': word = word[3:] self.processor = None self.processor_name = None self.processor_is_parser = 0 s_word = word.strip() if s_word == '#!': # empty bang paths lead to a normal code display # can be used to escape real, non-empty bang paths word = '' self.in_pre = 3 return self._closeP() + self.formatter.preformatted(1) elif s_word[:2] == '#!': # First try to find a processor for this (will go away in 2.0) processor_name = s_word[2:].split()[0] self.setProcessor(processor_name) if self.processor: self.processor_name = processor_name self.in_pre = 2 self.colorize_lines = [word] return '' elif s_word: self.in_pre = 3 return self._closeP() + self.formatter.preformatted(1) + \ self.formatter.text(s_word + ' (-)') else: self.in_pre = 1 return '' def _pre_repl(self, word): """Handle code displays.""" word = word.strip() if word == '{{{' and not self.in_pre: self.in_pre = 3 return self._closeP() + self.formatter.preformatted(self.in_pre) elif word == '}}}' and self.in_pre: self.in_pre = 0 self.inhibit_p = 0 return self.formatter.preformatted(self.in_pre) return self.formatter.text(word) def _smiley_repl(self, word): """Handle smileys.""" return self.formatter.smiley(word) _smileyA_repl = _smiley_repl def _comment_repl(self, word): # if we are in a paragraph, we must close it so that normal text following # in the line below the comment will reopen a new paragraph. if self.formatter.in_p: self.formatter.paragraph(0) self.line_is_empty = 1 # markup following comment lines treats them as if they were empty return self.formatter.comment(word) def _closeP(self): if self.formatter.in_p: return self.formatter.paragraph(0) return '' def _macro_repl(self, word): """Handle macros ([[macroname]]).""" macro_name = word[2:-2] self.inhibit_p = 0 # 1 fixes UserPreferences, 0 fixes paragraph formatting for macros # check for arguments args = None if macro_name.count("("): macro_name, args = macro_name.split('(', 1) args = args[:-1] # create macro instance if self.macro is None: self.macro = wikimacro.Macro(self) return self.formatter.macro(self.macro, macro_name, args) def scan(self, scan_re, line): """ Scans one line Append text before match, invoke replace() with match, and add text after match. """ result = [] lastpos = 0 ###result.append(u'[scan: "%s"]' % line) for match in scan_re.finditer(line): # Add text before the match if lastpos < match.start(): ###result.append(u'[add text before match: "%s"]' % line[lastpos:match.start()]) if not (self.inhibit_p or self.in_pre or self.formatter.in_p): result.append(self.formatter.paragraph(1, css_class="line862")) result.append(self.formatter.text(line[lastpos:match.start()])) # Replace match with markup if not (self.inhibit_p or self.in_pre or self.formatter.in_p or self.in_table or self.in_list): result.append(self.formatter.paragraph(1, css_class="line867")) result.append(self.replace(match)) lastpos = match.end() ###result.append('[no match, add rest: "%s"]' % line[lastpos:]) # Add paragraph with the remainder of the line if not (self.in_pre or self.in_li or self.in_dd or self.inhibit_p or self.formatter.in_p) and lastpos < len(line): result.append(self.formatter.paragraph(1, css_class="line874")) result.append(self.formatter.text(line[lastpos:])) return u''.join(result) def replace(self, match): """ Replace match using type name """ result = [] for type, hit in match.groupdict().items(): if hit is not None and type != "hmarker": ###result.append(u'[replace: %s: "%s"]' % (type, hit)) if self.in_pre and type not in ['pre', 'ent']: return self.formatter.text(hit) else: # Open p for certain types if not (self.inhibit_p or self.formatter.in_p or self.in_pre or (type in self.no_new_p_before)): result.append(self.formatter.paragraph(1, css_class="line891")) # Get replace method and replece hit replace = getattr(self, '_' + type + '_repl') result.append(replace(hit)) return ''.join(result) else: # We should never get here import pprint raise Exception("Can't handle match {}\n".format(match) + pprint.pformat(match.groupdict()) + "\n" + pprint.pformat(match.groups())) return "" def _line_anchordef(self): if self.line_anchors and not self.line_anchor_printed: self.line_anchor_printed = 1 return self.formatter.line_anchordef(self.lineno) else: return '' def format(self, formatter): """ For each line, scan through looking for magic strings, outputting verbatim any intervening text. """ self.formatter = formatter self.hilite_re = self.formatter.page.hilite_re # prepare regex patterns rules = self.formatting_rules.replace('\n', '|') if self.cfg.bang_meta: rules = r'(?P!%(word_rule)s)|%(rules)s' % { 'word_rule': self.word_rule, 'rules': rules, } self.request.clock.start('compile_huge_and_ugly') scan_re = re.compile(rules, re.UNICODE) number_re = re.compile(self.ol_rule, re.UNICODE) term_re = re.compile(self.dl_rule, re.UNICODE) indent_re = re.compile("^\s*", re.UNICODE) eol_re = re.compile(r'\r?\n', re.UNICODE) self.request.clock.stop('compile_huge_and_ugly') # get text and replace TABs rawtext = self.raw.expandtabs() # go through the lines self.lineno = self.start_line self.lines = eol_re.split(rawtext) self.line_is_empty = 0 self.in_processing_instructions = 1 # Main loop for line in self.lines: self.lineno += 1 self.line_anchor_printed = 0 if not self.in_table: self.request.write(self._line_anchordef()) self.table_rowstart = 1 self.line_was_empty = self.line_is_empty self.line_is_empty = 0 self.first_list_item = 0 self.inhibit_p = 0 # ignore processing instructions if self.in_processing_instructions: found = False for pi in ("##", "#format", "#refresh", "#redirect", "#deprecated", "#pragma", "#form", "#acl", "#language"): if line.lower().startswith(pi): self.request.write(self.formatter.comment(line)) found = True break if not found: self.in_processing_instructions = 0 else: continue # do not parse this line if self.in_pre: # TODO: move this into function # still looking for processing instructions # TODO: use strings for pre state, not numbers if self.in_pre == 1: self.processor = None self.processor_is_parser = 0 processor_name = '' if (line.strip()[:2] == "#!"): processor_name = line.strip()[2:].split()[0] self.setProcessor(processor_name) if self.processor: self.in_pre = 2 self.colorize_lines = [line] self.processor_name = processor_name continue else: self.request.write(self._closeP() + self.formatter.preformatted(1)) self.in_pre = 3 if self.in_pre == 2: # processing mode endpos = line.find("}}}") if endpos == -1: self.colorize_lines.append(line) continue if line[:endpos]: self.colorize_lines.append(line[:endpos]) # Close p before calling processor # TODO: do we really need this? self.request.write(self._closeP()) res = self.formatter.processor(self.processor_name, self.colorize_lines, self.processor_is_parser) self.request.write(res) del self.colorize_lines self.in_pre = 0 self.processor = None # send rest of line through regex machinery line = line[endpos+3:] if not line.strip(): # just in the case "}}} " when we only have blanks left... continue else: # we don't have \n as whitespace any more # This is the space between lines we join to one paragraph line += ' ' # Paragraph break on empty lines if not line.strip(): if self.in_table: self.request.write(self.formatter.table(0)) self.request.write(self._line_anchordef()) self.in_table = 0 # CHANGE: removed check for not self.list_types # p should close on every empty line if self.formatter.in_p: self.request.write(self.formatter.paragraph(0)) self.line_is_empty = 1 continue # Check indent level indent = indent_re.match(line) indlen = len(indent.group(0)) indtype = "ul" numtype = None numstart = None if indlen: match = number_re.match(line) if match: numtype, numstart = match.group(0).strip().split('.') numtype = numtype[0] if numstart and numstart[0] == "#": numstart = int(numstart[1:]) else: numstart = None indtype = "ol" else: match = term_re.match(line) if match: indtype = "dl" # output proper indentation tags self.request.write(self._indent_to(indlen, indtype, numtype, numstart)) # Table mode # TODO: move into function? if (not self.in_table and line[indlen:indlen + 2] == "||" and line[-3:] == "|| " and len(line) >= 5 + indlen): # Start table if self.list_types and not self.in_li: self.request.write(self.formatter.listitem(1, style="list-style-type:none")) ## CHANGE: no automatic p on li ##self.request.write(self.formatter.paragraph(1)) self.in_li = 1 # CHANGE: removed check for self.in_li # paragraph should end before table, always! if self.formatter.in_p: self.request.write(self.formatter.paragraph(0)) attrs, attrerr = self._getTableAttrs(line[indlen+2:]) self.request.write(self.formatter.table(1, attrs) + attrerr) self.in_table = True # self.lineno elif (self.in_table and not # intra-table comments should not break a table (line[:2] == "##" or line[indlen:indlen + 2] == "||" and line[-3:] == "|| " and len(line) >= 5 + indlen)): # Close table self.request.write(self.formatter.table(0)) self.request.write(self._line_anchordef()) self.in_table = 0 # Scan line, format and write formatted_line = self.scan(scan_re, line) self.request.write(formatted_line) if self.in_pre == 3: self.request.write(self.formatter.linebreak()) # Close code displays, paragraphs, tables and open lists self.request.write(self._undent()) if self.in_pre: self.request.write(self.formatter.preformatted(0)) if self.formatter.in_p: self.request.write(self.formatter.paragraph(0)) if self.in_table: self.request.write(self.formatter.table(0)) # -------------------------------------------------------------------- # Private helpers def setProcessor(self, name): """ Set processer to either processor or parser named 'name' """ cfg = self.request.cfg try: self.processor = wikiutil.importPlugin(cfg, "processor", name, "process") self.processor_is_parser = 0 except wikiutil.PluginMissingError: try: self.processor = wikiutil.importPlugin(cfg, "parser", name, "Parser") self.processor_is_parser = 1 except wikiutil.PluginMissingError: self.processor = None class Request: def __init__(self): self._s = '' def clock(self, *args, **kwds): pass def write(self, w): print("writing {}".format(w)) self._s += w def getText(self): return '' class Page: pass class Cfg: pass def wiki2html(s): """ INPUT: s -- a string formatted using wiki markup OUTPUT: string -- formatted as HTML """ request = Request() request.form = '' request.rootpage = Page() request.cfg = Cfg() request.cfg.siteid = '' request.cfg.data_underlay_dir = '' request._page_headings = '' sagenb-1.0.1/sagenb/notebook/worksheet.py000066400000000000000000004451121311436262400204250ustar00rootroot00000000000000# -*- coding: utf-8 -*- r""" A Worksheet A worksheet is embedded in a web page that is served by the Sage server. It is a linearly-ordered collections of numbered cells, where a cell is a single input/output block. The worksheet module is responsible for running calculations in a worksheet, spawning Sage processes that do all of the actual work and are controlled via pexpect, and reporting on results of calculations. The state of the cells in a worksheet is stored on the file system (not in the notebook pickle sobj). AUTHORS: - William Stein """ from __future__ import absolute_import ########################################################################### # Copyright (C) 2006-2009 William Stein # # Distributed under the terms of the GNU General Public License (GPL) # http://www.gnu.org/licenses/ ########################################################################### from six import iteritems # Import standard Python libraries that we will use below import base64 import bz2 import calendar import copy import os import re import shutil import string import time import traceback import locale # General sage library code from sagenb.misc.misc import (cython, load, save, verbose, DOT_SAGENB, walltime, ignore_nonexistent_files, set_restrictive_permissions, set_permissive_permissions, encoded_str, unicode_str) from sagenb.misc.remote_file import get_remote_file from sagenb.interfaces import (WorksheetProcess_ExpectImplementation, WorksheetProcess_ReferenceImplementation, WorksheetProcess_RemoteExpectImplementation) from sagenb.misc.format import relocate_future_imports # Imports specifically relevant to the sage notebook from .cell import Cell, TextCell from .template import template, clean_name, prettify_time_ago from flask.ext.babel import gettext, lazy_gettext _ = gettext # Set some constants that will be used for regular expressions below. whitespace = re.compile('\s') # Match any whitespace character non_whitespace = re.compile('\S') # The file to which the Sage code that will be evaluated is written. CODE_PY = "___code___.py" # Constants that control the behavior of the worksheet. INTERRUPT_TRIES = 3 # number of times to send control-c to # subprocess before giving up INITIAL_NUM_CELLS = 1 # number of empty cells in new worksheets WARN_THRESHOLD = 100 # The number of seconds, so if there was no # activity on this worksheet for this many # seconds, then editing is considered safe. # Used when multiple people are editing the # same worksheet. # The strings used to synchronized the compute subprocesses. # WARNING: If you make any changes to this, be sure to change the # error line below that looks like this: # cmd += 'print("\\x01r\\x01e%s")' % self.synchro() SC = '\x01' SAGE_BEGIN = SC + 'b' SAGE_END = SC + 'e' SAGE_ERROR = SC + 'r' # Integers that define which folder this worksheet is in relative to a # given user. ARCHIVED = 0 ACTIVE = 1 TRASH = 2 all_worksheet_processes = [] def update_worksheets(): """ Iterate through and "update" all the worksheets. This is needed for things like wall timeouts. """ for S in all_worksheet_processes: S.update() def worksheet_filename(name, owner): """ Return the relative directory name of this worksheet with given name and owner. INPUT: - ``name`` - string, which may have spaces and funny characters, which are replaced by underscores. - ``owner`` - string, with no spaces or funny characters OUTPUT: string EXAMPLES:: sage: sagenb.notebook.worksheet.worksheet_filename('Example worksheet 3', 'sage10') 'sage10/Example_worksheet_3' sage: sagenb.notebook.worksheet.worksheet_filename('Example#%&! work\\sheet 3', 'sage10') 'sage10/Example_____work_sheet_3' """ return os.path.join(owner, clean_name(name)) def Worksheet_from_basic(obj, notebook_worksheet_directory): """ INPUT: - ``obj`` -- a dictionary (a basic Python objet) from which a worksheet can be reconstructed. - ``notebook_worksheet_directory`` - string; the directory in which the notebook object that contains this worksheet stores worksheets, i.e., nb.worksheet_directory(). OUTPUT: - a worksheet EXAMPLES:: sage: import sagenb.notebook.worksheet sage: W = sagenb.notebook.worksheet.Worksheet('test', 0, tmp_dir(), system='gap', owner='sageuser', pretty_print=True, auto_publish=True) sage: _=W.new_cell_after(0); B = W.basic() sage: W0 = sagenb.notebook.worksheet.Worksheet_from_basic(B, tmp_dir()) sage: W0.basic() == B True """ W = Worksheet() W.reconstruct_from_basic(obj, notebook_worksheet_directory) return W class Worksheet(object): def __init__(self, name=None, id_number=None, notebook_worksheet_directory=None, system=None, owner=None, pretty_print=False, auto_publish=False, create_directories=True, live_3D=False): r""" Create and initialize a new worksheet. INPUT: - ``name`` - string; the name of this worksheet - ``id_number`` - Integer; name of the directory in which the worksheet's data is stored - ``notebook_worksheet_directory`` - string; the directory in which the notebook object that contains this worksheet stores worksheets, i.e., nb.worksheet_directory(). - ``system`` - string; 'sage', 'gp', 'singular', etc. - the math software system in which all code is evaluated by default - ``owner`` - string; username of the owner of this worksheet - ``pretty_print`` - bool (default: False); whether all output is pretty printed by default. - ``create_directories`` -- bool (default: True): if True, creates various files and directories where data will be stored. This option is here only for the migrate_old_notebook method in notebook.py - ``live_3D`` - bool (default: False); whether 3-D plots should be loaded live (interactive). Too many live plots may make a worksheet unresponsive because of the javascript load. EXAMPLES: We test the constructor via an indirect doctest:: sage: nb = sagenb.notebook.notebook.Notebook(tmp_dir(ext='.sagenb')) sage: nb.create_default_users('password') sage: import sagenb.notebook.misc sage: sagenb.notebook.misc.notebook = nb sage: W = nb.create_new_worksheet('Test with unicode ěšÄřžýáíéÄÄŽ', 'admin') sage: W admin/0: [Cell 1: in=, out=] """ if name is None: # A fresh worksheet self.clear() return # Record the basic properties of the worksheet self.__system = system self.__pretty_print = pretty_print self.__owner = owner self.__viewers = [] self.__collaborators = [] self.__autopublish = auto_publish self.__saved_by_info = {} self.__live_3D = live_3D # state sequence number, used for sync self.__state_number = 0 # Initialize the cell id counter. self.__next_id = 0 self.set_name(name) # set the directory in which the worksheet files will be stored. # We also add the hash of the name, since the cleaned name loses info, e.g., # it could be all _'s if all characters are funny. self.__id_number = int(id_number) filename = os.path.join(owner, str(id_number)) self.__filename = filename self.__dir = os.path.join(notebook_worksheet_directory, str(id_number)) if create_directories: self.create_directories() self.clear() def increase_state_number(self): if self.is_published() or self.docbrowser(): return try: self.__state_number += 1 except AttributeError: self.__state_number = 0 def state_number(self): if self.is_published() or self.docbrowser(): return 0 try: return self.__state_number except AttributeError: self.__state_number = 0 return 0 def create_directories(self): # creating directories should be a function of the storage backend, not here if not os.path.exists(self.__dir): os.makedirs(self.__dir) set_restrictive_permissions(self.__dir, allow_execute=True) set_restrictive_permissions(self.snapshot_directory()) set_restrictive_permissions(self.cells_directory()) def id_number(self): """ Return the id number of this worksheet, which is an integer. EXAMPLES:: sage: from sagenb.notebook.worksheet import Worksheet sage: W = Worksheet('test', 2, tmp_dir(), owner='sageuser') sage: W.id_number() 2 sage: type(W.id_number()) """ try: return self.__id_number except AttributeError: self.__id_number = int(os.path.split(self.__filename)[1]) return self.__id_number def basic(self): """ Output a dictionary of basic Python objects that defines the configuration of this worksheet, except the actual cells and the data files in the DATA directory and images and other data in the individual cell directories. EXAMPLES:: sage: import sagenb.notebook.worksheet sage: W = sagenb.notebook.worksheet.Worksheet('test', 0, tmp_dir(), owner='sage') sage: sorted((W.basic().items())) [('auto_publish', False), ('collaborators', []), ('id_number', 0), ('last_change', ('sage', ...)), ('live_3D', False), ('name', u'test'), ('owner', 'sage'), ('pretty_print', False), ('published_id_number', None), ('ratings', []), ('saved_by_info', {}), ('system', None), ('tags', {'sage': [1]}), ('viewers', []), ('worksheet_that_was_published', ('sage', 0))] """ try: published_id_number = int(os.path.split(self.__published_version)[1]) except AttributeError: published_id_number = None try: ws_pub = self.__worksheet_came_from except AttributeError: ws_pub = (self.owner(), self.id_number()) try: saved_by_info = self.__saved_by_info except AttributeError: saved_by_info = {} d = {############# # basic identification 'name': unicode(self.name()), 'id_number': int(self.id_number()), ############# # default type of computation system that evaluates cells 'system': self.system(), ############# # permission: who can look at the worksheet 'owner': self.owner(), 'viewers': self.viewers(), 'collaborators': self.collaborators(), ############# # publishing worksheets (am I published?); auto-publish me? # If this worksheet is published, then the published_id_number # is the id of the published version of this worksheet. Otherwise, # it is None. 'published_id_number': published_id_number, # If this is a published worksheet, then ws_pub # is a 2-tuple ('username', id_number) of a non-published # worksheet. Otherwise ws_pub is None. 'worksheet_that_was_published': ws_pub, # Whether or not this worksheet should automatically be # republished when changed. 'auto_publish': self.is_auto_publish(), # Appearance: e.g., whether to pretty print this # worksheet by default 'pretty_print': self.pretty_print(), # Whether to load 3-D live. Should only be set to # true by the user as worksheets with more than 1 or 2 # live (interactive) 3-D plots may bog down because of # javascript overload. 'live_3D': self.live_3D(), # what other users think of this worksheet: list of # triples # (username, rating, comment) 'ratings': self.ratings(), #??? 'saved_by_info':saved_by_info, # dictionary mapping usernames to list of tags that # reflect what the tages are for that user. A tag can be # an integer: # 0,1,2 (=ARCHIVED,ACTIVE,TRASH), # or a string (not yet supported). # This is used for now to fill in the __user_views. 'tags': self.tags(), # information about when this worksheet was last changed, # and by whom: # last_change = ('username', time.time()) 'last_change': self.last_change(), } return d def reconstruct_from_basic(self, obj, notebook_worksheet_directory=None): """ Reconstruct as much of the worksheet's configuration as possible from the properties that happen to be set in the basic dictionary obj. INPUT: - ``obj`` -- a dictionary of basic Python objects - ``notebook_worksheet_directory`` -- must be given if ``id_number`` is a key of obj; otherwise not. EXAMPLES:: sage: import sagenb.notebook.worksheet sage: W = sagenb.notebook.worksheet.Worksheet('test', 0, tmp_dir(), system='gap', owner='sageuser', pretty_print=True, auto_publish=True) sage: W.new_cell_after(0) Cell 1: in=, out= sage: b = W.basic() sage: W0 = sagenb.notebook.worksheet.Worksheet() sage: W0.reconstruct_from_basic(b, tmp_dir()) sage: W0.basic() == W.basic() True """ try: del self.__cells except AttributeError: pass for key, value in iteritems(obj): if key == 'name': if repr(value) == '<_LazyString broken>': value = '' self.set_name(value) elif key == 'id_number': self.__id_number = value if 'owner' in obj: owner = obj['owner'] self.__owner = owner filename = os.path.join(owner, str(value)) self.__filename = filename self.__dir = os.path.join(notebook_worksheet_directory, str(value)) elif key in ['system', 'owner', 'viewers', 'collaborators', 'pretty_print', 'ratings', 'live_3D']: # ugly setattr(self, '_Worksheet__' + key, value) elif key == 'auto_publish': self.__autopublish = value elif key == 'tags': self.set_tags(value) elif key == 'last_change': self.set_last_change(value[0], value[1]) elif key == 'published_id_number' and value is not None: self.set_published_version('pub/%s' % value) elif key == 'worksheet_that_was_published': self.set_worksheet_that_was_published(value) self.create_directories() def __eq__(self, other): """ We compare two worksheets. INPUT: - ``self, other`` -- worksheets OUTPUT: - boolean - comparison is on the underlying file names. EXAMPLES:: sage: nb = sagenb.notebook.notebook.Notebook(tmp_dir(ext='.sagenb')) sage: nb.create_default_users('password') sage: W2 = nb.create_new_worksheet('test2', 'admin') sage: W1 = nb.create_new_worksheet('test1', 'admin') sage: W1 == W1 True sage: W2 == W1 False """ return self.filename() == other.filename() def __ne__(self, other): """ We compare two worksheets. INPUT: - ``self, other`` -- worksheets OUTPUT: - boolean - comparison is on the underlying file names. EXAMPLES:: sage: nb = sagenb.notebook.notebook.Notebook(tmp_dir(ext='.sagenb')) sage: nb.create_default_users('password') sage: W2 = nb.create_new_worksheet('test2', 'admin') sage: W1 = nb.create_new_worksheet('test1', 'admin') sage: W1 != W1 False sage: W2 != W1 True """ return self.filename() != other.filename() def __lt__(self, other): """ We compare two worksheets. INPUT: - ``self, other`` -- worksheets OUTPUT: - boolean - comparison is on the underlying file names. EXAMPLES:: sage: nb = sagenb.notebook.notebook.Notebook(tmp_dir(ext='.sagenb')) sage: nb.create_default_users('password') sage: W2 = nb.create_new_worksheet('test2', 'admin') sage: W1 = nb.create_new_worksheet('test1', 'admin') sage: W1 < W2 False sage: W2 < W1 True """ return self.filename() < other.filename() def __gt__(self, other): """ We compare two worksheets. INPUT: - ``self, other`` -- worksheets OUTPUT: - boolean - comparison is on the underlying file names. EXAMPLES:: sage: nb = sagenb.notebook.notebook.Notebook(tmp_dir(ext='.sagenb')) sage: nb.create_default_users('password') sage: W2 = nb.create_new_worksheet('test2', 'admin') sage: W1 = nb.create_new_worksheet('test1', 'admin') sage: W1 > W2 True sage: W2 > W1 False """ return self.filename() > other.filename() def __le__(self, other): """ We compare two worksheets. INPUT: - ``self, other`` -- worksheets OUTPUT: - boolean - comparison is on the underlying file names. EXAMPLES:: sage: nb = sagenb.notebook.notebook.Notebook(tmp_dir(ext='.sagenb')) sage: nb.create_default_users('password') sage: W2 = nb.create_new_worksheet('test2', 'admin') sage: W1 = nb.create_new_worksheet('test1', 'admin') sage: W1 <= W2 False sage: W2 <= W1 True """ return self.filename() <= other.filename() def __ge__(self, other): """ We compare two worksheets. INPUT: - ``self, other`` -- worksheets OUTPUT: - boolean - comparison is on the underlying file names. EXAMPLES:: sage: nb = sagenb.notebook.notebook.Notebook(tmp_dir(ext='.sagenb')) sage: nb.create_default_users('password') sage: W2 = nb.create_new_worksheet('test2', 'admin') sage: W1 = nb.create_new_worksheet('test1', 'admin') sage: W1 >= W2 True sage: W2 >= W1 False """ return self.filename() >= other.filename() def __repr__(self): r""" Return string representation of this worksheet, which is simply the string representation of the underlying list of cells. OUTPUT: string EXAMPLES:: sage: nb = sagenb.notebook.notebook.Notebook(tmp_dir(ext='.sagenb')) sage: nb.create_default_users('password') sage: W = nb.create_new_worksheet('test1', 'admin') sage: W.__repr__() 'admin/0: [Cell 1: in=, out=]' sage: W.edit_save('{{{\n2+3\n///\n5\n}}}\n{{{id=10|\n2+8\n///\n10\n}}}') sage: W.__repr__() 'admin/0: [Cell 0: in=2+3, out=\n5, Cell 10: in=2+8, out=\n10]' """ return '%s/%s: %s' % (self.owner(), self.id_number(), self.cell_list()) def __len__(self): r""" Return the number of cells in this worksheet. OUTPUT: int EXAMPLES:: sage: nb = sagenb.notebook.notebook.Notebook(tmp_dir(ext='.sagenb')) sage: nb.create_default_users('password') sage: W = nb.create_new_worksheet('test1', 'admin') sage: len(W) 1 sage: W.edit_save('{{{\n2+3\n///\n5\n}}}\n{{{id=10|\n2+8\n///\n10\n}}}') sage: len(W) 2 """ return len(self.cell_list()) def worksheet_html_filename(self): """ Return path to the underlying plane text file that defines the worksheet. """ return os.path.join(self.__dir, 'worksheet.html') def download_name(self): """ Return the download name of this worksheet. """ return os.path.split(self.name())[-1] def docbrowser(self): """ Return True if this is a docbrowser worksheet. OUTPUT: bool EXAMPLES: We first create a standard worksheet for which docbrowser is of course False:: sage: nb = sagenb.notebook.notebook.Notebook(tmp_dir(ext='.sagenb')) sage: nb.create_default_users('password') sage: W = nb.create_new_worksheet('test1', 'admin') sage: W.docbrowser() False We create a worksheet for which docbrowser is True:: sage: W = nb.create_new_worksheet('doc_browser_0', '_sage_') sage: W.docbrowser() True """ return self.owner() == '_sage_' ########################################################## # Basic properties ########################################################## def collaborators(self): """ Return a (reference to the) list of the collaborators who can also view and modify this worksheet. OUTPUT: list EXAMPLES:: sage: nb = sagenb.notebook.notebook.Notebook(tmp_dir(ext='.sagenb')) sage: nb.create_default_users('password') sage: W = nb.create_new_worksheet('test1', 'admin') sage: C = W.collaborators(); C [] sage: C.append('sage') sage: W.collaborators() ['sage'] """ try: return self.__collaborators except AttributeError: self.__collaborators = [] return self.__collaborators def collaborator_names(self, max=None): """ Returns a string of the non-owner collaborators on this worksheet. INPUT: - ``max`` - an integer. If this is specified, then only max number of collaborators are shown. EXAMPLES:: sage: nb = sagenb.notebook.notebook.Notebook(tmp_dir(ext='.sagenb')) sage: nb.create_default_users('password') sage: W = nb.create_new_worksheet('test1', 'admin') sage: C = W.collaborators(); C [] sage: C.append('sage') sage: C.append('wstein') sage: W.collaborator_names() 'sage, wstein' sage: W.collaborator_names(max=1) 'sage, ...' """ collaborators = [x for x in self.collaborators() if x != self.owner()] if max is not None and len(collaborators) > max: collaborators = collaborators[:max] + ['...'] return ", ".join(collaborators) def set_collaborators(self, v): """ Set the list of collaborators to those listed in the list v of strings. INPUT: - ``v`` - a list of strings EXAMPLES:: sage: nb = sagenb.notebook.notebook.load_notebook(tmp_dir(ext='.sagenb')) sage: nb.create_default_users('password') sage: nb.user_manager().add_user('sage','sage','sage@sagemath.org',force=True) sage: nb.user_manager().add_user('hilbert','sage','sage@sagemath.org',force=True) sage: W = nb.create_new_worksheet('test1', 'admin') sage: W.set_collaborators(['sage', 'admin', 'hilbert', 'sage']) Note that repeats are not added multiple times and admin - the owner - isn't added:: sage: W.collaborators() ['hilbert', 'sage'] """ users = self.notebook().user_manager().users() owner = self.owner() collaborators = set([u for u in v if u in users and u != owner]) self.__collaborators = sorted(collaborators) def viewers(self): """ Return list of viewers of this worksheet. OUTPUT: - ``list`` - of string EXAMPLES:: sage: nb = sagenb.notebook.notebook.Notebook(tmp_dir(ext='.sagenb')) sage: nb.create_default_users('password') sage: nb.user_manager().add_user('sage','sage','sage@sagemath.org',force=True) sage: nb.user_manager().add_user('hilbert','sage','sage@sagemath.org',force=True) sage: W = nb.create_new_worksheet('test1', 'admin') sage: W.add_viewer('hilbert') sage: W.viewers() ['hilbert'] sage: W.add_viewer('sage') sage: W.viewers() ['hilbert', 'sage'] """ try: return self.__viewers except AttributeError: self.__viewers = [] return self.__viewers def viewer_names(self, max=None): """ Returns a string of the non-owner viewers on this worksheet. INPUT: - ``max`` - an integer. If this is specified, then only max number of viewers are shown. EXAMPLES:: sage: nb = sagenb.notebook.notebook.Notebook(tmp_dir(ext='.sagenb')) sage: nb.create_default_users('password') sage: W = nb.create_new_worksheet('test1', 'admin') sage: C = W.viewers(); C [] sage: C.append('sage') sage: C.append('wstein') sage: W.viewer_names() 'sage, wstein' sage: W.viewer_names(max=1) 'sage, ...' """ viewers = [x for x in self.viewers() if x != self.owner()] if max is not None and len(viewers) > max: viewers = viewers[:max] + ['...'] return ", ".join(viewers) def delete_notebook_specific_data(self): """ Delete data from this worksheet this is specific to a certain notebook. This means deleting the attached files, collaborators, and viewers. EXAMPLES:: sage: nb = sagenb.notebook.notebook.Notebook(tmp_dir(ext='.sagenb')) sage: nb.create_default_users('password') sage: nb.user_manager().add_user('hilbert','sage','sage@sagemath.org',force=True) sage: W = nb.create_new_worksheet('test1', 'admin') sage: W.add_viewer('hilbert') sage: W.delete_notebook_specific_data() sage: W.viewers() [] sage: W.add_collaborator('hilbert') sage: W.collaborators() ['admin', 'hilbert'] sage: W.delete_notebook_specific_data() sage: W.collaborators() ['admin'] """ self.__attached = {} self.__collaborators = [self.owner()] self.__viewers = [] def name(self, username=None): r""" Return the name of this worksheet. OUTPUT: string EXAMPLES:: sage: nb = sagenb.notebook.notebook.Notebook(tmp_dir(ext='.sagenb')) sage: nb.create_default_users('password') sage: W = nb.create_new_worksheet('A Test Worksheet', 'admin') sage: W.name() u'A Test Worksheet' sage: W = nb.create_new_worksheet('ěšÄřžýáíéÄÄŽ', 'admin') sage: W.name() u'\u011b\u0161\u010d\u0159\u017e\xfd\xe1\xed\xe9\u010f\u010e' """ try: return self.__name except AttributeError: self.__name = gettext("Untitled") return self.__name def set_name(self, name): """ Set the name of this worksheet. INPUT: - ``name`` - string EXAMPLES: We create a worksheet and change the name:: sage: nb = sagenb.notebook.notebook.Notebook(tmp_dir(ext='.sagenb')) sage: nb.create_default_users('password') sage: W = nb.create_new_worksheet('A Test Worksheet', 'admin') sage: W.set_name('A renamed worksheet') sage: W.name() u'A renamed worksheet' """ if len(name.strip()) == 0: name = gettext('Untitled') name = unicode_str(name) self.__name = name def set_filename_without_owner(self, nm): r""" Set this worksheet filename (actually directory) by getting the owner from the pre-stored owner via ``self.owner()``. INPUT: - ``nm`` - string EXAMPLES:: sage: nb = sagenb.notebook.notebook.load_notebook(tmp_dir(ext='.sagenb')) sage: nb.create_default_users('password') sage: W = nb.create_new_worksheet('A Test Worksheet', 'admin') sage: W.filename() 'admin/0' sage: W.set_filename_without_owner('5') sage: W.filename() 'admin/5' """ filename = os.path.join(self.owner(), nm) self.set_filename(filename) def set_filename(self, filename): """ Set the worksheet filename (actually directory). INPUT: - ``filename`` - string EXAMPLES:: sage: nb = sagenb.notebook.notebook.load_notebook(tmp_dir(ext='.sagenb')) sage: nb.create_default_users('password') sage: W = nb.create_new_worksheet('A Test Worksheet', 'admin') sage: W.filename() 'admin/0' sage: W.set_filename('admin/10') sage: W.filename() 'admin/10' """ old_filename = self.__filename self.__filename = filename self.__dir = os.path.join(self.notebook()._dir, filename) self.notebook().change_worksheet_key(old_filename, filename) def filename(self): """ Return the filename (really directory) where the files associated to this worksheet are stored. EXAMPLES:: sage: nb = sagenb.notebook.notebook.Notebook(tmp_dir(ext='.sagenb')) sage: nb.create_default_users('password') sage: W = nb.create_new_worksheet('A Test Worksheet', 'admin') sage: W.filename() 'admin/0' sage: os.path.isdir(os.path.join(nb._dir, 'home', W.filename())) True """ return self.__filename def filename_without_owner(self): """ Return the part of the worksheet filename after the last /, i.e., without any information about the owner of this worksheet. EXAMPLES:: sage: nb = sagenb.notebook.notebook.Notebook(tmp_dir(ext='.sagenb')) sage: nb.create_default_users('password') sage: W = nb.create_new_worksheet('A Test Worksheet', 'admin') sage: W.filename_without_owner() '0' sage: W.filename() 'admin/0' """ return os.path.split(self.__filename)[-1] def directory(self): """ Return the full path to the directory where this worksheet is stored. OUTPUT: string EXAMPLES:: sage: nb = sagenb.notebook.notebook.Notebook(tmp_dir(ext='.sagenb')) sage: nb.create_default_users('password') sage: W = nb.create_new_worksheet('A Test Worksheet', 'admin') sage: W.directory() '.../home/admin/0' """ return self.__dir def data_directory(self): """ Return path to directory where worksheet data is stored. OUTPUT: string EXAMPLES:: sage: nb = sagenb.notebook.notebook.Notebook(tmp_dir(ext='.sagenb')) sage: nb.create_default_users('password') sage: W = nb.create_new_worksheet('A Test Worksheet', 'admin') sage: W.data_directory() '.../home/admin/0/data' """ d = os.path.join(self.directory(), 'data') if not os.path.exists(d): os.makedirs(d) return d def attached_data_files(self): """ Return a list of the file names of files in the worksheet data directory. OUTPUT: list of strings EXAMPLES:: sage: nb = sagenb.notebook.notebook.Notebook(tmp_dir(ext='.sagenb')) sage: nb.create_default_users('password') sage: W = nb.create_new_worksheet('A Test Worksheet', 'admin') sage: W.attached_data_files() [] sage: open('%s/foo.data'%W.data_directory(),'w').close() sage: W.attached_data_files() ['foo.data'] """ D = self.data_directory() if not os.path.exists(D): return [] return os.listdir(D) def cells_directory(self): """ Return the directory in which the cells of this worksheet are evaluated. OUTPUT: string EXAMPLES:: sage: nb = sagenb.notebook.notebook.Notebook(tmp_dir(ext='.sagenb')) sage: nb.create_default_users('password') sage: W = nb.create_new_worksheet('A Test Worksheet', 'admin') sage: W.cells_directory() '.../home/admin/0/cells' """ path = os.path.join(self.directory(), 'cells') if not os.path.exists(path): os.makedirs(path) return path def notebook(self): """ Return the notebook that contains this worksheet. OUTPUT: a Notebook object. .. note:: This really returns the Notebook object that is set as a global variable of the misc module. This is done *even* in the Flask version of the notebook as it is set in func:`sagenb.notebook.notebook.load_notebook`. EXAMPLES:: sage: nb = sagenb.notebook.notebook.Notebook(tmp_dir(ext='.sagenb')) sage: nb.create_default_users('password') sage: W = nb.create_new_worksheet('A Test Worksheet', 'admin') sage: W.notebook() <...sagenb.notebook.notebook.Notebook...> sage: W.notebook() is sagenb.notebook.misc.notebook True """ if not hasattr(self, '_notebook'): from . import misc self._notebook = misc.notebook return self._notebook def save(self, conf_only=False): self.notebook().save_worksheet(self, conf_only=conf_only) def system(self): """ Return the math software system in which by default all input to the notebook is evaluated. OUTPUT: string EXAMPLES:: sage: nb = sagenb.notebook.notebook.Notebook(tmp_dir(ext='.sagenb')) sage: nb.create_default_users('password') sage: W = nb.create_new_worksheet('A Test Worksheet', 'admin') sage: W.system() 'sage' sage: W.set_system('mathematica') sage: W.system() 'mathematica' """ try: return self.__system except AttributeError: self.__system = 'sage' return 'sage' def system_index(self): """ Return the index of the current system into the Notebook's list of systems. If the current system isn't in the list, then change to the default system. This can happen if, e.g., the list changes, e.g., when changing from a notebook with Sage installed to running a server from the same directory without Sage installed. We might as well support this. OUTPUT: integer """ S = self.system() names = self.notebook().system_names() if S not in names: S = names[0] self.set_system(S) return 0 else: return names.index(S) def set_system(self, system='sage'): """ Set the math software system in which input is evaluated by default. INPUT: - ``system`` - string (default: 'sage') EXAMPLES:: sage: nb = sagenb.notebook.notebook.Notebook(tmp_dir(ext='.sagenb')) sage: nb.create_default_users('password') sage: W = nb.create_new_worksheet('A Test Worksheet', 'admin') sage: W.set_system('magma') sage: W.system() 'magma' """ self.__system = system.strip() def pretty_print(self): """ Return True if output should be pretty printed by default. OUTPUT: - ``bool`` - True of False EXAMPLES:: sage: nb = sagenb.notebook.notebook.Notebook(tmp_dir(ext='.sagenb')) sage: nb.create_default_users('password') sage: W = nb.create_new_worksheet('A Test Worksheet', 'admin') sage: W.pretty_print() False sage: W.set_pretty_print('true') sage: W.pretty_print() True sage: W.quit() sage: nb.delete() """ try: return self.__pretty_print except AttributeError: self.__pretty_print = False return self.__pretty_print def set_pretty_print(self, check='false'): """ Set whether or not output should be pretty printed by default. INPUT: - ``check`` - string (default: 'false'); either 'true' or 'false'. .. note:: The reason the input is a string and lower case instead of a Python bool is because this gets called indirectly from JavaScript. (And, Jason Grout wrote this and didn't realize how unpythonic this design is - it should be redone to use True/False.) EXAMPLES:: sage: nb = sagenb.notebook.notebook.Notebook(tmp_dir(ext='.sagenb')) sage: nb.create_default_users('password') sage: W = nb.create_new_worksheet('A Test Worksheet', 'admin') sage: W.set_pretty_print('false') sage: W.pretty_print() False sage: W.set_pretty_print('true') sage: W.pretty_print() True sage: W.quit() sage: nb.delete() """ if check == 'false': check = False else: check = True self.__pretty_print = check self.eval_asap_no_output("pretty_print_default(%r)" % check) ########################################################## # 3-D plots ########################################################## def live_3D(self): """ Return True if the 3-D plots should be loaded live (interactive) by default. OUTPUT: - ``bool`` - True of False EXAMPLES:: sage: nb = sagenb.notebook.notebook.Notebook(tmp_dir(ext='.sagenb')) sage: nb.create_default_users('password') sage: W = nb.create_new_worksheet('A Test Worksheet', 'admin') sage: W.live_3D() False sage: W.quit() sage: nb.delete() """ try: return self.__live_3D except AttributeError: self.__live_3D = False return self.__live_3D def set_live_3D(self, check=False): """ Set whether or not 3-D plots should be live by default. Not a good idea for worksheets with more than 1 or 2 3-D plots. INPUT: - ``check`` - boolean EXAMPLES:: sage: nb = sagenb.notebook.notebook.Notebook(tmp_dir(ext='.sagenb')) sage: nb.create_default_users('password') sage: W = nb.create_new_worksheet('A Test Worksheet', 'admin') sage: W.set_live_3D(False) sage: W.live_3D() False sage: W.set_live_3D(True) sage: W.live_3D() True sage: W.quit() sage: nb.delete() """ self.__live_3D = check ########################################################## # Publication ########################################################## def is_auto_publish(self): """ Returns True if this worksheet should be automatically published. """ try: return self.__autopublish except AttributeError: self.__autopublish = False return False def set_auto_publish(self, x): self.__autopublish = x def is_published(self): """ Return True if this worksheet is a published worksheet. OUTPUT: - ``bool`` - whether or not owner is 'pub' EXAMPLES:: sage: nb = sagenb.notebook.notebook.Notebook(tmp_dir(ext='.sagenb')) sage: nb.create_default_users('password') sage: W = nb.create_new_worksheet('Publish Test', 'admin') sage: W.is_published() False sage: W.set_owner('pub') sage: W.is_published() True """ return self.owner() == 'pub' def worksheet_that_was_published(self): """ Return a fresh copy of the worksheet that was published to get this worksheet, if this worksheet was published. Otherwise just return this worksheet. OUTPUT: Worksheet EXAMPLES:: sage: nb = sagenb.notebook.notebook.load_notebook(tmp_dir(ext='.sagenb')) sage: nb.create_default_users('password') sage: W = nb.create_new_worksheet('Publish Test', 'admin') sage: W.worksheet_that_was_published() is W True sage: S = nb.publish_worksheet(W, 'admin') sage: S.worksheet_that_was_published() is S False sage: S.worksheet_that_was_published() is W True """ try: return self.notebook().get_worksheet_with_filename('%s/%s' % self.__worksheet_came_from) except Exception: # things can go wrong (especially with old migrated # Sage notebook servers!), but we don't want such # problems to crash the notebook server. return self def publisher(self): """ Return username of user that published this worksheet. OUTPUT: string EXAMPLES:: sage: nb = sagenb.notebook.notebook.Notebook(tmp_dir(ext='.sagenb')) sage: nb.create_default_users('password') sage: W = nb.create_new_worksheet('Publish Test', 'admin') sage: S = nb.publish_worksheet(W, 'admin') sage: S.publisher() 'admin' """ return self.worksheet_that_was_published().owner() def is_publisher(self, username): """ Return True if username is the username of the publisher of this worksheet, assuming this worksheet was published. INPUT: - ``username`` - string EXAMPLES:: sage: nb = sagenb.notebook.notebook.load_notebook(tmp_dir(ext='.sagenb')) sage: nb.create_default_users('password') sage: W = nb.create_new_worksheet('Publish Test', 'admin') sage: P = nb.publish_worksheet(W, 'admin') sage: P.is_publisher('hearst') False sage: P.is_publisher('admin') True """ return self.publisher() == username def has_published_version(self): """ Return True if there is a published version of this worksheet. OUTPUT: bool EXAMPLES:: sage: nb = sagenb.notebook.notebook.Notebook(tmp_dir(ext='.sagenb')) sage: nb.create_default_users('password') sage: W = nb.create_new_worksheet('Publish Test', 'admin') sage: P = nb.publish_worksheet(W, 'admin') sage: P.has_published_version() False sage: W.has_published_version() True """ try: self.published_version() return True except ValueError: return False def set_published_version(self, filename): """ Set the published version of this worksheet to be the worksheet with given filename. INPUT: - ``filename`` - string EXAMPLES:: sage: nb = sagenb.notebook.notebook.Notebook(tmp_dir(ext='.sagenb')) sage: nb.create_default_users('password') sage: W = nb.create_new_worksheet('Publish Test', 'admin') sage: P = nb.publish_worksheet(W, 'admin') # indirect test sage: W._Worksheet__published_version 'pub/0' sage: W.set_published_version('pub/1') sage: W._Worksheet__published_version 'pub/1' """ self.__published_version = filename def published_version(self): """ If this worksheet was published, return the published version of this worksheet. Otherwise, raise a ValueError. OUTPUT: a worksheet (or raise a ValueError) EXAMPLES:: sage: nb = sagenb.notebook.notebook.load_notebook(tmp_dir(ext='.sagenb')) sage: nb.create_default_users('password') sage: W = nb.create_new_worksheet('Publish Test', 'admin') sage: P = nb.publish_worksheet(W, 'admin') sage: W.published_version() is P True """ try: filename = self.__published_version try: W = self.notebook().get_worksheet_with_filename(filename) return W except KeyError: del self.__published_version raise ValueError except AttributeError: raise ValueError("no published version") def set_worksheet_that_was_published(self, W): """ Set the owner and id_number of the worksheet that was published to get self. INPUT: - ``W`` -- worksheet or 2-tuple ('owner', id_number) EXAMPLES:: sage: nb = sagenb.notebook.notebook.load_notebook(tmp_dir(ext='.sagenb')) sage: nb.create_default_users('password') sage: W = nb.create_new_worksheet('Publish Test', 'admin') sage: P = nb.publish_worksheet(W, 'admin') sage: P.worksheet_that_was_published() is W True We fake things and make it look like P published itself:: sage: P.set_worksheet_that_was_published(P) sage: P.worksheet_that_was_published() is P True """ if isinstance(W, tuple): self.__worksheet_came_from = W else: self.__worksheet_came_from = (W.owner(), W.id_number()) def rate(self, x, comment, username): """ Set the rating on this worksheet by the given user to x and also set the given comment. INPUT: - ``x`` - integer - ``comment`` - string - ``username`` - string EXAMPLES: We create a worksheet and rate it, then look at the ratings. :: sage: nb = sagenb.notebook.notebook.Notebook(tmp_dir(ext='.sagenb')) sage: nb.create_default_users('password') sage: W = nb.create_new_worksheet('Publish Test', 'admin') sage: W.rate(3, 'this is great', 'hilbert') sage: W.ratings() [('hilbert', 3, 'this is great')] Note that only the last rating by a user counts:: sage: W.rate(1, 'this lacks content', 'riemann') sage: W.rate(0, 'this lacks content', 'riemann') sage: W.ratings() [('hilbert', 3, 'this is great'), ('riemann', 0, 'this lacks content')] """ r = self.ratings() x = int(x) for i in range(len(r)): if r[i][0] == username: r[i] = (username, x, comment) return else: r.append((username, x, comment)) def is_rater(self, username): """ Return True is the user with given username has rated this worksheet. INPUT: - ``username`` - string OUTPUT: bool EXAMPLES:: sage: nb = sagenb.notebook.notebook.Notebook(tmp_dir(ext='.sagenb')) sage: nb.create_default_users('password') sage: W = nb.create_new_worksheet('Publish Test', 'admin') sage: W.rate(0, 'this lacks content', 'riemann') sage: W.is_rater('admin') False sage: W.is_rater('riemann') True """ try: return username in [x[0] for x in self.ratings()] except TypeError: return False def ratings(self): """ Return all the ratings of this worksheet. OUTPUT: - ``list`` - a reference to the list of ratings. EXAMPLES:: sage: nb = sagenb.notebook.notebook.Notebook(tmp_dir(ext='.sagenb')) sage: nb.create_default_users('password') sage: W = nb.create_new_worksheet('Publish Test', 'admin') sage: W.ratings() [] sage: W.rate(0, 'this lacks content', 'riemann') sage: W.rate(3, 'this is great', 'hilbert') sage: W.ratings() [('riemann', 0, 'this lacks content'), ('hilbert', 3, 'this is great')] """ try: return self.__ratings except AttributeError: v = [] self.__ratings = v return v def html_ratings_info(self, username=None): r""" Return html that renders to give a summary of how this worksheet has been rated. OUTPUT: - ``string`` -- a string of HTML as a bunch of table rows. EXAMPLES:: sage: from sagenb.flask_version import base # random output -- depends on warnings issued by other sage packages sage: app = base.create_app(tmp_dir(ext='.sagenb')) sage: ctx = app.app_context() sage: ctx.push() sage: nb = base.notebook sage: nb.create_default_users('password') sage: W = nb.create_new_worksheet('Publish Test', 'admin') sage: W.rate(0, 'this lacks content', 'riemann') sage: W.rate(3, 'this is great', 'hilbert') sage: W.html_ratings_info() u'...hilbert...3...this is great...this lacks content...' """ return template(os.path.join('html', 'worksheet', 'ratings_info.html'), worksheet = self, username = username) def rating(self): """ Return overall average rating of self. OUTPUT: float or the int -1 to mean "not rated" EXAMPLES:: sage: nb = sagenb.notebook.notebook.Notebook(tmp_dir(ext='.sagenb')) sage: nb.create_default_users('password') sage: W = nb.create_new_worksheet('Publish Test', 'admin') sage: W.rating() -1 sage: W.rate(0, 'this lacks content', 'riemann') sage: W.rate(3, 'this is great', 'hilbert') sage: W.rating() 1.5 """ r = [x[1] for x in self.ratings()] if len(r) == 0: rating = -1 # means "not rated" else: rating = float(sum(r)) / float(len(r)) return rating ########################################################## # Active, trash can and archive ########################################################## def everyone_has_deleted_this_worksheet(self): """ Return True if all users have deleted this worksheet, so we know we can safely purge it from disk. OUTPUT: bool EXAMPLES:: sage: nb = sagenb.notebook.notebook.Notebook(tmp_dir(ext='.sagenb')) sage: nb.create_default_users('password') sage: W = nb.create_new_worksheet('Publish Test', 'admin') sage: W.everyone_has_deleted_this_worksheet() False sage: W.move_to_trash('admin') sage: W.everyone_has_deleted_this_worksheet() True """ for user in self.collaborators() + [self.owner()]: # When the worksheet has been deleted by the owner, # self.owner() returns None, so we have to be careful # about that case. if user is not None and not self.is_trashed(user): return False return True def user_view(self, user): """ Return the view that the given user has of this worksheet. If the user currently doesn't have a view set it to ACTIVE and return ACTIVE. INPUT: - ``user`` - a string OUTPUT: - ``Python int`` - one of ACTIVE, ARCHIVED, TRASH, which are defined in worksheet.py EXAMPLES: We create a new worksheet and get the view, which is ACTIVE:: sage: nb = sagenb.notebook.notebook.Notebook(tmp_dir(ext='.sagenb')) sage: nb.create_default_users('password') sage: W = nb.create_new_worksheet('Publish Test', 'admin') sage: W.user_view('admin') 1 sage: sagenb.notebook.worksheet.ACTIVE 1 Now for the admin user we move W to the archive:: sage: W.move_to_archive('admin') The view is now archive. :: sage: W.user_view('admin') 0 sage: sagenb.notebook.worksheet.ARCHIVED 0 For any other random viewer the view is set by default to ACTIVE. :: sage: W.user_view('foo') 1 """ try: return self.__user_view[user] except AttributeError: self.__user_view = {} except KeyError: pass self.__user_view[user] = ACTIVE return ACTIVE def tags(self): """ A temporary trivial tags implementation. """ try: d = dict(self.__user_view) except AttributeError: self.user_view(self.owner()) d = copy.copy(self.__user_view) for user, val in iteritems(d): if not isinstance(val, list): d[user] = [val] return d def set_tags(self, tags): """ Set the tags -- for now we ignore everything except ACTIVE, ARCHIVED, TRASH. INPUT: - ``tags`` -- dictionary with keys usernames and values a list of tags, where a tag is a string or ARCHIVED, ACTIVE, TRASH. """ d = {} for user, v in iteritems(tags): if len(v) >= 1: d[user] = v[0] # must be a single int for now, until # the tag system is implemented self.__user_view = d def set_user_view(self, user, x): """ Set the view on this worksheet for the given user. INPUT: - ``user`` - a string - ``x`` - int, one of the variables ACTIVE, ARCHIVED, TRASH in worksheet.py EXAMPLES:: sage: nb = sagenb.notebook.notebook.Notebook(tmp_dir(ext='.sagenb')) sage: nb.create_default_users('password') sage: W = nb.create_new_worksheet('Publish Test', 'admin') sage: W.set_user_view('admin', sagenb.notebook.worksheet.ARCHIVED) sage: W.user_view('admin') == sagenb.notebook.worksheet.ARCHIVED True """ if not isinstance(user, (str, unicode)): raise TypeError("user (=%s) must be a string" % user) try: self.__user_view[user] = x except (KeyError, AttributeError): self.user_view(user) self.__user_view[user] = x # it is important to save the configuration and changing the # views, e.g., moving to trash, etc., since the user can't # easily click save without changing the view back. self.save(conf_only=True) def user_view_is(self, user, x): """ Return True if the user view of user is x. INPUT: - ``user`` - a string - ``x`` - int, one of the variables ACTIVE, ARCHIVED, TRASH in worksheet.py EXAMPLES:: sage: nb = sagenb.notebook.notebook.Notebook(tmp_dir(ext='.sagenb')) sage: nb.create_default_users('password') sage: W = nb.create_new_worksheet('Publish Test', 'admin') sage: W.user_view_is('admin', sagenb.notebook.worksheet.ARCHIVED) False sage: W.user_view_is('admin', sagenb.notebook.worksheet.ACTIVE) True """ return self.user_view(user) == x def is_archived(self, user): """ Return True if this worksheet is archived for the given user. INPUT: - ``user`` - string OUTPUT: bool EXAMPLES:: sage: nb = sagenb.notebook.notebook.Notebook(tmp_dir(ext='.sagenb')) sage: nb.create_default_users('password') sage: W = nb.create_new_worksheet('Archived Test', 'admin') sage: W.is_archived('admin') False sage: W.move_to_archive('admin') sage: W.is_archived('admin') True """ return self.user_view_is(user, ARCHIVED) def is_active(self, user): """ Return True if this worksheet is active for the given user. INPUT: - ``user`` - string OUTPUT: bool EXAMPLES:: sage: nb = sagenb.notebook.notebook.Notebook(tmp_dir(ext='.sagenb')) sage: nb.create_default_users('password') sage: W = nb.create_new_worksheet('Active Test', 'admin') sage: W.is_active('admin') True sage: W.move_to_archive('admin') sage: W.is_active('admin') False """ return self.user_view_is(user, ACTIVE) def is_trashed(self, user): """ Return True if this worksheet is in the trash for the given user. INPUT: - ``user`` - string OUTPUT: bool EXAMPLES:: sage: nb = sagenb.notebook.notebook.Notebook(tmp_dir(ext='.sagenb')) sage: nb.create_default_users('password') sage: W = nb.create_new_worksheet('Trash Test', 'admin') sage: W.is_trashed('admin') False sage: W.move_to_trash('admin') sage: W.is_trashed('admin') True """ return self.user_view_is(user, TRASH) def move_to_archive(self, user): """ Move this worksheet to be archived for the given user. INPUT: - ``user`` - string EXAMPLES:: sage: nb = sagenb.notebook.notebook.Notebook(tmp_dir(ext='.sagenb')) sage: nb.create_default_users('password') sage: W = nb.create_new_worksheet('Archive Test', 'admin') sage: W.move_to_archive('admin') sage: W.is_archived('admin') True """ self.set_user_view(user, ARCHIVED) if self.viewers() == [user]: self.quit() def set_active(self, user): """ Set his worksheet to be active for the given user. INPUT: - ``user`` - string EXAMPLES:: sage: nb = sagenb.notebook.notebook.Notebook(tmp_dir(ext='.sagenb')) sage: nb.create_default_users('password') sage: W = nb.create_new_worksheet('Active Test', 'admin') sage: W.move_to_archive('admin') sage: W.is_active('admin') False sage: W.set_active('admin') sage: W.is_active('admin') True """ self.set_user_view(user, ACTIVE) def move_to_trash(self, user): """ Move this worksheet to the trash for the given user. INPUT: - ``user`` - string EXAMPLES:: sage: nb = sagenb.notebook.notebook.Notebook(tmp_dir(ext='.sagenb')) sage: nb.create_default_users('password') sage: W = nb.create_new_worksheet('Trash Test', 'admin') sage: W.move_to_trash('admin') sage: W.is_trashed('admin') True """ self.set_user_view(user, TRASH) if self.viewers() == [user]: self.quit() def move_out_of_trash(self, user): """ Exactly the same as set_active(user). INPUT: - ``user`` - string EXAMPLES:: sage: nb = sagenb.notebook.notebook.Notebook(tmp_dir(ext='.sagenb')) sage: nb.create_default_users('password') sage: W = nb.create_new_worksheet('Active Test', 'admin') sage: W.move_to_trash('admin') sage: W.is_active('admin') False sage: W.move_out_of_trash('admin') sage: W.is_active('admin') True """ self.set_active(user) def delete_cells_directory(self): r""" Delete the directory in which all the cell computations occur. EXAMPLES:: sage: nb = sagenb.notebook.notebook.Notebook(tmp_dir(ext='.sagenb')) sage: nb.create_default_users('password') sage: nb.user_manager().add_user('sage','sage','sage@sagemath.org',force=True) sage: W = nb.create_new_worksheet('Test', 'sage') sage: W.edit_save('{{{\n3^20\n}}}') sage: W.cell_list()[0].evaluate() sage: W.check_comp() # random output -- depends on computer speed sage: sorted(os.listdir(W.directory())) ['cells', 'data', 'worksheet.html', 'worksheet_conf.pickle'] sage: W.save_snapshot('admin') sage: sorted(os.listdir(W.directory())) ['cells', 'data', 'snapshots', 'worksheet.html', 'worksheet_conf.pickle'] sage: W.delete_cells_directory() sage: sorted(os.listdir(W.directory())) ['data', 'snapshots', 'worksheet.html', 'worksheet_conf.pickle'] sage: W.quit() sage: nb.delete() """ dir = self.cells_directory() if os.path.exists(dir): shutil.rmtree(dir) ########################################################## # Owner/viewer/user management ########################################################## def owner(self): try: return self.__owner except AttributeError: self.__owner = 'pub' return 'pub' def is_owner(self, username): return self.owner() == username def set_owner(self, owner): self.__owner = owner if not owner in self.collaborators(): self.__collaborators.append(owner) def is_only_viewer(self, user): try: return user in self.__viewers except AttributeError: return False def is_viewer(self, user): try: return user in self.__viewers or user in self.__collaborators or user == self.publisher() except AttributeError: return True def is_collaborator(self, user): return user in self.collaborators() def user_can_edit(self, user): """ Return True if the user with given name is allowed to edit this worksheet. INPUT: - ``user`` - string OUTPUT: bool EXAMPLES: We create a notebook with one worksheet and two users. :: sage: nb = sagenb.notebook.notebook.Notebook(tmp_dir(ext='.sagenb')) sage: nb.user_manager().add_user('sage','sage','sage@sagemath.org',force=True) sage: nb.user_manager().add_user('william', 'william', 'wstein@sagemath.org', force=True) sage: W = nb.create_new_worksheet('Test', 'sage') sage: W.user_can_edit('sage') True At first the user 'william' can't edit this worksheet:: sage: W.user_can_edit('william') False After adding 'william' as a collaborator he can edit the worksheet. :: sage: W.add_collaborator('william') sage: W.user_can_edit('william') True Clean up:: sage: nb.delete() """ return self.is_collaborator(user) or self.is_owner(user) def delete_user(self, user): """ Delete a user from having any view or ownership of this worksheet. INPUT: - ``user`` - string; the name of a user EXAMPLES: We create a notebook with 2 users and 1 worksheet that both view. :: sage: nb = sagenb.notebook.notebook.Notebook(tmp_dir(ext='.sagenb')) sage: nb.user_manager().add_user('wstein','sage','wstein@sagemath.org',force=True) sage: nb.user_manager().add_user('sage','sage','sage@sagemath.org',force=True) sage: W = nb.new_worksheet_with_title_from_text('Sage', owner='sage') sage: W.add_viewer('wstein') sage: W.owner() 'sage' sage: W.viewers() ['wstein'] We delete the sage user from the worksheet W. This makes wstein the new owner. :: sage: W.delete_user('sage') sage: W.viewers() ['wstein'] sage: W.owner() 'wstein' Then we delete wstein from W, which makes the owner None. :: sage: W.delete_user('wstein') sage: W.owner() is None True sage: W.viewers() [] Finally, we clean up. :: sage: nb.delete() """ if user in self.collaborators(): self.__collaborators.remove(user) if user in self.__viewers: self.__viewers.remove(user) if self.__owner == user: if len(self.__collaborators) > 0: self.__owner = self.__collaborators[0] elif len(self.__viewers) > 0: self.__owner = self.__viewers[0] else: # Now there is nobody to take over ownership. We # assign the owner None, which means nobody owns it. # It will get purged elsewhere. self.__owner = None def add_viewer(self, user): """ Add the given user as an allowed viewer of this worksheet. INPUT: - ``user`` - string (username) EXAMPLES:: sage: nb = sagenb.notebook.notebook.Notebook(tmp_dir(ext='.sagenb')) sage: nb.create_default_users('password') sage: nb.user_manager().add_user('diophantus','sage','sage@sagemath.org',force=True) sage: W = nb.create_new_worksheet('Viewer test', 'admin') sage: W.add_viewer('diophantus') sage: W.viewers() ['diophantus'] """ try: if not user in self.__viewers: self.__viewers.append(user) except AttributeError: self.__viewers = [user] def add_collaborator(self, user): """ Add the given user as a collaborator on this worksheet. INPUT: - ``user`` - a string EXAMPLES:: sage: nb = sagenb.notebook.notebook.Notebook(tmp_dir(ext='.sagenb')) sage: nb.create_default_users('password') sage: nb.user_manager().add_user('diophantus','sage','sage@sagemath.org',force=True) sage: W = nb.create_new_worksheet('Collaborator test', 'admin') sage: W.collaborators() [] sage: W.add_collaborator('diophantus') sage: W.collaborators() ['diophantus'] """ try: if not user in self.__collaborators: self.__collaborators.append(user) except AttributeError: self.__collaborators = [user] ########################################################## # Searching ########################################################## def satisfies_search(self, search): """ Return True if all words in search are in the saved text of the worksheet. INPUT: - ``search`` - a string that describes a search query, i.e., a space-separated collections of words. OUTPUT: - a boolean """ # Load the worksheet data file from disk. filename = self.worksheet_html_filename() if os.path.exists(filename): contents = open(filename).read().decode('utf-8', 'ignore') else: contents = u' ' try: r = [unicode(x.lower()) for x in [self.owner(), self.publisher(), self.name(), contents]] r = u" ".join(r) except UnicodeDecodeError as e: return False # Check that every single word is in the file from disk. for W in split_search_string_into_keywords(search): W = unicode_str(W) if W.lower() not in r: # Some word from the text is not in the search list, so # we return False. return False # Every single word is there. return True ########################################################## # Saving ########################################################## def save_snapshot(self, user, E=None): if not self.body_is_loaded(): return self.uncache_snapshot_data() path = self.snapshot_directory() basename = str(int(time.time())) filename = os.path.join(path, '%s.bz2' % basename) if E is None: E = self.edit_text() worksheet_html = self.worksheet_html_filename() open(filename, 'w').write(bz2.compress(E.encode('utf-8', 'ignore'))) open(worksheet_html, 'w').write(self.body().encode('utf-8', 'ignore')) self.limit_snapshots() try: X = self.__saved_by_info except AttributeError: X = {} self.__saved_by_info = X X[basename] = user if self.is_auto_publish(): self.notebook().publish_worksheet(self, user) def get_snapshot_text_filename(self, name): path = self.snapshot_directory() return os.path.join(path, name) def user_autosave_interval(self, username): return self.notebook().user(username)['autosave_interval'] def autosave(self, username): return try: last = self.__last_autosave except AttributeError: self.__last_autosave = time.time() return t = time.time() if t - last >= self.user_autosave_interval(username): self.__last_autosave = t self.save_snapshot(username) def revert_to_snapshot(self, name): path = self.snapshot_directory() filename = os.path.join(path, '%s.txt' % name) E = bz2.decompress(open(filename).read()) self.edit_save(E) def _saved_by_info(self, x, username=None): try: u = self.__saved_by_info[x] return u except (KeyError, AttributeError): return '' def snapshot_data(self): try: self.__filenames except AttributeError: filenames = os.listdir(self.snapshot_directory()) filenames.sort() self.__filenames = filenames t = time.time() v = [] for x in self.__filenames: base = os.path.splitext(x)[0] if self._saved_by_info(x): v.append((_('%(t)s ago by %(le)s',) % {'t': prettify_time_ago(t - float(base)), 'le': self._saved_by_info(base)}, x)) else: v.append((_('%(seconds)s ago', seconds=prettify_time_ago(t - float(base))), x)) return v def uncache_snapshot_data(self): try: del self.__snapshot_data except AttributeError: pass def revert_to_last_saved_state(self): filename = self.worksheet_html_filename() if os.path.exists(filename): E = open(filename).read() else: # nothing was ever saved! E = '' self.edit_save(E) def snapshot_directory(self): path = os.path.join(os.path.abspath(self.__dir), 'snapshots') if not os.path.exists(path): os.makedirs(path) return path def limit_snapshots(self): r""" This routine will limit the number of snapshots of a worksheet, as specified by a hard-coded value below. Prior behavior was to allow unlimited numbers of snapshots and so this routine will not delete files created prior to this change. This assumes snapshot names correspond to the ``time.time()`` method used to create base filenames in seconds in UTC time, and that there are no other extraneous files in the directory. """ # This should be user-configurable with an option like 'max_snapshots' max_snaps = 30 amnesty = int(calendar.timegm(time.strptime("01 May 2009", "%d %b %Y"))) path = self.snapshot_directory() snapshots = os.listdir(path) snapshots.sort() for i in range(len(snapshots) - max_snaps): creation = int(os.path.splitext(snapshots[i])[0]) if creation > amnesty: os.remove(os.path.join(path, snapshots[i])) ########################################################## # Exporting the worksheet in plain text command-line format ########################################################## def plain_text(self, prompts=False, banner=True): """ Return a plain-text version of the worksheet. INPUT: - ``prompts`` - if True format for inclusion in docstrings. """ s = '' if banner: s += "#" * 80 + '\n' s += "# Worksheet: %s" % self.name() + '\n' s += "#" * 80 + '\n\n' for C in self.cell_list(): t = C.plain_text(prompts=prompts).strip('\n') if t != '': s += '\n' + t return s def input_text(self): """ Return text version of the input to the worksheet. """ return '\n\n---\n\n'.join([C.input_text() for C in self.cell_list()]) ########################################################## # Editing the worksheet in plain text format (export and import) ########################################################## def body(self): """ OUTPUT: -- ``string`` -- Plain text representation of the body of the worksheet. """ s = '' for C in self.cell_list(): t = C.edit_text().strip() if t: s += '\n\n' + t return s def set_body(self, body): self.edit_save(body) def body_is_loaded(self): """ Return True if the body if this worksheet has been loaded from disk. """ try: self.__cells return True except AttributeError: return False def edit_text(self): """ Returns a plain-text version of the worksheet with {{{}}} wiki-formatting, suitable for hand editing. """ return self.body() def reset_interact_state(self): """ Reset the interact state of this worksheet. """ try: S = self.__sage except AttributeError: return try: S.execute('sagenb.notebook.interact.reset_state()') except OSError: # Doesn't matter, since if S is not running, no need # to zero out the state dictionary. return def edit_save_old_format(self, text, username=None): text.replace('\r\n', '\n') name, i = extract_name(text) self.set_name(name) text = text[i:] system, i = extract_system(text) if system == "None": system = "sage" self.set_system(system) text = text[i:] self.edit_save(text) def edit_save(self, text, ignore_ids=False): r""" Set the contents of this worksheet to the worksheet defined by the plain text string text, which should be a sequence of HTML and code blocks. INPUT: - ``text`` - a string - ``ignore_ids`` - bool (default: False); if True ignore all the IDs in the {{{}}} code block. EXAMPLES: We create a new test notebook and a worksheet. :: sage: nb = sagenb.notebook.notebook.Notebook(tmp_dir(ext='.sagenb')) sage: nb.user_manager().add_user('sage','sage','sage@sagemath.org',force=True) sage: W = nb.create_new_worksheet('Test Edit Save', 'sage') We set the contents of the worksheet using the edit_save command. :: sage: W.edit_save('{{{\n2+3\n///\n5\n}}}\n{{{\n2+8\n///\n10\n}}}') sage: W sage/0: [Cell 0: in=2+3, out= 5, Cell 1: in=2+8, out= 10] sage: W.name() u'Test Edit Save' We check that loading a worksheet whose last cell is a :class:`~sagenb.notebook.cell.TextCell` properly increments the worksheet's cell count (see Sage trac ticket `#8443`_). .. _#8443: http://trac.sagemath.org/sage_trac/ticket/8443 :: sage: nb = sagenb.notebook.notebook.Notebook(tmp_dir(ext='.sagenb')) sage: nb.user_manager().add_user('sage', 'sage', 'sage@sagemath.org', force=True) sage: W = nb.create_new_worksheet('Test trac #8443', 'sage') sage: W.edit_save('{{{\n1+1\n///\n}}}') sage: W.cell_id_list() [0] sage: W.next_id() 1 sage: W.edit_save("{{{\n1+1\n///\n}}}\n\n

    a text cell

    ") sage: len(set(W.cell_id_list())) == 3 True sage: W.cell_id_list() [0, 1, 2] sage: W.next_id() 3 """ # Clear any caching. try: del self.__html except AttributeError: pass self.reset_interact_state() text.replace('\r\n', '\n') data = [] while True: plain_text = extract_text_before_first_compute_cell(text).strip() if len(plain_text) > 0: T = plain_text data.append(('plain', T)) try: meta, input, output, i = extract_first_compute_cell(text) data.append(('compute', (meta, input, output))) except EOFError as msg: # print(msg) # -- don't print msg, just outputs a blank # line every time, which makes for an # ugly and unprofessional log. break text = text[i:] ids = set([x[0]['id'] for typ, x in data if typ == 'compute' and 'id' in x[0]]) used_ids = set([]) cells = [] for typ, T in data: if typ == 'plain': if len(T) > 0: id = next_available_id(ids) ids.add(id) cells.append(self._new_text_cell(T, id=id)) used_ids.add(id) elif typ == 'compute': meta, input, output = T if not ignore_ids and 'id' in meta: id = meta['id'] if id in used_ids: # In this case don't reuse, since ids must be unique. id = next_available_id(ids) ids.add(id) html = True else: id = next_available_id(ids) ids.add(id) html = False used_ids.add(id) try: self.__cells C = self.get_cell_with_id(id = id) if C.is_text_cell(): C = self._new_cell(id) except AttributeError: C = self._new_cell(id) C.set_input_text(input) C.set_output_text(output, '') if html: C.update_html_output(output) cells.append(C) self.__cells = cells # Set the next id. This *depends* on self.cell_list() being # set!! self.set_cell_counter() # There must be at least one cell. if len(cells) == 0 or cells[-1].is_text_cell(): self.append_new_cell() if not self.is_published(): for c in self.cell_list(): if c.is_interactive_cell(): c.delete_output() ########################################################## # HTML rendering of the whole worksheet ########################################################## def html_cell_list(self, do_print=False, username=None): """ INPUT: - do_print - a boolean OUTPUT: - string -- the HTML for the list of cells """ ncols = self.notebook().conf()['word_wrap_cols'] cells_html = "" if self.is_published(): try: return self.__html except AttributeError: for cell in self.cell_list(): cells_html += cell.html(ncols, do_print=True, username=self.username) + '\n' s = template(os.path.join('html', 'worksheet', 'published_worksheet.html'), ncols = ncols, cells_html = cells_html, username=username) self.__html = s return s for cell in self.cell_list(): try: cells_html += cell.html(ncols, do_print=do_print, username=self.username) + '\n' except Exception as msg: # catch any exception, since this exception is raised # sometimes, at least for some worksheets: # exceptions.UnicodeDecodeError: 'ascii' codec can't decode byte # 0xc2 in position 825: ordinal not in range(128) # and this causes the entire worksheet to fail to # save/render, which is obviously *not* good (much # worse than a weird issue with one cell). print(msg) return cells_html def html(self, do_print=False, publish=False, username=None): r""" INPUT: - publish - a boolean stating whether the worksheet is published - do_print - a boolean OUTPUT: - string -- the HTML for the worksheet EXAMPLES:: sage: nb = sagenb.notebook.notebook.Notebook(tmp_dir(ext='.sagenb')) sage: nb.create_default_users('password') sage: W = nb.create_new_worksheet('Test', 'admin') sage: W.html() u'...cell_input_active...worksheet_cell_list...cell_1...cell_output_html_1...' """ if self.is_published(): try: return self.__html except AttributeError: pass s = template(os.path.join("html", "notebook", "worksheet.html"), do_print=do_print, publish=publish, worksheet=self, username=username) if self.is_published(): self.__html = s return s def truncated_name(self, max=30): name = self.name() if len(name) > max: name = name[:max] + ' ...' return name ########################################################## # Last edited ########################################################## def last_change(self): """ Return information about when this worksheet was last changed and by whom. OUTPUT: - ``username`` -- string of username who last edited this worksheet - ``float`` -- seconds since epoch of the time when this worksheet was last edited """ return (self.last_to_edit(), self.last_edited()) def set_last_change(self, username, tm): """ Set the time and who last changed this worksheet. INPUT: - ``username`` -- (string) name of a user - ``tm`` -- (float) seconds since epoch EXAMPLES:: sage: W = sagenb.notebook.worksheet.Worksheet('test', 0, tmp_dir(), owner='sage') sage: W.last_change() ('sage', ...) sage: W.set_last_change('john', 1255029800) sage: W.last_change() ('john', 1255029800.0) We make sure these other functions have been correctly updated:: sage: W.last_edited() 1255029800.0 sage: W.last_to_edit() 'john' sage: W.date_edited() # Output depends on timezone time.struct_time(tm_year=2009, tm_mon=10, ...) sage: t = W.time_since_last_edited() # just test that call works """ username = str(username) tm = float(tm) self.__date_edited = (time.localtime(tm), username) self.__last_edited = (tm, username) # TODO: all code below needs to be re-organized, but without # breaking old worksheet migration. Do this after I wrote a # "basic" method for the *old* sage notebook codebase. At that # point I'll be able to greatly simplify worksheet migration and # totally refactor anything I want in the new sagenb code. def last_edited(self): try: return self.__last_edited[0] except AttributeError: t = time.time() self.__last_edited = (t, self.owner()) return t def date_edited(self): """ Returns the date the worksheet was last edited. """ try: return self.__date_edited[0] except AttributeError: t = time.localtime() self.__date_edited = (t, self.owner()) return t def last_to_edit(self): try: return self.__last_edited[1] except AttributeError: return self.owner() def record_edit(self, user): self.__last_edited = (time.time(), user) self.__date_edited = (time.localtime(), user) self.autosave(user) def time_since_last_edited(self): return time.time() - self.last_edited() def warn_about_other_person_editing(self, username, threshold = WARN_THRESHOLD): r""" Check to see if another user besides username was the last to edit this worksheet during the last ``threshold`` seconds. If so, return True and that user name. If not, return False. INPUT: - ``username`` - user who would like to edit this file. - ``threshold`` - number of seconds, so if there was no activity on this worksheet for this many seconds, then editing is considered safe. """ if self.time_since_last_edited() < threshold: user = self.last_to_edit() if user != username: return True, user return False def html_time_since_last_edited(self, username=None): t = self.time_since_last_edited() tm = prettify_time_ago(t) return template(os.path.join("html", "worksheet", "time_since_last_edited.html"), last_editor = self.last_to_edit(), time = tm, username=username) def html_time_last_edited(self, username=None): return template(os.path.join("html", "worksheet", "time_last_edited.html"), time = convert_time_to_string(self.last_edited()), last_editor = self.last_to_edit(), username=username) def html_time_nice_edited(self, username=None): """ Returns a "nice" html time since last edit. If the last edit was in the last 24 hours, return a "x hours ago". Otherwise, return a specific date. """ t = self.time_since_last_edited() if t < 3600*24: return self.html_time_since_last_edited(username=username) else: return self.html_time_last_edited(username=username) ########################################################## # Managing cells and groups of cells in this worksheet ########################################################## def cell_id_list(self): r""" Returns a list of ID's of all cells in this worksheet. OUTPUT: - a new list of integers and/or strings EXAMPLES:: sage: nb = sagenb.notebook.notebook.Notebook(tmp_dir(ext='.sagenb')) sage: nb.create_default_users('password') sage: W = nb.create_new_worksheet('Test Edit Save', 'admin') Now we set the worksheet to have two cells with the default id of 0 and another with id 10. :: sage: W.edit_save('{{{\n2+3\n///\n5\n}}}\n{{{id=10|\n2+8\n///\n10\n}}}') sage: W.cell_id_list() [0, 10] """ return [C.id() for C in self.cell_list()] def compute_cell_id_list(self): """ Returns a list of ID's of all compute cells in this worksheet. OUTPUT: - a new list of integers and/or strings """ return [C.id() for C in self.cell_list() if C.is_compute_cell()] def onload_id_list(self): """ Returns a list of ID's of cells the remote client should evaluate after the worksheet loads. Unlike '%auto' cells, which the server chooses to evaluate, onload cells fire only after the client sends a request. Currently, we use onload cells to set up published interacts. OUTPUT: - a new list of integer and/or string IDs """ return [C.id() for C in self.cell_list() if C.is_interactive_cell()] def cell_list(self): r""" Returns a reference to the list of this worksheet's cells. OUTPUT: - a list of :class:`sagenb.notebook.cell.Cell_generic` instances .. note:: This function loads the cell list from disk (the file worksheet.html) if it isn't available in memory. EXAMPLES:: sage: nb = sagenb.notebook.notebook.Notebook(tmp_dir(ext='.sagenb')) sage: nb.create_default_users('password') sage: W = nb.create_new_worksheet('Test Edit Save', 'admin') sage: W.edit_save('{{{\n2+3\n///\n5\n}}}\n{{{\n2+8\n///\n10\n}}}') sage: v = W.cell_list(); v [Cell 0: in=2+3, out= 5, Cell 1: in=2+8, out= 10] sage: v[0] Cell 0: in=2+3, out= 5 """ try: return self.__cells except AttributeError: # load from disk worksheet_html = self.worksheet_html_filename() if not os.path.exists(worksheet_html): self.__cells = [] else: self.set_body(open(worksheet_html).read()) return self.__cells def compute_cell_list(self): r""" Returns a list of this worksheet's compute cells. OUTPUT: - a list of :class:`sagenb.notebook.cell.Cell` instances EXAMPLES:: sage: nb = sagenb.notebook.notebook.Notebook(tmp_dir(ext='.sagenb')) sage: nb.create_default_users('password') sage: W = nb.create_new_worksheet('Test', 'admin') sage: W.edit_save('foo\n{{{\n2+3\n///\n5\n}}}bar\n{{{\n2+8\n///\n10\n}}}') sage: v = W.compute_cell_list(); v [Cell 1: in=2+3, out= 5, Cell 3: in=2+8, out= 10] sage: v[0] Cell 1: in=2+3, out= 5 """ return [C for C in self.cell_list() if C.is_compute_cell()] def append_new_cell(self): """ Creates and appends a new compute cell to this worksheet's list of cells. OUTPUT: - a new :class:`sagenb.notebook.cell.Cell` instance EXAMPLES:: sage: nb = sagenb.notebook.notebook.Notebook(tmp_dir(ext='.sagenb')) sage: nb.create_default_users('password') sage: W = nb.create_new_worksheet('Test Edit Save', 'admin') sage: W admin/0: [Cell 1: in=, out=] sage: W.append_new_cell() Cell 2: in=, out= sage: W admin/0: [Cell 1: in=, out=, Cell 2: in=, out=] """ C = self._new_cell() self.cell_list().append(C) return C def new_cell_before(self, id, input=''): """ Inserts a new compute cell before a cell with the given ID. If the ID does not match any cell in this worksheet's list, it inserts a new cell at the end. INPUT: - ``id`` - an integer or a string; the ID of the cell to find - ``input`` - a string (default: ''); the new cell's input text OUTPUT: - a new :class:`sagenb.notebook.cell.Cell` instance """ cells = self.cell_list() for i in range(len(cells)): if cells[i].id() == id: C = self._new_cell(input=input) cells.insert(i, C) return C C = self._new_cell(input=input) cells.append(C) return C def new_text_cell_before(self, id, input=''): """ Inserts a new text cell before the cell with the given ID. If the ID does not match any cell in this worksheet's list, it inserts a new cell at the end. INPUT: - ``id`` - an integer or a string; the ID of the cell to find - ``input`` - a string (default: ''); the new cell's input text OUTPUT: - a new :class:`sagenb.notebook.cell.TextCell` instance """ cells = self.cell_list() for i in range(len(cells)): if cells[i].id() == id: C = self._new_text_cell(plain_text=input) cells.insert(i, C) return C C = self._new_text_cell(plain_text=input) cells.append(C) return C def new_cell_after(self, id, input=''): """ Inserts a new compute cell into this worksheet's cell list after the cell with the given ID. If the ID does not match any cell, it inserts the new cell at the end of the list. INPUT: - ``id`` - an integer or a string; the ID of the cell to find - ``input`` - a string (default: ''); the new cell's input text OUTPUT: - a new :class:`sagenb.notebook.cell.Cell` instance """ cells = self.cell_list() for i in range(len(cells)): if cells[i].id() == id: C = self._new_cell(input=input) cells.insert(i + 1, C) return C C = self._new_cell(input=input) cells.append(C) return C def new_text_cell_after(self, id, input=''): """ Inserts a new text cell into this worksheet's cell list after the cell with the given ID. If the ID does not match any cell, it inserts the new cell at the end of the list. INPUT: - ``id`` - an integer or a string; the ID of the cell to find - ``input`` - a string (default: ''); the new cell's input text OUTPUT: - a new :class:`sagenb.notebook.cell.TextCell` instance """ cells = self.cell_list() for i in range(len(cells)): if cells[i].id() == id: C = self._new_text_cell(plain_text=input) cells.insert(i + 1, C) return C C = self._new_text_cell(plain_text=input) cells.append(C) return C def delete_cell_with_id(self, id): r""" Deletes a cell from this worksheet's cell list. This also deletes the cell's output and files. INPUT: - ``id`` - an integer or string; the cell's ID OUTPUT: - an integer or string; ID of the preceding cell EXAMPLES:: sage: nb = sagenb.notebook.notebook.Notebook(tmp_dir(ext='.sagenb')) sage: nb.create_default_users('password') sage: W = nb.create_new_worksheet('Test Delete Cell', 'admin') sage: W.edit_save('{{{id=foo|\n2+3\n///\n5\n}}}\n{{{id=9|\n2+8\n///\n10\n}}}{{{id=dont_delete_me|\n2*3\n///\n6\n}}}\n') sage: W.cell_id_list() ['foo', 9, 'dont_delete_me'] sage: C = W.cell_list()[1] # save a reference to the cell sage: C.output_text(raw=True) u'\n10' sage: open(os.path.join(C.directory(), 'bar'), 'w').write('hello') sage: C.files() ['bar'] sage: C.files_html('') u'bar' sage: W.delete_cell_with_id(C.id()) 'foo' sage: C.output_text(raw=True) u'' sage: C.files() [] sage: W.cell_id_list() ['foo', 'dont_delete_me'] """ cells = self.cell_list() for i in range(len(cells)): if cells[i].id() == id: # Delete this cell from the queued up calculation list: C = cells[i] if C in self.__queue and self.__queue[0] != C: self.__queue.remove(C) # Delete the cell's output. C.delete_output() # Delete this cell from the list of cells in this worksheet: del cells[i] if i > 0: return cells[i - 1].id() else: break return cells[0].id() ########################################################## # Managing whether computing is happening: stop, start, clear, etc. ########################################################## def clear(self): self.__comp_is_running = False self.__queue = [] self.__cells = [] for i in range(INITIAL_NUM_CELLS): self.append_new_cell() def computing(self): """ Return whether or not a cell is currently being run in the worksheet Sage process. """ try: return self.__comp_is_running except AttributeError: return False def set_not_computing(self): self.__comp_is_running = False self.__queue = [] def quit(self): try: S = self.__sage except AttributeError: # no sage running anyways! self.notebook().quit_worksheet(self) return try: S.quit() except AttributeError as msg: print("WARNING: %s" % msg) except Exception as msg: print(msg) print("WARNING: Error deleting Sage object!") try: os.kill(pid, 9) except: pass del self.__sage # We do this to avoid getting a stale Sage that uses old code. self.save() self.clear_queue() del self.__cells import shutil for cell in self.cell_list(): try: dir = cell._directory_name() except AttributeError: continue if os.path.exists(dir) and not os.listdir(dir): shutil.rmtree(dir, ignore_errors=True) self.notebook().quit_worksheet(self) def next_block_id(self): try: i = self.__next_block_id except AttributeError: i = 0 i += 1 self.__next_block_id = i return i def compute_process_has_been_started(self): """ Return True precisely if the compute process has been started, irregardless of whether or not it is currently churning away on a computation. """ try: return self.__sage.is_started() except AttributeError: return False def initialize_sage(self): S = self.__sage try: from . import misc cmd = """ import base64 import sagenb.misc.support as _support_ import sagenb.notebook.interact as _interact_ # for setting current cell id DATA = %r DIR = %r import sys; sys.path.append(DATA) _support_.init(None, globals()) # The following is Sage-specific -- this immediately bombs out if sage isn't installed. from sage.all_notebook import * sage.plot.plot.EMBEDDED_MODE=True sage.misc.latex.EMBEDDED_MODE=True # TODO: For now we take back sagenb interact; do this until the sage notebook # gets removed from the sage library. from sagenb.notebook.all import * try: load(os.path.join(os.environ['DOT_SAGE'], 'init.sage'), globals(),attach=True) except (KeyError, IOError): pass """ % (os.path.join(os.path.abspath(self.data_directory()),''), misc.DIR) S.execute(cmd) S.output_status() except Exception as msg: print("ERROR initializing compute process:\n") print(msg) del self.__sage raise RuntimeError(msg) # make sure we have a __sage attribute # We do this to diagnose google issue 81; once we # have fixed that issue, we can remove this next statement T = self.__sage A = self.attached_files() for F in A.iterkeys(): A[F] = 0 # expire all # Check to see if the typeset/pretty print button is checked. # If so, send code to initialize the worksheet to have the # right pretty printing mode. if self.pretty_print(): S.execute('pretty_print_default(True);') if not self.is_published(): self._enqueue_auto_cells() # make sure we have a __sage attribute # We do this to diagnose google issue 81; once we # have fixed that issue, we can remove this next statement T = self.__sage return S def sage(self): """ Return a started up copy of Sage initialized for computations. If this is a published worksheet, just return None, since published worksheets must not have any compute functionality. OUTPUT: a Sage interface """ if self.is_published(): return None try: S = self.__sage if S.is_started(): return S except AttributeError: pass self.__sage = self.notebook().new_worksheet_process() all_worksheet_processes.append(self.__sage) self.__next_block_id = 0 # make sure we have a __sage attribute # We do this to diagnose google issue 81; once we # have fixed that issue, we can remove this next statement S = self.__sage self.initialize_sage() # make sure we have a __sage attribute # We do this to diagnose google issue 81; once we # have fixed that issue, we can remove this next statement S = self.__sage return self.__sage def eval_asap_no_output(self, cmd, username=None): C = self._new_cell(hidden=True) C.set_asap(True) C.set_no_output(True) C.set_input_text(cmd) self.enqueue(C, username=username) def cell_directory(self, C): return C.directory() def start_next_comp(self): if len(self.__queue) == 0: return if self.__comp_is_running: #self._record_that_we_are_computing() return C = self.__queue[0] cell_system = self.get_cell_system(C) percent_directives = C.percent_directives() if C.interrupted(): # don't actually compute return if cell_system == 'sage' and C.introspect(): before_prompt, after_prompt = C.introspect() I = before_prompt else: I = C.cleaned_input_text() if I in ['restart', 'quit', 'exit']: self.restart_sage() S = self.system() if S is None: S = 'sage' C.set_output_text('Exited %s process' % S,'') return #Handle any percent directives if 'save_server' in percent_directives: self.notebook().save() id = self.next_block_id() C.code_id = id # prevent directory disappear problems input = '' # This is useful mainly for interact -- it allows a cell to # know its ID. input += '_interact_.SAGE_CELL_ID=%r\n__SAGE_TMP_DIR__=os.getcwd()\n' % C.id() if C.time(): input += '__SAGE_t__=cputime()\n__SAGE_w__=walltime()\n' # If the input ends in a question mark and is *not* a comment # line, then we introspect on it. if cell_system == 'sage' and len(I) != 0: #Get the last line of a possible multiline input Istrip = I.strip().split('\n').pop() if Istrip.endswith('?') and not Istrip.startswith('#'): C.set_introspect(I, '') #Handle line continuations: join lines that end in a backslash #_except_ in LaTeX mode. if cell_system not in ['latex', 'sage', 'python']: I = I.replace('\\\n','') C._before_preparse = input + I input += self.preparse_input(I, C) try: input = relocate_future_imports(input) except SyntaxError as msg: t = traceback.format_exc() s = 'File "",' i = t.find(s) if i != -1: t = t[i+len(s):] i = t.find('\n') try: n = int(t[t[:i].rfind(' '):i]) # line number of the exception try: t = 'Syntax Error:\n %s'%C._before_preparse.split('\n')[n-1] except IndexError: pass if False: if i != -1: t = t[i:] v = [w for w in t.split('\n') if w] t = '\n'.join(['Syntax Error:'] + v[0:-1]) C.set_output_text(t, '') del self.__queue[0] return except ValueError: pass if C.time() and not C.introspect(): input += '; print("CPU time: %.2f s, Wall time: %.2f s"%(cputime(__SAGE_t__), walltime(__SAGE_w__)))\n' self.__comp_is_running = True self.sage().execute(input, os.path.abspath(self.data_directory())) def check_comp(self, wait=0.2): r""" Check on currently computing cells in the queue. INPUT: - ``wait`` - float (default: 0.2); how long to wait for output. EXAMPLES:: sage: nb = sagenb.notebook.notebook.load_notebook(tmp_dir(ext='.sagenb')) sage: nb.user_manager().add_user('sage','sage','sage@sagemath.org',force=True) sage: W = nb.create_new_worksheet('Test', 'sage') sage: W.edit_save('{{{\n3^20\n}}}') sage: W.cell_list()[0].evaluate() sage: W.check_comp() # random output -- depends on computer speed ('d', Cell 0: in=3^20, out= 3486784401 ) sage: W.quit() sage: nb.delete() """ if len(self.__queue) == 0: return 'e', None S = self.sage() C = self.__queue[0] if C.interrupted(): self.__comp_is_running = False del self.__queue[0] return 'd', C try: output_status = S.output_status() except RuntimeError as msg: verbose("Computation was interrupted or failed. Restarting.\n%s" % msg) self.__comp_is_running = False self.start_next_comp() return 'w', C out = self.postprocess_output(output_status.output, C) if not output_status.done: # Still computing if not C.introspect(): C.set_output_text(out, '') ######################################################## # Create temporary symlinks to output files seen so far if len(output_status.filenames) > 0: cell_dir = os.path.abspath(self.cell_directory(C)) if not os.path.exists(cell_dir): os.makedirs(cell_dir) for X in output_status.filenames: if os.path.split(X)[1] == CODE_PY: continue target = os.path.join(cell_dir, os.path.split(X)[1]) if os.path.exists(target): os.unlink(target) os.symlink(X, target) ######################################################## return 'w', C if C.introspect() and not C.is_no_output(): before_prompt, after_prompt = C.introspect() if len(before_prompt) == 0: return if before_prompt[-1] != '?': # completions if hasattr(C, '_word_being_completed'): c = self.best_completion(out, C._word_being_completed) else: c = '' C.set_changed_input_text(before_prompt + c + after_prompt) out = self.completions_html(C.id(), out) C.set_introspect_html(out, completing=True) else: if C.eval_method == 'introspect': C.set_introspect_html(out, completing=False) else: C.set_introspect_html('') C.set_output_text('' + out + '', '') # Finished a computation. self.__comp_is_running = False del self.__queue[0] if C.is_no_output(): # Clean up the temp directories associated to C, and do # not set any output text that C might have got. d = self.cell_directory(C) for X in os.listdir(d): if os.path.split(X)[-1] != CODE_PY: Y = os.path.join(d, X) if os.path.isfile(Y): try: os.unlink(Y) except: pass else: shutil.rmtree(Y, ignore_errors=True) return 'd', C if not C.introspect(): filenames = output_status.filenames if len(filenames) > 0: # Move files to the cell directory cell_dir = os.path.abspath(self.cell_directory(C)) # We wipe the cell directory and make a new one to # clean up any cruft (like dead symbolic links to # temporary files that were deleted, old files from # old evaluations, ...). try: shutil.rmtree(cell_dir) except OSError: # Probably the directory didn't exist. If there # is a different problem, the makedirs() below will # see it. pass os.makedirs(cell_dir) for X in filenames: if os.path.split(X)[-1] == CODE_PY: continue target = os.path.join(cell_dir, os.path.split(X)[1]) # We move X to target. Note that we don't actually # do a rename: in a client/server setup, X might be # owned by a different Unix user than ourselves. if os.path.isdir(X): shutil.copytree(X, target, ignore=ignore_nonexistent_files) shutil.rmtree(X, ignore_errors=True) else: shutil.copy(X, target) os.unlink(X) set_restrictive_permissions(target) # Generate html, etc. html = C.files_html(out) C.set_output_text(out, html, sage=self.sage()) C.set_introspect_html('') return 'd', C def interrupt(self, callback = None, timeout = 1): r""" Interrupt all currently queued up calculations. INPUT: - ``timeout`` -- time to wait for interruption to succeed - ``callback`` -- callback to be called. Called with True if interrupt succeeds, else called with False. OUTPUT: - ``deferred`` - a Deferred object with the given callbacks and errbacks EXAMPLES: We create a worksheet and start a large factorization going:: sage: nb = sagenb.notebook.notebook.load_notebook(tmp_dir(ext='.sagenb')) sage: nb.user_manager().add_user('sage','sage','sage@sagemath.org',force=True) sage: W = nb.create_new_worksheet('Test', 'sage') sage: W.edit_save('{{{\nfactor(2^997-1)\n}}}') sage: W.cell_list()[0].evaluate() It's running still:: sage: W.check_comp() ('w', Cell 0: in=factor(2^997-1), out=...) We interrupt it successfully. :: sage: W.interrupt() # not tested -- needs running reactor True Now we check and nothing is computing. :: sage: W.check_comp() # random -- could fail on heavily loaded machine ('e', None) Clean up. :: sage: W.quit() sage: nb.delete() """ if len(self.__queue) == 0: # nothing to do return True # stop the current computation in the running Sage S = self.__sage S.interrupt() import time time.sleep(timeout) if S.is_computing(): return False else: return True def clear_queue(self): # empty the queue for C in self.__queue: C.interrupt() self.__queue = [] self.__comp_is_running = False def restart_sage(self): """ Restart Sage kernel. """ self.quit() self.sage() self.start_next_comp() def worksheet_command(self, cmd): # return URL in the web browser of the given cmd return '/home/%s/%s' % (self.filename(), cmd) ########################################################## # Idle timeout ########################################################## def quit_if_idle(self, timeout): r""" Quit the worksheet process if it has been "idle" for more than ``timeout`` seconds, where idle is by definition that the worksheet has not reported back that it is actually computing. I.e., an ignored worksheet process (since the user closed their browser) is also considered idle, even if code is running. """ # Quit only if timeout is greater than zero if timeout > 0 and self.time_idle() > timeout: # worksheet name may contain unicode, so we use %r, which prints # the \xXX form for unicode characters print("Quitting ignored worksheet process for %r." % self.name()) self.quit() def time_idle(self): return walltime() - self.last_compute_walltime() def last_compute_walltime(self): try: return self.__last_compute_walltime except AttributeError: t = walltime() self.__last_compute_walltime = t return t def _record_that_we_are_computing(self, username=None): self.__last_compute_walltime = walltime() if username: self.record_edit(username) def ping(self, username): if self.is_published(): return self._record_that_we_are_computing(username) ########################################################## # Enqueuing cells ########################################################## def queue(self): return list(self.__queue) def queue_id_list(self): return [c.id() for c in self.__queue] def enqueue(self, C, username=None, next=False): r""" Queue a cell for evaluation in this worksheet. INPUT: - ``C`` - a :class:`sagenb.notebook.cell.Cell` instance - ``username`` - a string (default: None); the name of the user evaluating this cell (mainly used for login) - ``next`` - a boolean (default: False); ignored .. note:: If ``C.is_asap()`` is True, then we put ``C`` as close to the beginning of the queue as possible, but after all "asap" cells. Otherwise, ``C`` goes at the end of the queue. """ if self.is_published(): return self._record_that_we_are_computing(username) if not C.is_compute_cell(): raise TypeError if C.worksheet() != self: raise ValueError("C must be have self as worksheet.") # Now enqueue the requested cell. if not (C in self.__queue): if C.is_asap(): if self.computing(): i = 1 else: i = 0 while i < len(self.__queue) and self.__queue[i].is_asap(): i += 1 self.__queue.insert(i, C) else: self.__queue.append(C) self.start_next_comp() def _enqueue_auto_cells(self): for c in self.cell_list(): if c.is_auto_cell(): self.enqueue(c) def next_id(self): try: return self.__next_id except AttributeError: self.set_cell_counter() return self.__next_id def set_cell_counter(self): self.__next_id = 1 + max([C.id() for C in self.cell_list() if isinstance(C.id(), int)] + [-1]) def _new_text_cell(self, plain_text, id=None): if id is None: id = self.next_id() self.__next_id += 1 return TextCell(id, plain_text, self) def next_hidden_id(self): try: i = self.__next_hidden_id self.__next_hidden_id -= 1 except AttributeError: i = -1 self.__next_hidden_id = -2 return i def _new_cell(self, id=None, hidden=False, input=''): if id is None: if hidden: id = self.next_hidden_id() else: id = self.next_id() self.__next_id += 1 return Cell(id, input, '', self) def append(self, L): self.cell_list().append(L) ########################################################## # Accessing existing cells ########################################################## def get_cell_with_id_or_none(self, id): """ Gets a pre-existing cell with this id, or returns None. """ for c in self.cell_list(): if c.id() == id: return c return None def get_cell_with_id(self, id): """ Get a pre-existing cell with this id, or creates a new one with it. """ return self.get_cell_with_id_or_none(id) or self._new_cell(id) def synchronize(self, s): try: i = (self.__synchro + 1)%65536 except AttributeError: i = 0 self.__synchro = i return 'print("%s%s")\n'%(SAGE_BEGIN,i) + s + '\nprint("%s%s")\n' % (SAGE_END, i) def synchro(self): try: return self.__synchro except AttributeError: return 0 def check_cell(self, id): """ Checks the status of a given compute cell. INPUT: - ``id`` - an integer or a string; the cell's ID. OUTPUT: - a (string, :class:`sagenb.notebook.cell.Cell`)-tuple; the cell's status ('d' for "done" or 'w' for "working") and the cell itself. """ cell = self.get_cell_with_id(id) if cell in self.__queue: status = 'w' else: status = 'd' return status, cell def is_last_id_and_previous_is_nonempty(self, id): if self.cell_list()[-1].id() != id: return False if len(self.cell_list()) == 1: return False if len(self.cell_list()[-2].output_text(ncols=0)) == 0: return False return True ########################################################## # (Tab) Completions ########################################################## def best_completion(self, s, word): completions = s.split() if len(completions) == 0: return '' n = len(word) i = n m = min([len(x) for x in completions]) while i <= m: word = completions[0][:i] for w in completions[1:]: if w[:i] != word: return w[n:i-1] i += 1 return completions[0][n:m] def completions_html(self, id, s, cols=3): if 'no completions of' in s: return '' completions = s.split() n = len(completions) l = n / cols + n % cols if n == 1: return '' # don't show a window, just replace it rows = [] for r in range(0, l): row = [] for c in range(cols): try: cell = completions[r + l * c] row.append(cell) except: row.append('') rows.append(row) return format_completions_as_html(id, rows) ########################################################## # Processing of input and output to worksheet process. ########################################################## def preparse_input(self, input, C): introspect = C.introspect() if introspect: input = self.preparse_introspection_input(input, C, introspect) else: switched, input = self.check_for_system_switching(input, C) if not switched: input = self.preparse_nonswitched_input(input) input += '\n' return input def preparse_introspection_input(self, input, C, introspect): before_prompt, after_prompt = introspect i = 0 while i < len(after_prompt): if after_prompt[i] == '?': if i < len(after_prompt)-1 and after_prompt[i + 1] == '?': i += 1 before_prompt += after_prompt[:i + 1] after_prompt = after_prompt[i + 1:] C.set_introspect(before_prompt, after_prompt) break elif after_prompt[i] in ['"', "'", ' ', '\t', '\n']: break i += 1 if before_prompt.endswith('??'): input = self._get_last_identifier(before_prompt[:-2]) input = 'print(_support_.source_code("%s", globals(), system="%s"))' % (input, self.system()) elif before_prompt.endswith('?'): input = self._get_last_identifier(before_prompt[:-1]) input = 'print(_support_.docstring("%s", globals(), system="%s"))' % (input, self.system()) else: input = self._get_last_identifier(before_prompt) C._word_being_completed = input input = 'print("\\n".join(_support_.completions("%s", globals(), system="%s")))' % (input, self.system()) return input def preparse_nonswitched_input(self, input): """ Preparse the input to a Sage Notebook cell. INPUT: - ``input`` -- a string OUTPUT: - a string """ input = ignore_prompts_and_output(input).rstrip() input = self.preparse(input) return input def _strip_synchro_from_start_of_output(self, s): z = SAGE_BEGIN + str(self.synchro()) i = s.find(z) if i == -1: # Did not find any synchronization info in the output # stream. j = s.find('Traceback') if j != -1: # Probably there was an error; better not hide it. return s[j:] else: # Maybe we just read too early -- suppress displaying # anything yet. return '' else: return s[i + len(z):] def postprocess_output(self, out, C): if C.introspect(): return out out = out.replace("NameError: name 'os' is not defined", "NameError: name 'os' is not defined\nTHERE WAS AN ERROR LOADING THE SAGE LIBRARIES. Try starting Sage from the command line to see what the error is.") # Todo: what does this do? document this try: tb = 'Traceback (most recent call last):' i = out.find(tb) if i != -1: t = '.py", line' j = out.find(t) z = out[j+5:].find(',') n = int(out[j+len(t):z + j+5]) k = out[j:].find('\n') if k != -1: k += j l = out[k+1:].find('\n') if l != -1: l += k+1 I = C._before_preparse.split('\n') out = out[:i + len(tb)+1] + ' ' + I[n-2] + out[l:] except (ValueError, IndexError): pass return out def _get_last_identifier(self, s): import sagenb.misc.support as support return support.get_rightmost_identifier(s) def preparse(self, s): """ Return preparsed version of input code ``s``, ready to be sent to the Sage process for evaluation. The output is a "safe string" (no funny characters). INPUT: - ``s`` -- a string OUTPUT: - a string """ # The extra newline below is necessary, since otherwise source # code introspection doesn't include the last line. return 'open("%s","w").write("# -*- coding: utf-8 -*-\\n" + _support_.preparse_worksheet_cell(base64.b64decode("%s"),globals())+"\\n"); execfile(os.path.abspath("%s"))'%(CODE_PY, base64.b64encode(s.encode('utf-8', 'ignore')), CODE_PY) ########################################################## # Loading and attaching files ########################################################## def load_any_changed_attached_files(self, s): r""" Modify ``s`` by prepending any necessary load commands corresponding to attached files that have changed. """ A = self.attached_files() init_sage = DOT_SAGENB + 'init.sage' if not init_sage in A.keys() and os.path.exists(init_sage): A[init_sage] = 0 # since we change A during the iteration # we need to make a copy first for F, tm in list(A.items()): try: new_tm = os.path.getmtime(F) except OSError: del A[F] else: if new_tm > tm: A[F] = new_tm s = 'load %s\n' % F + s return s def attached_files(self): try: A = self.__attached except AttributeError: A = {} self.__attached = A return A def attach(self, filename): A = self.attached_files() try: A[filename] = os.path.getmtime(filename) except OSError: print("WARNING: File %s vanished" % filename) def detach(self, filename): A = self.attached_files() try: A.pop(filename) except KeyError: pass def _normalized_filenames(self, L): i = L.find('#') if i != -1: L = L[:i] a = [] for filename in L.split(): filename = filename.strip('"\'') if not filename.endswith('.py') and not filename.endswith('.sage') and \ not filename.endswith('.sobj') and not os.path.exists(filename): if os.path.exists(filename + '.sage'): filename = filename + '.sage' elif os.path.exists(filename + '.py'): filename = filename + '.py' elif os.path.exists(filename + '.sobj'): filename = filename + '.sobj' a.append(filename) return a def load_path(self): D = self.cells_directory() return [os.path.join(self.directory(), 'data')] + [D + x for x in os.listdir(D)] def hunt_file(self, filename): if filename.lower().startswith('http://'): filename = get_remote_file(filename) if not os.path.exists(filename): fn = os.path.split(filename)[-1] for D in self.load_path(): t = os.path.join(D, fn) if os.path.exists(t): filename = t break if os.path.exists(t + '.sobj'): filename = t + '.sobj' break return os.path.abspath(filename) def _load_file(self, filename, files_seen_so_far, this_file): if filename.endswith('.sobj'): name = os.path.splitext(filename)[0] name = os.path.split(name)[-1] return '%s = load("%s");'%(name, filename) if filename in files_seen_so_far: t = "print('WARNING: Not loading %s -- would create recursive load')" % filename try: F = open(filename).read() except IOError: return "print('Error loading %s -- file not found')" % filename else: filename_orig = filename filename = filename.rstrip('.txt') if filename.endswith('.py'): t = F elif filename.endswith('.spyx') or filename.endswith('.pyx'): cur = os.path.abspath(os.curdir) try: mod, dir = cython.cython(filename_orig, compile_message=True, use_cache=True) except (IOError, OSError, RuntimeError) as msg: return "print(r'''Error compiling cython file:\n%s''')" % msg t = "import sys\n" t += "sys.path.append('%s')\n"%dir t += "from %s import *\n"%mod return t elif filename.endswith('.sage'): t = self.preparse(F) else: t = "print('Loading of file \"%s\" has type not implemented.')" % filename t = self.do_sage_extensions_preparsing(t, files_seen_so_far + [this_file], filename) return t def _save_objects(self, s): s = s.replace(',',' ').replace('(',' ').replace(')',' ') v = s.split() return ';'.join(['save(%s,"%s")'%(x,x) for x in v]) def _eval_cmd(self, system, cmd): return u"print(_support_.syseval(%s, %r, __SAGE_TMP_DIR__))" % (system, cmd) ########################################################## # Parsing the %cython, %mathjax, %python, etc., extension. ########################################################## def get_cell_system(self, cell): r""" Returns the system that will run the input in cell. This defaults to worksheet's system if there is not one specifically given in the cell. EXAMPLES:: sage: nb = sagenb.notebook.notebook.Notebook(tmp_dir(ext='.sagenb')) sage: nb.user_manager().add_user('sage','sage','sage@sagemath.org',force=True) sage: W = nb.create_new_worksheet('Test', 'sage') sage: W.edit_save('{{{\n2+3\n}}}\n\n{{{\n%gap\nSymmetricGroup(5)\n}}}') sage: c0, c1 = W.cell_list() sage: W.get_cell_system(c0) 'sage' sage: W.get_cell_system(c1) u'gap' sage: W.edit_save('{{{\n%sage\n2+3\n}}}\n\n{{{\nSymmetricGroup(5)\n}}}') sage: W.set_system('gap') sage: c0, c1 = W.cell_list() sage: W.get_cell_system(c0) u'sage' sage: W.get_cell_system(c1) 'gap' """ if cell.system() is not None: system = cell.system() else: system = self.system() return system def cython_import(self, cmd, cell): # Choice: Can use either C.relative_id() or # self.next_block_id(). C.relative_id() has the advantage # that block evals are cached, i.e., no need to recompile. On # the other hand tracebacks don't work if you change a cell # and create a new function in it. Caching is also annoying # since the linked .c file disappears. # TODO: This design will *only* work on local machines -- need # to redesign so works even if compute worksheet process is # remote! id = self.next_block_id() code = os.path.join(self.directory(), 'code') if not os.path.exists(code): os.makedirs(code) spyx = os.path.abspath(os.path.join(code, 'sage%s.spyx'%id)) if not (os.path.exists(spyx) and open(spyx).read() == cmd): open(spyx,'w').write(cmd.encode('utf-8', 'ignore')) return '_support_.cython_import_all("%s", globals())'%spyx def check_for_system_switching(self, input, cell): r""" Check for input cells that start with ``%foo``, where ``foo`` is an object with an eval method. INPUT: - ``s`` - a string of the code from the cell to be executed - ``C`` - the cell object EXAMPLES: First, we set up a new notebook and worksheet. :: sage: nb = sagenb.notebook.notebook.load_notebook(tmp_dir(ext='.sagenb')) sage: nb.user_manager().add_user('sage','sage','sage@sagemath.org',force=True) sage: W = nb.create_new_worksheet('Test', 'sage') We first test running a native command in 'sage' mode and then a GAP cell within Sage mode. :: sage: W.edit_save('{{{\n2+3\n}}}\n\n{{{\n%gap\nSymmetricGroup(5)\n}}}') sage: c0, c1 = W.cell_list() sage: W.check_for_system_switching(c0.cleaned_input_text(), c0) (False, u'2+3') sage: W.check_for_system_switching(c1.cleaned_input_text(), c1) (True, u"print(_support_.syseval(gap, u'SymmetricGroup(5)', __SAGE_TMP_DIR__))") :: sage: c0.evaluate() sage: W.check_comp() #random output -- depends on the computer's speed ('d', Cell 0: in=2+3, out= 5 ) sage: c1.evaluate() sage: W.check_comp() #random output -- depends on the computer's speed ('d', Cell 1: in=%gap SymmetricGroup(5), out= Sym( [ 1 .. 5 ] ) ) Next, we run the same commands but from 'gap' mode. :: sage: W.edit_save('{{{\n%sage\n2+3\n}}}\n\n{{{\nSymmetricGroup(5)\n}}}') sage: W.set_system('gap') sage: c0, c1 = W.cell_list() sage: W.check_for_system_switching(c0.cleaned_input_text(), c0) (False, u'2+3') sage: W.check_for_system_switching(c1.cleaned_input_text(), c1) (True, u"print(_support_.syseval(gap, u'SymmetricGroup(5)', __SAGE_TMP_DIR__))") sage: c0.evaluate() sage: W.check_comp() #random output -- depends on the computer's speed ('d', Cell 0: in=%sage 2+3, out= 5 ) sage: c1.evaluate() sage: W.check_comp() #random output -- depends on the computer's speed ('d', Cell 1: in=SymmetricGroup(5), out= Sym( [ 1 .. 5 ] ) ) sage: W.quit() sage: nb.delete() """ system = self.get_cell_system(cell) if system == 'sage': return False, input elif system in ['cython', 'pyrex', 'sagex']: return True, self.cython_import(input, cell) else: cmd = self._eval_cmd(system, input) return True, cmd ########################################################## # List of attached files. ########################################################## def attached_html(self, username=None): return template(os.path.join("html", "worksheet", "attached.html"), attached_files = self.attached_files(), username=username) ########################################################## # Showing and hiding all cells ########################################################## def show_all(self): for C in self.cell_list(): try: C.set_cell_output_type('wrap') except AttributeError: # for backwards compatibility pass def hide_all(self): for C in self.cell_list(): try: C.set_cell_output_type('hidden') except AttributeError: pass def delete_all_output(self, username): r""" Delete all the output, files included, in all the worksheet cells. INPUT: - ``username`` - name of the user requesting the deletion. EXAMPLES: We create a new notebook, user, and a worksheet:: sage: nb = sagenb.notebook.notebook.load_notebook(tmp_dir(ext='.sagenb')) sage: nb.user_manager().add_user('sage','sage','sage@sagemath.org',force=True) sage: W = nb.create_new_worksheet('Test', 'sage') sage: W.edit_save("{{{\n2+3\n///\n5\n}}}\n{{{\nopen('afile', 'w').write('some text')\nprint('hello')\n///\n\n}}}") We have two cells:: sage: W.cell_list() [Cell 0: in=2+3, out= 5, Cell 1: in=open('afile', 'w').write('some text') print('hello'), out= ] sage: C0 = W.cell_list()[1] sage: open(os.path.join(C0.directory(), 'xyz'), 'w').write('bye') sage: C0.files() ['xyz'] sage: C1 = W.cell_list()[1] sage: C1.evaluate() sage: W.check_comp() # random output -- depends on computer speed ('w', Cell 1: in=open('afile', 'w').write('some text') print('hello'), out=) sage: W.check_comp() # random output -- depends on computer speed ('d', Cell 1: in=open('afile', 'w').write('some text') print('hello'), out= hello ) sage: W.check_comp() # random output -- depends on computer speed ('e', None) sage: C1.files() # random output -- depends on computer speed ['afile'] We now delete the output, observe that it is gone:: sage: W.delete_all_output('sage') sage: W.cell_list() [Cell 0: in=2+3, out=, Cell 1: in=open('afile', 'w').write('some text') print('hello'), out=] sage: C0.files(), C1.files() ([], []) If an invalid user tries to delete all output, a ValueError is raised:: sage: W.delete_all_output('hacker') Traceback (most recent call last): ... ValueError: user 'hacker' not allowed to edit this worksheet Clean up:: sage: W.quit() sage: nb.delete() """ if not self.user_can_edit(username): raise ValueError("user '%s' not allowed to edit this worksheet" % username) for C in self.cell_list(): C.delete_output() __internal_test1 = 'def foo(x):\n """\n EXAMPLES:\n sage: 2+2\n 4\n """\n return x\n'.lstrip() __internal_test2 = ''' sage: 2 + 2 4 '''.lstrip() def ignore_prompts_and_output(aString): r""" Given a string s that defines an input block of code, if the first line begins in ``sage:`` (or ``>>>``), strip out all lines that don't begin in either ``sage:`` (or ``>>>``) or ``...``, and remove all ``sage:`` (or ``>>>``) and ``...`` from the beginning of the remaining lines. TESTS:: sage: test1 = sagenb.notebook.worksheet.__internal_test1 sage: test1 == sagenb.notebook.worksheet.ignore_prompts_and_output(test1) True sage: test2 = sagenb.notebook.worksheet.__internal_test2 sage: sagenb.notebook.worksheet.ignore_prompts_and_output(test2) '2 + 2\n' """ s = aString.lstrip() is_example = s.startswith('sage:') or s.startswith('>>>') if not is_example: return aString # return original, not stripped copy new = '' lines = s.split('\n') for line in lines: line = line.lstrip() if line.startswith('sage:'): new += after_first_word(line).lstrip() + '\n' elif line.startswith('>>>'): new += after_first_word(line).lstrip() + '\n' elif line.startswith('...'): new += after_first_word(line) + '\n' return new def extract_text_before_first_compute_cell(text): """ OUTPUT: Everything in text up to the first {{{. """ i = text.find('{{{') if i == -1: return text return text[:i] def extract_first_compute_cell(text): """ INPUT: a block of wiki-like marked up text OUTPUT: - ``meta`` - meta information about the cell (as a dictionary) - ``input`` - string, the input text - ``output`` - string, the output text - ``end`` - integer, first position after }}} in text. """ # Find the input block i = text.find('{{{') if i == -1: raise EOFError j = text[i:].find('\n') if j == -1: raise EOFError k = text[i:].find('|') if k != -1 and k < j: try: meta = dictify(text[i + 3:i + k]) except TypeError: meta = {} i += k + 1 else: meta = {} i += 3 j = text[i:].find('\n}}}') if j == -1: j = len(text) else: j += i k = text[i:].find('\n///') if k == -1 or k + i > j: input = text[i:j] output = '' else: input = text[i:i + k].strip() output = text[i + k + 4:j] return meta, input.strip(), output, j + 4 def after_first_word(s): r""" Return everything after the first whitespace in the string s. Returns the empty string if there is nothing after the first whitespace. INPUT: - ``s`` - string OUTPUT: a string EXAMPLES:: sage: from sagenb.notebook.worksheet import after_first_word sage: after_first_word("\%gap\n2+2\n") '2+2\n' sage: after_first_word("2+2") '' """ i = whitespace.search(s) if i is None: return '' return s[i.start() + 1:] def first_word(s): r""" Returns everything before the first whitespace in the string s. If there is no whitespace, then the entire string s is returned. EXAMPLES:: sage: from sagenb.notebook.worksheet import first_word sage: first_word("\%gap\n2+2\n") '\\%gap' sage: first_word("2+2") '2+2' """ i = whitespace.search(s) if i is None: return s return s[:i.start()] def format_completions_as_html(cell_id, completions, username=None): """ Returns tabular HTML code for a list of introspection completions. INPUT: - ``cell_id`` - an integer or a string; the ID of the ambient cell - ``completions`` - a nested list of completions in row-major order OUTPUT: - a string """ if len(completions) == 0: return '' return template(os.path.join("html", "worksheet", "completions.html"), cell_id = cell_id, # Transpose and enumerate completions to column-major completions_enumerated = enumerate(map(list, zip(*completions)))) def extract_name(text): # The first line is the title i = non_whitespace.search(text) if i is None: name = _('Untitled') n = 0 else: i = i.start() j = text[i:].find('\n') if j != -1: name = text[i:i + j] n = j + 1 else: name = text[i:] n = len(text) - 1 return name.strip(), n def extract_system(text): # If the first line is "system: ..." , then it is the system. Otherwise the system is Sage. i = non_whitespace.search(text) if i is None: return 'sage', 0 else: i = i.start() if not text[i:].startswith('system:'): return 'sage', 0 j = text[i:].find('\n') if j != -1: system = text[i:i + j][7:].strip() n = j + 1 else: system = text[i:][7:].strip() n = len(text) - 1 return system, n def dictify(s): """ INPUT: - ``s`` - a string like 'in=5, out=7' OUTPUT: - ``dict`` - such as 'in':5, 'out':7 """ w = [] try: for v in s.split(','): a, b = v.strip().split('=') try: b = eval(b) except: pass w.append([a, b]) except ValueError: return {} return dict(w) def next_available_id(v): """ Return smallest nonnegative integer not in v. """ i = 0 while i in v: i += 1 return i def convert_time_to_string(t): """ Converts ``t`` (in Unix time) to a locale-specific string describing the time and date. """ from flask.ext.babel import format_datetime import datetime, time try: return format_datetime(datetime.datetime.fromtimestamp(float(t))) except AttributeError: #testing as opposed to within the Flask app return time.strftime('%B %d, %Y %I:%M %p', time.localtime(float(t))) # For pybabel lazy_gettext('January') lazy_gettext('February') lazy_gettext('March') lazy_gettext('April') lazy_gettext('May') lazy_gettext('June') lazy_gettext('July') lazy_gettext('August') lazy_gettext('September') lazy_gettext('October') lazy_gettext('November') lazy_gettext('December') def split_search_string_into_keywords(s): r""" The point of this function is to allow for searches like this:: "ws 7" foo bar Modular '"the" end' i.e., where search terms can be in quotes and the different quote types can be mixed. INPUT: - ``s`` - a string OUTPUT: - ``list`` - a list of strings """ ans = [] while len(s) > 0: word, i = _get_next(s, '"') if i != -1: ans.append(word) s = s[i:] word, j = _get_next(s, "'") if j != -1: ans.append(word) s = s[j:] if i == -1 and j == -1: break ans.extend(s.split()) return ans def _get_next(s, quote='"'): i = s.find(quote) if i != -1: j = s[i + 1:].find(quote) if j != -1: return s[i + 1:i + 1 + j].strip(), i + 1 + j return None, -1 sagenb-1.0.1/sagenb/simple/000077500000000000000000000000001311436262400155025ustar00rootroot00000000000000sagenb-1.0.1/sagenb/simple/__init__.py000066400000000000000000000000271311436262400176120ustar00rootroot00000000000000# -*- coding: utf-8 -* sagenb-1.0.1/sagenb/simple/twist.py000066400000000000000000000307341311436262400172350ustar00rootroot00000000000000# -*- coding: utf-8 -* r"""nodoctest Simple Sage Server API This module provides a very simple API for interacting with a Sage session over HTTP. It runs as part of the notebook server. .. warning:: This code currently doesn't work, since the notebook moved to a flask-based architecture. Volunteers are welcome to port this to the new flask notebook. .. note:: The exact data in the JSON header may vary over time (for example, further data may be added), but should remain backwards compatible if it is being parsed as JSON data. TESTS: Here's a usage example which demonstrates all the features of this server/API. Start the notebook server.:: sage: from sagenb.misc.misc import find_next_available_port sage: port = find_next_available_port(9000, verbose=False) sage: from sagenb.notebook.notebook_object import test_notebook sage: passwd = str(randint(1,1<<128)) sage: nb = test_notebook(passwd, secure=False, address='localhost', port=port, verbose=True) ... Notebook started. Now here's what you can do on the client side. Import `urllib `_ and define a convenience function:: sage: import urllib, re sage: def get_url(url): h = urllib.urlopen(url); data = h.read(); h.close(); return data Login to a new session:: sage: sleep(1) sage: login_page = get_url('http://localhost:%s/simple/login?username=admin&password=%s' % (port, passwd)) sage: print(login_page) # random session id { "session": "2afee978c09b3d666c88b9b845c69608" } ___S_A_G_E___ sage: session = re.match(r'.*"session": "([^"]*)"', login_page, re.DOTALL).groups()[0] Run a command:: sage: sleep(0.5) sage: print(get_url('http://localhost:%s/simple/compute?session=%s&code=2*2&timeout=60' % (port, session))) { "status": "done", "files": [], "cell_id": 1 } ___S_A_G_E___ 4 This API returns information as a string, the first part of which is a `JSON-encoded `_ dictionary. The second part -- after the separator ``___S_A_G_E___`` -- is the text of the output. To parse output, you just need to split the string and parse the JSON data into your local format. Do a longer-running example:: sage: n = next_prime(10^25)*next_prime(10^30) sage: print(get_url('http://localhost:%s/simple/compute?session=%s&code=factor(%s)&timeout=0.1' % (port, session, n))) { "status": "computing", "files": [], "cell_id": 2 } ___S_A_G_E___ Get the status of the computation:: sage: print(get_url('http://localhost:%s/simple/status?session=%s&cell=2' % (port, session))) { "status": "computing", "files": [], "cell_id": 2 } ___S_A_G_E___ Interrupt the computation:: sage: _ = get_url('http://localhost:%s/simple/interrupt?session=%s' % (port, session)) You can download files that your code creates on the remote server. Here we write a file, and then download it to our client:: sage: code = "h = open('a.txt', 'w'); h.write('test'); h.close()" sage: print(get_url('http://localhost:%s/simple/compute?session=%s&code=%s' % (port, session, urllib.quote(code)))) { "status": "done", "files": ["a.txt"], "cell_id": 3 } ___S_A_G_E___ sage: print(get_url('http://localhost:%s/simple/file?session=%s&cell=3&file=a.txt' % (port, session))) test When you are done, log out:: sage: _ = get_url('http://localhost:%s/simple/logout?session=%s' % (port, session)) sage: nb.dispose() .. warning:: It's important that your code log out the session. Otherwise, it is very easy to create an unintentional denial-of-service attack by having the server accumulate a large number of idle worksheets which consume a lot of memory and make the server unresponsive! """ ############################################################################# # Copyright (C) 2007 Robert Bradshaw # Distributed under the terms of the GNU General Public License (GPL) # The full text of the GPL is available at: # http://www.gnu.org/licenses/ ############################################################################# # # 2010 - David Poetzsch-Heffter: Fixed trac #9327 # import re import random import os.path import shutil import time from six import iteritems from twisted.internet.task import LoopingCall from twisted.python import log from twisted.internet import defer, reactor from twisted.cred import credentials from twisted.web2 import server, http, resource, channel from twisted.web2 import static, http_headers, responsecode sessions = {} # There must be a better way to avoid circular imports... late_import_done = False def late_import(): global SEP, notebook_twist, late_import_done if not late_import_done: from sagenb.notebook.twist import SEP import sagenb.notebook.twist as notebook_twist late_import_done = True def simple_jsonize(data): """ This will be replaced by a JSON spkg when Python 2.6 gets into Sage. EXAMPLES:: sage: from sagenb.simple.twist import simple_jsonize sage: print(simple_jsonize({'a': [1,2,3], 'b': "yep"})) { "a": [1, 2, 3], "b": "yep" } """ if isinstance(data, dict): values = ['"%s": %s' % (key, simple_jsonize(value)) for key, value in iteritems(data)] return "{\n%s\n}" % ',\n'.join(values) elif isinstance(data, (list, tuple)): values = [simple_jsonize(value) for value in data] return "[%s]" % ",\n".join(values) elif isinstance(data, bool): return str(data).lower() elif data is None: return "null" else: value = str(data) if re.match(r'^\d+(\.\d*)?$', value): return value else: return '"%s"' % value class SessionObject: def __init__(self, id, username, worksheet, timeout=5): self.id = id self.username = username self.worksheet = worksheet self.default_timeout = timeout def get_status(self): """ Return a dictionary to be returned (in JSON format) representing the status of self. TEST:: sage: from sagenb.simple.twist import SessionObject sage: s = SessionObject(id=1, username=None, worksheet=None) sage: s.get_status() {'session': 1} """ return { 'session': self.id } class LoginResource(resource.Resource): def render(self, ctx): late_import() try: username = ctx.args['username'][0] password = ctx.args['password'][0] U = notebook_twist.notebook.user(username) if not U.password_is(password): raise ValueError # want to return the same error message except (KeyError, ValueError): return http.Response(stream = "Invalid login.") worksheet = notebook_twist.notebook.create_new_worksheet("_simple_session_", username, add_to_list=False) worksheet.sage() # create the sage session worksheet.initialize_sage() # is this a secure enough random number? session_id = "%x" % random.randint(1, 1 << 128) session = SessionObject(session_id, username, worksheet) sessions[session_id] = session status = session.get_status() print(ctx.args) return http.Response(stream = "%s\n%s\n" % (simple_jsonize(status), SEP)) class LogoutResource(resource.Resource): def render(self, ctx): try: session = sessions[ctx.args['session'][0]] except KeyError: return http.Response(stream = "Invalid session.") session.worksheet.quit() shutil.rmtree(session.worksheet.directory()) status = session.get_status() del sessions[ctx.args['session'][0]] return http.Response(stream = "%s\n%s\n" % (simple_jsonize(status), SEP)) class InterruptResource(resource.Resource): def render(self, ctx): try: session = sessions[ctx.args['session'][0]] except KeyError: return http.Response(stream = "Invalid session.") session.worksheet.interrupt() status = session.get_status() return http.Response(stream = "%s\n%s\n" % (simple_jsonize(status), SEP)) class RestartResource(resource.Resource): def render(self, ctx): try: session = sessions[ctx.args['session'][0]] except KeyError: return http.Response(stream = "Invalid session.") session.worksheet.restart_sage() status = session.get_status() return http.Response(stream = "%s\n%s\n" % (simple_jsonize(status), SEP)) class CellResource(resource.Resource): def start_comp(self, cell, timeout): start_time = time.time() looper_list = [] looper = LoopingCall(self.check_comp, cell, start_time, timeout, looper_list) looper_list.append(looper) # so check_comp has access looper.cell = cell # to pass it on d = looper.start(0.25, now=True) d.addCallback(self.render_cell_result) return d def check_comp(self, cell, start_time, timeout, looper_list): cell.worksheet().check_comp(wait=0.01) # don't want to block, delay handled by twisted if not cell.computing() or time.time() - start_time > timeout: looper_list[0].stop() def render_cell_result(self, looper): cell = looper.cell if cell.interrupted(): cell_status = 'interrupted' elif cell.computing(): cell_status = 'computing' else: cell_status = 'done' status = { 'cell_id': cell.id(), 'status': cell_status, 'files': cell.files() } result = cell.output_text(raw=True) # The conversion to str must be done because unicode strings are somehow not # supported by http.Response return http.Response(stream = str("\n".join([simple_jsonize(status), SEP, result]))) class ComputeResource(CellResource): def render(self, ctx): print(ctx.args) try: session = sessions[ctx.args['session'][0]] except KeyError: return http.Response(stream = "Invalid session.") try: timeout = float(ctx.args['timeout'][0]) except (KeyError, ValueError): timeout = session.default_timeout cell = session.worksheet.append_new_cell() cell.set_input_text(ctx.args['code'][0]) cell.evaluate(username = session.username) print(cell) return self.start_comp(cell, timeout) class StatusResource(CellResource): def render(self, ctx): try: session = sessions[ctx.args['session'][0]] except KeyError: return http.Response(stream = "Invalid session.") try: cell_id = int(ctx.args['cell'][0]) cell = session.worksheet.get_cell_with_id(cell_id) try: timeout = float(ctx.args['timeout'][0]) except (KeyError, ValueError): timeout = -1 return self.start_comp(cell, timeout) except KeyError: status = session.get_status() return http.Response(stream = "%s\n%s\n" % (simple_jsonize(status), SEP)) class FileResource(resource.Resource): """ This differs from the rest as it does not print a header, just the raw file data. """ def render(self, ctx): try: session = sessions[ctx.args['session'][0]] except KeyError: return http.Response(code=404, stream = "Invalid session.") try: cell_id = int(ctx.args['cell'][0]) file_name = ctx.args['file'][0] except KeyError: return http.Response(code=404, stream = "Unspecified cell or file.") cell = session.worksheet.get_cell_with_id(cell_id) if file_name in cell.files(): return static.File(os.path.join(cell.directory(), file_name)) else: return http.Response(code=404, stream = "No such file %s in cell %s." % (file_name, cell_id)) class SimpleServer(resource.Resource): child_login = LoginResource() child_logout = LogoutResource() child_interrupt = InterruptResource() child_restart = RestartResource() child_compute = ComputeResource() child_status = StatusResource() child_file = FileResource() def render(self, ctx): return http.Response(stream="Please login.") sagenb-1.0.1/sagenb/storage/000077500000000000000000000000001311436262400156555ustar00rootroot00000000000000sagenb-1.0.1/sagenb/storage/__init__.py000066400000000000000000000001141311436262400177620ustar00rootroot00000000000000# -*- coding: utf-8 -* from .filesystem_storage import FilesystemDatastore sagenb-1.0.1/sagenb/storage/abstract_storage.py000066400000000000000000000102701311436262400215560ustar00rootroot00000000000000# -*- coding: utf-8 -* """ Sage Notebook Storage Abstraction Layer """ import os class Datastore(object): """ The Sage Notebook storage abstraction layer abstract base class. Each storage abstraction layer derives from this. """ def __repr__(self): """ String representation of this abstract datastore. EXAMPLES:: sage: from sagenb.storage.abstract_storage import Datastore sage: Datastore().__repr__() 'Abstract Datastore' """ return "Abstract Datastore" def load_server_conf(self): raise NotImplementedError def save_server_conf(self, server_conf): raise NotImplementedError def load_openid(self): raise NotImplementedError def save_openid(self, openid_dict): raise NotImplementedError def load_users(self): """ OUTPUT: - dictionary of user info """ raise NotImplementedError def save_users(self, users): """ INPUT: - ``users`` -- dictionary mapping user names to users """ raise NotImplementedError def load_user_history(self, username): """ Return the history log for the given user. INPUT: - ``username`` -- string OUTPUT: - list of strings """ raise NotImplementedError def save_user_history(self, username, history): """ Save the history log (a list of strings) for the given user. INPUT: - ``username`` -- string - ``history`` -- list of strings """ raise NotImplementedError def save_worksheet(self, worksheet, conf_only=False): """ INPUT: - ``worksheet`` -- a Sage worksheet - ``conf_only`` -- default: False; if True, only save the config file, not the actual body of the worksheet """ raise NotImplementedError def create_worksheet(self, username, id_number): """ Create worksheet with given id_number belonging to the given user. If the worksheet already exists, return ValueError. INPUT: - ``username`` -- string - ``id_number`` -- integer OUTPUT: - a worksheet """ raise NotImplementedError def load_worksheet(self, username, id_number): """ Return worksheet with given id_number belonging to the given user. If the worksheet does not exist, return ValueError. INPUT: - ``username`` -- string - ``id_number`` -- integer OUTPUT: - a worksheet """ raise NotImplementedError def export_worksheet(self, username, id_number, filename, title): """ Export the worksheet with given username and id_number to the given filename (e.g., 'worksheet.sws'). INPUT: - ``title`` - title to use for the exported worksheet (if None, just use current title) """ raise NotImplementedError def import_worksheet(self, username, id_number, filename): """ Input the worksheet username/id_number from the file with given filename. """ raise NotImplementedError def worksheets(self, username): """ Return list of all the worksheets belonging to the user with given name. If the given user does not exists, an empty list is returned. EXAMPLES: The load_user_data function must be defined in the derived class:: sage: from sagenb.storage.abstract_storage import Datastore sage: Datastore().worksheets('foobar') Traceback (most recent call last): ... NotImplementedError """ raise NotImplementedError def delete(self): """ Delete all files associated with this datastore. Dangerous! This is only here because it is useful for doctesting. """ raise NotImplementedError sagenb-1.0.1/sagenb/storage/filesystem_storage.py000066400000000000000000000647251311436262400221550ustar00rootroot00000000000000# -*- coding: utf-8 -* """ A Filesystem-based Sage Notebook Datastore Here is the filesystem layout for this datastore. Note that the all of the pickles are pickles of basic Python objects, so can be unpickled in any version of Python with or without Sage or the Sage notebook installed. They are also not compressed, so are reasonably easy to read ASCII. The filesystem layout is as follows. It mirrors the URL's used by the Sage notebook server:: sage_notebook.sagenb conf.pickle users.pickle openid.pickle (optional) readonly.txt (optional) home/ username0/ history.pickle id_number0/ worksheet.html worksheet_conf.pickle cells/ data/ snapshots/ id_number1/ worksheet.html worksheet_conf.pickle cells/ data/ snapshots/ ... username1/ ... """ import copy import shutil import tarfile import tempfile import os try: import cPickle as pickle except ImportError: import pickle from six import iteritems from .abstract_storage import Datastore from sagenb.misc.misc import set_restrictive_permissions, encoded_str from sage.misc.temporary_file import atomic_write def is_safe(a): """ Used when importing contents of various directories from Sage worksheet files. We define this function to avoid the possibility of a user crafting fake sws file such that extracting it creates files outside where we want, e.g., by including .. or / in the path of some file. """ # NOTE: Windows port -- I'm worried about whether a.name will have # / or \ on windows. The code below assume \. return '..' not in a and not a.startswith('/') class FilesystemDatastore(Datastore): def __init__(self, path): """ INPUT: - ``path`` -- string, path to this datastore EXAMPLES:: sage: from sagenb.storage import FilesystemDatastore sage: FilesystemDatastore(tmp_dir()) Filesystem Sage Notebook Datastore at ... """ path = os.path.abspath(path) self._path = path self._makepath(os.path.join(self._path, 'home')) self._home_path = 'home' self._conf_filename = 'conf.pickle' self._users_filename = 'users.pickle' self._readonly_filename = 'readonly.txt' self._readonly_mtime = 0 self._readonly = None def __repr__(self): return "Filesystem Sage Notebook Datastore at %s"%self._path ######################################################################### # Paths ######################################################################### def _makepath(self, path): p = self._abspath(path) try: os.makedirs(p) except OSError: if not os.path.isdir(p): raise return path def _deep_user_path(self, username): from hashlib import md5 h = md5(username).hexdigest() base = ['__store__', h[:1], h[:2], h[:3], h[:4]] path = os.path.join(*base) self._makepath(self._abspath(os.path.join(self._home_path, path))) return os.path.join(path, username) def _user_path(self, username): # There are weird cases, e.g., old notebook server migration # where username is None, and if we don't string it here, # saving can be broken (at a bad moment!). # There are also some cases where the username could have unicode in it. username = str(username) home = self._abspath(self._home_path) path = os.path.join(home, username) if not os.path.islink(path): self._makepath(home) old_dir = os.getcwd() os.chdir(home) new_path = self._deep_user_path(username) # Ensure that new_path exists: if os.path.exists(path): # If the old path exists, move it to the new path. # If both the old and new path exist, that's an error # and this will raise an exception. os.rename(path, new_path) else: # Otherwise, simply create the new path. self._makepath(os.path.join(home, new_path)) # new_path now points to the actual directory os.symlink(new_path, username) os.chdir(old_dir) return path def _worksheet_pathname(self, username, id_number): return os.path.join(self._user_path(username), str(id_number)) def _worksheet_path(self, username, id_number=None): if id_number is None: return self._makepath(self._user_path(username)) return self._makepath(self._worksheet_pathname(username, id_number)) def _worksheet_conf_filename(self, username, id_number): return os.path.join(self._worksheet_path(username, id_number), 'worksheet_conf.pickle') def _worksheet_html_filename(self, username, id_number): return os.path.join(self._worksheet_path(username, id_number), 'worksheet.html') def _history_filename(self, username): return os.path.join(self._user_path(username), 'history.pickle') def _abspath(self, file): """ Return absolute path to filename got by joining self._path with the string file. OUTPUT: -- ``string`` EXAMPLES:: sage: from sagenb.storage import FilesystemDatastore sage: FilesystemDatastore(tmp_dir())._abspath('foo.pickle') '...foo.pickle' """ return os.path.join(self._path, file) ######################################################################### # Loading and saving basic Python objects to disk. # The input filename is always relative to self._path. ######################################################################### def _load(self, filename): with open(self._abspath(filename)) as f: result = pickle.load(f) return result def _save(self, obj, filename): """ TESTS: Check that interrupting ``_save`` is safe:: sage: from sagenb.storage.filesystem_storage import FilesystemDatastore sage: D = FilesystemDatastore(tmp_dir()) sage: fn = tmp_filename() sage: s = "X" * 100000 sage: D._save(s, fn) sage: try: # long time ....: alarm(1) ....: while True: ....: D._save(s, fn) ....: except (AlarmInterrupt, OSError, AttributeError): ....: # OSError could happen due to a double close() in ....: # Python's tempfile module. ....: # AttributeError could happen due to interrupting ....: # in _TemporaryFileWrapper.__init__ ....: # (see https://trac.sagemath.org/ticket/22423) ....: pass sage: len(D._load(fn)) 100000 """ s = pickle.dumps(obj) if len(s) == 0: raise ValueError("Invalid Pickle") with atomic_write(self._abspath(filename)) as f: f.write(s) def _permissions(self, filename): f = self._abspath(filename) if os.path.exists(f): set_restrictive_permissions(f, allow_execute=False) ######################################################################### # Conversions to and from basic Python database (so that json # storage will work). ######################################################################### def _basic_to_users(self, obj): from sagenb.notebook.user import User_from_basic return dict([(name, User_from_basic(basic)) for name, basic in obj]) def _users_to_basic(self, users): new = sorted([[name, U.basic()] for name, U in iteritems(users)]) return new def _basic_to_server_conf(self, obj): from sagenb.notebook.server_conf import ServerConfiguration_from_basic return ServerConfiguration_from_basic(obj) def _server_conf_to_basic(self, server): return server.basic() def _basic_to_worksheet(self, obj): """ Given a basic Python object obj, return corresponding worksheet. """ from sagenb.notebook.worksheet import Worksheet_from_basic path = self._abspath(self._worksheet_path(obj['owner'])) return Worksheet_from_basic(obj, path) def _worksheet_to_basic(self, worksheet): """ Given a worksheet, create a corresponding basic Python object that completely defines that worksheet. """ return worksheet.basic() ######################################################################### # Now we implement the API we're supposed to implement ######################################################################### def load_server_conf(self): return self._basic_to_server_conf(self._load('conf.pickle')) def save_server_conf(self, server_conf): """ INPUT: - ``server`` -- """ basic = self._server_conf_to_basic(server_conf) self._save(basic, 'conf.pickle') self._permissions('conf.pickle') def load_openid(self): """ Loads an open_id dict read from the disk. """ return self._load('openid.pickle') def save_openid(self, openid_dict): """ Saves an open_id dict to the disk. """ self._save(openid_dict, 'openid.pickle') self._permissions('openid.pickle') def load_users(self, user_manager): """ OUTPUT: - dictionary of user info EXAMPLES:: sage: from sagenb.notebook.user import User sage: from sagenb.notebook.user_manager import SimpleUserManager sage: U = SimpleUserManager() sage: users = {'admin':User('admin','abc','a@b.c','admin'), 'wstein':User('wstein','xyz','b@c.d','user')} sage: from sagenb.storage import FilesystemDatastore sage: ds = FilesystemDatastore(tmp_dir()) sage: ds.save_users(users) sage: 'users.pickle' in os.listdir(ds._path) True sage: users = ds.load_users(U) sage: U.users() {'admin': admin, 'wstein': wstein} """ for user in self._basic_to_users(self._load('users.pickle')).itervalues(): user_manager.add_user_object(user, force=True) user_manager.set_password(user.username(), user.password(), encrypt = False) return user_manager def save_users(self, users): """ INPUT: - ``users`` -- dictionary mapping user names to users EXAMPLES:: sage: from sagenb.notebook.user import User sage: from sagenb.notebook.user_manager import SimpleUserManager sage: U = SimpleUserManager() sage: users = {'admin':User('admin','abc','a@b.c','admin'), 'wstein':User('wstein','xyz','b@c.d','user')} sage: from sagenb.storage import FilesystemDatastore sage: ds = FilesystemDatastore(tmp_dir()) sage: ds.save_users(users) sage: 'users.pickle' in os.listdir(ds._path) True sage: users = ds.load_users(U) sage: U.users() {'admin': admin, 'wstein': wstein} """ self._save(self._users_to_basic(users), 'users.pickle') self._permissions('users.pickle') def load_user_history(self, username): """ Return the history log for the given user. INPUT: - ``username`` -- string OUTPUT: - list of strings """ filename = self._history_filename(username) if not os.path.exists(self._abspath(filename)): return [] return self._load(filename) def save_user_history(self, username, history): """ Save the history log (a list of strings) for the given user. INPUT: - ``username`` -- string - ``history`` -- list of strings """ filename = self._history_filename(username) self._save(history, filename) self._permissions(filename) def save_worksheet(self, worksheet, conf_only=False): """ INPUT: - ``worksheet`` -- a Sage worksheet - ``conf_only`` -- default: False; if True, only save the config file, not the actual body of the worksheet EXAMPLES:: sage: from sagenb.notebook.worksheet import Worksheet sage: tmp = tmp_dir() sage: W = Worksheet('test', 2, tmp, system='gap', owner='sageuser') sage: from sagenb.storage import FilesystemDatastore sage: DS = FilesystemDatastore(tmp) sage: DS.save_worksheet(W) """ username = worksheet.owner(); id_number = worksheet.id_number() basic = self._worksheet_to_basic(worksheet) if not hasattr(worksheet, '_last_basic') or worksheet._last_basic != basic: # only save if changed self._save(basic, self._worksheet_conf_filename(username, id_number)) worksheet._last_basic = basic if not conf_only and worksheet.body_is_loaded(): # only save if loaded # todo -- add check if changed filename = self._worksheet_html_filename(username, id_number) with atomic_write(self._abspath(filename)) as f: f.write(worksheet.body().encode('utf-8', 'ignore')) def create_worksheet(self, username, id_number): """ Create worksheet with given id_number belonging to the given user. If the worksheet already exists, return ValueError. INPUT: - ``username`` -- string - ``id_number`` -- integer OUTPUT: - a worksheet """ filename = self._worksheet_html_filename(username, id_number) html_file = self._abspath(filename) if os.path.exists(html_file): raise ValueError("Worksheet %s/%s already exists"%(username, id_number)) # We create the worksheet W = self._basic_to_worksheet({'owner':username, 'id_number':id_number}) W.clear() return W def load_worksheet(self, username, id_number): """ Return worksheet with given id_number belonging to the given user. If the worksheet does not exist, return ValueError. INPUT: - ``username`` -- string - ``id_number`` -- integer OUTPUT: - a worksheet """ # Prevent arbitrary directories from being created by # self.__worksheet_html_filename dirname = self._worksheet_pathname(username, id_number) if not os.path.exists(dirname): raise ValueError("Worksheet %s/%s does not exist"%(username, id_number)) filename = self._worksheet_html_filename(username, id_number) html_file = self._abspath(filename) if not os.path.exists(html_file): raise ValueError("Worksheet %s/%s does not exist"%(username, id_number)) try: basic = self._load(self._worksheet_conf_filename(username, id_number)) basic['owner'] = username basic['id_number'] = id_number W = self._basic_to_worksheet(basic) W._last_basic = basic # cache except Exception: #the worksheet conf loading didn't work, so we make up one import traceback print("Warning: problem loading config for %s/%s; using default config: %s" % (username, id_number, traceback.format_exc())) W = self._basic_to_worksheet({'owner':username, 'id_number': id_number}) if username=='_sage_': # save the default configuration, since this may be loaded by a random other user # since *anyone* looking at docs will load all _sage_ worksheets print("Saving default configuration (overwriting corrupt configuration) for %s/%s" % (username, id_number)) self.save_worksheet(W, conf_only=True) return W def export_worksheet(self, username, id_number, filename, title): """ Export the worksheet with given username and id_number to the given filename (e.g., 'worksheet.sws'). INPUT: - ``title`` - title to use for the exported worksheet (if None, just use current title) """ T = tarfile.open(filename, 'w:bz2') worksheet = self.load_worksheet(username, id_number) basic = copy.deepcopy(self._worksheet_to_basic(worksheet)) if title: # change the title basic['name'] = title basic['name'] = encoded_str(basic['name']) # Remove metainformation that perhaps shouldn't be distributed for k in ['owner', 'ratings', 'worksheet_that_was_published', 'viewers', 'tags', 'published_id_number', 'collaborators', 'auto_publish']: if k in basic: del basic[k] self._save(basic, self._worksheet_conf_filename(username, id_number) + '2') tmp = self._abspath(self._worksheet_conf_filename(username, id_number) + '2') T.add(tmp, os.path.join('sage_worksheet','worksheet_conf.pickle')) os.unlink(tmp) worksheet_html = self._abspath(self._worksheet_html_filename(username, id_number)) T.add(worksheet_html, os.path.join('sage_worksheet','worksheet.html')) # The following is purely for backwards compatibility with old # notebook servers prior to sage-4.1.2. fd, worksheet_txt = tempfile.mkstemp() old_heading = "%s\nsystem:%s\n"%(basic['name'], basic['system']) with open(worksheet_txt,'w') as f: with open(worksheet_html) as g: f.write(old_heading + g.read()) T.add(worksheet_txt, os.path.join('sage_worksheet','worksheet.txt')) os.unlink(worksheet_txt) # important, so we don't leave an open file handle! os.close(fd) # end backwards compat block. # Add the contents of the DATA directory path = self._abspath(self._worksheet_pathname(username, id_number)) data = os.path.join(path, 'data') if os.path.exists(data): for X in os.listdir(data): T.add(os.path.join(data, X), os.path.join('sage_worksheet','data',X)) # Add the contents of each of the cell directories. cells = os.path.join(path, 'cells') if os.path.exists(cells): for X in os.listdir(cells): T.add(os.path.join(cells, X), os.path.join('sage_worksheet','cells',X)) # NOTE: We do not export the snapshot/undo data. People # frequently *complain* about Sage exporting a record of their # mistakes anyways. T.close() def _import_old_worksheet(self, username, id_number, filename): """ Import a worksheet from an old version of Sage. """ T = tarfile.open(filename, 'r:bz2') members = [a for a in T.getmembers() if 'worksheet.txt' in a.name and is_safe(a.name)] if len(members) == 0: raise RuntimeError("unable to import worksheet") worksheet_txt = members[0].name W = self.load_worksheet(username, id_number) W.edit_save_old_format(T.extractfile(worksheet_txt).read().decode('utf-8', 'ignore')) # '/' is right, since old worksheets always unix dir = worksheet_txt.split('/')[0] path = self._abspath(self._worksheet_pathname(username, id_number)) base = os.path.join(dir,'data') members = [a for a in T.getmembers() if a.name.startswith(base) and is_safe(a.name)] if len(members) > 0: T.extractall(path, members) dest = os.path.join(path, 'data') if os.path.exists(dest): shutil.rmtree(dest) shutil.move(os.path.join(path,base), path) base = os.path.join(dir,'cells') members = [a for a in T.getmembers() if a.name.startswith(base) and is_safe(a.name)] if len(members) > 0: T.extractall(path, members) dest = os.path.join(path, 'cells') if os.path.exists(dest): shutil.rmtree(dest) shutil.move(os.path.join(path, base), path) tmp = os.path.join(path, dir) if os.path.exists(tmp): shutil.rmtree(tmp) T.close() return W def import_worksheet(self, username, id_number, filename): """ Import the worksheet username/id_number from the file with given filename. """ path = self._abspath(self._worksheet_pathname(username, id_number)) if os.path.exists(path): shutil.rmtree(path, ignore_errors=True) os.makedirs(path) T = tarfile.open(filename, 'r:bz2') try: with open(self._abspath(self._worksheet_conf_filename(username, id_number)),'w') as f: f.write(T.extractfile(os.path.join('sage_worksheet','worksheet_conf.pickle')).read()) except KeyError: # Not a valid worksheet. This might mean it is an old # worksheet from a previous version of Sage. return self._import_old_worksheet(username, id_number, filename) with open(self._abspath(self._worksheet_html_filename(username, id_number)),'w') as f: f.write(T.extractfile(os.path.join('sage_worksheet','worksheet.html')).read()) base = os.path.join('sage_worksheet','data') members = [a for a in T.getmembers() if a.name.startswith(base) and is_safe(a.name)] if len(members) > 0: T.extractall(path, members) shutil.move(os.path.join(path,base), path) base = os.path.join('sage_worksheet','cells') members = [a for a in T.getmembers() if a.name.startswith(base) and is_safe(a.name)] if len(members) > 0: T.extractall(path, members) shutil.move(os.path.join(path, base), path) tmp = os.path.join(path, 'sage_worksheet') if os.path.exists(tmp): shutil.rmtree(tmp) T.close() return self.load_worksheet(username, id_number) def worksheets(self, username): """ Return list of all the worksheets belonging to the user with given name. If the given user does not exists, an empty list is returned. EXAMPLES: The load_user_data function must be defined in the derived class:: sage: from sagenb.storage import FilesystemDatastore sage: tmp = tmp_dir() sage: FilesystemDatastore(tmp).worksheets('foobar') [] sage: from sagenb.notebook.worksheet import Worksheet sage: W = Worksheet('test', 2, tmp, system='gap', owner='sageuser') sage: from sagenb.storage import FilesystemDatastore sage: DS = FilesystemDatastore(tmp) sage: DS.save_worksheet(W) sage: DS.worksheets('sageuser') [sageuser/2: [Cell 0: in=, out=]] """ path = self._abspath(self._user_path(username)) if not os.path.exists(path): return [] v = [] for id_number in os.listdir(path): if id_number.isdigit(): try: v.append(self.load_worksheet(username, int(id_number))) except Exception: import traceback print("Warning: problem loading %s/%s: %s" % (username, id_number, traceback.format_exc())) return v def readonly_user(self, username): """ Each line of the readonly file has a username. """ filename = os.path.join(self._path, self._readonly_filename) if not os.path.exists(filename): return False mtime = os.path.getmtime(filename) if mtime > self._readonly_mtime: with open(filename) as f: self._readonly = set(line for line in (l.strip() for l in f) if len(line)>0) self._readonly_mtime = mtime return username in self._readonly def delete(self): """ Delete all files associated with this datastore. Dangerous! This is only here because it is useful for doctesting. """ shutil.rmtree(self._path, ignore_errors=True) ############################################################################## # # Why not use JSON, YAML, or XML?? # # I experimented with using these, but they are 10-100 times slower, # and there is no real benefit. More precisely, the time for # dumping/loading a worksheet basic datastructure in each of the # following is given below. XML is also very bad compared to cPickle. # # cPickle, # pickle # json # yaml # yaml + C # # This is all on OS X 10.6 64-bit. Here b = w.basic() for any worksheet w. # # sage: import cPickle # sage: timeit('cPickle.loads(cPickle.dumps(b))') # 625 loops, best of 3: 51.9 us (microseconds) per loop # sage: import pickle # sage: timeit('pickle.loads(pickle.dumps(b))') # 625 loops, best of 3: 464 us (microseconds) per loop # sage: import json # sage: timeit('json.loads(json.dumps(b))') # 625 loops, best of 3: 449 us (microseconds) per loop # sage: timeit('json.loads(json.dumps(b,indent=4))') # 625 loops, best of 3: 625 us (microseconds) per loop # sage: import yaml # sage: timeit('yaml.load(yaml.dump(b))') # 25 loops, best of 3: 13.5 ms per loop # sage: from yaml import load, dump # sage: from yaml import CLoader as Loader # sage: from yaml import CDumper as Dumper # sage: timeit('yaml.load(yaml.dump(b,Dumper=Dumper),Loader=Loader)') # c++ yaml # 125 loops, best of 3: 1.77 ms per loop # # Other problems: json.load(json.dump(b)) != b, because of unicode and # all kinds of weirdness # Yaml C library is hard to install; and yaml itself is not included in python (json is). # Anyway, the difference between 2-13ms and 52 microseconds is significant. # At 2ms, 100,000 worksheets takes 200 seconds, versus only 5 seconds # at 52 microseconds. cPickle just can't be beat. # # NOTE! Actually simplejson does just as well at cPickle for this benchmark. # Thanks to Mitesh Patel for pointing this out. # ############################################################################# sagenb-1.0.1/sagenb/testing/000077500000000000000000000000001311436262400156665ustar00rootroot00000000000000sagenb-1.0.1/sagenb/testing/HTMLTestRunner.py000066400000000000000000000426411311436262400210450ustar00rootroot00000000000000# -*- coding: utf-8 -* """ HTML Test Runner This is a test runner for use with Python's `unit testing framework`_. A replacement for the standard :class:`unittest.TextTestRunner`, it generates a HTML report of the test results. .. _unit testing framework: http://docs.python.org/library/unittest.html The simplest way to use :module:`HTMLTestRunner` is to invoke its main method: import unittest import HTMLTestRunner ... define your tests ... if __name__ == '__main__': HTMLTestRunner.main() For more customization options, instantiate a :class:`HTMLTestRunner` object: # output to a file fp = file('my_report.html', 'wb') runner = HTMLTestRunner.HTMLTestRunner( stream=fp, title='My unit test', description='Unit test report by HTMLTestRunner.' ) # run the test runner.run(my_test_suite) AUTHORS: - The original version is Wai Yip Tung's HTMLTestRunner_, which is available under a modified BSD license. .. _HTMLTestRunner: http://tungwaiyip.info/software/HTMLTestRunner.html """ from __future__ import print_function # must be here ! # The original license. """ ------------------------------------------------------------------------ Copyright (c) 2004-2006, Wai Yip Tung All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name Wai Yip Tung nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. """ # TODO and CHANGES. """ TODO * Add timings. * Support multiple results tables (e.g., for doctests). * Use a backend server to select, run, and monitor live tests. CHANGES #7390 (added to sagenb 0.4): * Use Jinja2. * Use jQuery. * Added hide, show, toggle options. * Output and tracebacks are inline. * Use Pygments to highlight tracebacks. 0.8.1: * Thank you for Wolfgang Borgert's patch. * Validated XHTML. * Added description of test classes and test cases. 0.8.0: * Define Template_mixin class for customization. * Workaround a IE 6 bug that it does not treat ' return template(os.path.join('html', 'test_report.html'), **template_dict) def report_for_one_test(self, rows, case_id, test_num, status, test_case, output, trace): """ Generate the HTML for one test's results. """ # Test description. name = test_case.id().split('.')[-1] test_id = name + '_%d' % test_num doc = test_case.shortDescription() or '' desc = jinja2.escape(doc and ('%s: %s' % (name, doc)) or name) # Include output, syntax-highlight tracebacks. out_trace = '' for x in [output, trace]: if isinstance(x, str): x = unicode(x.encode('string_escape')) # x = x.decode('latin-1') trace = highlight(trace, self.trace_lexer, self.formatter) out_trace = jinja2.escape(output) + jinja2.Markup(trace) test_class = '' if status == _TestResult.PASS: status = 'pass' test_class += 'hidden ' elif status == _TestResult.FAIL: status = 'fail' else: status = 'error' test_class += 'test_' + status rows.append(REPORT_TEST_TMPL.render(locals())) ############################################################################## # Facilities for running tests from the command line ############################################################################## # Note: Reuse unittest.TestProgram to launch test. In the future we # may build our own launcher to support more specific command line # parameters like test title, CSS, etc. class TestProgram(unittest.TestProgram): """ A variation of the unittest.TestProgram. Please refer to the base class for command line parameters. """ def runTests(self): # Pick HTMLTestRunner as the default test runner. The base # class's testRunner parameter is not useful, because it means # we have to instantiate HTMLTestRunner before we know # self.verbosity. if self.testRunner is None: self.testRunner = HTMLTestRunner(verbosity=self.verbosity) unittest.TestProgram.runTests(self) main = TestProgram ############################################################################## # Executing this module from the command line ############################################################################## if __name__ == "__main__": main(module=None) sagenb-1.0.1/sagenb/testing/__init__.py000066400000000000000000000001051311436262400177730ustar00rootroot00000000000000# -*- coding: utf-8 -* # Code for stress testing of notebook servers sagenb-1.0.1/sagenb/testing/grinder/000077500000000000000000000000001311436262400173205ustar00rootroot00000000000000sagenb-1.0.1/sagenb/testing/grinder/grinder.properties000066400000000000000000000150171311436262400230740ustar00rootroot00000000000000# # Sample grinder.properties # # # The properties can be specified in three ways. # - In the console. A properties file in the distribution directory # can be selected in the console. # - As a Java system property in the command line used to start the # agent. (e.g. java -Dgrinder.threads=20 net.grinder.Grinder). # - In an agent properties file. A local properties file named # "grinder.properties" can be placed in the working directory of # each agent, or a different file name passed as an agent command # line argument. # # Properties present in a console selected file take precedence over # agent command line properties, which in turn override those in # an agent properties file. # # Any line which starts with a ; (semi-colon) or a # (hash) is a # comment and is ignored. In this example we will use a # for # commentary and a ; for parts of the config file that you may wish to # enable # # Please refer to # http://net.grinder.sourceforge.net/g3/properties.html for further # documentation. # # Commonly used properties # # The file name of the script to run. # # Relative paths are evaluated from the directory containing the # properties file. The default is "grinder.py". grinder.script = logineval.py # The number of worker processes each agent should start. The default # is 1. grinder.processes = 1 # The number of worker threads each worker process should start. The # default is 1. grinder.threads = 10 # The number of runs each worker process will perform. When using the # console this is usually set to 0, meaning "run until the console # sneds a stop or reset signal". The default is 1. grinder.runs = 0 # The IP address or host name that the agent and worker processes use # to contact the console. The default is all the network interfaces # of the local machine. ; grinder.consoleHost = consolehost # The IP port that the agent and worker processes use to contact the # console. Defaults to 6372. ; grinder.consolePort # # Less frequently used properties # ### Logging ### # The directory in which worker process logs should be created. If not # specified, the agent's working directory is used. grinder.logDirectory = log # The number of archived logs from previous runs that should be kept. # The default is 1. grinder.numberOfOldLogs = 2 # Overrides the "host" string used in log filenames and logs. The # default is the host name of the machine running the agent. ; grinder.hostID = myagent # Set to false to disable the logging of output and error steams for # worker processes. You might want to use this to reduce the overhead # of running a client thread. The default is true. grinder.logProcessStreams = false ### Script sleep time #### # The maximum time in milliseconds that each thread waits before # starting. Unlike the sleep times specified in scripts, this is # varied according to a flat random distribution. The actual sleep # time will be a random value between 0 and the specified value. # Affected by grinder.sleepTimeFactor, but not # grinder.sleepTimeVariation. The default is 0ms. ; grinder.initialSleepTime=500 # Apply a factor to all the sleep times you've specified, either # through a property of in a script. Setting this to 0.1 would run the # script ten times as fast. The default is 1. ; grinder.sleepTimeFactor=0.01 # The Grinder varies the sleep times specified in scripts according to # a Normal distribution. This property specifies a fractional range # within which nearly all (99.75%) of the times will lie. E.g., if the # sleep time is specified as 1000 and the sleepTimeVariation is set to # 0.1, then 99.75% of the actual sleep times will be between 900 and # 1100 milliseconds. The default is 0.2. ; grinder.sleepTimeVariation=0.005 ### Worker process control ### # If set, the agent will ramp up the number of worker processes, # starting the number specified every # grinder.processesIncrementInterval milliseconds. The upper limit is # set by grinder.processes. The default is to start all worker # processes together. ; grinder.processIncrement = 1 # Used in conjunction with grinder.processIncrement, this property # sets the interval in milliseconds at which the agent starts new # worker processes. The value is in milliseconds. The default is 60000 # ms. ; grinder.processIncrementInterval = 10000 # Used in conjunction with grinder.processIncrement, this property # sets the initial number of worker processes to start. The default is # the value of grinder.processIncrement. ; process.initialProcesses = 1 # The maximum length of time in milliseconds that each worker process # should run for. grinder.duration can be specified in conjunction # with grinder.runs, in which case the worker processes will terminate # if either the duration time or the number of runs is exceeded. The # default is to run forever. ; grinder.duration = 60000 # If set to true, the agent process spawns engines in threads rather # than processes, using special class loaders to isolate the engines. # This allows the engine to be easily run in a debugger. This is # primarily a tool for debugging The Grinder engine, but it might also # be useful to advanced users. The default is false. ; grinder.debug.singleprocess = true # If set to true, the new DCR instrumentation engine will be used. The # new engine will always be used if Jython 2.1/2.2 is not found. ; grinder.dcrinstrumentation = false ### Java ### # Use an alternate JVM for worker processes. The default is "java" so # you do not need to specify this if java is in your PATH. ; grinder.jvm = /opt/jrockit/jrockit-R27.5.0-jdk1.5.0_14/bin/java # Use to adjust the classpath used for the worker process JVMs. # Anything specified here will be prepended to the classpath used to # start the Grinder processes. ; grinder.jvm.classpath = /tmp/myjar.jar # Additional arguments to worker process JVMs. grinder.jvm.arguments = -Dpython.home=/usr/share/jython ### Console communications ### # (See above for console address properties). # If you are not using the console, and don't want the agent to try to # contact it, set grinder.useConsole = false. The default is true. ; grinder.useConsole = false # The period at which each process sends updates to the console. This # also controls the frequency at which the data files are flushed. # The default is 500 ms. ; grinder.reportToConsole.interval = 100 ### Statistics ### # Set to false to disable reporting of timing information to the # console; other statistics are still reported. See # http://grinder.sourceforge.net/faq.html#timing for why you might # want to do this. The default is true. ; grinder.reportTimesToConsole = false sagenb-1.0.1/sagenb/testing/grinder/logineval.py000066400000000000000000000053761311436262400216650ustar00rootroot00000000000000from net.grinder.script.Grinder import grinder from net.grinder.script import Test from net.grinder.plugin.http import HTTPRequest from HTTPClient import NVPair from java.util import Random protectedResourceTest = Test(1, "Request home") authenticationTest = Test(2, "POST to login") newCellTest = Test(3, "Make a new Cell") evaluationTest = Test(4, "Evaluate 2 + 2") updateTest = Test(5, "Get 4") deleteCellTest = Test(6, "Delete Cell") user = 'radotest' password = 'test' class TestRunner: def __call__(self): worksheet = '1' request = protectedResourceTest.wrap( HTTPRequest(url="http://localhost:8080/")) result = request.GET() result = maybeAuthenticate(result) result = request.GET('/home/%s/%s/' % (user, worksheet)) base_url = 'http://localhost:8080/home/%s/%s' % (user, worksheet) request = newCellTest.wrap(HTTPRequest(url=base_url + "/new_cell_after")) result = request.POST((NVPair("id","0"),)) new_cell = result.text.split()[0].rstrip('___S_A_G_E___') request = evaluationTest.wrap(HTTPRequest(url=base_url + "/eval")) random = Random() a, b = random.nextInt(10**1), random.nextInt(10**1) evalData = ( NVPair("id", new_cell), NVPair("input", "%s * %s"% (a,b)), NVPair("newcell", "0"),) result = request.POST(evalData) count = 0 while (True): #grinder.sleep(5000) request = updateTest.wrap(HTTPRequest(url=base_url + "/cell_update")) getData = ( NVPair("id", new_cell),) result = request.POST(getData) count += 1 if result.text.find('pre') != -1: txt = 'wait {} test {} * {} = {}' print(txt.format(count, a, b, strip_answer(result.text))) break request = deleteCellTest.wrap(HTTPRequest(url=base_url + "/delete_cell")) getData = ( NVPair("id", new_cell),) result = request.POST(getData) # Function that checks the passed HTTPResult to see whether # authentication is necessary. If it is, perform the authentication # and record performance information against Test 2. def maybeAuthenticate(lastResult): if lastResult.statusCode == 401 \ or lastResult.text.find("password") != -1: authenticationFormData = ( NVPair("email", user), NVPair("password", password),) request = authenticationTest.wrap( HTTPRequest(url="%s/login" % lastResult.originalURI)) return request.POST(authenticationFormData) def strip_answer(text): #
    532962756677
    st = text.find('') return text[st + 20 : end] sagenb-1.0.1/sagenb/testing/grinder/make_users.sh000077500000000000000000000001151311436262400220120ustar00rootroot00000000000000for i in {1..$1} do curl -d username=test$i localhost:8080/adduser done sagenb-1.0.1/sagenb/testing/grinder/make_worksheets.sh000077500000000000000000000001001311436262400230410ustar00rootroot00000000000000for i in {1..$1} do curl localhost:8080/new_worksheet done sagenb-1.0.1/sagenb/testing/grinder/nodoctest.py000066400000000000000000000006601311436262400216760ustar00rootroot00000000000000""" This directory contains files related to using Grinder (http://grinder.sourceforge.net/) to do testing of the Sage notebook server. The imports necessary to even load these files do not work without a Grinder instance running, and there is also some hard-coding that you would need to fix to use it, so we do not run tests. However, the Grinder objects could be useful to someone seeking an alternative to Selenium testing. """ sagenb-1.0.1/sagenb/testing/grinder/pub.py000066400000000000000000000121401311436262400204560ustar00rootroot00000000000000# The Grinder 3.6 # HTTP script recorded by TCPProxy at Nov 8, 2011 8:34:41 AM from net.grinder.script import Test from net.grinder.script.Grinder import grinder from net.grinder.plugin.http import HTTPPluginControl, HTTPRequest from HTTPClient import NVPair connectionDefaults = HTTPPluginControl.getConnectionDefaults() httpUtilities = HTTPPluginControl.getHTTPUtilities() # To use a proxy server, uncomment the next line and set the host and port. # connectionDefaults.setProxyServer("localhost", 8001) # These definitions at the top level of the file are evaluated once, # when the worker process is started. connectionDefaults.defaultHeaders = \ [ NVPair('Accept-Language', 'en-us,en;q=0.5'), NVPair('Accept-Charset', 'ISO-8859-1,utf-8;q=0.7,*;q=0.7'), NVPair('Accept-Encoding', 'gzip, deflate'), NVPair('User-Agent', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.6; rv:7.0.1) Gecko/20100101 Firefox/7.0.1'), ] headers0= \ [ NVPair('Accept', 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8'), ] headers1= \ [ NVPair('Accept', 'text/css,*/*;q=0.1'), NVPair('Referer', 'http://test.sagenb.org/pub/'), ] headers2= \ [ NVPair('Accept', '*/*'), NVPair('Referer', 'http://test.sagenb.org/pub/'), ] headers3= \ [ NVPair('Accept', 'image/png,image/*;q=0.8,*/*;q=0.5'), NVPair('Referer', 'http://test.sagenb.org/pub/'), ] url0 = 'http://test.sagenb.org:80' url1 = 'http://www.google-analytics.com:80' # Create an HTTPRequest for each request, then replace the # reference to the HTTPRequest with an instrumented version. # You can access the unadorned instance using request101.__target__. request101 = HTTPRequest(url=url0, headers=headers0) request101 = Test(101, 'GET /').wrap(request101) request102 = HTTPRequest(url=url0, headers=headers1) request102 = Test(102, 'GET main.css').wrap(request102) request103 = HTTPRequest(url=url0, headers=headers2) request103 = Test(103, 'GET localization.js').wrap(request103) request201 = HTTPRequest(url=url1, headers=headers3) request201 = Test(201, 'GET __utm.gif').wrap(request201) class TestRunner: """A TestRunner instance is created for each worker thread.""" # A method for each recorded page. def page1(self): """GET / (requests 101-103).""" result = request101.GET('/pub/') # 3 different values for token_sort found in response, using the first one. self.token_sort = \ httpUtilities.valueFromBodyURI('sort') # 'rating' # 2 different values for token_typ found in response, using the first one. self.token_typ = \ httpUtilities.valueFromBodyURI('typ') # 'active' self.token_reverse = \ httpUtilities.valueFromBodyURI('reverse') # 'True' grinder.sleep(218) request102.GET('/css/main.css') request103.GET('/javascript/dynamic/localization.js') return result def page2(self): """GET __utm.gif (request 201).""" self.token_utmwv = \ '5.2.0' self.token_utms = \ '4' self.token_utmn = \ '1624681580' self.token_utmhn = \ 'test.sagenb.org' self.token_utmcs = \ 'UTF-8' self.token_utmsr = \ '1680x1050' self.token_utmsc = \ '24-bit' self.token_utmul = \ 'en-us' self.token_utmje = \ '1' self.token_utmfl = \ '10.2 r153' self.token_utmdt = \ 'Published Worksheets -- Sage' self.token_utmhid = \ '25603674' self.token_utmr = \ '-' self.token_utmp = \ '/pub/' self.token_utmac = \ 'UA-24214040-1' self.token_utmcc = \ '__utma=199536369.2072460302.1309502470.1320725328.1320762863.9;+__utmz=199536369.1309502470.1.1.utmcsr=(direct)|utmccn=(direct)|utmcmd=(none);' self.token_utmu = \ 'qB~' result = request201.GET('/__utm.gif' + '?utmwv=' + self.token_utmwv + '&utms=' + self.token_utms + '&utmn=' + self.token_utmn + '&utmhn=' + self.token_utmhn + '&utmcs=' + self.token_utmcs + '&utmsr=' + self.token_utmsr + '&utmsc=' + self.token_utmsc + '&utmul=' + self.token_utmul + '&utmje=' + self.token_utmje + '&utmfl=' + self.token_utmfl + '&utmdt=' + self.token_utmdt + '&utmhid=' + self.token_utmhid + '&utmr=' + self.token_utmr + '&utmp=' + self.token_utmp + '&utmac=' + self.token_utmac + '&utmcc=' + self.token_utmcc + '&utmu=' + self.token_utmu) return result def __call__(self): """This method is called for every run performed by the worker thread.""" self.page1() # GET / (requests 101-103) grinder.sleep(1230) self.page2() # GET __utm.gif (request 201) def instrumentMethod(test, method_name, c=TestRunner): """Instrument a method with the given Test.""" unadorned = getattr(c, method_name) import new method = new.instancemethod(test.wrap(unadorned), None, c) setattr(c, method_name, method) # Replace each method with an instrumented version. # You can call the unadorned method using self.page1.__target__(). instrumentMethod(Test(100, 'Page 1'), 'page1') instrumentMethod(Test(200, 'Page 2'), 'page2') sagenb-1.0.1/sagenb/testing/grinder/setGrinderEnv.sh000077500000000000000000000002521311436262400224350ustar00rootroot00000000000000#!/bin/bash GRINDERPATH=/Users/rado/grinder-3.4 GRINDERPROPERTIES=grinder.properties CLASSPATH=$GRINDERPATH/lib/grinder.jar:$CLASSPATH export CLASSPATH GRINDERPROPERTIES sagenb-1.0.1/sagenb/testing/grinder/simpleeval.py000066400000000000000000000035021311436262400220330ustar00rootroot00000000000000from __future__ import print_function from net.grinder.script.Grinder import grinder from net.grinder.script import Test from net.grinder.plugin.http import HTTPRequest from HTTPClient import NVPair from java.util import Random newCellTest = Test(1, "Make a new Cell") evaluationTest = Test(2, "Evaluate") updateTest = Test(3, "Poll until evaluated") deleteCellTest = Test(4, "Delete Cell") class TestRunner: def __call__(self): sheets = 10 random = Random() worksheet = str(40 + random.nextInt(sheets)) base_url = 'http://localhost:8080/home/admin/%s' % worksheet request = newCellTest.wrap(HTTPRequest(url=base_url + "/new_cell_after")) result = request.POST((NVPair("id","0"),)) new_cell = result.text.split()[0].rstrip('___S_A_G_E___') request = evaluationTest.wrap(HTTPRequest(url=base_url + "/eval")) a, b = random.nextInt(10**1), random.nextInt(10**1) evalData = ( NVPair("id", new_cell), NVPair("input", "%s * %s"% (a,b)), NVPair("newcell", "0"),) result = request.POST(evalData) count = 0 while (True): request = updateTest.wrap(HTTPRequest(url=base_url + "/cell_update")) getData = ( NVPair("id", new_cell),) result = request.POST(getData) count += 1 if result.text.find('pre') != -1: print('wait', count, 'test', a, '*', b, '=', strip_answer(result.text)) break request = deleteCellTest.wrap(HTTPRequest(url=base_url + "/delete_cell")) getData = ( NVPair("id", new_cell),) result = request.POST(getData) def strip_answer(text): #
    532962756677
    st = text.find('') return text[st + 20 : end] sagenb-1.0.1/sagenb/testing/grinder/simpleeval_factor.py000066400000000000000000000034611311436262400233750ustar00rootroot00000000000000from net.grinder.script.Grinder import grinder from net.grinder.script import Test from net.grinder.plugin.http import HTTPRequest from HTTPClient import NVPair from java.util import Random newCellTest = Test(1, "Make a new Cell") evaluationTest = Test(2, "Evaluate") updateTest = Test(3, "Poll until evaluated") deleteCellTest = Test(4, "Delete Cell") class TestRunner: def __call__(self): sheets = 10 random = Random() worksheet = str(40 + random.nextInt(sheets)) base_url = 'http://localhost:8080/home/admin/%s' % worksheet request = newCellTest.wrap(HTTPRequest(url=base_url + "/new_cell_after")) result = request.POST((NVPair("id","0"),)) new_cell = result.text.split()[0].rstrip('___S_A_G_E___') request = evaluationTest.wrap(HTTPRequest(url=base_url + "/eval")) a = random.nextInt(2**30) b = random.nextInt(2**30) evalData = ( NVPair("id", new_cell), NVPair("input", "factor(%s%s)"% (a,b)), NVPair("newcell", "0"),) result = request.POST(evalData) count = 0 while (True): request = updateTest.wrap(HTTPRequest(url=base_url + "/cell_update")) getData = ( NVPair("id", new_cell),) result = request.POST(getData) count += 1 if result.text.find('pre') != -1: print('wait %s test factor %s%s = %s' % (count, a, b, strip_answer(result.text))) break request = deleteCellTest.wrap(HTTPRequest(url=base_url + "/delete_cell")) getData = ( NVPair("id", new_cell),) result = request.POST(getData) def strip_answer(text): #
    532962756677
    st = text.find('') return text[st + 20 : end] sagenb-1.0.1/sagenb/testing/grinder/simpleeval_multi.py000066400000000000000000000034401311436262400232460ustar00rootroot00000000000000from __future__ import print_function from net.grinder.script.Grinder import grinder from net.grinder.script import Test from net.grinder.plugin.http import HTTPRequest from HTTPClient import NVPair from java.util import Random newCellTest = Test(1, "Make a new Cell") evaluationTest = Test(2, "Evaluate") updateTest = Test(3, "Poll until evaluated") deleteCellTest = Test(4, "Delete Cell") class TestRunner: def __call__(self): random = Random() worksheet = random.nextInt(10) base_url = 'http://localhost:8080/home/admin/%s' % worksheet request = newCellTest.wrap(HTTPRequest(url=base_url + "/new_cell_after")) result = request.POST((NVPair("id","0"),)) new_cell = result.text.split()[0].rstrip('___S_A_G_E___') request = evaluationTest.wrap(HTTPRequest(url=base_url + "/eval")) a, b = random.nextInt(10**1), random.nextInt(10**1) evalData = ( NVPair("id", new_cell), NVPair("input", "%s * %s"% (a,b)), NVPair("newcell", "0"),) result = request.POST(evalData) count = 0 while (True): request = updateTest.wrap(HTTPRequest(url=base_url + "/cell_update")) getData = ( NVPair("id", new_cell),) result = request.POST(getData) count += 1 if result.text.find('pre') != -1: print('wait', count, 'test', a, '*', b, '=', strip_answer(result.text)) break request = deleteCellTest.wrap(HTTPRequest(url=base_url + "/delete_cell")) getData = ( NVPair("id", new_cell),) result = request.POST(getData) def strip_answer(text): #
    532962756677
    st = text.find('') return text[st + 20 : end] sagenb-1.0.1/sagenb/testing/grinder/simpleopen.py000066400000000000000000000007711311436262400220520ustar00rootroot00000000000000from net.grinder.script.Grinder import grinder from net.grinder.script import Test from net.grinder.plugin.http import HTTPRequest from HTTPClient import NVPair # We declare a default URL for the HTTPRequest. request = HTTPRequest(url = "http://localhost:8080") def page1(): request.GET('/') #request.GET('/console/login/LoginForm.jsp') #request.GET('/console/login/bea_logo.gif') page1Test = Test(1, "First page").wrap(page1) class TestRunner: def __call__(self): page1Test() sagenb-1.0.1/sagenb/testing/grinder/sstest.py000066400000000000000000000021541311436262400212210ustar00rootroot00000000000000from net.grinder.script.Grinder import grinder from net.grinder.script import Test from net.grinder.plugin.http import HTTPRequest from HTTPClient import NVPair from java.util import Random # We declare a default URL for the HTTPRequest. request = HTTPRequest(url = "http://www.google.com") #request = HTTPRequest(url = "http://aleph.sagemath.org") def evalss(): wait = 250 random = Random() a, b = (random.nextInt(), random.nextInt()) #input = '%s*%s' % (a, b) input = 'from+sage.all+import+*;factor(ZZ.random_element(10**40))' result = request.GET('/execute?input=%s' % input) id = result.text count = 0 while (True): grinder.sleep(wait) result = request.GET('/get?id=%s' % id) count += 1 if result.text.find('wait') == -1: break ans = eval(result.text) print('test waited%s ans = %s' % (count, ans['output'])) evalssTest = Test(1, "Exec testpage").wrap(evalss) def homess(): request.GET('/') homessTest = Test(2, "query homepage").wrap(homess) class TestRunner: def __call__(self): #evalssTest() homessTest() sagenb-1.0.1/sagenb/testing/grinder/startAgent.sh000077500000000000000000000001321311436262400217670ustar00rootroot00000000000000#!/bin/bash . setGrinderEnv.sh java -cp $CLASSPATH net.grinder.Grinder $GRINDERPROPERTIES sagenb-1.0.1/sagenb/testing/grinder/startConsole.sh000077500000000000000000000001071311436262400223350ustar00rootroot00000000000000#!/bin/bash . setGrinderEnv.sh java -cp $CLASSPATH net.grinder.Console sagenb-1.0.1/sagenb/testing/grinder/startProxy.sh000077500000000000000000000001441311436262400220550ustar00rootroot00000000000000#!/bin/bash . setGrinderEnv.sh java -cp $CLASSPATH net.grinder.TCPProxy -console -http > grinder.py sagenb-1.0.1/sagenb/testing/notebook_test_case.py000066400000000000000000000343161311436262400221210ustar00rootroot00000000000000# -*- coding: utf-8 -*- """ Notebook Test Case This contains the base class for all SageNB test cases. """ from __future__ import absolute_import import copy import os import pexpect import re import shutil import signal import subprocess import tempfile import time import unittest from .selenium.selenium import selenium # Default options. NB_OPTIONS = { 'address': 'localhost', # Should *not* be left empty. 'directory': '', # Set automatically if empty. Must end # in '.sagenb'. 'automatic_login': False, 'port': 8080, 'secure': False } SEL_OPTIONS = { 'server_host': 'localhost', 'server_port': 4444, 'environment': '*firefox3 /usr/bin/firefox', 'browser_url': '' # Set automatically if empty. } KEY_CODES = { 'tab': 9, 'enter': 10, 'shift': 16 } class NotebookTestCase(unittest.TestCase): """ Base class for SageNB test cases. Contains multiple utility functions, and sets up fixtures. """ tags = ('seleniumtest',) def cleanup(self): nb_dir = self.nb_options['directory'] if os.path.exists(nb_dir): twistd_pid_path = os.path.join(nb_dir, 'twistd.pid') if os.path.exists(twistd_pid_path): twistd_pid_fd = open(twistd_pid_path, 'r') twistd_pid = int(twistd_pid_fd.read()) try: os.kill(twistd_pid, signal.SIGTERM) os.kill(twistd_pid, signal.SIGKILL) except OSError: pass twistd_pid_fd.close() shutil.rmtree(nb_dir, ignore_errors=True) def setUp(self): """ Makes sure that the tests start from a fresh slate, and starts the server. """ self.nb_options = copy.deepcopy(NB_OPTIONS) self.nb_options['directory'] = (self.nb_options['directory'] or os.path.join(tempfile.gettempdir(), 'sagenb_tests.sagenb')) self.sel_options = copy.deepcopy(SEL_OPTIONS) self.cleanup() os.mkdir(self.nb_options['directory']) self.start_notebook(initial=True) self.selenium = selenium(self.sel_options['server_host'], self.sel_options['server_port'], self.sel_options['environment'], self.sel_options['browser_url']) self.selenium.start() self.selenium.open("/") def start_notebook(self, initial=False): """ Starts the Sage notebook. If initial is True, then it expects to have to enter the initial password twice. """ self._p = pexpect.spawn(self._sage_startup_command()) if initial: self._p.sendline("asdfasdf") self._p.sendline("asdfasdf") port_re = re.compile(r'http(?:s)?://' + self.nb_options['address'] + r':(\d+)') line = self._p.readline() while not port_re.search(line): line = self._p.readline() m = port_re.search(line) self.sel_options['browser_url'] = (self.sel_options['browser_url'] or m.group(0)) self.sagenb_port = int(m.group(1)) self._p.expect("Starting factory") def _sage_startup_command(self): """ Command to send to pexpect to start the notebook. """ return 'sage -c "notebook(**%r)"' % self.nb_options def focus_cell(self, id): """ Moves focus to cell with id ``id``. """ sel = self.selenium sel.focus("cell_input_%s" % id) def eval_cell(self, id, text, timeout=20000, output=True): """ Evaluates the cell id with input text text. If output is True, then the cell output is returned. """ sel = self.selenium id = str(id) sel.type("cell_input_"+id, text) self.evaluate(id) self.wait_for_no_queued_cells() if output: return self.get_cell_output(id) def evaluate(self, id): """ Triggers evaluation of a given cell. """ # self.shift_enter("cell_input_"+id) self.selenium.get_eval('window.evaluate_cell(%s, 0);' % id) def _get_cell_output_type(self, id, type='nowrap'): out = '' try: out = self.selenium.get_eval("window.document.getElementById('cell_output_%s_%s').innerHTML" % (type, id)).strip() except: pass return out def get_cell_output(self, id): """ Gets the output of cell id. """ out = '' out = self._get_cell_output_type(id, 'nowrap') if out == '': out = self._get_cell_output_type(id, 'html') # Browser contortions. TODO: Simplify this with regular # expressions. preshrunk = '
    '
            PREshrunk = '
    '
            PREshrunk2 = '
    '
    
            if out.startswith(preshrunk) or out.startswith(PREshrunk):
                out = out[len(preshrunk):-6]
            if out.startswith(PREshrunk2):
                out = out[len(PREshrunk2):-6]
    
            out = out.strip()
            return out
    
        def wait_for_no_queued_cells(self, timeout=20000):
            """
            Tells Selenium to wait until they're are no queued cells on
            the worksheet.
            """
            self.selenium.wait_for_condition("selenium.browserbot.getCurrentWindow().queue_id_list.length == 0", "%s"%timeout)
    
        def enter(self, locator):
            """
            Presses enter in the element ``locator``.
            """
    #        self.selenium.focus(locator)
            self.selenium.key_press(locator, '13')
    #        self.selenium.key_press_native(KEY_CODES['enter'])
    
        def shift_enter(self, locator):
            """
            Presses shift-enter in the element ``locator``.   For example,
            self.shift_enter('cell_input_0')
            """
            sel = self.selenium
    #        self.selenium.focus(locator)
            sel.shift_key_down()
    #        sel.key_down_native(KEY_CODES['shift'])
            self.enter(locator)
            sel.shift_key_up()
    #        sel.key_up_native(KEY_CODES['shift'])
    
        def tab(self, locator):
            """
            Presses tab in the element ``locator``.
            """
            self.selenium.focus(locator)
            self.selenium.key_press_native(KEY_CODES['tab'])
    
        def introspect(self, id):
            """
            Evaluates introspection in the given cell.
            """
    #        self.tab('cell_input_%s' % id)
            self.selenium.get_eval('window.set_cursor_position(window.get_cell(%s), 100);' % id)
            self.selenium.get_eval('window.evaluate_cell_introspection(%s, null, null);' % id)
    
        def save_and_quit(self):
            """
            Save and close the current worksheet and wait until we
            arrive at the main page.
            """
            sel = self.selenium
            sel.click("//button[@name='button_save' and @onclick='save_worksheet_and_close();']")
            sel.wait_for_page_to_load("30000")
            self.wait_for_title('Active Worksheets -- Sage')
    
        def wait_for_title(self, title):
            """
            Tells Selenium to wait until the title of the page has changed
            to title since it doesn't recognize many of the page reloads
            in the Sage notebook.
            """
            self.selenium.wait_for_condition('selenium.browserbot.getCurrentWindow().document.title.replace(/^\s+|\s+$/g, "") == "%s"'%title, 30000)
    
        def rename_worksheet(self, new_title):
            """
            Renames the current worksheet.
            """
            sel = self.selenium
            sel.click("worksheet_title")
            # Note: These locators also detect modal prompts that have
            # been hidden, but not deleted.
            sel.type('//div[contains(@class,"modal-prompt")]//input[@type="text"]', new_title)
            sel.click('//div[contains(@class, "modal-prompt")]/form/div[@class="button-div"]/button[@type="submit"]')
            sel.wait_for_condition('selenium.browserbot.getCurrentWindow().$("#worksheet_title").text() == "%s"' % new_title, 5000)
    
        def register_user(self, username, password='asdfasdf'):
            """
            Registers a new user for the Sage notebook.
    
            This assumes that you're at the login page.
            """
            sel = self.selenium
            sel.click("id=register-link")
            sel.wait_for_page_to_load(30000)
            self.wait_for_title("Sign up -- Sage")
    
            sel.type("username", username)
            sel.type("password", password)
            sel.type("retype_password", password)
            sel.click("id=create-account-button")
            sel.wait_for_page_to_load(30000)
            self.wait_for_title('Sign in -- Sage')
            self.assertTrue(sel.is_text_present('regexp:Congratulations'))
    
        def login_as(self, username, password='asdfasdf'):
            """
            Login as user username.  This assumes that you're at
            the login page.
            """
            self.username = username
            self.password = password
    
            sel = self.selenium
            sel.type("email", self.username)
            sel.type("password", self.password)
            sel.click("//button[text()='Sign in']")
            sel.wait_for_page_to_load("30000")
    
        def logout(self):
            """
            This logs the user out by clicking the 'Sign out' link.
            """
            self.username = None
            self.password = None
    
            sel = self.selenium
            sel.click("link=Sign out")
            sel.wait_for_page_to_load("30000")
    
        def go_home(self):
            """
            Open the currently logged-in user's home page (i.e., active
            worksheet list).
            """
            sel = self.selenium
            sel.open('/home/' + self.username)
            sel.wait_for_page_to_load("30000")
    
        def create_new_worksheet(self, title = "My New Worksheet"):
            sel = self.selenium
            self.go_home()
            sel.run_script('window.location="/new_worksheet"')
            sel.wait_for_page_to_load("30000")
            self.assert_(sel.is_element_present('//a[@id="worksheet_title" and contains(text(),"Untitled")]'))
            sel.type('//div[contains(@class,"modal-prompt")]//input[@type="text"]', title)
            sel.click('//div[contains(@class, "modal-prompt")]/form/div[@class="button-div"]/button[@type="submit"]')
            sel.wait_for_condition('selenium.browserbot.getCurrentWindow().$("#worksheet_title").text() == "%s"' % title, 5000)
    
        def open_worksheet_with_title(self, title):
            """
            Open the worksheet with the given title, starting at
            worksheet list.  This assumes the list contains the title.
            """
            self.go_home()
            sel = self.selenium
            sel.click('link=%s' % title)
            sel.wait_for_page_to_load("30000")
    
        def publish_worksheet(self):
            """
            Publishes the current worksheet.  This assumes you're at the
            main worksheet page.  After it has finished publishing, it
            returns back to the worksheet.
            """
            sel = self.selenium
            sel.click("link=Publish")
            sel.wait_for_page_to_load("30000")
            sel.click("//input[@value='Yes']")
            sel.wait_for_page_to_load("30000")
            sel.click("link=Worksheet")
            sel.wait_for_page_to_load("30000")
    
        def republish_worksheet(self):
            """
            Re-publish the current worksheet.  Begins and ends at the main
            worksheet page.
            """
            sel = self.selenium
            sel.click("link=Publish")
            sel.wait_for_page_to_load("30000")
            sel.click("//button[text()='Re-publish worksheet']")
            sel.wait_for_page_to_load("30000")
            sel.click("link=Worksheet")
            sel.wait_for_page_to_load("30000")
    
        def goto_published_worksheets(self):
            """
            Go to the "Published Worksheets" page.
            """
            sel = self.selenium
            sel.open('/pub')
            sel.wait_for_page_to_load("30000")
            
        def is_worksheet_published(self, name):
            """
            Returns True if worksheet id is published, False otherwise.
            """
            name = str(name)
            sel = self.selenium
            sel.click("link=Published")
            sel.wait_for_page_to_load("30000")
            return sel.is_text_present(name)
    
        def goto_published_worksheet(self, id):
            """
            Goto the publishes worksheet with specified id.
            """
            id = str(id)
            sel = self.selenium
            sel.click("link=Published")
            sel.wait_for_page_to_load("30000")
            sel.click("name-pub-"+id)
            sel.wait_for_page_to_load("30000")
            #broken by public interacts, worksheet_filename changes at every viewing
            #to allow for independent interacts
            #sel.wait_for_condition('selenium.browserbot.getCurrentWindow().worksheet_filename == "%s"'%('pub/'+id), 30000)
    
        def open_worksheet_with_name(self, name):
            """
            Opens the worksheet with the given name. Assumes that client
            is at list page.
            """
            sel = self.selenium
            self.wait_in_window(u'return this.$("a.worksheetname").attr("title").indexOf("{0}") != -1'.format(name),
                               30000)
            sel.click(u'//a[contains(@class, "worksheetname") and contains(@title, "{0}")]'.format(name))
            sel.wait_for_page_to_load(30000)
    
        def share_worksheet(self, collaborators):
            """
            Share the current worksheet with collaborators.
            """
            sel = self.selenium
            sel.click("link=Share")
            sel.wait_for_page_to_load("30000")
            sel.type("collaborators", collaborators)
            sel.click("//input[@value='Invite Collaborators']")
            sel.wait_for_page_to_load("30000")
    
        def wait_in_window(self, string, timeout):
            """
            Evaluates a javascript string until it returns true or timeout
            is reached. The string is evaluated in the scope of the
            browser window. Use ``this`` to access the browser window.
            """
            self.selenium.wait_for_condition('(function(){ %s }).apply(selenium.browserbot.getCurrentWindow())'
                                             % string, timeout)
    
        def stop_notebook(self):
            """
            Stops the Sage notebook.
            """
            self._p.sendline(chr(3)+chr(3))
            self._p.kill(signal.SIGKILL)
            self._p = None
    
        def tearDown(self):
            """
            Stops the notebook and cleans up.
            """
            self.stop_notebook()
            self.cleanup()
            self.selenium.stop()
    sagenb-1.0.1/sagenb/testing/run_tests.py000066400000000000000000000212641311436262400202730ustar00rootroot00000000000000# -*- coding: utf-8 -*
    #!/usr/bin/env python
    """
    Running SageNB Tests
    
    Functions for running SageNB tests. This can also be used a script.
    
    NOTE:
    
    The SageNB tests tests assume a Selenium server or Grid hub is running
    with the options given in :mod:`sagenb.testing.notebook_test_case` or
    set by :func:`setup_tests`.
    
    
    Selenium server can be downloaded from the Selenium `download page
    `_ as part of the Selenium RC package
    and can be run with `java -jar selenium-server.jar`.  To set up
    Selenium Grid, please visit its `home page
    `_ for instructions.
    
    TODO:
    
    - Add extra functionality to this script
    
    - Include a proxy to this script in the Sage scripts repo.
    """
    # Developer note:
    # The Selenium server cannot be included in the package because
    # of the possibility of incompatible libraries and binaries with
    # those of the user's browser (e.g., Python, etc.)
    
    import unittest
    
    from . import notebook_test_case
    from sagenb.misc.misc import browser
    from .tests import test_accounts, test_worksheet, test_worksheet_list
    
    CASES = {
        'TestAccounts': test_accounts,
        'TestWorksheet': test_worksheet,
        'TestWorksheetList': test_worksheet_list
        }
    
    all_tests = unittest.TestSuite((test_accounts.suite,
                                   test_worksheet.suite,
                                   test_worksheet_list.suite))
    
    
    def setup_tests(address='localhost', secure=False,
                    environment='*firefox3 /usr/bin/firefox'):
        """
        Sets selected options for SageNB Selenium tests.
    
        INPUT:
    
        - ``address`` - a string (default: 'localhost'); address of the
          network interface at which the notebook server listens.  Do not
          leave this empty; see :mod:`sagenb.testing.notebook_test_case`
          for details.
    
        - ``secure`` - a boolean (default: False); whether to launch a
          secure notebook server.  Note: Browser security warnings will
          yield failed tests.  To work around these in Firefox, close all
          windows, create a new profile (e.g., `firefox -P selenium`),
          browse to a secure notebook server, accept the certificate, and
          quit.  Then launch the Selenium server with, e.g.,
    
            java -jar selenium-server -firefoxProfileTemplate $HOME/selenium/firefox
    
          and run the tests.  A minimal profile template directory can
          contain just the files `cert8.db` and `cert_override.txt`.
    
        - ``environment`` - a string (default: '*firefox3
          /usr/bin/firefox'); the browser environment in which to run the
          tests.  The path is optional.  However, for the Selenium server
          to have complete control over the launched browser, it's best to
          give the full path to the browser *executable* (i.e., not a
          shell script).
    
          Possible environments include '*chrome', '*firefox',
          '*firefox3', '*googlechrome', '*iexplore', '*opera', '*safari'.
    
        EXAMPLES::
    
            sage: import sagenb.testing.run_tests as rt               # not tested
            sage: env = '*firefox3 /usr/lib64/firefox-3.5.6/firefox'  # not tested
            sage: rt.setup_tests('localhost', True, env)              # not tested
            sage: rt.run_any()                                        # not tested
            sage: rt.setup_tests('localhost', True, '*opera')         # not tested
            sage: rt.run_and_report()                                 # not tested
        """
        # TODO: Add a directory option for parallel testing.
        notebook_test_case.NB_OPTIONS['address'] = address
        notebook_test_case.NB_OPTIONS['secure'] = secure
        notebook_test_case.SEL_OPTIONS['environment'] = environment
    
    
    def run_any(tests=all_tests, make_report=False, **kwargs):
        """
        Creates and runs an ad hoc test suite from a test name, case,
        suite, or a mixed list thereof.  If no matching tests are found,
        no tests are run.
    
        INPUT:
    
        - ``tests`` - a string, :class:`unittest.TestCase`,
          :class:`unittest.TestSuite`, or a mixed list thereof.  Strings
          can be test names, with or without the prefix 'test_'.
    
        - ``make_report`` - a boolean (default: False); whether to
          generate a HTML report of the test results.
    
        - ``kwargs`` - a dictionary; additional keyword options to pass to
          :func:`run_suite` or :func:`run_and_report`.
    
        EXAMPLES::
    
            sage: import sagenb.testing.run_tests as rt              # not tested
            sage: rt.run_any('simple_evaluation', make_report=True)  # not tested
            sage: rt.run_any(['4088', 'test_3711'], verbosity=1)     # not tested
            sage: rt.run_any('foo', False)                           # not tested
            sage: rt.run_any(rt.test_accounts.TestAccounts)          # not tested
            sage: rt.run_any(make_report=True)                       # not tested
        """
        import inspect
        from_name = unittest.TestLoader().loadTestsFromName
        from_case = unittest.TestLoader().loadTestsFromTestCase
    
        if not isinstance(tests, list):
            tests = [tests]
    
        alist = []
        for t in tests:
            if isinstance(t, str):
                if not t.startswith('test_'):
                    t = 'test_' + t
                for c in CASES:
                    try:
                        alist.append(from_name(c + '.' + t, module = CASES[c]))
                    except AttributeError:
                        pass
            elif inspect.isclass(t) and issubclass(t, unittest.TestCase):
                alist.append(from_case(t))
            elif isinstance(t, unittest.TestSuite):
                alist.append(t)
    
        if alist:
            suite = unittest.TestSuite(alist)
            tot = suite.countTestCases()
    
            environment = notebook_test_case.SEL_OPTIONS['environment']
            print('Running %d test%s in environment %s...' % (tot, '' if tot == 1 else 's', environment))
    
            if make_report:
                run_and_report(suite, environment = environment, **kwargs)
            else:
                run_suite(suite, **kwargs)
    
    
    def run_suite(suite=all_tests, verbosity=2):
        """
        Runs a test suite.
    
        For the SageNB test suite, this assumes a Selenium server or Grid
        hub is running with the options given in
        :mod:`sagenb.testing.notebook_test_case` or set by
        :func:`setup_tests`
    
        INPUT:
    
        - ``suite`` - a TestSuite instance (default: all_tests); the test
          suite to run
    
        - ``verbosity`` - an integer (default: 2); how verbosely to report
          instantaneous test results
    
        EXAMPLES::
    
            sage: import sagenb.testing.run_tests as rt               # not tested
            sage: rt.run_suite()                                      # not tested
            sage: rt.run_suite(rt.test_worksheet.suite, verbosity=1)  # not tested
        """
        unittest.TextTestRunner(verbosity=verbosity).run(suite)
    
    
    def run_and_report(suite=all_tests, verbosity=2, report_filename='report.html',
                       title='Sage Notebook Tests',
                       description='Selenium test results',
                       open_viewer=True, **kwargs):
        """
        Runs a test suite and generates a HTML report with the outcome
        (pass, fail, or error) and output, including any tracebacks, for
        each test, plus overall statistics.
    
        For the SageNB test suite, this assumes a Selenium server or Grid
        hub is running with the options given in
        :mod:`sagenb.testing.notebook_test_case` or set by
        :func:`setup_tests`.
    
        INPUT:
    
        - ``suite`` - a TestSuite instance (default: all_tests); the test
          suite to run
    
        - ``verbosity`` - an integer (default: 2); how verbosely to report
          instantaneous test results
    
        - ``report_filename`` - a string (default: 'report.html'); the
          report's filename
    
        - ``title`` - a string (default: 'Sage Notebook Tests'); the
          report's title
    
        - ``description`` - a string (default: 'Selenium test results'); a
          description included near the beginning of the report
    
        - ``open_viewer`` - a boolean (default: True); whether to open
          the report in a web browser
    
        - ``kwargs`` - a dictionary; extra keyword arguments passed to the
          test runner's constructor
    
        EXAMPLES::
    
            sage: import sagenb.testing.run_tests as rt             # not tested
            sage: rt.run_and_report()                               # not tested
            sage: rt.run_and_report(report_filename='test1.html')   # not tested
            sage: rt.run_and_report(rt.test_accounts.suite)         # not tested
        """
        from .HTMLTestRunner import HTMLTestRunner
    
        report_fd = open(report_filename, 'w')
        runner = HTMLTestRunner(verbosity = verbosity, stream = report_fd,
                                title = title, description = description,
                                **kwargs)
        runner.run(suite)
    
        if open_viewer:
            import os, subprocess
            subprocess.Popen(browser() + ' ' + os.path.abspath(report_filename),
                             shell=True)
    
    
    if __name__ == '__main__':
        run_suite()
    sagenb-1.0.1/sagenb/testing/selenium/000077500000000000000000000000001311436262400175075ustar00rootroot00000000000000sagenb-1.0.1/sagenb/testing/selenium/__init__.py000066400000000000000000000000311311436262400216120ustar00rootroot00000000000000# -*- coding: utf-8 -*
     
    sagenb-1.0.1/sagenb/testing/selenium/selenium.py000066400000000000000000002327371311436262400217200ustar00rootroot00000000000000# -*- coding: utf-8 -*
    
    """
    Copyright 2006 ThoughtWorks, Inc.
    
    Licensed under the Apache License, Version 2.0 (the "License");
    you may not use this file except in compliance with the License.
    You may obtain a copy of the License at
    
        http://www.apache.org/licenses/LICENSE-2.0
    
    Unless required by applicable law or agreed to in writing, software
    distributed under the License is distributed on an "AS IS" BASIS,
    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    See the License for the specific language governing permissions and
    limitations under the License.
    """
    __docformat__ = "restructuredtext en"
    
    # This file has been automatically generated via XSL
    
    import http.client
    import urllib
    import re
    
    class selenium:
        """
        Defines an object that runs Selenium commands.
        
        Element Locators
        ~~~~~~~~~~~~~~~~
        
        Element Locators tell Selenium which HTML element a command refers to.
        The format of a locator is:
        
        \ *locatorType*\ **=**\ \ *argument*
        
        
        We support the following strategies for locating elements:
        
        
        *   \ **identifier**\ =\ *id*: 
            Select the element with the specified @id attribute. If no match is
            found, select the first element whose @name attribute is \ *id*.
            (This is normally the default; see below.)
        *   \ **id**\ =\ *id*:
            Select the element with the specified @id attribute.
        *   \ **name**\ =\ *name*:
            Select the first element with the specified @name attribute.
            
            *   username
            *   name=username
            
            
            The name may optionally be followed by one or more \ *element-filters*, separated from the name by whitespace.  If the \ *filterType* is not specified, \ **value**\  is assumed.
            
            *   name=flavour value=chocolate
            
            
        *   \ **dom**\ =\ *javascriptExpression*: 
            
            Find an element by evaluating the specified string.  This allows you to traverse the HTML Document Object
            Model using JavaScript.  Note that you must not return a value in this string; simply make it the last expression in the block.
            
            *   dom=document.forms['myForm'].myDropdown
            *   dom=document.images[56]
            *   dom=function foo() { return document.links[1]; }; foo();
            
            
        *   \ **xpath**\ =\ *xpathExpression*: 
            Locate an element using an XPath expression.
            
            *   xpath=//img[@alt='The image alt text']
            *   xpath=//table[@id='table1']//tr[4]/td[2]
            *   xpath=//a[contains(@href,'#id1')]
            *   xpath=//a[contains(@href,'#id1')]/@class
            *   xpath=(//table[@class='stylee'])//th[text()='theHeaderText']/../td
            *   xpath=//input[@name='name2' and @value='yes']
            *   xpath=//\*[text()="right"]
            
            
        *   \ **link**\ =\ *textPattern*:
            Select the link (anchor) element which contains text matching the
            specified \ *pattern*.
            
            *   link=The link text
            
            
        *   \ **css**\ =\ *cssSelectorSyntax*:
            Select the element using css selectors. Please refer to CSS2 selectors, CSS3 selectors for more information. You can also check the TestCssLocators test in the selenium test suite for an example of usage, which is included in the downloaded selenium core package.
            
            *   css=a[href="#id3"]
            *   css=span#firstChild + span
            
            
            Currently the css selector locator supports all css1, css2 and css3 selectors except namespace in css3, some pseudo classes(:nth-of-type, :nth-last-of-type, :first-of-type, :last-of-type, :only-of-type, :visited, :hover, :active, :focus, :indeterminate) and pseudo elements(::first-line, ::first-letter, ::selection, ::before, ::after). 
            
        *   \ **ui**\ =\ *uiSpecifierString*:
            Locate an element by resolving the UI specifier string to another locator, and evaluating it. See the Selenium UI-Element Reference for more details.
            
            *   ui=loginPages::loginButton()
            *   ui=settingsPages::toggle(label=Hide Email)
            *   ui=forumPages::postBody(index=2)//a[2]
            
            
        
        
        
        Without an explicit locator prefix, Selenium uses the following default
        strategies:
        
        
        *   \ **dom**\ , for locators starting with "document."
        *   \ **xpath**\ , for locators starting with "//"
        *   \ **identifier**\ , otherwise
        
        Element Filters
        ~~~~~~~~~~~~~~~
        
        Element filters can be used with a locator to refine a list of candidate elements.  They are currently used only in the 'name' element-locator.
        
        Filters look much like locators, ie.
        
        \ *filterType*\ **=**\ \ *argument*
        
        Supported element-filters are:
        
        \ **value=**\ \ *valuePattern*
        
        
        Matches elements based on their values.  This is particularly useful for refining a list of similarly-named toggle-buttons.
        
        \ **index=**\ \ *index*
        
        
        Selects a single element based on its position in the list (offset from zero).
        
        String-match Patterns
        ~~~~~~~~~~~~~~~~~~~~~
        
        Various Pattern syntaxes are available for matching string values:
        
        
        *   \ **glob:**\ \ *pattern*:
            Match a string against a "glob" (aka "wildmat") pattern. "Glob" is a
            kind of limited regular-expression syntax typically used in command-line
            shells. In a glob pattern, "\*" represents any sequence of characters, and "?"
            represents any single character. Glob patterns match against the entire
            string.
        *   \ **regexp:**\ \ *regexp*:
            Match a string using a regular-expression. The full power of JavaScript
            regular-expressions is available.
        *   \ **regexpi:**\ \ *regexpi*:
            Match a string using a case-insensitive regular-expression.
        *   \ **exact:**\ \ *string*:
            
            Match a string exactly, verbatim, without any of that fancy wildcard
            stuff.
        
        
        
        If no pattern prefix is specified, Selenium assumes that it's a "glob"
        pattern.
        
        
        
        For commands that return multiple values (such as verifySelectOptions),
        the string being matched is a comma-separated list of the return values,
        where both commas and backslashes in the values are backslash-escaped.
        When providing a pattern, the optional matching syntax (i.e. glob,
        regexp, etc.) is specified once, as usual, at the beginning of the
        pattern.
        
        
        """
    
    ### This part is hard-coded in the XSL
        def __init__(self, host, port, browserStartCommand, browserURL):
            self.host = host
            self.port = port
            self.browserStartCommand = browserStartCommand
            self.browserURL = browserURL
            self.sessionId = None
            self.extensionJs = ""
    
        def setExtensionJs(self, extensionJs):
            self.extensionJs = extensionJs
            
        def start(self):
            result = self.get_string("getNewBrowserSession", [self.browserStartCommand, self.browserURL, self.extensionJs])
            try:
                self.sessionId = result
            except ValueError:
                raise Exception(result)
            
        def stop(self):
            self.do_command("testComplete", [])
            self.sessionId = None
    
        def do_command(self, verb, args):
            conn = http.client.HTTPConnection(self.host, self.port)
            body = u'cmd=' + urllib.quote_plus(unicode(verb).encode('utf-8'))
            for i in range(len(args)):
                body += '&' + unicode(i+1) + '=' + urllib.quote_plus(unicode(args[i]).encode('utf-8'))
            if (None != self.sessionId):
                body += "&sessionId=" + unicode(self.sessionId)
            headers = {"Content-Type": "application/x-www-form-urlencoded; charset=utf-8"}
            conn.request("POST", "/selenium-server/driver/", body, headers)
        
            response = conn.getresponse()
            data = unicode(response.read(), "UTF-8")
            result = response.reason
            if (not data.startswith('OK')):
                raise Exception(data)
            return data
        
        def get_string(self, verb, args):
            result = self.do_command(verb, args)
            return result[3:]
        
        def get_string_array(self, verb, args):
            csv = self.get_string(verb, args)
            token = ""
            tokens = []
            escape = False
            for i in range(len(csv)):
                letter = csv[i]
                if (escape):
                    token = token + letter
                    escape = False
                    continue
                if (letter == '\\'):
                    escape = True
                elif (letter == ','):
                    tokens.append(token)
                    token = ""
                else:
                    token = token + letter
            tokens.append(token)
            return tokens
    
        def get_number(self, verb, args):
            # Is there something I need to do here?
            return self.get_string(verb, args)
        
        def get_number_array(self, verb, args):
            # Is there something I need to do here?
            return self.get_string_array(verb, args)
    
        def get_boolean(self, verb, args):
            boolstr = self.get_string(verb, args)
            if ("true" == boolstr):
                return True
            if ("false" == boolstr):
                return False
            raise ValueError("result is neither 'true' nor 'false': " + boolstr)
        
        def get_boolean_array(self, verb, args):
            boolarr = self.get_string_array(verb, args)
            for i in range(len(boolarr)):
                if ("true" == boolstr):
                    boolarr[i] = True
                    continue
                if ("false" == boolstr):
                    boolarr[i] = False
                    continue
                raise ValueError("result is neither 'true' nor 'false': " + boolarr[i])
            return boolarr
        
        
    
    ### From here on, everything's auto-generated from XML
    
    
        def click(self,locator):
            """
            Clicks on a link, button, checkbox or radio button. If the click action
            causes a new page to load (like a link usually does), call
            waitForPageToLoad.
            
            'locator' is an element locator
            """
            self.do_command("click", [locator,])
    
    
        def double_click(self,locator):
            """
            Double clicks on a link, button, checkbox or radio button. If the double click action
            causes a new page to load (like a link usually does), call
            waitForPageToLoad.
            
            'locator' is an element locator
            """
            self.do_command("doubleClick", [locator,])
    
    
        def context_menu(self,locator):
            """
            Simulates opening the context menu for the specified element (as might happen if the user "right-clicked" on the element).
            
            'locator' is an element locator
            """
            self.do_command("contextMenu", [locator,])
    
    
        def click_at(self,locator,coordString):
            """
            Clicks on a link, button, checkbox or radio button. If the click action
            causes a new page to load (like a link usually does), call
            waitForPageToLoad.
            
            'locator' is an element locator
            'coordString' is specifies the x,y position (i.e. - 10,20) of the mouse      event relative to the element returned by the locator.
            """
            self.do_command("clickAt", [locator,coordString,])
    
    
        def double_click_at(self,locator,coordString):
            """
            Doubleclicks on a link, button, checkbox or radio button. If the action
            causes a new page to load (like a link usually does), call
            waitForPageToLoad.
            
            'locator' is an element locator
            'coordString' is specifies the x,y position (i.e. - 10,20) of the mouse      event relative to the element returned by the locator.
            """
            self.do_command("doubleClickAt", [locator,coordString,])
    
    
        def context_menu_at(self,locator,coordString):
            """
            Simulates opening the context menu for the specified element (as might happen if the user "right-clicked" on the element).
            
            'locator' is an element locator
            'coordString' is specifies the x,y position (i.e. - 10,20) of the mouse      event relative to the element returned by the locator.
            """
            self.do_command("contextMenuAt", [locator,coordString,])
    
    
        def fire_event(self,locator,eventName):
            """
            Explicitly simulate an event, to trigger the corresponding "on\ *event*"
            handler.
            
            'locator' is an element locator
            'eventName' is the event name, e.g. "focus" or "blur"
            """
            self.do_command("fireEvent", [locator,eventName,])
    
    
        def focus(self,locator):
            """
            Move the focus to the specified element; for example, if the element is an input field, move the cursor to that field.
            
            'locator' is an element locator
            """
            self.do_command("focus", [locator,])
    
    
        def key_press(self,locator,keySequence):
            """
            Simulates a user pressing and releasing a key.
            
            'locator' is an element locator
            'keySequence' is Either be a string("\" followed by the numeric keycode  of the key to be pressed, normally the ASCII value of that key), or a single  character. For example: "w", "\119".
            """
            self.do_command("keyPress", [locator,keySequence,])
    
    
        def shift_key_down(self):
            """
            Press the shift key and hold it down until doShiftUp() is called or a new page is loaded.
            
            """
            self.do_command("shiftKeyDown", [])
    
    
        def shift_key_up(self):
            """
            Release the shift key.
            
            """
            self.do_command("shiftKeyUp", [])
    
    
        def meta_key_down(self):
            """
            Press the meta key and hold it down until doMetaUp() is called or a new page is loaded.
            
            """
            self.do_command("metaKeyDown", [])
    
    
        def meta_key_up(self):
            """
            Release the meta key.
            
            """
            self.do_command("metaKeyUp", [])
    
    
        def alt_key_down(self):
            """
            Press the alt key and hold it down until doAltUp() is called or a new page is loaded.
            
            """
            self.do_command("altKeyDown", [])
    
    
        def alt_key_up(self):
            """
            Release the alt key.
            
            """
            self.do_command("altKeyUp", [])
    
    
        def control_key_down(self):
            """
            Press the control key and hold it down until doControlUp() is called or a new page is loaded.
            
            """
            self.do_command("controlKeyDown", [])
    
    
        def control_key_up(self):
            """
            Release the control key.
            
            """
            self.do_command("controlKeyUp", [])
    
    
        def key_down(self,locator,keySequence):
            """
            Simulates a user pressing a key (without releasing it yet).
            
            'locator' is an element locator
            'keySequence' is Either be a string("\" followed by the numeric keycode  of the key to be pressed, normally the ASCII value of that key), or a single  character. For example: "w", "\119".
            """
            self.do_command("keyDown", [locator,keySequence,])
    
    
        def key_up(self,locator,keySequence):
            """
            Simulates a user releasing a key.
            
            'locator' is an element locator
            'keySequence' is Either be a string("\" followed by the numeric keycode  of the key to be pressed, normally the ASCII value of that key), or a single  character. For example: "w", "\119".
            """
            self.do_command("keyUp", [locator,keySequence,])
    
    
        def mouse_over(self,locator):
            """
            Simulates a user hovering a mouse over the specified element.
            
            'locator' is an element locator
            """
            self.do_command("mouseOver", [locator,])
    
    
        def mouse_out(self,locator):
            """
            Simulates a user moving the mouse pointer away from the specified element.
            
            'locator' is an element locator
            """
            self.do_command("mouseOut", [locator,])
    
    
        def mouse_down(self,locator):
            """
            Simulates a user pressing the left mouse button (without releasing it yet) on
            the specified element.
            
            'locator' is an element locator
            """
            self.do_command("mouseDown", [locator,])
    
    
        def mouse_down_right(self,locator):
            """
            Simulates a user pressing the right mouse button (without releasing it yet) on
            the specified element.
            
            'locator' is an element locator
            """
            self.do_command("mouseDownRight", [locator,])
    
    
        def mouse_down_at(self,locator,coordString):
            """
            Simulates a user pressing the left mouse button (without releasing it yet) at
            the specified location.
            
            'locator' is an element locator
            'coordString' is specifies the x,y position (i.e. - 10,20) of the mouse      event relative to the element returned by the locator.
            """
            self.do_command("mouseDownAt", [locator,coordString,])
    
    
        def mouse_down_right_at(self,locator,coordString):
            """
            Simulates a user pressing the right mouse button (without releasing it yet) at
            the specified location.
            
            'locator' is an element locator
            'coordString' is specifies the x,y position (i.e. - 10,20) of the mouse      event relative to the element returned by the locator.
            """
            self.do_command("mouseDownRightAt", [locator,coordString,])
    
    
        def mouse_up(self,locator):
            """
            Simulates the event that occurs when the user releases the mouse button (i.e., stops
            holding the button down) on the specified element.
            
            'locator' is an element locator
            """
            self.do_command("mouseUp", [locator,])
    
    
        def mouse_up_right(self,locator):
            """
            Simulates the event that occurs when the user releases the right mouse button (i.e., stops
            holding the button down) on the specified element.
            
            'locator' is an element locator
            """
            self.do_command("mouseUpRight", [locator,])
    
    
        def mouse_up_at(self,locator,coordString):
            """
            Simulates the event that occurs when the user releases the mouse button (i.e., stops
            holding the button down) at the specified location.
            
            'locator' is an element locator
            'coordString' is specifies the x,y position (i.e. - 10,20) of the mouse      event relative to the element returned by the locator.
            """
            self.do_command("mouseUpAt", [locator,coordString,])
    
    
        def mouse_up_right_at(self,locator,coordString):
            """
            Simulates the event that occurs when the user releases the right mouse button (i.e., stops
            holding the button down) at the specified location.
            
            'locator' is an element locator
            'coordString' is specifies the x,y position (i.e. - 10,20) of the mouse      event relative to the element returned by the locator.
            """
            self.do_command("mouseUpRightAt", [locator,coordString,])
    
    
        def mouse_move(self,locator):
            """
            Simulates a user pressing the mouse button (without releasing it yet) on
            the specified element.
            
            'locator' is an element locator
            """
            self.do_command("mouseMove", [locator,])
    
    
        def mouse_move_at(self,locator,coordString):
            """
            Simulates a user pressing the mouse button (without releasing it yet) on
            the specified element.
            
            'locator' is an element locator
            'coordString' is specifies the x,y position (i.e. - 10,20) of the mouse      event relative to the element returned by the locator.
            """
            self.do_command("mouseMoveAt", [locator,coordString,])
    
    
        def type(self,locator,value):
            """
            Sets the value of an input field, as though you typed it in.
            
            
            Can also be used to set the value of combo boxes, check boxes, etc. In these cases,
            value should be the value of the option selected, not the visible text.
            
            
            'locator' is an element locator
            'value' is the value to type
            """
            self.do_command("type", [locator,value,])
    
    
        def type_keys(self,locator,value):
            """
            Simulates keystroke events on the specified element, as though you typed the value key-by-key.
            
            
            This is a convenience method for calling keyDown, keyUp, keyPress for every character in the specified string;
            this is useful for dynamic UI widgets (like auto-completing combo boxes) that require explicit key events.
            
            Unlike the simple "type" command, which forces the specified value into the page directly, this command
            may or may not have any visible effect, even in cases where typing keys would normally have a visible effect.
            For example, if you use "typeKeys" on a form element, you may or may not see the results of what you typed in
            the field.
            
            In some cases, you may need to use the simple "type" command to set the value of the field and then the "typeKeys" command to
            send the keystroke events corresponding to what you just typed.
            
            
            'locator' is an element locator
            'value' is the value to type
            """
            self.do_command("typeKeys", [locator,value,])
    
    
        def set_speed(self,value):
            """
            Set execution speed (i.e., set the millisecond length of a delay which will follow each selenium operation).  By default, there is no such delay, i.e.,
            the delay is 0 milliseconds.
            
            'value' is the number of milliseconds to pause after operation
            """
            self.do_command("setSpeed", [value,])
    
    
        def get_speed(self):
            """
            Get execution speed (i.e., get the millisecond length of the delay following each selenium operation).  By default, there is no such delay, i.e.,
            the delay is 0 milliseconds.
            
            See also setSpeed.
            
            """
            return self.get_string("getSpeed", [])
    
    
        def check(self,locator):
            """
            Check a toggle-button (checkbox/radio)
            
            'locator' is an element locator
            """
            self.do_command("check", [locator,])
    
    
        def uncheck(self,locator):
            """
            Uncheck a toggle-button (checkbox/radio)
            
            'locator' is an element locator
            """
            self.do_command("uncheck", [locator,])
    
    
        def select(self,selectLocator,optionLocator):
            """
            Select an option from a drop-down using an option locator.
            
            
            
            Option locators provide different ways of specifying options of an HTML
            Select element (e.g. for selecting a specific option, or for asserting
            that the selected option satisfies a specification). There are several
            forms of Select Option Locator.
            
            
            *   \ **label**\ =\ *labelPattern*:
                matches options based on their labels, i.e. the visible text. (This
                is the default.)
                
                *   label=regexp:^[Oo]ther
                
                
            *   \ **value**\ =\ *valuePattern*:
                matches options based on their values.
                
                *   value=other
                
                
            *   \ **id**\ =\ *id*:
                
                matches options based on their ids.
                
                *   id=option1
                
                
            *   \ **index**\ =\ *index*:
                matches an option based on its index (offset from zero).
                
                *   index=2
                
                
            
            
            
            If no option locator prefix is provided, the default behaviour is to match on \ **label**\ .
            
            
            
            'selectLocator' is an element locator identifying a drop-down menu
            'optionLocator' is an option locator (a label by default)
            """
            self.do_command("select", [selectLocator,optionLocator,])
    
    
        def add_selection(self,locator,optionLocator):
            """
            Add a selection to the set of selected options in a multi-select element using an option locator.
            
            @see #doSelect for details of option locators
            
            'locator' is an element locator identifying a multi-select box
            'optionLocator' is an option locator (a label by default)
            """
            self.do_command("addSelection", [locator,optionLocator,])
    
    
        def remove_selection(self,locator,optionLocator):
            """
            Remove a selection from the set of selected options in a multi-select element using an option locator.
            
            @see #doSelect for details of option locators
            
            'locator' is an element locator identifying a multi-select box
            'optionLocator' is an option locator (a label by default)
            """
            self.do_command("removeSelection", [locator,optionLocator,])
    
    
        def remove_all_selections(self,locator):
            """
            Unselects all of the selected options in a multi-select element.
            
            'locator' is an element locator identifying a multi-select box
            """
            self.do_command("removeAllSelections", [locator,])
    
    
        def submit(self,formLocator):
            """
            Submit the specified form. This is particularly useful for forms without
            submit buttons, e.g. single-input "Search" forms.
            
            'formLocator' is an element locator for the form you want to submit
            """
            self.do_command("submit", [formLocator,])
    
    
        def open(self,url):
            """
            Opens an URL in the test frame. This accepts both relative and absolute
            URLs.
            
            The "open" command waits for the page to load before proceeding,
            ie. the "AndWait" suffix is implicit.
            
            \ *Note*: The URL must be on the same domain as the runner HTML
            due to security restrictions in the browser (Same Origin Policy). If you
            need to open an URL on another domain, use the Selenium Server to start a
            new browser session on that domain.
            
            'url' is the URL to open; may be relative or absolute
            """
            self.do_command("open", [url,])
    
    
        def open_window(self,url,windowID):
            """
            Opens a popup window (if a window with that ID isn't already open).
            After opening the window, you'll need to select it using the selectWindow
            command.
            
            
            This command can also be a useful workaround for bug SEL-339.  In some cases, Selenium will be unable to intercept a call to window.open (if the call occurs during or before the "onLoad" event, for example).
            In those cases, you can force Selenium to notice the open window's name by using the Selenium openWindow command, using
            an empty (blank) url, like this: openWindow("", "myFunnyWindow").
            
            
            'url' is the URL to open, which can be blank
            'windowID' is the JavaScript window ID of the window to select
            """
            self.do_command("openWindow", [url,windowID,])
    
    
        def select_window(self,windowID):
            """
            Selects a popup window using a window locator; once a popup window has been selected, all
            commands go to that window. To select the main window again, use null
            as the target.
            
            
            
            
            Window locators provide different ways of specifying the window object:
            by title, by internal JavaScript "name," or by JavaScript variable.
            
            
            *   \ **title**\ =\ *My Special Window*:
                Finds the window using the text that appears in the title bar.  Be careful;
                two windows can share the same title.  If that happens, this locator will
                just pick one.
                
            *   \ **name**\ =\ *myWindow*:
                Finds the window using its internal JavaScript "name" property.  This is the second 
                parameter "windowName" passed to the JavaScript method window.open(url, windowName, windowFeatures, replaceFlag)
                (which Selenium intercepts).
                
            *   \ **var**\ =\ *variableName*:
                Some pop-up windows are unnamed (anonymous), but are associated with a JavaScript variable name in the current
                application window, e.g. "window.foo = window.open(url);".  In those cases, you can open the window using
                "var=foo".
                
            
            
            
            If no window locator prefix is provided, we'll try to guess what you mean like this:
            
            1.) if windowID is null, (or the string "null") then it is assumed the user is referring to the original window instantiated by the browser).
            
            2.) if the value of the "windowID" parameter is a JavaScript variable name in the current application window, then it is assumed
            that this variable contains the return value from a call to the JavaScript window.open() method.
            
            3.) Otherwise, selenium looks in a hash it maintains that maps string names to window "names".
            
            4.) If \ *that* fails, we'll try looping over all of the known windows to try to find the appropriate "title".
            Since "title" is not necessarily unique, this may have unexpected behavior.
            
            If you're having trouble figuring out the name of a window that you want to manipulate, look at the Selenium log messages
            which identify the names of windows created via window.open (and therefore intercepted by Selenium).  You will see messages
            like the following for each window as it is opened:
            
            ``debug: window.open call intercepted; window ID (which you can use with selectWindow()) is "myNewWindow"``
            
            In some cases, Selenium will be unable to intercept a call to window.open (if the call occurs during or before the "onLoad" event, for example).
            (This is bug SEL-339.)  In those cases, you can force Selenium to notice the open window's name by using the Selenium openWindow command, using
            an empty (blank) url, like this: openWindow("", "myFunnyWindow").
            
            
            'windowID' is the JavaScript window ID of the window to select
            """
            self.do_command("selectWindow", [windowID,])
    
    
        def select_pop_up(self,windowID):
            """
            Simplifies the process of selecting a popup window (and does not offer
            functionality beyond what ``selectWindow()`` already provides).
            
            *   If ``windowID`` is either not specified, or specified as
                "null", the first non-top window is selected. The top window is the one
                that would be selected by ``selectWindow()`` without providing a
                ``windowID`` . This should not be used when more than one popup
                window is in play.
            *   Otherwise, the window will be looked up considering
                ``windowID`` as the following in order: 1) the "name" of the
                window, as specified to ``window.open()``; 2) a javascript
                variable which is a reference to a window; and 3) the title of the
                window. This is the same ordered lookup performed by
                ``selectWindow`` .
            
            
            
            'windowID' is an identifier for the popup window, which can take on a                  number of different meanings
            """
            self.do_command("selectPopUp", [windowID,])
    
    
        def deselect_pop_up(self):
            """
            Selects the main window. Functionally equivalent to using
            ``selectWindow()`` and specifying no value for
            ``windowID``.
            
            """
            self.do_command("deselectPopUp", [])
    
    
        def select_frame(self,locator):
            """
            Selects a frame within the current window.  (You may invoke this command
            multiple times to select nested frames.)  To select the parent frame, use
            "relative=parent" as a locator; to select the top frame, use "relative=top".
            You can also select a frame by its 0-based index number; select the first frame with
            "index=0", or the third frame with "index=2".
            
            
            You may also use a DOM expression to identify the frame you want directly,
            like this: ``dom=frames["main"].frames["subframe"]``
            
            
            'locator' is an element locator identifying a frame or iframe
            """
            self.do_command("selectFrame", [locator,])
    
    
        def get_whether_this_frame_match_frame_expression(self,currentFrameString,target):
            """
            Determine whether current/locator identify the frame containing this running code.
            
            
            This is useful in proxy injection mode, where this code runs in every
            browser frame and window, and sometimes the selenium server needs to identify
            the "current" frame.  In this case, when the test calls selectFrame, this
            routine is called for each frame to figure out which one has been selected.
            The selected frame will return true, while all others will return false.
            
            
            'currentFrameString' is starting frame
            'target' is new frame (which might be relative to the current one)
            """
            return self.get_boolean("getWhetherThisFrameMatchFrameExpression", [currentFrameString,target,])
    
    
        def get_whether_this_window_match_window_expression(self,currentWindowString,target):
            """
            Determine whether currentWindowString plus target identify the window containing this running code.
            
            
            This is useful in proxy injection mode, where this code runs in every
            browser frame and window, and sometimes the selenium server needs to identify
            the "current" window.  In this case, when the test calls selectWindow, this
            routine is called for each window to figure out which one has been selected.
            The selected window will return true, while all others will return false.
            
            
            'currentWindowString' is starting window
            'target' is new window (which might be relative to the current one, e.g., "_parent")
            """
            return self.get_boolean("getWhetherThisWindowMatchWindowExpression", [currentWindowString,target,])
    
    
        def wait_for_pop_up(self,windowID,timeout):
            """
            Waits for a popup window to appear and load up.
            
            'windowID' is the JavaScript window "name" of the window that will appear (not the text of the title bar)                 If unspecified, or specified as "null", this command will                 wait for the first non-top window to appear (don't rely                 on this if you are working with multiple popups                 simultaneously).
            'timeout' is a timeout in milliseconds, after which the action will return with an error.                If this value is not specified, the default Selenium                timeout will be used. See the setTimeout() command.
            """
            self.do_command("waitForPopUp", [windowID,timeout,])
    
    
        def choose_cancel_on_next_confirmation(self):
            """
            
            
            By default, Selenium's overridden window.confirm() function will
            return true, as if the user had manually clicked OK; after running
            this command, the next call to confirm() will return false, as if
            the user had clicked Cancel.  Selenium will then resume using the
            default behavior for future confirmations, automatically returning 
            true (OK) unless/until you explicitly call this command for each
            confirmation.
            
            
            
            Take note - every time a confirmation comes up, you must
            consume it with a corresponding getConfirmation, or else
            the next selenium operation will fail.
            
            
            
            """
            self.do_command("chooseCancelOnNextConfirmation", [])
    
    
        def choose_ok_on_next_confirmation(self):
            """
            
            
            Undo the effect of calling chooseCancelOnNextConfirmation.  Note
            that Selenium's overridden window.confirm() function will normally automatically
            return true, as if the user had manually clicked OK, so you shouldn't
            need to use this command unless for some reason you need to change
            your mind prior to the next confirmation.  After any confirmation, Selenium will resume using the
            default behavior for future confirmations, automatically returning 
            true (OK) unless/until you explicitly call chooseCancelOnNextConfirmation for each
            confirmation.
            
            
            
            Take note - every time a confirmation comes up, you must
            consume it with a corresponding getConfirmation, or else
            the next selenium operation will fail.
            
            
            
            """
            self.do_command("chooseOkOnNextConfirmation", [])
    
    
        def answer_on_next_prompt(self,answer):
            """
            Instructs Selenium to return the specified answer string in response to
            the next JavaScript prompt [window.prompt()].
            
            'answer' is the answer to give in response to the prompt pop-up
            """
            self.do_command("answerOnNextPrompt", [answer,])
    
    
        def go_back(self):
            """
            Simulates the user clicking the "back" button on their browser.
            
            """
            self.do_command("goBack", [])
    
    
        def refresh(self):
            """
            Simulates the user clicking the "Refresh" button on their browser.
            
            """
            self.do_command("refresh", [])
    
    
        def close(self):
            """
            Simulates the user clicking the "close" button in the titlebar of a popup
            window or tab.
            
            """
            self.do_command("close", [])
    
    
        def is_alert_present(self):
            """
            Has an alert occurred?
            
            
            
            This function never throws an exception
            
            
            
            """
            return self.get_boolean("isAlertPresent", [])
    
    
        def is_prompt_present(self):
            """
            Has a prompt occurred?
            
            
            
            This function never throws an exception
            
            
            
            """
            return self.get_boolean("isPromptPresent", [])
    
    
        def is_confirmation_present(self):
            """
            Has confirm() been called?
            
            
            
            This function never throws an exception
            
            
            
            """
            return self.get_boolean("isConfirmationPresent", [])
    
    
        def get_alert(self):
            """
            Retrieves the message of a JavaScript alert generated during the previous action, or fail if there were no alerts.
            
            
            Getting an alert has the same effect as manually clicking OK. If an
            alert is generated but you do not consume it with getAlert, the next Selenium action
            will fail.
            
            Under Selenium, JavaScript alerts will NOT pop up a visible alert
            dialog.
            
            Selenium does NOT support JavaScript alerts that are generated in a
            page's onload() event handler. In this case a visible dialog WILL be
            generated and Selenium will hang until someone manually clicks OK.
            
            
            """
            return self.get_string("getAlert", [])
    
    
        def get_confirmation(self):
            """
            Retrieves the message of a JavaScript confirmation dialog generated during
            the previous action.
            
            
            
            By default, the confirm function will return true, having the same effect
            as manually clicking OK. This can be changed by prior execution of the
            chooseCancelOnNextConfirmation command. 
            
            
            
            If an confirmation is generated but you do not consume it with getConfirmation,
            the next Selenium action will fail.
            
            
            
            NOTE: under Selenium, JavaScript confirmations will NOT pop up a visible
            dialog.
            
            
            
            NOTE: Selenium does NOT support JavaScript confirmations that are
            generated in a page's onload() event handler. In this case a visible
            dialog WILL be generated and Selenium will hang until you manually click
            OK.
            
            
            
            """
            return self.get_string("getConfirmation", [])
    
    
        def get_prompt(self):
            """
            Retrieves the message of a JavaScript question prompt dialog generated during
            the previous action.
            
            
            Successful handling of the prompt requires prior execution of the
            answerOnNextPrompt command. If a prompt is generated but you
            do not get/verify it, the next Selenium action will fail.
            
            NOTE: under Selenium, JavaScript prompts will NOT pop up a visible
            dialog.
            
            NOTE: Selenium does NOT support JavaScript prompts that are generated in a
            page's onload() event handler. In this case a visible dialog WILL be
            generated and Selenium will hang until someone manually clicks OK.
            
            
            """
            return self.get_string("getPrompt", [])
    
    
        def get_location(self):
            """
            Gets the absolute URL of the current page.
            
            """
            return self.get_string("getLocation", [])
    
    
        def get_title(self):
            """
            Gets the title of the current page.
            
            """
            return self.get_string("getTitle", [])
    
    
        def get_body_text(self):
            """
            Gets the entire text of the page.
            
            """
            return self.get_string("getBodyText", [])
    
    
        def get_value(self,locator):
            """
            Gets the (whitespace-trimmed) value of an input field (or anything else with a value parameter).
            For checkbox/radio elements, the value will be "on" or "off" depending on
            whether the element is checked or not.
            
            'locator' is an element locator
            """
            return self.get_string("getValue", [locator,])
    
    
        def get_text(self,locator):
            """
            Gets the text of an element. This works for any element that contains
            text. This command uses either the textContent (Mozilla-like browsers) or
            the innerText (IE-like browsers) of the element, which is the rendered
            text shown to the user.
            
            'locator' is an element locator
            """
            return self.get_string("getText", [locator,])
    
    
        def highlight(self,locator):
            """
            Briefly changes the backgroundColor of the specified element yellow.  Useful for debugging.
            
            'locator' is an element locator
            """
            self.do_command("highlight", [locator,])
    
    
        def get_eval(self,script):
            """
            Gets the result of evaluating the specified JavaScript snippet.  The snippet may
            have multiple lines, but only the result of the last line will be returned.
            
            
            Note that, by default, the snippet will run in the context of the "selenium"
            object itself, so ``this`` will refer to the Selenium object.  Use ``window`` to
            refer to the window of your application, e.g. ``window.document.getElementById('foo')``
            
            If you need to use
            a locator to refer to a single element in your application page, you can
            use ``this.browserbot.findElement("id=foo")`` where "id=foo" is your locator.
            
            
            'script' is the JavaScript snippet to run
            """
            return self.get_string("getEval", [script,])
    
    
        def is_checked(self,locator):
            """
            Gets whether a toggle-button (checkbox/radio) is checked.  Fails if the specified element doesn't exist or isn't a toggle-button.
            
            'locator' is an element locator pointing to a checkbox or radio button
            """
            return self.get_boolean("isChecked", [locator,])
    
    
        def get_table(self,tableCellAddress):
            """
            Gets the text from a cell of a table. The cellAddress syntax
            tableLocator.row.column, where row and column start at 0.
            
            'tableCellAddress' is a cell address, e.g. "foo.1.4"
            """
            return self.get_string("getTable", [tableCellAddress,])
    
    
        def get_selected_labels(self,selectLocator):
            """
            Gets all option labels (visible text) for selected options in the specified select or multi-select element.
            
            'selectLocator' is an element locator identifying a drop-down menu
            """
            return self.get_string_array("getSelectedLabels", [selectLocator,])
    
    
        def get_selected_label(self,selectLocator):
            """
            Gets option label (visible text) for selected option in the specified select element.
            
            'selectLocator' is an element locator identifying a drop-down menu
            """
            return self.get_string("getSelectedLabel", [selectLocator,])
    
    
        def get_selected_values(self,selectLocator):
            """
            Gets all option values (value attributes) for selected options in the specified select or multi-select element.
            
            'selectLocator' is an element locator identifying a drop-down menu
            """
            return self.get_string_array("getSelectedValues", [selectLocator,])
    
    
        def get_selected_value(self,selectLocator):
            """
            Gets option value (value attribute) for selected option in the specified select element.
            
            'selectLocator' is an element locator identifying a drop-down menu
            """
            return self.get_string("getSelectedValue", [selectLocator,])
    
    
        def get_selected_indexes(self,selectLocator):
            """
            Gets all option indexes (option number, starting at 0) for selected options in the specified select or multi-select element.
            
            'selectLocator' is an element locator identifying a drop-down menu
            """
            return self.get_string_array("getSelectedIndexes", [selectLocator,])
    
    
        def get_selected_index(self,selectLocator):
            """
            Gets option index (option number, starting at 0) for selected option in the specified select element.
            
            'selectLocator' is an element locator identifying a drop-down menu
            """
            return self.get_string("getSelectedIndex", [selectLocator,])
    
    
        def get_selected_ids(self,selectLocator):
            """
            Gets all option element IDs for selected options in the specified select or multi-select element.
            
            'selectLocator' is an element locator identifying a drop-down menu
            """
            return self.get_string_array("getSelectedIds", [selectLocator,])
    
    
        def get_selected_id(self,selectLocator):
            """
            Gets option element ID for selected option in the specified select element.
            
            'selectLocator' is an element locator identifying a drop-down menu
            """
            return self.get_string("getSelectedId", [selectLocator,])
    
    
        def is_something_selected(self,selectLocator):
            """
            Determines whether some option in a drop-down menu is selected.
            
            'selectLocator' is an element locator identifying a drop-down menu
            """
            return self.get_boolean("isSomethingSelected", [selectLocator,])
    
    
        def get_select_options(self,selectLocator):
            """
            Gets all option labels in the specified select drop-down.
            
            'selectLocator' is an element locator identifying a drop-down menu
            """
            return self.get_string_array("getSelectOptions", [selectLocator,])
    
    
        def get_attribute(self,attributeLocator):
            """
            Gets the value of an element attribute. The value of the attribute may
            differ across browsers (this is the case for the "style" attribute, for
            example).
            
            'attributeLocator' is an element locator followed by an @ sign and then the name of the attribute, e.g. "foo@bar"
            """
            return self.get_string("getAttribute", [attributeLocator,])
    
    
        def is_text_present(self,pattern):
            """
            Verifies that the specified text pattern appears somewhere on the rendered page shown to the user.
            
            'pattern' is a pattern to match with the text of the page
            """
            return self.get_boolean("isTextPresent", [pattern,])
    
    
        def is_element_present(self,locator):
            """
            Verifies that the specified element is somewhere on the page.
            
            'locator' is an element locator
            """
            return self.get_boolean("isElementPresent", [locator,])
    
    
        def is_visible(self,locator):
            """
            Determines if the specified element is visible. An
            element can be rendered invisible by setting the CSS "visibility"
            property to "hidden", or the "display" property to "none", either for the
            element itself or one if its ancestors.  This method will fail if
            the element is not present.
            
            'locator' is an element locator
            """
            return self.get_boolean("isVisible", [locator,])
    
    
        def is_editable(self,locator):
            """
            Determines whether the specified input element is editable, ie hasn't been disabled.
            This method will fail if the specified element isn't an input element.
            
            'locator' is an element locator
            """
            return self.get_boolean("isEditable", [locator,])
    
    
        def get_all_buttons(self):
            """
            Returns the IDs of all buttons on the page.
            
            
            If a given button has no ID, it will appear as "" in this array.
            
            
            """
            return self.get_string_array("getAllButtons", [])
    
    
        def get_all_links(self):
            """
            Returns the IDs of all links on the page.
            
            
            If a given link has no ID, it will appear as "" in this array.
            
            
            """
            return self.get_string_array("getAllLinks", [])
    
    
        def get_all_fields(self):
            """
            Returns the IDs of all input fields on the page.
            
            
            If a given field has no ID, it will appear as "" in this array.
            
            
            """
            return self.get_string_array("getAllFields", [])
    
    
        def get_attribute_from_all_windows(self,attributeName):
            """
            Returns every instance of some attribute from all known windows.
            
            'attributeName' is name of an attribute on the windows
            """
            return self.get_string_array("getAttributeFromAllWindows", [attributeName,])
    
    
        def dragdrop(self,locator,movementsString):
            """
            deprecated - use dragAndDrop instead
            
            'locator' is an element locator
            'movementsString' is offset in pixels from the current location to which the element should be moved, e.g., "+70,-300"
            """
            self.do_command("dragdrop", [locator,movementsString,])
    
    
        def set_mouse_speed(self,pixels):
            """
            Configure the number of pixels between "mousemove" events during dragAndDrop commands (default=10).
            
            Setting this value to 0 means that we'll send a "mousemove" event to every single pixel
            in between the start location and the end location; that can be very slow, and may
            cause some browsers to force the JavaScript to timeout.
            
            If the mouse speed is greater than the distance between the two dragged objects, we'll
            just send one "mousemove" at the start location and then one final one at the end location.
            
            
            'pixels' is the number of pixels between "mousemove" events
            """
            self.do_command("setMouseSpeed", [pixels,])
    
    
        def get_mouse_speed(self):
            """
            Returns the number of pixels between "mousemove" events during dragAndDrop commands (default=10).
            
            """
            return self.get_number("getMouseSpeed", [])
    
    
        def drag_and_drop(self,locator,movementsString):
            """
            Drags an element a certain distance and then drops it
            
            'locator' is an element locator
            'movementsString' is offset in pixels from the current location to which the element should be moved, e.g., "+70,-300"
            """
            self.do_command("dragAndDrop", [locator,movementsString,])
    
    
        def drag_and_drop_to_object(self,locatorOfObjectToBeDragged,locatorOfDragDestinationObject):
            """
            Drags an element and drops it on another element
            
            'locatorOfObjectToBeDragged' is an element to be dragged
            'locatorOfDragDestinationObject' is an element whose location (i.e., whose center-most pixel) will be the point where locatorOfObjectToBeDragged  is dropped
            """
            self.do_command("dragAndDropToObject", [locatorOfObjectToBeDragged,locatorOfDragDestinationObject,])
    
    
        def window_focus(self):
            """
            Gives focus to the currently selected window
            
            """
            self.do_command("windowFocus", [])
    
    
        def window_maximize(self):
            """
            Resize currently selected window to take up the entire screen
            
            """
            self.do_command("windowMaximize", [])
    
    
        def get_all_window_ids(self):
            """
            Returns the IDs of all windows that the browser knows about.
            
            """
            return self.get_string_array("getAllWindowIds", [])
    
    
        def get_all_window_names(self):
            """
            Returns the names of all windows that the browser knows about.
            
            """
            return self.get_string_array("getAllWindowNames", [])
    
    
        def get_all_window_titles(self):
            """
            Returns the titles of all windows that the browser knows about.
            
            """
            return self.get_string_array("getAllWindowTitles", [])
    
    
        def get_html_source(self):
            """
            Returns the entire HTML source between the opening and
            closing "html" tags.
            
            """
            return self.get_string("getHtmlSource", [])
    
    
        def set_cursor_position(self,locator,position):
            """
            Moves the text cursor to the specified position in the given input element or textarea.
            This method will fail if the specified element isn't an input element or textarea.
            
            'locator' is an element locator pointing to an input element or textarea
            'position' is the numerical position of the cursor in the field; position should be 0 to move the position to the beginning of the field.  You can also set the cursor to -1 to move it to the end of the field.
            """
            self.do_command("setCursorPosition", [locator,position,])
    
    
        def get_element_index(self,locator):
            """
            Get the relative index of an element to its parent (starting from 0). The comment node and empty text node
            will be ignored.
            
            'locator' is an element locator pointing to an element
            """
            return self.get_number("getElementIndex", [locator,])
    
    
        def is_ordered(self,locator1,locator2):
            """
            Check if these two elements have same parent and are ordered siblings in the DOM. Two same elements will
            not be considered ordered.
            
            'locator1' is an element locator pointing to the first element
            'locator2' is an element locator pointing to the second element
            """
            return self.get_boolean("isOrdered", [locator1,locator2,])
    
    
        def get_element_position_left(self,locator):
            """
            Retrieves the horizontal position of an element
            
            'locator' is an element locator pointing to an element OR an element itself
            """
            return self.get_number("getElementPositionLeft", [locator,])
    
    
        def get_element_position_top(self,locator):
            """
            Retrieves the vertical position of an element
            
            'locator' is an element locator pointing to an element OR an element itself
            """
            return self.get_number("getElementPositionTop", [locator,])
    
    
        def get_element_width(self,locator):
            """
            Retrieves the width of an element
            
            'locator' is an element locator pointing to an element
            """
            return self.get_number("getElementWidth", [locator,])
    
    
        def get_element_height(self,locator):
            """
            Retrieves the height of an element
            
            'locator' is an element locator pointing to an element
            """
            return self.get_number("getElementHeight", [locator,])
    
    
        def get_cursor_position(self,locator):
            """
            Retrieves the text cursor position in the given input element or textarea; beware, this may not work perfectly on all browsers.
            
            
            Specifically, if the cursor/selection has been cleared by JavaScript, this command will tend to
            return the position of the last location of the cursor, even though the cursor is now gone from the page.  This is filed as SEL-243.
            
            This method will fail if the specified element isn't an input element or textarea, or there is no cursor in the element.
            
            'locator' is an element locator pointing to an input element or textarea
            """
            return self.get_number("getCursorPosition", [locator,])
    
    
        def get_expression(self,expression):
            """
            Returns the specified expression.
            
            
            This is useful because of JavaScript preprocessing.
            It is used to generate commands like assertExpression and waitForExpression.
            
            
            'expression' is the value to return
            """
            return self.get_string("getExpression", [expression,])
    
    
        def get_xpath_count(self,xpath):
            """
            Returns the number of nodes that match the specified xpath, eg. "//table" would give
            the number of tables.
            
            'xpath' is the xpath expression to evaluate. do NOT wrap this expression in a 'count()' function; we will do that for you.
            """
            return self.get_number("getXpathCount", [xpath,])
    
    
        def assign_id(self,locator,identifier):
            """
            Temporarily sets the "id" attribute of the specified element, so you can locate it in the future
            using its ID rather than a slow/complicated XPath.  This ID will disappear once the page is
            reloaded.
            
            'locator' is an element locator pointing to an element
            'identifier' is a string to be used as the ID of the specified element
            """
            self.do_command("assignId", [locator,identifier,])
    
    
        def allow_native_xpath(self,allow):
            """
            Specifies whether Selenium should use the native in-browser implementation
            of XPath (if any native version is available); if you pass "false" to
            this function, we will always use our pure-JavaScript xpath library.
            Using the pure-JS xpath library can improve the consistency of xpath
            element locators between different browser vendors, but the pure-JS
            version is much slower than the native implementations.
            
            'allow' is boolean, true means we'll prefer to use native XPath; false means we'll only use JS XPath
            """
            self.do_command("allowNativeXpath", [allow,])
    
    
        def ignore_attributes_without_value(self,ignore):
            """
            Specifies whether Selenium will ignore xpath attributes that have no
            value, i.e. are the empty string, when using the non-native xpath
            evaluation engine. You'd want to do this for performance reasons in IE.
            However, this could break certain xpaths, for example an xpath that looks
            for an attribute whose value is NOT the empty string.
            
            The hope is that such xpaths are relatively rare, but the user should
            have the option of using them. Note that this only influences xpath
            evaluation when using the ajaxslt engine (i.e. not "javascript-xpath").
            
            'ignore' is boolean, true means we'll ignore attributes without value                        at the expense of xpath "correctness"; false means                        we'll sacrifice speed for correctness.
            """
            self.do_command("ignoreAttributesWithoutValue", [ignore,])
    
    
        def wait_for_condition(self,script,timeout):
            """
            Runs the specified JavaScript snippet repeatedly until it evaluates to "true".
            The snippet may have multiple lines, but only the result of the last line
            will be considered.
            
            
            Note that, by default, the snippet will be run in the runner's test window, not in the window
            of your application.  To get the window of your application, you can use
            the JavaScript snippet ``selenium.browserbot.getCurrentWindow()``, and then
            run your JavaScript in there
            
            
            'script' is the JavaScript snippet to run
            'timeout' is a timeout in milliseconds, after which this command will return with an error
            """
            self.do_command("waitForCondition", [script,timeout,])
    
    
        def set_timeout(self,timeout):
            """
            Specifies the amount of time that Selenium will wait for actions to complete.
            
            
            Actions that require waiting include "open" and the "waitFor\*" actions.
            
            The default timeout is 30 seconds.
            
            'timeout' is a timeout in milliseconds, after which the action will return with an error
            """
            self.do_command("setTimeout", [timeout,])
    
    
        def wait_for_page_to_load(self,timeout):
            """
            Waits for a new page to load.
            
            
            You can use this command instead of the "AndWait" suffixes, "clickAndWait", "selectAndWait", "typeAndWait" etc.
            (which are only available in the JS API).
            
            Selenium constantly keeps track of new pages loading, and sets a "newPageLoaded"
            flag when it first notices a page load.  Running any other Selenium command after
            turns the flag to false.  Hence, if you want to wait for a page to load, you must
            wait immediately after a Selenium command that caused a page-load.
            
            
            'timeout' is a timeout in milliseconds, after which this command will return with an error
            """
            self.do_command("waitForPageToLoad", [timeout,])
    
    
        def wait_for_frame_to_load(self,frameAddress,timeout):
            """
            Waits for a new frame to load.
            
            
            Selenium constantly keeps track of new pages and frames loading, 
            and sets a "newPageLoaded" flag when it first notices a page load.
            
            
            See waitForPageToLoad for more information.
            
            'frameAddress' is FrameAddress from the server side
            'timeout' is a timeout in milliseconds, after which this command will return with an error
            """
            self.do_command("waitForFrameToLoad", [frameAddress,timeout,])
    
    
        def get_cookie(self):
            """
            Return all cookies of the current page under test.
            
            """
            return self.get_string("getCookie", [])
    
    
        def get_cookie_by_name(self,name):
            """
            Returns the value of the cookie with the specified name, or throws an error if the cookie is not present.
            
            'name' is the name of the cookie
            """
            return self.get_string("getCookieByName", [name,])
    
    
        def is_cookie_present(self,name):
            """
            Returns true if a cookie with the specified name is present, or false otherwise.
            
            'name' is the name of the cookie
            """
            return self.get_boolean("isCookiePresent", [name,])
    
    
        def create_cookie(self,nameValuePair,optionsString):
            """
            Create a new cookie whose path and domain are same with those of current page
            under test, unless you specified a path for this cookie explicitly.
            
            'nameValuePair' is name and value of the cookie in a format "name=value"
            'optionsString' is options for the cookie. Currently supported options include 'path', 'max_age' and 'domain'.      the optionsString's format is "path=/path/, max_age=60, domain=.foo.com". The order of options are irrelevant, the unit      of the value of 'max_age' is second.  Note that specifying a domain that isn't a subset of the current domain will      usually fail.
            """
            self.do_command("createCookie", [nameValuePair,optionsString,])
    
    
        def delete_cookie(self,name,optionsString):
            """
            Delete a named cookie with specified path and domain.  Be careful; to delete a cookie, you
            need to delete it using the exact same path and domain that were used to create the cookie.
            If the path is wrong, or the domain is wrong, the cookie simply won't be deleted.  Also
            note that specifying a domain that isn't a subset of the current domain will usually fail.
            
            Since there's no way to discover at runtime the original path and domain of a given cookie,
            we've added an option called 'recurse' to try all sub-domains of the current domain with
            all paths that are a subset of the current path.  Beware; this option can be slow.  In
            big-O notation, it operates in O(n\*m) time, where n is the number of dots in the domain
            name and m is the number of slashes in the path.
            
            'name' is the name of the cookie to be deleted
            'optionsString' is options for the cookie. Currently supported options include 'path', 'domain'      and 'recurse.' The optionsString's format is "path=/path/, domain=.foo.com, recurse=true".      The order of options are irrelevant. Note that specifying a domain that isn't a subset of      the current domain will usually fail.
            """
            self.do_command("deleteCookie", [name,optionsString,])
    
    
        def delete_all_visible_cookies(self):
            """
            Calls deleteCookie with recurse=true on all cookies visible to the current page.
            As noted on the documentation for deleteCookie, recurse=true can be much slower
            than simply deleting the cookies using a known domain/path.
            
            """
            self.do_command("deleteAllVisibleCookies", [])
    
    
        def set_browser_log_level(self,logLevel):
            """
            Sets the threshold for browser-side logging messages; log messages beneath this threshold will be discarded.
            Valid logLevel strings are: "debug", "info", "warn", "error" or "off".
            To see the browser logs, you need to
            either show the log window in GUI mode, or enable browser-side logging in Selenium RC.
            
            'logLevel' is one of the following: "debug", "info", "warn", "error" or "off"
            """
            self.do_command("setBrowserLogLevel", [logLevel,])
    
    
        def run_script(self,script):
            """
            Creates a new "script" tag in the body of the current test window, and 
            adds the specified text into the body of the command.  Scripts run in
            this way can often be debugged more easily than scripts executed using
            Selenium's "getEval" command.  Beware that JS exceptions thrown in these script
            tags aren't managed by Selenium, so you should probably wrap your script
            in try/catch blocks if there is any chance that the script will throw
            an exception.
            
            'script' is the JavaScript snippet to run
            """
            self.do_command("runScript", [script,])
    
    
        def add_location_strategy(self,strategyName,functionDefinition):
            """
            Defines a new function for Selenium to locate elements on the page.
            For example,
            if you define the strategy "foo", and someone runs click("foo=blah"), we'll
            run your function, passing you the string "blah", and click on the element 
            that your function
            returns, or throw an "Element not found" error if your function returns null.
            
            We'll pass three arguments to your function:
            
            *   locator: the string the user passed in
            *   inWindow: the currently selected window
            *   inDocument: the currently selected document
            
            
            The function must return null if the element can't be found.
            
            'strategyName' is the name of the strategy to define; this should use only   letters [a-zA-Z] with no spaces or other punctuation.
            'functionDefinition' is a string defining the body of a function in JavaScript.   For example: ``return inDocument.getElementById(locator);``
            """
            self.do_command("addLocationStrategy", [strategyName,functionDefinition,])
    
    
        def capture_entire_page_screenshot(self,filename,kwargs):
            """
            Saves the entire contents of the current window canvas to a PNG file.
            Contrast this with the captureScreenshot command, which captures the
            contents of the OS viewport (i.e. whatever is currently being displayed
            on the monitor), and is implemented in the RC only. Currently this only
            works in Firefox when running in chrome mode, and in IE non-HTA using
            the EXPERIMENTAL "Snapsie" utility. The Firefox implementation is mostly
            borrowed from the Screengrab! Firefox extension. Please see
            http://www.screengrab.org and http://snapsie.sourceforge.net/ for
            details.
            
            'filename' is the path to the file to persist the screenshot as. No                  filename extension will be appended by default.                  Directories will not be created if they do not exist,                    and an exception will be thrown, possibly by native                  code.
            'kwargs' is a kwargs string that modifies the way the screenshot                  is captured. Example: "background=#CCFFDD" .                  Currently valid options:                  
            *    background
                the background CSS for the HTML document. This                     may be useful to set for capturing screenshots of                     less-than-ideal layouts, for example where absolute                     positioning causes the calculation of the canvas                     dimension to fail and a black background is exposed                     (possibly obscuring black text).
            
            
            """
            self.do_command("captureEntirePageScreenshot", [filename,kwargs,])
    
    
        def rollup(self,rollupName,kwargs):
            """
            Executes a command rollup, which is a series of commands with a unique
            name, and optionally arguments that control the generation of the set of
            commands. If any one of the rolled-up commands fails, the rollup is
            considered to have failed. Rollups may also contain nested rollups.
            
            'rollupName' is the name of the rollup command
            'kwargs' is keyword arguments string that influences how the                    rollup expands into commands
            """
            self.do_command("rollup", [rollupName,kwargs,])
    
    
        def add_script(self,scriptContent,scriptTagId):
            """
            Loads script content into a new script tag in the Selenium document. This
            differs from the runScript command in that runScript adds the script tag
            to the document of the AUT, not the Selenium document. The following
            entities in the script content are replaced by the characters they
            represent:
            
                <
                >
                &
            
            The corresponding remove command is removeScript.
            
            'scriptContent' is the Javascript content of the script to add
            'scriptTagId' is (optional) the id of the new script tag. If                       specified, and an element with this id already                       exists, this operation will fail.
            """
            self.do_command("addScript", [scriptContent,scriptTagId,])
    
    
        def remove_script(self,scriptTagId):
            """
            Removes a script tag from the Selenium document identified by the given
            id. Does nothing if the referenced tag doesn't exist.
            
            'scriptTagId' is the id of the script element to remove.
            """
            self.do_command("removeScript", [scriptTagId,])
    
    
        def use_xpath_library(self,libraryName):
            """
            Allows choice of one of the available libraries.
            
            'libraryName' is name of the desired library Only the following three can be chosen: 
            *   "ajaxslt" - Google's library
            *   "javascript-xpath" - Cybozu Labs' faster library
            *   "default" - The default library.  Currently the default library is "ajaxslt" .
            
             If libraryName isn't one of these three, then  no change will be made.
            """
            self.do_command("useXpathLibrary", [libraryName,])
    
    
        def set_context(self,context):
            """
            Writes a message to the status bar and adds a note to the browser-side
            log.
            
            'context' is the message to be sent to the browser
            """
            self.do_command("setContext", [context,])
    
    
        def attach_file(self,fieldLocator,fileLocator):
            """
            Sets a file input (upload) field to the file listed in fileLocator
            
            'fieldLocator' is an element locator
            'fileLocator' is a URL pointing to the specified file. Before the file  can be set in the input field (fieldLocator), Selenium RC may need to transfer the file    to the local machine before attaching the file in a web page form. This is common in selenium  grid configurations where the RC server driving the browser is not the same  machine that started the test.   Supported Browsers: Firefox ("\*chrome") only.
            """
            self.do_command("attachFile", [fieldLocator,fileLocator,])
    
    
        def capture_screenshot(self,filename):
            """
            Captures a PNG screenshot to the specified file.
            
            'filename' is the absolute path to the file to be written, e.g. "c:\blah\screenshot.png"
            """
            self.do_command("captureScreenshot", [filename,])
    
    
        def capture_screenshot_to_string(self):
            """
            Capture a PNG screenshot.  It then returns the file as a base 64 encoded string.
            
            """
            return self.get_string("captureScreenshotToString", [])
    
    
        def captureNetworkTraffic(self, type):
            """
            Returns the network traffic seen by the browser, including headers, AJAX requests, status codes, and timings. When this function is called, the traffic log is cleared, so the returned content is only the traffic seen since the last call.
    
            'type' is The type of data to return the network traffic as. Valid values are: json, xml, or plain.
            """
            return self.get_string("captureNetworkTraffic", [type,])
    
        def addCustomRequestHeader(self, key, value):
            """
            Tells the Selenium server to add the specificed key and value as a custom outgoing request header. This only works if the browser is configured to use the built in Selenium proxy.
    
            'key' the header name.
            'value' the header value.
            """
            return self.do_command("addCustomRequestHeader", [key,value,])
    
        def capture_entire_page_screenshot_to_string(self,kwargs):
            """
            Downloads a screenshot of the browser current window canvas to a 
            based 64 encoded PNG file. The \ *entire* windows canvas is captured,
            including parts rendered outside of the current view port.
            
            Currently this only works in Mozilla and when running in chrome mode.
            
            'kwargs' is A kwargs string that modifies the way the screenshot is captured. Example: "background=#CCFFDD". This may be useful to set for capturing screenshots of less-than-ideal layouts, for example where absolute positioning causes the calculation of the canvas dimension to fail and a black background is exposed  (possibly obscuring black text).
            """
            return self.get_string("captureEntirePageScreenshotToString", [kwargs,])
    
    
        def shut_down_selenium_server(self):
            """
            Kills the running Selenium Server and all browser sessions.  After you run this command, you will no longer be able to send
            commands to the server; you can't remotely start the server once it has been stopped.  Normally
            you should prefer to run the "stop" command, which terminates the current browser session, rather than 
            shutting down the entire server.
            
            """
            self.do_command("shutDownSeleniumServer", [])
    
    
        def retrieve_last_remote_control_logs(self):
            """
            Retrieve the last messages logged on a specific remote control. Useful for error reports, especially
            when running multiple remote controls in a distributed environment. The maximum number of log messages
            that can be retrieve is configured on remote control startup.
            
            """
            return self.get_string("retrieveLastRemoteControlLogs", [])
    
    
        def key_down_native(self,keycode):
            """
            Simulates a user pressing a key (without releasing it yet) by sending a native operating system keystroke.
            This function uses the java.awt.Robot class to send a keystroke; this more accurately simulates typing
            a key on the keyboard.  It does not honor settings from the shiftKeyDown, controlKeyDown, altKeyDown and
            metaKeyDown commands, and does not target any particular HTML element.  To send a keystroke to a particular
            element, focus on the element first before running this command.
            
            'keycode' is an integer keycode number corresponding to a java.awt.event.KeyEvent; note that Java keycodes are NOT the same thing as JavaScript keycodes!
            """
            self.do_command("keyDownNative", [keycode,])
    
    
        def key_up_native(self,keycode):
            """
            Simulates a user releasing a key by sending a native operating system keystroke.
            This function uses the java.awt.Robot class to send a keystroke; this more accurately simulates typing
            a key on the keyboard.  It does not honor settings from the shiftKeyDown, controlKeyDown, altKeyDown and
            metaKeyDown commands, and does not target any particular HTML element.  To send a keystroke to a particular
            element, focus on the element first before running this command.
            
            'keycode' is an integer keycode number corresponding to a java.awt.event.KeyEvent; note that Java keycodes are NOT the same thing as JavaScript keycodes!
            """
            self.do_command("keyUpNative", [keycode,])
    
    
        def key_press_native(self,keycode):
            """
            Simulates a user pressing and releasing a key by sending a native operating system keystroke.
            This function uses the java.awt.Robot class to send a keystroke; this more accurately simulates typing
            a key on the keyboard.  It does not honor settings from the shiftKeyDown, controlKeyDown, altKeyDown and
            metaKeyDown commands, and does not target any particular HTML element.  To send a keystroke to a particular
            element, focus on the element first before running this command.
            
            'keycode' is an integer keycode number corresponding to a java.awt.event.KeyEvent; note that Java keycodes are NOT the same thing as JavaScript keycodes!
            """
            self.do_command("keyPressNative", [keycode,])
    
    sagenb-1.0.1/sagenb/testing/stress.py000066400000000000000000000107721311436262400175720ustar00rootroot00000000000000# -*- coding: utf-8 -*
    import re
    
    from six.moves.urllib.request import urlopen
    
    from sage.misc.sage_timeit import sage_timeit
    from sagenb.misc.misc import walltime, cputime
    from signal import alarm
    
    def cancel_alarm():
        alarm(0)
    
    
    TIMEOUT = 'timeout'
    
    
    class PubStressTest:
        """
        Stress test viewing things that a non-authenticated viewer can
        look at, namely the login screen, list of published worksheets,
        and each individual published worksheet.
        """
        def __init__(self, url, verbose=True,
                     timeit_number=1, timeit_repeat=1,
                     url_timeout=10):
            """
            INPUT:
    
                - ``url`` -- url of the Sage notebook server
    
                - ``verbose`` -- bool; whether to print info about what is
                  being tested as it is tested
    
                - ``timeit_number`` -- integer (default: 1)
    
                - ``timeit_repeat`` -- integer (default: 1)
                
                
            """
            self._url = url
            self._verbose = verbose
            self._timeit_number = timeit_number
            self._timeit_repeat = timeit_repeat
            self._url_timeout = url_timeout
    
        def url_login_screen(self):
            """
            Return the url of the login screen for the notebook server.
            """
            return self._url
    
        def url_pub(self):
            """
            Return the url of the list list of published worksheets.
            """
            return self._url + '/pub'
    
        def _timeit(self, code):
            """
            Time evaluation of the given code, timing out after
            self._url_timeout seconds, and using the default number and
            repeat values as options to timeit.
            """
            try:
                alarm(self._url_timeout)
                T = sage_timeit(code, globals(), number=self._timeit_number,
                                   repeat=self._timeit_repeat)
            except KeyboardInterrupt:
                return TIMEOUT
            finally:
                cancel_alarm()
            return T
    
        def _geturlcode(self, url):
            """
            Return code that when evaluated returns the data at the given
            url as a string.
            """
            return "urlopen('%s').read()" % url
    
        def _geturl(self, url, use_alarm=True):
            """
            Download the given url.  If use_alarm is True (the default)
            timeout and return the TIMEOUT object if the default download
            timeout is exceeded.
            """
            if not use_alarm:
                return urlopen(url).read()
            try:
                alarm(self._url_timeout)
                return urlopen(url).read()
            except KeyboardInterrupt:
                return TIMEOUT
            finally:
                cancel_alarm()
            
        def test_login_screen(self):
            """
            Download the main login screen for the Sage notebook server.
            """
            if self._verbose:
                print("testing login screen...")
            return self._timeit(self._geturlcode(self.url_login_screen()))
    
        def test_pub(self):
            """
            Download the list of published worksheets.
            """
            if self._verbose:
                print("testing list of published worksheets...")
            return self._timeit(self._geturlcode(self.url_pub()))
    
        def get_urls_of_published_worksheets(self):
            """
            Get a list of the urls of all published worksheets.
            """
            pub = self._geturl(self.url_pub())
            if pub == TIMEOUT:
                print(TIMEOUT)
                return []
            return [self._url + X.strip('"').strip("'") for X in
                    re.findall('"/home/pub/[0-9]*"', pub)]
    
        def test_allpub(self):
            """
            View every single one of the published worksheets on the
            Sage notebook server.
            """
            if self._verbose:
                print("testing download of all published worksheets...")
            tm = walltime()
            pub = self.get_urls_of_published_worksheets()
            try:
                alarm(self._url_timeout)
                for i, X in enumerate(pub):
                    t0 = walltime()
                    self._geturl(X, use_alarm=False)
                    if self._verbose:
                        print("Got %s [%s/%s] %.2f seconds" % (X,i+1,len(pub), walltime(t0)))
                return walltime(tm)
            except KeyboardInterrupt:
                return TIMEOUT
            finally:
                cancel_alarm()
    
        def test(self):
            """
            Run all tests and return the rest as a dictionary of pairs
            {'test_name':output}.
            """
            v = {}
            for method in dir(self):
                if method.startswith('test_'):
                    v[method] = getattr(self, method)()
            return v
    sagenb-1.0.1/sagenb/testing/tests/000077500000000000000000000000001311436262400170305ustar00rootroot00000000000000sagenb-1.0.1/sagenb/testing/tests/__init__.py000066400000000000000000000001301311436262400211330ustar00rootroot00000000000000# -*- coding: utf-8 -*
    from . import test_accounts, test_worksheet, test_worksheet_list
    sagenb-1.0.1/sagenb/testing/tests/test_accounts.py000066400000000000000000000066601311436262400222700ustar00rootroot00000000000000# -*- coding: utf-8 -*-
    """
    Tests for SageNB Accounts
    
    AUTHORS:
    
    - Mike Hansen (?) -- initial revision
    
    - Tim Dumol (Oct. 28, 2009) -- made the tests work again. Separated
      this out.
    """
    import unittest
    
    from sagenb.testing.notebook_test_case import NotebookTestCase
    
    class TestAccounts(NotebookTestCase):
        def _sage_startup_command(self):
            self.nb_options['accounts'] = True
            return super(TestAccounts, self)._sage_startup_command()
    
        def setUp(self):
            super(TestAccounts, self).setUp()
            self.register_user('mike')
            self.register_user('chris')
    
        def test_3960(self):
            """
            Tests to make sure that Trac ticket #3960 is actually fixed.
            """
            sel = self.selenium
    
            self.login_as('mike')
            self.create_new_worksheet()
            out = self.eval_cell(1, '2+2')
            self.publish_worksheet()
            self.logout()
    
            self.login_as('chris')
            self.goto_published_worksheet(0)
    
            sel.click("link=Edit a copy.")
            # Simply waiting for the page to load fails with slow computers.
    #        self.wait_in_window('return this.location == "%s/home/chris/0/"' %
    #                            self.sel_options['browser_url'], 30000)
            sel.wait_for_page_to_load(30000)
    
            self.wait_in_window('return this.$.trim(this.$("#cell_output_nowrap_1").text()) == 4', 30000)
    
            self.assertEqual(sel.get_location(), '%s/home/chris/0/' %
                             self.sel_options['browser_url'])
            self.assertEqual(self.get_cell_output(1), '4')
            self.assert_(sel.is_text_present('by chris'),
                         'chris does not own the worksheet')
    
        def test_4088(self):
            """
            Check to see that the 'Welcome to Sage!' message is not
            visible on the published worksheets screen when there are no
            worksheets.
            """
            sel = self.selenium
    
            self.login_as('mike')
            sel.click("link=Published")
            sel.wait_for_page_to_load("30000")
    
            self.assert_(not sel.is_text_present('Welcome to Sage!'),
                         'welcome message is still present')
    
        def test_4050(self):
            """
            Tests to make sure that Trac ticket #4050 is actually fixed.
            """
            sel = self.selenium
    
            self.login_as('mike')
            self.create_new_worksheet()
            out = self.eval_cell(1, '2+2')
            self.rename_worksheet("Shared Worksheet")
            self.share_worksheet("chris")
            self.save_and_quit()
            self.logout()
    
            self.login_as('chris')
            sel.click("name-mike-0")
            sel.wait_for_page_to_load("30000")
            sel.select("//option[@value='copy_worksheet();']/parent::select",
                       "value=copy_worksheet();")
            sel.wait_for_page_to_load("30000")
            self.save_and_quit()
    
            sel.click("name-chris-1")
            sel.wait_for_page_to_load("30000")
    
            self.assertEqual(sel.get_location(), '%s/home/chris/1/' %
                             self.sel_options['browser_url'])
            self.assertEqual(sel.get_title(), u'Copy of Shared Worksheet -- Sage')
            self.assert_(sel.is_text_present('by chris'),
                         'chris does not own the worksheet')
            self.assertEqual(self.get_cell_output(1), '4')
    
            self.save_and_quit()
    
        def tearDown(self):
            self.logout()
            super(TestAccounts, self).tearDown()
    
    
    suite = unittest.TestLoader().loadTestsFromTestCase(TestAccounts)
    
    if __name__ == '__main__':
        unittest.main()
    sagenb-1.0.1/sagenb/testing/tests/test_worksheet.py000066400000000000000000000222301311436262400224530ustar00rootroot00000000000000# -*- coding: utf-8 -*-
    """
    Tests for SageNB Worksheets
    
    AUTHORS:
    
    - Mike Hansen (?) -- initial revision
    
    - Tim Dumol (Oct. 28, 2009) -- made the tests work again. Separated
      this out. Added some more tests.
    """
    
    import unittest, re
    
    from sagenb.testing.notebook_test_case import NotebookTestCase
    
    class TestWorksheet(NotebookTestCase):
        def setUp(self):
            super(TestWorksheet, self).setUp()
            self.login_as('admin', 'asdfasdf')
            self.create_new_worksheet()
    
        def test_7433(self):
            """
            Tests that #7433 notebook: changing title of worksheet changes
            title of corresponding published worksheet has been fixed.
            """
            sel = self.selenium
            self.rename_worksheet(u'To be publishedЋĉƸḾ﹢Յй')
            self.publish_worksheet()
            self.save_and_quit()
    
            sel.click('link=Published')
            sel.wait_for_page_to_load(30000)
            self.open_worksheet_with_name(u'To be publishedЋĉƸḾ﹢Յй')
            self.assert_(sel.is_element_present(u'//h1[contains(@class, "title") and contains(text(), "To be publishedЋĉƸḾ﹢Յй")]'))
    
            sel.open('/home/admin')
            sel.wait_for_page_to_load(30000)
            self.open_worksheet_with_name(u'To be publishedЋĉƸḾ﹢Յй')
            self.rename_worksheet('This has been published')
            self.save_and_quit()
    
            sel.click('link=Published')
            sel.wait_for_page_to_load(30000)
            self.open_worksheet_with_name('To be published')
            self.assert_(sel.is_element_present('//h1[contains(@class, "title") and contains(text(), "To be published")]'))
    
            sel.open('/home/admin')
        
        def test_7434(self):
            """
            Tests that #7434 (notebook: new modal jquery dialog boxes are covered
            by jmol 3d graphics) has been fixed.
            """
            sel = self.selenium
            self.eval_cell(1, "sphere()")
            java_applet_selector = 'object[type="application/x-java-applet"]'
            self.wait_in_window("return this.$('%s').length > 0"
                % java_applet_selector, 30000)
            sel.click("worksheet_title")
            self.wait_in_window("""
                var obj = this.$('%s');
                var offset = obj.offset();
                return offset.left + obj.width() < 0;""" % java_applet_selector,
                30000)
            sel.click("css=.ui-widget-overlay")
            self.wait_in_window("""
                var obj = this.$('%s');
                var offset = obj.offset();
                return offset.left > 0;""" % java_applet_selector,
                30000)
            
    
        def test_edit(self):
            sel = self.selenium
            sel.click('link=Edit')
            sel.wait_for_page_to_load("30000")
    
            sel.type('//textarea[@id="cell_intext"]',
                     u'''
    {{{id=1|
    print(5 + 5)
    print(u'ЋĉƸḾ﹢Յй')
    ///
    15
    ЋĉƸḾ﹢Յй
    }}}
    
    {{{id=2|
    print(13)
    ///
    }}}
    ''')
            sel.click('id=button_save')
            sel.wait_for_page_to_load(30000)
    
            self.assert_(sel.is_element_present(u'//textarea[@id="cell_input_1" and '
                                                u'contains(text(),"print(5 + 5)") and '
                                                u'contains(text(), "ЋĉƸḾ﹢Յй")]'))
            self.assert_(sel.is_element_present('//textarea[@id="cell_input_2" and contains(text(),"print(13)")]'))
    
            self.assertEqual(self.get_cell_output(1), u'15\nЋĉƸḾ﹢Յй')
    
        def test_7341(self):
            sel = self.selenium
            sel.type('cell_input_1', 'fo')
            self.introspect(1)
    
            sel.wait_for_condition('selenium.browserbot.getCurrentWindow().$("div.introspection ul").length > 0', 10000)
    
            self.assert_(sel.is_element_present('//a[text()="forall"]'))
            self.assert_(sel.is_element_present('//a[text()="forget"]'))
            self.assert_(sel.is_element_present('//a[text()="format"]'))
            self.assert_(sel.is_element_present('//a[text()="four_squares"]'))
            self.assert_(sel.is_element_present('//a[text()="fortran"]'))
    
        def test_3957(self):
            """
            Check to make sure that Trac #3957 works.
            """
            sel = self.selenium
            out = self.eval_cell(1, "plot(x^2, x)")
    
            self.assertTrue(u'For testing purposes")
    
            # Browser contortions.  TODO: Use regular expressions?
            try:
                self.assertEqual(out.lower(), """

    for testing purposes

    """) except AssertionError: self.assertEqual(out.lower(), """

    for testing purposes

    """) out = self.eval_cell(2, "var('a b c d')") self.assertEqual(out, '(a, b, c, d)') out = self.eval_cell(3, "expr1 = a+b - c + 2*d\nexpr2 = d*c-a*b") self.assertEqual(out, '') out = self.eval_cell(4, "expr1") self.assertEqual(out, u'a + b - c + 2*d') out = self.eval_cell(5, "expr2") self.assertEqual(out, u'-a*b + c*d') sel.select("id=action-menu", "label=Action...") sel.click("//option[@value='evaluate_all();']") def tearDown(self): self.logout() super(TestWorksheet, self).tearDown() suite = unittest.TestLoader().loadTestsFromTestCase(TestWorksheet) if __name__ == '__main__': unittest.main() sagenb-1.0.1/sagenb/testing/tests/test_worksheet_list.py000066400000000000000000000107651311436262400235200ustar00rootroot00000000000000# -*- coding: utf-8 -*- """ Tests to be run on the worksheet list. AUTHORS: - Tim Dumol (Oct. 28, 2009) -- inital version. """ import unittest from sagenb.testing.notebook_test_case import NotebookTestCase class TestWorksheetList(NotebookTestCase): def setUp(self): super(TestWorksheetList, self).setUp() self.login_as('admin', 'asdfasdf') def test_opening_worksheet(self): """ Makes sure that opening a worksheet works. """ sel = self.selenium self.create_new_worksheet('New worksheet') self.save_and_quit() sel.click("//a[@class='worksheetname']") sel.wait_for_page_to_load("30000") def test_creating_worksheet(self): """ Tests worksheet creation. """ sel = self.selenium self.create_new_worksheet(u'Worksheet Creation - ΫäĻƾṀБ') # Verify that the page has all the requisite elements. elements = ('link=Home', 'link=Help', 'link=Worksheet', 'link=Sign out', 'link=Toggle', 'link=Settings', 'link=Report a Problem', 'link=Log', 'link=Published', '//a[@id="worksheet_title"]', '//button[@name="button_save"]') for element in elements: self.assert_(sel.is_element_present(element)) def _search(self, phrase): """ Searches for a phrase. """ sel = self.selenium self.wait_in_window('return this.$("#search-worksheets").length > 0;', 30000) sel.type('id=search-worksheets', phrase) sel.click('id=search-worksheets-button') # TODO: Fix for l18n sel.wait_for_page_to_load("30000") def test_searching_for_worksheets(self): """ Tests search function. """ sel = self.selenium worksheet_names = [ u'Did you just say ЋĉƸḾ﹢Յй?', u'My ЋĉƸḾ﹢Յй search phrase', 'Not a search target' ] for name in worksheet_names: self.create_new_worksheet(name) self.publish_worksheet() self.save_and_quit() pages = ('/home/admin/', '/pub') for page in pages: sel.open(page) self._search(u'ЋĉƸḾ﹢Յй') self.assert_(sel.is_element_present(u'//a[@class="worksheetname" and contains(text(), "My ЋĉƸḾ﹢Յй search phrase")]'), 'Search phrase not found on %s' % page) self.failIf(sel.is_element_present('//a[@class="worksheetname" and contains(text(), "Not a search target")]'), 'Non-matching search results found on %s' % page) def test_7428(self): """ #7428: Newly/Re-published worksheets should be at the top of the "Published Worksheets" list and their "Last Edited" fields should contain the username, not 'pub' (assuming it's not shared). """ sel = self.selenium ws_titles = ['apple', 'orange'] def check_pub(title, prefix='Newly'): self.goto_published_worksheets() self.assertEqual(sel.get_text('css=td.worksheet_link'), title, '%s-published worksheet %s not listed first' % (prefix, title)) lastedit = sel.get_text('css=.lastedit') self.assert_(self.username in lastedit, '%s-published worksheet has wrong last edited field %s' % (prefix, lastedit)) for w in ws_titles: self.create_new_worksheet(w) self.publish_worksheet() self.save_and_quit() check_pub(w) self.open_worksheet_with_title(ws_titles[0]) self.republish_worksheet() self.save_and_quit() check_pub(ws_titles[0], prefix='Re') def test_7444(self): """ #7444: Searching published worksheets after publishing a worksheet for the first time should not raise an error. """ sel = self.selenium self.create_new_worksheet('banana') self.publish_worksheet() self.save_and_quit() self.goto_published_worksheets() self._search('anything') self.failIf(sel.is_text_present('Internal Server Error'), 'Published worksheet search caused a server error') def tearDown(self): self.logout() super(TestWorksheetList, self).tearDown() suite = unittest.TestLoader().loadTestsFromTestCase(TestWorksheetList) if __name__ == '__main__': unittest.main() sagenb-1.0.1/sagenb/todo.txt000066400000000000000000000505361311436262400157300ustar00rootroot00000000000000TODO: See http://wiki.sagemath.org/SageTasks for a related list. [ ] Fix this: sage: pwd --> '/some/random/directory' sage: notebook() # then let the notebook start up, then hit ctrl-c sage: pwd --> '/Users/palmieri/.sage' [ ] admin should *NOT* see all users worksheets. This is not good, e.g., when there are 50,000 worksheets! [ ] Clicking publish should update the "last changed" time. E.g., take an old worksheet and publish it -- should always make it new. [ ] change number word wrap columns in notebook settings has no immediate impact, though it does after restarting the server. [ ] implement base_url [ ] make communication between twist.py and notebook_lib.js use JSON instead of encode_list and response_text.split. [ ] Get peter.jipsen's "canvas3d_lib.js + Pre3d does shaded surfaces" into Sage [ ] codenode's engine/interpreter.py has a function with this comment: """input_string could contain multiple lines, multiple commands, or multiple multiline commands. This method builds a compiled command line by line until a complete command has been compiled. Once it has a complete command, it execs it in the username space and the output is stored in the output trap. There may be more than one command; the number of complete commands is counted (Based off of ipython1.core.shell.InteractiveShell._runlines)""" This approach means that in codenode we would have {{{ a = 5; b = 7 a+b a-b print a*b /// 12 -2 35 }}} which is more natural, since it mimics the command line. We should change Sage so it does the same. I think this would simply involving changing the interfaces/* stuff a little. This is probably easy, and is now high priority since it is something that has bugged me for a long time. [ ] idea from codenode: in their revisions log they label each revision with two columns, one being the last changed input in that worksheet (meant to jar ones memory), and second the total number of cells. [ ] "shift-enter to save tinymce cell" on safari goes "beep", which is annoying [ ] make it possible to set the default font in tinymce [ ] The startup of the notebook involves reading all the directories and creating worksheets. This takes anywhere from 5 minutes to an *hour* with sagenb.org. So this *must* be fixed to be massively faster. This is a top optimization priority. [ ] download just the text version of the worksheet [ ] "untitled renaming". Make it an option in the user confs, which is on by default, by you can turn it off. [ ] get coverage to 100%. [ ] we can make it so that if worksheet.html file changes on disk but not currently open, then when reopen it uses the new version from disk. More precisely, make it so "save and quit" deletes body of worksheet, so if user opens that worksheet again it'll grab the content from disk. [ ] page through list of worksheets (don't show hundreds at once) [ ] do something about this in worksheet.py def autosave(self, username): return [ ] add info about when user last logged in to user.py. [ ] way to send all registered users an email [ ] instructions about running a daemon sage server with conf scripts: http://groups.google.com/group/sage-support/browse_thread/thread/b0d15b82eea3d652 [ ] "data" link appears in reference implementation in output of every cell [ ] filesize limit -- option so that any computation that produces a file that exceeds a certain size would get deleted and replaced by a message. This would limit (though not prevent) damages. [ ] Jonathan Gutow -- redo how jmol works [ ] maybe get rid of list of 'Sage Users' when publishing worksheets -- that's not appropriate given how sage has grown. [ ] notebook(default_mode="python") way to make the notebook default to use python instead of sage. [ ] fulltext -- when output long, make it all available with a link even before computation finishes, and definitely if it is interrupted! [ ] write an overview of how the sage notebook works: http://wiki.sagemath.org/SageNotebook [ ] switch from twisted.web2 to twisted.web. Alex Clemesha says "Pretty easily actually... the Resource object is pretty similar, the main difference is that the Web2 Resource object has the "locateChild" method, where as the Web Resource has "getChild" - and even those are pretty similar. Also, there's some subtle differences in the way you doing "rendering"... i.e. with Web2 you subclass Resource/PostableResource and then you use the "render" method, where are with Web you just subclass Resource and implemented either "render_GET" or "render_POST". Probably just looking through the examples here: http://jcalderone.livejournal.com/tag/sixty+seconds would be good enough to do the switch." [ ] move is_valid_username (etc.) out of twist.py, which is definitely *not* where it belongs [ ] ldap support (see, eg., http://math.univ-lyon1.fr/~tdumont/sage) but make sure to first abstract away authentication first so it is much CLEARER. [ ] find a way to provide same info as data directory but without making it super-permissive. Maybe I can make an api for getting files from a data location or something... [ ] control-c doesn't quite work for reference implementation quitting notebook server [ ] make it so uploading a worksheet does not lock the server like it does now. [ ] secure mode outside of sage -- fix it to work with openssl, etc. [ ] more stress testing, etc., using mechanize: http://wwwsearch.sourceforge.net/mechanize/ [ ] have a worksheet export screen and the option to save just certain parts (e.e., images, DATA, etc.) with checkboxes. [ ] change api for notebook command; in particular enable capability to have different sage command on remote machine [ ] worksheet processes using named pipes [ ] code to benchmark notebook externally [ ] implement %cython mode outside sage (and as a full mode?) [ ] worksheet processes using server on remote machine [ ] worksheet processes using fork [ ] worksheet process using multiprocessing [ ] genuine infinite undo implemented not using stupid snapshots but a revision log [ ] @interact: make it so docstring of function is somehow nicely typeset and accessible [ ] @interact's that can be included with sage [ ] "browse your computer" field of upload is not editable. fix that. [ ] improve tracebacks of % modes, e.g., %python then 1/0 is ugly. [ ] and small hint about google accounts: in gmail at the bottom is a "last account activity" line and if you click on details, you can see what has happened recently. login IPs, type and time. you can also invalidate all other sessions on other PCs where cookies are stored. [ ] somehow connect http://qwebirc.org with Sage? [ ] statistics of notebooks, e.g., how many per user, names of all users, how many users? [ ] a way to put a code block between two text blocks that lie one right after the other. [ ] component architecture (??): see Brickenstein sage-devel email that mentions http://python-rum.org/browser/rum/component.py [ ] use memory mapped files for worksheet processes?? http://docs.python.org/library/mmap.html ============ DONE: [x] preparser [x] make sure all "/" is replaced by os.path.join, so will work on windows eventually. [x] worksheet_process.py -- make it so graphics work, i.e., files created [x] jsmath [x] static documentation [x] jmol [x] tinymce [x] @interact -- need to properly preparse and base64 encode maybe? [x] live documentation [x] introspection [x] fill in not implemented stuff [x] %cython [x] control-c to stop notebook [x] write pexpect based worksheet process system using the filesystem as before. [x] reference should have restart reset state [x] one user running another user's sage install on OS X -- Abort! [x] implement ulimit/ssh/etc options like before [x] good error message on crash of the sage process... [x] max_walltime -- doesnt' work [x] push my hg repo somewhere [x] start public demo server using ssh [x] simple notebook stress test [x] trim list of alternative notebooks sessions when not run as part of sage. [x] secure mode with sage present -- fix it [x] uploading: "rbeezer -- williamstein: I tried one URL, one on disk, both came back "internal server error" - I can try a few more. Do you want bugs in Trac or Google group" [x] open(DATA+'/foo.txt','w') DATA directory permissions issue -- the whole design of the "DATA" directory needs to be redone, since I vastly improved the security model of how the two-user notebook works (now all computations are done by a user that does *not* have permission to view or change *anything* in the server's sage_notebook directory -- everything happens in /tmp -- this is a VAST improvement, but means that DATA directory just doesn't work anymore as implemented). [x] "Upload or create data file attached to the worksheet '%s'" [x] pure python mode now broken with expect implementation -- every input crashes worksheet [x] notebook(...) command should *not* remember options from last run. that's just obnoxious. [x] Downloading a file from data doesn't work [x] data dropdown doesn't list uploaded files [x] publishing + automically republish crashes with internal server error (harald schilly reported) [x] "edit a copy" doesn't work [for published] [x] "download" from published doesn't work right. [x] (invalid) permissions of .sagenb directory: drwxr-xr-x 5 wstein staff 170 Sep 26 15:28 .sagenb this is a problem unless we just switch back to using .sage directory in official release (which we will do!) [x] notebook server should take ownership of all files it gets back [x] Uploading file (button at bottom of page is misleading). [x] (invalid) make patch to remove notebook from sage itself. We *can't* do this, because if we do, then old notebooks can't be migrated. Ouch. [x] make sure that the old notebook directory "just works" with the new notebook: problem -- old notebooks unpickle into the old notebook code. [x] discard and quit crashes weirdly with *this* worksheet: http://buzzard.ups.edu/private/Sample.sws (this was fixed by getting rid of the conf.sobj useless crap, which according to hg I = William Stein wrote! ouch) [x] expect-based worksheet process without ssh and with ulimit -- see todo in interfaces/expect.py [x] make it so usernames can be shorter/more arbitrary (requested by tom boothby, and he has a point) [x] make an official spkg for inclusion in sage-4.1.2. [x] show(plot(sin)); show(plot(cos)) only shows one plot [x] reimplement sphinx introspection. * confdir in cell.py won't work without a trivial Sphinx directory, when not in Sage. make it. [x] sphinx: crazy insane whitespace -- see screenshot here: http://sage.math.washington.edu/home/wstein/patches/whitespace.png got from E = EllipticCurve([0,-39409298,0,5554231502,0]); E.Lambda( [x] "Sign into the Sage Notebook v" <-- missing version number [x] version not listed in upper left corner of worksheet either [x] sphinx: get math macros working on sphinx mode, e.g., if you do "ZZ?" you see "ZZ" in the docstring, but should get a bold ZZ. [x] Copy your "a random test worksheet full of stuff". Go to "Data|foo.txt"; Change the text; Click "Save Changes" An error page appears. [x] sphinx: factorial?? hangs [x] bug search_doc(...) reported by victor miller [x] migration didn't update user's conf field. [X] loading of old worksheets -- need to deal with {{{ -->
    {{{ change.
    
    [x] move password over to new notebook.
    
    [x] new filestructure
    
    
    [x] sagenb.org itself currently has about 50,000 worksheets.  Loading them all on
    startup -- even there conf info, isn't a good idea.  At 10ms each, which is what it
    would take given using YAML, that would be 100/second or 500 seconds to load!
    And that's just the metadata.  Another option would be to "load" a very lightweight
    version of the worksheets, with no metadata exception owner and id_number.
    Then the first time any additional metadata is needed about a specific worksheet,
    load it from disk. E.g., for our 50000 on sagenb.org, it's very rare any particular
    one is needed. ...   I'm just using pickle, which works fine for 50000 worksheets...
    
    [x] rewrite this in notebook.py:     
         def export_worksheet(self, worksheet_filename, output_filename, verbose=True):
    
    [x] make sure latest worksheet state is what is dumped when saving
    worksheet, including the name
    
    [x] id_number: for a given user must never repeat -- store id with username
    [x] change notebooks so they use a 100% sobj free data format for
    storage, so that code refactoring is possible.  The plan is to do this
    little by little, until no sobjs are needed.  Subtodolist:
    
    TODO: 
       * implement to/from basic for server data
       * add that to data store
       * implement all worksheet data (except ratings) being stored in worksheet
         in say a JSON or Python header?  Maybe even make this info programmatically 
         accessible in worksheet?
       * switch over to using new model
       * when transitioning put new notebook in a directory with .sagenb extension:
             sage_notebook.sagenb
    
      [x] worksheets -- the file worksheet.txt + filesystem
      [x] worksheet attributes:   
      [x] list of worksheets -- determined by the filesytem
      [x] notebook:
      [x] user:
    [x] last cell: "exceptions.AttributeError: TextCell instance has no attribute 'evaluate'"
    
    [x] yikes: one run two notebook servers on the same directory at same time (?)
    
    [x] delete worksheet doesn't work, in sense that delete, quit notebook
        server, restart, then worksheets are back!
    
    [x] rewrite file upload, noting a remark in the python docs (!)
    Warning: Never extract archives from untrusted sources without prior
    inspection. It is possible that files are created outside of path,
    e.g. members that have absolute filenames starting with "/" or
    filenames with two dots "..".
    
    Incidentally, this implies somebody could hack the Sage notebook
    server by uploading a foo.sws that overwrites key information, e.g.,
    nb.sobj or worksheet source code (!)
    
    [x] docstring bug:
    import numpy
    numpy.load?
    
    [x] (wontfix) additional user conf data beyond just username/password could just
    be stored in the user's home directory -- that would make the only
    slow power of save/load faster.
    
    [x] delete "class PublicWorksheetsHome(resource.Resource):" since it is not used.
    
    [x] running worksheets not explicitly listed as running in /home/ display
    
    [x] stop button in home screen should save worksheet.
    
    [x] search worksheets should include title
    
    [x] get rid of file menu in big worksheet list -- it is probably
    massively slowing things down, and serves no real purpose (and google
    docs got rid of it).   Also make the worksheet titles bolder and black.
    
    [x] check that autopublish activating and deactiving didn't get
    totally broken.  That code was very confusing.
    
    [x] clean up the other abstract_storage layers (maybe get rid of them?):
         1. delete all of the others (ouch!)
         2. rename simple_filesystem.py --> filesystem_storage.py
    
    [x] fix DownloadWorksheets object to be truly async, since that will
    clarify to me how to improve a lot of other things.
    [x] force choice of title
    [x] make it so new notebooks work
    
    [x] Starting w/o an existing .sage, I get exceptions.KeyError: "No key
     'email' and no default for this key" with the latest
      sagenb, if I click on "Settings" as admin.
      Actually, simply clicking "Sign out" triggers the 'email' KeyError, 
    [x] http://trac.sagemath.org/sage_trac/ticket/7110
    
    [x] add the new sagenb icon from here somehow:
    http://groups.google.com/group/sage-notebook/pendmsg?hl=en
    
    [x] accounts=True is broken
    [x] after migration last modified times wrong?
    [x] login doesn't work anymore, but does if you make a new account
    
    [x] DATA directory not copied over during migration.
    
    [x] after migration the fact that a worksheet was published is lost
    
    [x] implement loading of old-format worksheets: reading old worksheet
       format (see "def edit_save_old_format(self, text):" in
       worksheet.py)
    
    [x] (seems fixed, but need to test more later) server_pool -- keeps getting set to null in server conf?
    
    [x] I could make DATA be of the form: DATA = ...' + os.path.sep which
     on UNIX would still have / at the end and on Windows would end in \.
     Should I do that?
    
    [X] Jason Grout: "I don't like that the icon takes up a lot of vertical space that is not
    used otherwise.  On a computer projector at 800x600 or 1024x768,
    especially with a mac where you can't make the browser go full-screen,
    the vertical real-estate is premium.  Ideally, when you "Toggle" the
    header, there would be only one line at the top of the notebook before
    the cells start.
    
    At the very least, maybe putting the version number right under "Sage
    Notebook" would justify the extra vertical space.  I think it would be
    better if the icon were only one line high, and the toggle collapsed
    everything to one line."
    
    [x] Incorporate "parenthesis matching introduced in trac #3646"
    
    
    [x] BUG: This traceback occurs several times with with sagenb.org:
                return super(Resource, self).http_GET(request)
                s = notebook.html(worksheet_filename = self.name,  username=self.username)
              File "/home/sage/sage_install/sage/local/lib/python2.6/site-packages/sagenb/notebook/notebook
    .py", line 1833, in html
    
              File "/home/sage/sage_install/sage/local/lib/python2.6/site-packages/sagenb/notebook/workshee
    t.py", line 2336, in html
                for cell in self.cell_list():
            exceptions.UnicodeDecodeError: 'ascii' codec can't decode byte 0xc2 in position 825: ordinal no
    t in range(128)
    
    [x] jsmath image fonts spkg (especially on sagenb.org!):
    
    [x] easy way for admin to change people's password
    
    [x] Review and incorporate http://trac.sagemath.org/sage_trac/ticket/7110
    
    [x] make it so the set of worksheets for a given user is 100% determined by the filesystem, not the nb sobj
    
    [x] make it so the conf object is not an sobj
    
    [x] worksheet process -- runs as another unix user.
    [x] deprecate the objects directory (see notebook.py) -- I think this
    is used nowhere
    
    [x] "When I try to save a worksheet on uw... I first get "undefined" in
    Safari 4.0.3, and then the second time I click a save button it works
    fine.  This *always* happens." -- from kcrisman
    [x] "Save as" option when downloading worksheets (requested by bill
    page) " prompts you with a pop-up for a name in the same way as
    'Rename worksheet' and then does a Save.
    [x] If a worksheet is still named "untitled" then perhaps the system
    should not just blindly save it with that pseudo-title when you click
    'Save' but rather automatically pop-up the rename box and invite the
    user to change it before saving.
    [x] BUG "$D<1$ is good." renders without leaving the $-environment
    
    [x] when printing to pdf the output is shown twice. 
    
    [x] insert new cell above text cells (finish fixing bug)
    
    
    [x] synchronization between the browser and server. 
    
    [x] permissions issues -- since the DATA directory must be readable,
    currently by default all the directories are *readable*, including
    history, output etc.  Definitely history should be made readable only
    by the server, and the conf files (including user accounts) should be
    forced to be only readable by the server on startup (no matter what
    the user sets up).
    
    [X] I saw this traceback: "	    ).addCallback(lambda res: self.render(request))
    	  File "/Users/wstein/sage/build/64bit/sage/local/lib/python2.6/site-packages/sagenb/notebook/twist.py", line 1146, in render
    	    worksheet.check_comp()
    	  File "/Users/wstein/sage/build/64bit/sage/local/lib/python2.6/site-packages/sagenb/notebook/worksheet.py", line 3122, in check_comp
    	    c = self.best_completion(out, C._word_being_completed)
    	exceptions.AttributeError: Cell instance has no attribute '_word_being_completed'"
    [x] Also remove 'cell_input_color':'#000000',
    'cell_output_color':'#0000EE', since I think they are used nowhere.
    Also, server confs is a weird place to put such things.
    Alternatively, actually use these.
    
    [x] Deprecate "Number of backups" from server settings, since backups
    aren't made anymore.  Or use this somehow.
    
    [x] When saving a worksheet, the default filename has "..." in it. 
    
    [x] add message to the top of each *old* sage notebook .py file
     stating that one should work on sagenb instead.  This is a patch to
     the core Sage library.
    
    [x] fix all doctests in sagenb code and make a patch against core
    sage library that imports enough of sagenb by default so I can 
    run all these doctests.  
    
    [x] rate a worksheet -- note that the top of the browser (title) says
    error, though in fact there is no error.
    
    [x] change to 100% html format for worksheets.
    
    [x] notebook docs -- something in "doc/en/sagenb"
    
    [x] automated testing -- "Windmill seems to be more popular now -- especially with Python stuff "
    sagenb-1.0.1/sagenb/translations/000077500000000000000000000000001311436262400167325ustar00rootroot00000000000000sagenb-1.0.1/sagenb/translations/cs_CZ/000077500000000000000000000000001311436262400177335ustar00rootroot00000000000000sagenb-1.0.1/sagenb/translations/cs_CZ/LC_MESSAGES/000077500000000000000000000000001311436262400215205ustar00rootroot00000000000000sagenb-1.0.1/sagenb/translations/cs_CZ/LC_MESSAGES/messages.mo000066400000000000000000001450531311436262400236740ustar00rootroot00000000000000Þ•í„ìí#0Tcj«r: ,Y °† F7!G~!IÆ!«"§¼"d#u#	†##—#©#¶#
    ¿#Í#bà#
    C$N$T$O\$¬$µ$É$Û$â$ñ$.%$;%`%m%z%7ú%2&0R&:ƒ&§¾&f'm'
    |'Š'¤'º'*Ê']õ'‚S(,Ö()2)mL)(º)ã)*ï!*
    ,,',	@,?J,
    Š,˜,¡,µ,Ä,Ê,Ù,Nð,?-V-h-4w-¬-»-Ê-
    ç-õ-	...%.4.;.M.@Y.š.¬.½.Ð.à.!ï.&/
    8/
    F/T/]/q/	Ž/„˜/0"0/0#?0
    c0n0v0†0L’0ß0ø0101<1(B1k1*w1!¢1(Ä10í1*2I2V2'c2‹2)š2$Ä2é26î20%3-V30„3µ3º3)Ô3þ344!4=4#M45q41§4	Ù4ã48ù425G5
    L5W5t5}5‚5’5¢5³³5•g6ý67
    7*7I7f7„7s›78(898E8U8j8 †8	§8±8Ð8ï85979R9h9y9
    Ž9™9¡9=´9
    ò9ý9:::':3:P:%o:•:³:Ï:ê:;
    ;;(;%E;k;x;~;•;ì™;-†<)´< Þ<ÿ<
    =
    =(=5=
    L=Z=`=g=j=
    †=”=«=½=Ð=
    â=ð=>>&>3>J>P>
    W>€e>&æ>0
    ?7>?v?“?™?¨?­?¶?Í?=Ý?'@"C@#f@%Š@"°@$Ó@Âø@»AŽÛBjCˆCŽC<£CàCèC	ùCDDr+DlžDYE´eEF5Fl
    ]lhlMql¿l	ÅlÏlålúlm$m-m>m	DmNmOTm4¤nÙnénoo0o7o­=o5ëo1!p·SpNqZZqLµq¬r¶¯rfs„s–sžs§s¼s×sêsÿsmtt†t
    Œt[—tótuu.u5u,Au;nuªu
    ÇuÕu}ôuFrv%¹v&ßv)wÍ0wþwxx-xIxcx px‘x”yC¦y1êy5z‰Rz>Üz){%E{ñk{]}
    n}(y}	¢}N¬} û}~(~E~\~c~t~0Ž~¿~Ú~ù~4MUgsƒ’¡©¿ÎÕï=€D€^€q€†€œ€"³€#Ö€
    ú€	%D
    cšn	‚‚"‚":‚
    ]‚k‚t‚ƒ‚[‚)ì‚Qƒhƒ‡ƒ“ƒ-™ƒǃÖƒ!õƒ3„;K„@‡„Ȅ܄2ì„…#3…(W…€…@†…)Ç…1ñ…6#†	Z†$d†%‰†¯†	¸††Ô†í†=‡>D‡)ƒ‡­‡¾‡;܇ˆ
    0ˆ;ˆ$Rˆ
    wˆ‚ˆ‰ˆ¢ˆ»ˆÊÒˆ¦‰DŠMŠSŠlŠ,ŒŠ¹Š׊tîŠc‹s‹„‹–‹¶‹Ö‹$ì‹
    Œ"Œ%?ŒeŒ0zŒ«Œ¾ŒÙŒöŒ!=5s‹"•¸Î"á9Ž#>ŽbŽ!€Ž¢ŽÁŽߎ㎠òŽ%9Uio‹]>í(,‘+U‘"‘¤‘µ‘‘Αé‘
    ú‘
    ’’’/’E’d’z’#™’½’É’Þ’÷’ÿ’“(“1“ =“…^“%ä“6
    ”DA”"†”©”±”Ĕ͔Ӕç”G•$L•2q•"¤•#Ç•,ë•3–öL–]C—§¡˜ I™j™o™;‹™
    Ǚҙ
    ã™ñ™šˆ"š~«šb*›Ù›(gœ
    œ›œ¯œ,Åœòœ(;Hf~0Ž'¿	çñýžÈ3žüžŸ,Ÿ2Ÿ?Ÿ
    NŸ\ŸyŸ
    “Ÿ¡ŸµŸÔŸŽáŸp | •  ° ¿ Ò á ¡"¡B¡`¡g¡…¢%¤¢)Ê¢ô¢£)£
    0£;£C£K£\£m£u££«£	·£Á£7Í£B¤1H¤Mz¤Ȥפ󤥥*¥1¥:¥S¥s¥ {¥œ¥¥¥4²¥.ç¥,¦!C¦e¦œj¦ã§bë§N¨½h¨%&©CL©©/­©°Ý©¼Žª/K«({«‰¤«:.¬²i¬D®&a®,ˆ®qµ®'¯6¯‡V¯+Þ¯–
    °	¡°«°°ɰаcÕ°9±&K±ƒr±‰ö±€²˜’²+³%E³k³X}³Ö³Þ³ç³
    ï³ú³	´'´:´HX´J¡´ì´E
    µäPµ5¶ºA·Åü·<¸åÿ¸.å¹(º,=ºÁjº,¼	=¼KG¼“¼§¼¼¼1Û¼%
    ½3½R½^½=d½¢½F¸½ÿ½%¾Ð@¾	¿;¿W¿j¿)ƒ¿Ô­¿‚À
    –À@¡À`âÀCÁ.\Á‹ÁšÁ%žÁSÄÁ`Â]yÂT×Â?,ÃJlÃI·ÃŽÄÏÄa`ʼnÂÅoLÆ©¼Æ|fÇãÇ,ùÇ&ÈDÈZÈrÈ
    …ÈÈ(£ÈÌÈ
    ÜÈPçÈ8ÉLÉYÉoɄɢÉ1®ÉàÉ%óÉÊ%Ê%(num)d second%(num)d seconds%(seconds)s ago%(t)s ago by %(le)s(note that images are not recorded)24|twenty-four5|five8|eightWork through the tutorial (if you have trouble with it, view the static version).Restart, instead?

    Email address confirmed for user %s

    Invalid confirmation key

    You are reporting a confirmation key that has not been assigned by this server. Please register with the server.

    Sage is a different approach to mathematics software.A session is a worksheet and a set of variables in some state.A worksheet is an ordered list of Sage calculations with output.A new password will be emailed to the email address connected to your account. However if you didn't confirm your email address you will be unable to recover your account.Access %(f)s in this worksheet by typing DATA+'%(f)s'. Here DATA is a special variable that gives the exact path to all data files uploaded to this worksheet.Account RecoveryAccount SettingsAction...ActiveActive WorksheetsAdd New UserAdd UserAdd or DeleteAnswer a challengeAny cells with "#auto" in the input is automatically evaluated when the worksheet is first opened.AppearanceAprilArchiveArchive selected worksheets so they do not appear in the default worksheet listArchivedArchived WorksheetsAttaching ScriptsAugustAuthenticationAutoevaluate Cells on LoadAutomatically re-publish when changes are madeBack to your personal worksheet listBad passwordBad usernameBegin a block with %sh to have the rest of the block evaluated as a shell script. The current working directory is maintained.Browse published Sage worksheets
    (no login required)Browse the published worksheetsBrowse your computer to select a file to upload:Browse your computer to select a worksheet file to upload:By using Sage you help to support a viable open source alternative to Magma, Maple, Mathematica, and MATLAB. Sage includes many high-quality open source math packages.CancelCancel changesCases / TestsChange Auto-Save IntervalChange E-mail AddressChange PasswordChange account settings including passwordClick log commands you have entered in any worksheet of this notebook.Click Interrupt or press escape in any input cell. This will (attempt) to interrupt SAGE by sending many interrupt signals.Click here or press shift-return to evaluateClick here to pop outClick here to turn the above into a Sage worksheetClick on the left side of output to toggle between hidden, shown with word wrap, and shown without word wrap.Click to download and install tex fonts.Click to rename this worksheetClose this box to stop trying.Code is evaluated by exec'ing (after preparsing). Only the output of the last line of the cell is implicitly printed. If any line starts with "sage:" or ">>>" the entire block is assumed to contain text and examples, so only lines that begin with a prompt are executed. Thus you can paste in complete examples from the docs without any editing, and you can write input cells that contains non-evaluated plain text mixed with examples by starting the block with ">>>" or including an example.CollaboratorsCommentComment/Uncomment BlocksConfirmedCongratulations %(u)s! You can now sign into the Sage Notebook.ConstructionsContinueCopy this worksheetCopy worksheetCountCreate AccountCreate a good passwordCreate a new Sage worksheet version of the last 100 commands in the above log.Create a new worksheetCreate a usernameCreate accountCreating new users is disabled by the administrator.Current FolderCurrent e-mailCustomizing the Notebook CSSDATA VariableDIR VariableData fileData...Default LanguageDefault systemDeleteDelete All OutputDelete CellDelete all cell contents, then press backspace.Delete all outputDelete worksheetDeleted WorksheetsDeveloper GuideDiscard & quitDiscard changes to this worksheetDo you want to publish this worksheet?Doc pool sizeDocumentationDownloadDownload All ActiveDownload selected worksheetsDownload.Each block of code is run from its own directory. If any images are created as a side effect, they will automatically be displayed.EditEdit a copy.Edit plain textEdit text version of this worksheetEdit this.ElapsedEmail ConfirmedEmpty TrashEmptying the trash will permanently delete all items in the trash. Continue?Enable user registrationEnable/disable pretty_printingEnter your email addressEnvironmentErrorError applying function to worksheet(s).Error foundError in introspection -- invalid cell id.Error updating cell output after Error uploading file (missing %s arg).%sError uploading file (missing fileField file).%sError uploading file (missing filename).%sErrors foundEvaluate AllEvaluate Cell using GAP, Singular, etc.Evaluate InputEvaluate all input cells in the worksheetEvaluate all input cells using %(i)sExitExpected "%(wanted)s" after "%(key)s", got "%(token)s"Expected a color value "%(arg)s" after "%(key)s"Expected an integer "%(arg)s" after "%(key)s"Expected an integer "%(key)s" before "%(token)s"FailFailed to save worksheet.Fast Static Versions of the DocumentationFebruaryFile...Files and ScriptsFind Help and DocumentationForgot passwordFull Text Search of Docs and SourceGees -- You can't fool the rating system that easily!General and Advanced Pure and Applied MathematicsGet ImageGet Started with SageGive access to your worksheet to the above collaboratorsGo to the worksheet.HelpHelp AboutHelp via Internet Chat (IRC)Hi %s! HideHide All OutputHide all outputHide/Show OutputHighlight text and press ctrl-. to comment it and ctrl-, to uncomment it. Alternatively, use ctrl-3 and ctrl-4.Highlight text and press > to indent it all and < to unindent it all (works in Safari and Firefox). In Firefox you can also press tab and shift-tab.HistoryHomeHow do I construct ... in Sage?How many bits are in one byte?How to use the Sage NotebookIdle check interval (seconds)Idle timeout (seconds)If you create a file $HOME/.sage/notebook.css then it will get applied when rendering the notebook. See Incorrect password givenIndenting BlocksInput RulesInsert New CellInsert New Text CellInteractive Dynamic WidgetsInteractively use this worksheetInterruptInterrupt Running CalculationsInterrupt and Restart SessionsInterrupt attemptInterrupt currently running calculations, if possibleInvalid challenge responseInvalid email addressInvalid usernameInvite CollaboratorsIs pi > e?JanuaryJava Applet HiddenJavascript must be enabled in order to use the Sage Notebook.Jmol ImageJulyJuneKey and Mouse BindingsLanguageLast EditedLearn to write Sage programsLet others edit this worksheetLoad a new worksheet stored in a fileLoad worksheet from a file...Loading SAGE/Python ScriptsLoading and Saving ObjectsLoading and Saving SessionsLogLog inLog in to edit a copy.Log out of the Sage notebookMake this worksheet publicly viewableManage UsersMarchMaximum history lengthMayMove the mouse between cells until a blue bar appears. Shift-click on the blue bar to create a new text cell. Double click on existing text to edit it. Use $...$ and $$...$$ to include typeset math in the text block.Move the selected worksheets out of the trashMove the selected worksheets to the trashMove this worksheet to the trashMulti Cell ModeNew WorksheetNew e-mailNew passwordNew password not givenNew worksheetNewerNewestNoNo challenge response givenNo data filesNo email address givenNo password givenNo such worksheet.No username givenNot confirmedNotebook SettingsNumber of word-wrap columnsOctoberOld passwordOld password not givenOlderOldestOne Cell ModeOnly the owner of a worksheet is allowed to share it. You can do whatever you want if you make your own copy.Or enter the URL of a file on the web:Or enter the URL of a worksheet file on the web:Or enter the name of a new file, which will be created:Other published documents...OwnerParen matchingPassPasswordPasswords didn't matchPick a usernamePlease ask the server administrator to configure a challenge!Please enter a name for this worksheet.Please log in to the Sage notebookPlease request a specific worksheetPlease specify a worksheet to load.%sPlease type in new password again.Possible failure deleting worksheet.Press ctrl-; in a cell to split it into two cells, and ctrl-backspace to join them. Press ctrl-enter to split a cell and evaluate both pieces.Press shift-enter. You can start several calculations at once. If you press alt-enter instead, then a new cell is created after the current one. If you press ctrl-enter then the cell is split and both pieces are evaluated separately.Press tab while the cursor is on an identifier. On some web browsers (e.g., Opera) you must use control-space instead of tab.Pretty print (typeset) outputPrintPrint this worksheetProblem inserting new input cell after current input cell.\nPublishPublish this onePublishedPublished WorksheetsPublished on %(t)sPut "%gap", "%singular", etc. as the first input line of a cell; the rest of the cell is evaluated in that system.Put ?? after the object and press tab or shift-enter (shift-enter overwrites output and saves to worksheet).Put @interact on the line before a function definition. Type interact? for more details.Put the mouse between an output and input until the horizontal line appears and click. If you press Alt-Enter in a cell, the cell is evaluated and a new cell is inserted after it.Quit the worksheet processRatingRating AcceptedRatings for %(wn)sRe-publish worksheetRe-type your passwordReference ManualRemember meRenameRename this worksheetRename worksheetReport a ProblemReport a problem or submit a bug to improve SageRequire e-mail for account registrationResetRestartRestart the worksheet processRestart worksheetReturn to Upload or Create Data File or %s.Retype new passwordRevert to this oneRevisionRevision %(lr)sRevision HistoryRevision ListRevision from %(ta)s agoSage DocumentationSage NotebookSage Notebook versionSage Source BrowserSage Users:Sage makes it easy for you to use most mathematics software together. Sage includes GAP, GP/PARI, Maxima, and Singular, and dozens of other open packages.Sage versionSage: History for %(u)sSaveSave & quitSave ChangesSave and quit worksheetSave changesSave changes and close windowSave interval (seconds)Save this worksheet to an sws fileSave worksheet to a file...Search WorksheetsSearch the SAGE documentation by typing
    search_doc("my query")
    in an input cell and press shift-enter. Search the source code of SAGE by typing
    search_src("my query")
    and pressing shift-enter. Arbitrary regular expressions are allowed as queries.Searching for Sage server...Select a file related functionSelect a worksheet functionSelect an OpenID providerSelect an attached fileServerSettingsShareShare nowShare this documentShell ScriptsShowShow All OutputShow all outputSign inSign outSign upSign up for a Sage Notebook accountSign up for a new Sage Notebook accountSomeone else is viewing this worksheetSorry, but you need a browser that supports the <canvas> tag.Source CodeSpecial Cell BlocksSplit and Join CellsStartStatic version...StatusStopStop publishingStop selected worksheetsSubmitSuccessfully deleted "%s"SuspendSuspensionSuspicious filename "%s" encountered uploading file.%sSwitch to multi-cell modeSwitch to single-cell modeTab CompletionTextThank you for rating the worksheet %s! You can see all ratings of this worksheet.Thank you for registering for the Sage notebook. To complete your registration, copy and paste the following link into your browser: %s://%s:%s/confirm?key=%s You will be taken to a page which will confirm that you have indeed registered.The Sage notebook is a collection of worksheets, saved objects, and user information.The Sage NotebookThe Sage Notebook was primarily written by William Stein with substantial contributions from Tom Boothby, Timothy Clemans, Alex Clemesha, Mike Hansen, Bobby Moretti, Yi Qiang, and Dorian Raymer.The confirmation system is not active.The password for the user %(u)s has been reset to %(p)sThe passwords you entered do not match.The user "%s" has no worksheet "%s".The username must start with a letter and be between 4 and 32 characters long. It can only consist of letters, numbers, underscores, and one dot (.).The variable DIR contains the directory from which you started the SAGE notebook. For example, to open a file in that directory, do "open(DIR+'filename')".The worksheet operation "%s" is not defined.There are no published worksheets.There is no published worksheet with name "%s". Redirecting to the index of published worksheets in 10 seconds...

    There was an error uploading "%s" (please recheck the URL).%sThere was an error uploading the worksheet. It could be an old unsupported format or worse. If you desperately need its contents contact the sage-support group and post a link to your worksheet. Alternatively, an sws file is just a bzip2 tarball; take a look inside!%sThis Sage Worksheet is currently shared with the people listed in the box below.This page is rated %(wr).1f.This url can only be accessed through a POST request.This worksheet is read only. Please make a copy or contact the owner to change it.TimeTitle of saved worksheetTo fix unmatched or mis-matched parentheses, braces or brackets, press ctrl-0. Parentheses before the cursor will be matched, minding strings and (Python) comments.To quickly try out Sage start hereTo save this image, you can try right-clicking on the image to copy it or save it to a file, or you may be able to just drag the image to your desktop.ToggleToggle the top barTotalTotalsTrashTrying again in %(num)d second...Trying again in %(num)d seconds...TutorialType "%time" at the beginning of the cell.Type "restart" to restart the SAGE interpreter for a given worksheet. (You have to interrupt first.)Type ? immediately after the object or function and press tab or shift-enter (shift-enter overwrites output and saves to worksheet).Type of challengeType pretty_print_default() in an input cell and press shift-enter. All future output will be typeset automatically.Typesetting All OutputUnable to interrupt calculation.UnarchiveUnarchive selected worksheets so it appears in the default worksheet listUndeleteUndoUnsuspendUntitledUpdatedUploadUpload WorksheetUpload or Create Data FileUpload or Create Data File to attach to worksheet "%(wn)s"Upload or create a data file in a wide range of formatsUpload or create file...Upload worksheet (an sws or txt file) to the Sage NotebookUse "attach filename.sage" or "attach filename.py". Attached files are automatically reloaded when the file changes. The file $HOME/.sage/init.sage is attached on startup if it exists.Use "load filename.sage" and "load filename.py". Load is relative to the path you started the notebook in. The .sage files are preparsed and .py files are not. You may omit the .sage or .py extension. Files may load other files.Use "save obj1 obj2 ..." and "load obj1 obj2 ...". This allows for easy moving of objects from one worksheet to another, and saving of objects for later use.Use "save_session('name')" to save all variables to an object. Use "load_session('name')" to merge in all variables from a saved session.Use Most Mathematics Software from Within SageUse Sage for studying calculus, elementary to very advanced number theory, cryptography, commutative algebra, group theory, graph theory, numerical and exact linear algebra, and more.Use a Mainstream Programming LanguageUse a challenge for account registrationUse an Open Source AlternativeUse the Data menu to upload images and other files, and create new files that can be shared between worksheets. The DATA variable contains the path to the data files. For example, to open a file in that directory, do "open(DATA+'filename')". If foo.sage is a Sage file that you uploaded, type "load foo.sage"; if foo.py is a Python file, you can import it by typing "import foo".Useful TipsUserUser "%s" does not have permission to view the home page of "%s".User ManagementUsernameUsername ErrorUsername already in useUsername is not in the systemUsername takenUsersVersionView a 4000+ page reference manual about SageView a log of recent computationsView changes to this worksheet over timeView plain textView plain text version of this worksheetWelcome to Sage! You can create a new worksheet, view published worksheets, or read the documentation.Welcome!What do you want to call it? (if different than the original name)What is 2 plus 3?What is 3 times 8?What is the largest prime factor of 15?With the Sage Notebook anyone can create, collaborate on, and publish interactive worksheets. In a worksheet, one can write code using Sage, Python, and other software included in Sage.Working DirectoryWorksheetWorksheet is locked. Cannot insert cells.Worksheet is publicly viewable at %(u)sWorksheet process limitsWorksheet process users (comma-separated list)Wrong passwordYesYou are not authorized to move "%s"You are not logged in or do not have access to the worksheet "%s".You can publish your worksheet to the Internet, where anyone will be able to access and view it online.You may add or remove collaborators (separate user names by commas).You may download %(f)s or create a linked copy to the worksheetYou must login first in order to edit this worksheet.You must login first in order to rate this worksheet.You requested to evaluate a cell that, for some reason, the server is unaware of.You work with Sage using the highly regarded scripting language Python. You can write programs that combine serious mathematics with anything else.Your browser / OS combination is not supported.\nPlease use Firefox or Opera under Linux, Windows, or Mac OS X, or Safari.Your email address is required for account confirmation and recovery. You will be emailed a confirmation link right after you successfully sign up.Your new password is %s Sign in at %s://%s:%s/ Make sure to reset your password by going to Settings in the upper right bar.Your password must be between 4 and 32 characters long. Your password can not contain your username nor spaces.Your username must start with a letter and be between 3 and 64 characters long. You may only use letters, numbers, underscores, @, and dots.Your worksheet will be assigned a unique address (URL) that you can send to your friends and colleagues.browse directorycan't evaluate worksheet cellscs_CZde_ATen_USes_ESevaluatefr_FRlast edited on %(t)s by %(le)sloading...optionalor delete %(f)s.pt_BRpublishedreCAPTCHA private keyreCAPTCHA public keyru_RUrunnings (canceling further update checks).select worksheetuk_UAunprintedy|yesProject-Id-Version: sagenb Report-Msgid-Bugs-To: EMAIL@ADDRESS POT-Creation-Date: 2011-06-13 12:49-0700 PO-Revision-Date: 2011-06-13 12:55-0800 Last-Translator: Mike Hansen Language-Team: MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit Generated-By: Babel 1.3 %(num)d sekundou%(num)d sekundami%(num)d sekundami%(seconds)s agopÅ™ed %(t)s, autor %(le)s(obrázky nejsou uloženy)24|dvacet ÄtyÅ™i5|pÄ›t8|osmAnglický tutoriál (pokud pÅ™i práci máte problémy, použijte statickou verzi).Restartovat?

    Emailová adresa uživatele %s potvrzena

    Chybný potvrzovací kód

    Používáte jiný potvrzovací kód než ten, který byl vystaven tímto serverem. Registrujte se prosím na serveru.

    Sage pÅ™edstavuje jiný přístup k matematickým programům.Sezení je zápisník a množina promÄ›nných v nÄ›jakých definovaných stavech.Zápisník je uspořádaný seznam bunÄ›k a výstupů programu SageNové heslo Vám bude zasláno na emailovou adresu spojenou s vaším úÄtem. Pokud nepotvrdíte správnÄ› VaÅ¡i mailovou adresu, nebudete mít k obnovÄ› úÄtu přístup.Soubor %(f)s v tomto zápisníku zpřístupníte pomocí DATA+'%(f)s'. Speciální promÄ›nná DATA obsahuje cestu ke vÅ¡em datům, která byla nahrána k tomuto zápisníku.Obnova uživatelského úÄtuNastavení úÄtuAkce...AktivníAktivní zápisníkyPÅ™idat nového uživatelePÅ™idat uživatelePÅ™idat nebo vymazatZodpovÄ›zte úkolKaždá buňka s Å™etÄ›zcem "#auto" na vstupu je automaticky zpracována pÅ™i prvním otevÅ™ení zápisníku.VzhledAprilArchivovatArchivovat vybrané zápisníky tak, aby se neobjevovaly ve výchozím seznamu zápisníkůArchivovanéArchivované zápisníkyPÅ™ipojení skriptůAugustAutentizaceAutomatické vyhodnocení bunÄ›k pÅ™i startuPo zmÄ›nách aktualizovat automaticky i zveÅ™ejnÄ›nou verziZpÄ›t na seznam zápisníkůChybné hesloNeplatné uživatelské jménoPoužijte %sh na zaÄátku buňky a zbytek buňky bude vyhodnocen linuxovým shellem. Pracovní adresář zůstane zachován.Prohlížet zveÅ™ejnÄ›né zápisníky
    (není nutné pÅ™ihlášení)Prohlížet zveÅ™ejnÄ›né zápisníkyVyberte soubor pro uložení na serverNajdÄ›te soubor na lokálním poÄítaÄiPoužitím Sage pomáháte podporovat životaschopnou alternativu k programům Magma, Maple, Mathematica a MATLAB. Sage obsahuje mnoho kvalitních volnÄ› Å¡iÅ™itelných matematických programů a knihoven.ZruÅ¡itZruÅ¡it zmÄ›nyTestyZmÄ›nit interval pro automatické ukládáníZmÄ›nit e-mailovou adresuZmÄ›na heslaZmÄ›na nastavení úÄtu a heslaPoužijte odkaz log pro zobrazení vaÅ¡ich posledních příkazů použitých v libovolném zápisníku.StisknÄ›te PÅ™eruÅ¡it nebo stisknÄ›te escape v libovolné vstupní buňce. Sage zaÅ¡le signál k pÅ™eruÅ¡ení vÅ¡em běžícím podprocesům.KliknÄ›te sem nebo stisknÄ›te shift+enter pro spuÅ¡tÄ›ní výpoÄtuKliknÄ›te sem pro vložení do samostatného oknaKliknÄ›te zde pro pÅ™evod na zápisník programu SageKliknÄ›te na levou stranu výstupem pro pÅ™epnutí mezi skrytím, zobrazením se řádkovým zlomem a zobrazením bez řádkového zlomu.Kliknutím spustíte stažení a instalaci TeXovských fontů.KliknÄ›te pro pÅ™ejmenování zápisníkuZavÅ™ete rámeÄek pro konec pokusů.Kód je spouÅ¡tÄ›n po pÅ™edformátování. ImplicitnÄ› je vytiÅ¡tÄ›n je pouze výstup posledního řádku. Pokud libovolný řádek zaÄíná Å™etÄ›zcem "sage:" nebo ">>>", potom se pÅ™edpokládá, že celý blok obsahuje ukázky a příklady a vyhodnoceny jsou pouze řádky s tÄ›mito Å™etÄ›zci. Můžete tedy zkopírovat úplné příklady z dokumentace bez dodateÄných úprav. Můžete také používat vstupní buňky, kde jsou kombinovány textové komentáře s příkazy uvozenými ">>>".SpolupracovníciKomentářZakomentování a odkomentování blokůPotvrzenoGratulujeme %(u)s! Nyní se můžete pÅ™ihlásit do prostÅ™edí Sage Notebook.NÄ›které programové konstrukcePokraÄovatZkopírovat tento zápisníkZkopírovat zápisníkPoÄetVytvoÅ™it úÄetVytvoÅ™te si silné hesloVytvoÅ™it zápisník s posledními 100 příkazyVytvoÅ™it nový zápisníkZvolte si uživatelské jménoVytvoÅ™it uživatelský úÄetCreating new users is disabled by the administrator.SložkySouÄasný e-mailÚprava CSSPromÄ›nná DATAPromÄ›nná DIRDatový souborData...PÅ™ednastavený jazykDefault systemSmazatVymazat vÅ¡echny výstupyVýmaz vstupní buňkyVymažte celý obsah a stisknÄ›te backspace.Vymazat vÅ¡echny výstupyVymazat zápisníkSmazané zápisníkyPrůvodce vývojářeZavřít bez uloženíZahodit zmÄ›ny v tomto zápisníkuChcete zveÅ™ejnit tento zápisník?Doc pool sizeDokumentaceStáhnoutUložit vÅ¡echny aktivní zápisníkyStáhnout vybrané zápisníkyStáhnout.Každá vstupní buňka je spouÅ¡tÄ›na ve vlastním adresáři. Pokud jsou bÄ›hem výpoÄtu vytvoÅ™eny obrázky, jsou tyto obrázky automaticky zobrazeny.EditovatEditovat kopii.Editovat textovou verziEditace textové verze zápisníkuEditovat zde.UplynuloEmail potvrzenVysypat koÅ¡Vysypání koÅ¡e definitivnÄ› odstraní vÅ¡echny položky,které v koÅ¡i jsou. PokraÄovat?Umožnit registraci dalších uživatelůPovolit/zakázat pretty_printing (pÄ›kné formátování matematických výrazů)Zadejte svoji emailovou adresuProstÅ™edíChybaChyby pÅ™i použití funkce na zápisník(y).Nalezena chybaChyba -- Å¡patné id u buňky.Chyba pÅ™i aktualizaci buňky po Chyba pÅ™i nahrávání souboru (missing %s arg).%sChyba pÅ™i nahrávání souboru (missing fileField file).%sChyba pÅ™i nahrávání soubodu (chybÄ›jící jméno souboru).%sByly nalezeny chybyVyhodnotit vÅ¡eVyhodnocení pomocí programů GAP, Singular, atd.Vyhodnocení vstupuVyhodnotit vÅ¡echny vstupní buňkyVyhodnotit vÅ¡echny buňky pomocí %(i)sKonecOÄekáváváno "%(wanted)s" po "%(key)s", obdrženo "%(token)s"OÄekávána barva "%(arg)s" po "%(key)s"OÄekáváno celé Äíslo "%(arg)s" po "%(key)s"OÄekáváno celé Äíslo "%(key)s" pÅ™ed "%(token)s"SelháníUložení zápisníku se nezdaÅ™ilo.Dokumentace (rychlá statická verze)FebruarySoubor...Soubory a skriptyNápovÄ›da a dokumentaceZapomnÄ›l(-a) jsem hesloFulltextové prohledávání dokumentace a zdrojových kódůFujtajbl -- Systém hodnocení nemůžete ošálit tak snadno!Obecná, Äistá a aplikovaná matematikaUložit obrázekPrvní kroky s programem SageZpřístupnit zápisník následujícím spolupracovníkůmPÅ™ejít na zápisník.NápovÄ›daKontextová nápovÄ›daPomoc na kanálu IRC (Internet Chat)Ahoj %s! SkrýtUkrýt vÅ¡echny výstupyUkrýt vÅ¡echny výstupySkrýt/ukázat výstupOznaÄený text můžete zakomentovat pomocí ctrl-. a zruÅ¡it zakomentování pomocí ctrl-,. Můžete též použit ctrl-3 a ctrl-4.OznaÄte text a stisknÄ›te > pro odsazení a < pro zruÅ¡ení odsazení (funguje v prohlížeÄích Safari a Firefox). Ve Firefoxu můžete použít i tab a shift-tab.HistorieDomůJak udÄ›lám ... v Sage?Kolik bitů je v jednom bajtu? Návod k použití prostÅ™edí Sage NotebookIdle check interval (seconds)Idle timeout (seconds)Pokud existuje soubor $HOME/.sage/notebook.css je tento soubor použit pÅ™i formátování zápisníku. VizNeplatné hesloOdsazení blokůVstupní pravidlaVložení nové vstupní buňkyVložení nové buňky s textemInteraktivní objektyInteraktivní práce se zápisníkemPÅ™eruÅ¡itPÅ™eruÅ¡ení bežícího výpoÄtuPÅ™eruÅ¡ení a restartování sezeníPokus o pÅ™eruÅ¡eníPozastavit bežící výpoÄet, je-li to možnéŠpatná odpovÄ›ÄNeplatná emailová adresaChybné uživatelské jménoPÅ™izvat spolupracovníkyJe pi>e?JanuarySkrytý Java appletJavascript must be enabled in order to use the Sage Notebook.Obrázek programu JmollJulyJuneKlávesové povely a povely myšíPÅ™ednastavený jazykNaposledy upravenoNauÄte se psát programy pro SagePovolit ostatním prohlížet a editovat tento zápisníkNahrát nový zápisník ze souboruNahrát zápisník ze souboruNahrávání skriptů Sage/PythonUkládání a Ätení objektůUložení a obnovení sezeníLogPÅ™ihlášeníPÅ™ihlásit se a editovat kopii.Odhlásit z prostÅ™edí programu SageZveÅ™ejnit tento zápisníkSpráva uživatelůMarchMaximální délka historieMayPÅ™emisÅ¥ujte ukazatel myÅ¡i mezi buňkami, dokud se neobjeví modrá linka. Shift-click na modré lince vytvoří novou textovou buňku. Pro editaci existující textové buňky na tuto buňku kliknÄ›te dvakrát.Pro formátování matematických výrazů použijte $...$ a $$...$$. Výraz mezi dolary zapiÅ¡te pomocí jazyka LaTeX.PÅ™esunout vybrané zápisníky z koÅ¡e do výchozího seznamuPÅ™esunout vybrané zápisníky do koÅ¡ePÅ™esunout zápisník do odpadkového koÅ¡eRežim s více vstupními buňkamiNový zápisníkNový e-mailNové hesloNebylo zadáno nové hesloNový zápisníkNovÄ›jšíNejnovÄ›jšíNeNebyla zadána odpovÄ›ÄNejsou datové souborNení zadána emailová adresaNebylo zadáno heslo.Takový zápisník neexistuje.Nebylo zadáno uživatelské jménoNepotvrzenoNastavení NotebookuPoÄet znaků na řádekOctoberStaré hesloStaré heslo nebylo zadánoStaršíNejstaršíRežim s jednou vstupní buňkouPouze majitel zápisníku jej může sdílet. Pro vlastní úpravy si můžete udÄ›lat vlastní kopii zápisníku.Nebo zadejte URL souboru na internetuNebo zadejte URL zápisníku vystaveného na InternetuNebo můžete zadat jméno nového souboru, který chcete vytvoÅ™it:Jiné zveÅ™ejnÄ›né zápisníky...MajitelPárovost závorekVynechatHesloHesla se neshodujíVyberte uživatelské jménoPožádejte administrátora serveru o konfiguraci kontrolních otázek!Prosím, zadejte název zápisníku.PÅ™ihlaste se prosím do prostÅ™edí Sage NotebookPožadujte konkrétní zápisník.Vyberte zápisník pro nahrání.%sProsím, zadejte nové heslo jeÅ¡tÄ› jednou.PravdÄ›podobnÄ› nastala chyba pÅ™i mazání souboruStisknÄ›te ctrl-; v buňce pro rozdÄ›lení na dvÄ› buňky a ctrl-backspace pro slouÄení bunÄ›k. Použijte ctrl-enter pro rozdÄ›lení buňky na dvÄ› a vyhodnocení obsahů obou tÄ›chto bunÄ›k. StisknÄ›te shift-enter. Můžete spustit i více výpoÄtů souÄasnÄ›. Stiskem kombinace alt-enter se navíc za aktuální vstupní buňku vloží další, prázdná. Stiskem ctrl-enter dojde k rozdÄ›lení buňky v místÄ› kurzoru na dvÄ› a obÄ› nové buňky jsou vyhodnoceny nezávisle na sobÄ›.StisknÄ›te tab když je kurzor na identifikátoru.V nÄ›kterých prohlížeÄích (napÅ™. Opera) musíte místo tabelátoru použít control-mezerník.Vykreslovat matematické výrazyTiskVytisknout tento zápisníkNepodaÅ™ilo se vložit novou buňku za buňku souÄasnou.\nZveÅ™ejnitZveÅ™ejnit tohleZveÅ™ejnÄ›néZveÅ™ejnÄ›né zápisníkyZveÅ™ejnÄ›no dne %(t)sZapiÅ¡te "%gap", "%singular", atd. na první řádek vstupní buňky; další řádky buňky budou zpracovány přísluÅ¡ným programem.ZapiÅ¡te ?? bezprostÅ™ednÄ› za objekt a stisknÄ›te tab nebo shift-enter (shift-enter pÅ™epíše výstup buňky v zápisníku).Vložte @interact na řádek pÅ™ed definici funkce. Použijte interact? pro nápovÄ›du a ukázky.UmístÄ›te ukazatel myÅ¡i mezi vstupní a výstupní buňku, dokud se neobjeví vodorovná linka a na tuto linku kliknÄ›te. Stiskem Alt-Enter v buňce je obsah této buňky zpracován a nová buňka je vložena za ni.UkonÄit proces náležící zápisníkuHodnoceníHodnocení uloženoHodnocení pro %(wn)sAktualizovat zveÅ™ejnÄ›nou verzi zápisníkuZadejte heslo jeÅ¡tÄ› jednouReferenÄní příruÄkaZapamatovat si mÄ›PÅ™ejmenovatPÅ™ejmenovat tento zápisníkPÅ™ejmenovat zápisníkNahlásit chybuOhlásit problém nebo chybu pro zlepÅ¡ení SageRequire e-mail for account registrationResetovatRestartovatRestartovat proces zápisníkuRestartovat zápisníkZpÄ›t na Nahrát nebo vytvoÅ™it datový soubor nebo %s.Znovu zadejte nové hesloVrátit na tuto verziVerzeVerze %(lr)sHistorie zmÄ›nSeznam verzíVerze uložená pÅ™ed %(ta)sDokumentace programu SageSage NotebookSage Notebook verzeProhlížeÄ zdrojového kóduUživatelé:Sage umožňuje používat mnoho programů z jednotného prostÅ™edí. Sage obsahuje programy GAP, GP/PARI, Maxima, Singular a mnoho dalších.Sage verze Sage: Historie pro %(u)sUložitUložit a zavřítUložit zmÄ›nyUložit a ukonÄitUložit zmÄ›nyUložit zmÄ›ny a zavřít oknoInterval ukládání (sekundy)Uložit zápisník jako sws souborUložit zápisník do souboruHledatDokumentaci programu SAGE můžete prohledávat pomocí příkazu
    search_doc("dotaz")
    ve vstupním poli a následně stiskem shift-enter. Zdrojové kódy je možno prohledávat pomocí
    search_src("dotaz")
    . Jako dotaz může sloužit libovolný regulární výraz.Vyhledávání Sage serveru...Vyberte funkci pro práci se souboremVyberte funkci pro práci se zápisníkemSelect an OpenID providerVyberte pÅ™ipojený souborServerNastaveníSdíletSdíletSdílet dokumentPříkazy shelluUkázatZobrazit vÅ¡echny výstupyZobrazit vÅ¡echny výstupyPÅ™ihlásitOdhlásitPÅ™ihlásitZaložení nového úÄtu pro prostÅ™edí Sage NotebookVytvoÅ™it nový uživatelský úÄet pro prostÅ™edí Sage NotebookDalší uživatel si prohlíží tento zápisníkLitujeme, musíte použít prohlížeÄ, který podporuje tag <canvas>.Zdrojový kódSpeciální vstupní buňkyRozdÄ›lení a spojení bunÄ›kStartStatická verze...StatusZastavitPozastavit zveÅ™ejnÄ›níPozastavit vybrané zápisníkyOdeslatSoubor "%s" úspěšnÄ› smazán.ZakázatPozastaveníNekorektní jméno souboru "%s" pÅ™i nahrávání.%sPÅ™epnout do módu s více vstupními buňkamiPÅ™epnout do módu s jednou vstupní buňkouDoplňování pomocí tabelátoruTextDÄ›kujeme za zadání hodnocení pro zápisník %s! Můžete si prohlédnout vÅ¡echna hodnocení tohoto zápisníku.DÄ›kujeme za registraci. Pro dokonÄení registrace zkopírujte následující odkaz do VaÅ¡eho internetového prohlížeÄe: %s://%s:%s/confirm?key=%s Budete pÅ™esmÄ›rováni na stránku, kde budete moci dokonÄit registraci.Sage notebook je kolekce zápisníků, uložených objektů a uživatelských informací.ProstÅ™edí Sage NotebookPůvodním autorem programu Sage Notebook je William Stein, dalšími autory jsou Tom Boothby, Timothy Clemans, Alex Clemesha, Mike Hansen, Bobby Moretti, Yi Qiang, Dorian Raymer a další.Systém potvrzování není aktivní.Heslo pro uživatele %(u)s bylo nastaveno na %(p)sZadaná hesla se neshodují.Uživatel "%s" nemá vytvoÅ™en zápisník "%s".Uživatelské jméno musí zaÄínat písmenem a musí být alespoň 4 a nejvýše 32 znaků dlouhé. Může obsahovat pouze písmena, Äísla, podtržítka a jednu teÄku (.).PromÄ›nná DIR obsahuje jméno adresáře, odkud byl spuÅ¡tÄ›n program Sage Notebook. Například pro otevÅ™ení souboru v tomto adresáři můžete použít příkaz "open(DIR+'soubor')".Operace "%s" se zápisníkem není definována.Nejsou zveÅ™ejnÄ›ny žádné zápisníkyZápisník se jménem "%s" není zveÅ™ejnÄ›n. BÄ›hem 10 vteÅ™in budete pÅ™esmÄ›rováni na seznam zveÅ™ejnÄ›ných zápisníků...

    Chyba pÅ™i nahrávání "%s" (zkontrolujte prosím URL).%sNahrávání zápisníku skonÄilo chybou. Může být ve starém nebo nepodporovaném formátu. Pokud nutnÄ› potÅ™ebujete přístup k tomuto zápisníku, kontaktujte sage-support group a poÅ¡lete sem odkaz na Váš soubor (jedná se o anglicky mluvící diskusní skupinu). Můžete se také pokusit sws soubor rozbalit, jedná se o balíÄek zabalený pomocí tar a bzip2!%sTento zápisník v souÄasnosti sdílí níže uvedení uživatelé.Tato stránka má hodnocení %(wr).1f.Toto URL je přístupné pouze metodou POST.Tento zápisník je pouze ke Ätení. Prosím udÄ›lejte si kopii nebo kontaktujte majitele pro zmÄ›nu nastavení.ÄŒas výpoÄtuNázev ukládaného zápisníkuPro opravení párovosti závorek můžete použít ctrl-0. Bude nalezena párová závorka k závorce pÅ™ed kurzorem.Pro rychlé vyzkouÅ¡ení Sage zaÄnÄ›te zdeObrázek můžete uložit do souboru pomocí pravého tlaÄítka myÅ¡i. V nÄ›kterých prostÅ™edích je možno obrázek přímo pÅ™etáhnout na plochu.PÅ™epnoutPÅ™epnout horní panelCelkemCelkemKoÅ¡Nový pokus za %(num)d sekundu...Nový pokus za %(num)d sekund...Nový pokus za %(num)d sekund...Tutoriál (angl.)Použijte "%time" na zaÄátku buňky.Použijte příkaz "restart" pro restartování Sage interpretru pro souÄasný zápisník. (Musíte nejprve pÅ™eruÅ¡it výpoÄty.)ZapiÅ¡te ? bezprostÅ™ednÄ› za objekt nebo funkci a stisknÄ›te tab nebo shift-enter (shift-enter pÅ™epíše výstup buňky v zápisníku).Type of challengeSpusÅ¥te pretty_print_default() ve vstupní buňce (zapiÅ¡te a stisknÄ›te shift-enter). Následující výstupy budou automaticky pÄ›knÄ› formátovány.Sazba vzorců na výstupuPÅ™eruÅ¡ení výpoÄtu se nezdaÅ™ilo.ZruÅ¡it archivaciOdstranit vybrané zápisníky z archivu (objeví se ve výchozím seznamu zápisníků)ObnovitHistoriePovolitBezejménaAktualizovánoVložit zápisník ze souboruNahrát zápisníkNahrát nebo vytvoÅ™it souborNahrát nebo vytvoÅ™it datový soubor pÅ™ipojený k zápisníku "%(wn)s"Můžete nahrát nebo vytvoÅ™it soubor s daty v Å¡iroké Å¡kále formátůNahrát nebo vytvoÅ™it souborNahrát zápisník (sws nebo txt soubor) do prostÅ™edí Sage NotebookPoužijte "attach filename.sage" nebo "attach filename.py". PÅ™ipojené skripty jsou pÅ™i zmÄ›nách automaticky opÄ›tovnÄ› nahrány. Pokud v systému existuje soubor $HOME/.sage/init.sage, je tento soubor pÅ™ipojen pÅ™i startu.Použijte "load filename.sage" a "load filename.py". Nahrávání je vzhledem k cestÄ›, odkud je spuÅ¡tÄ›n zápisník. Sobory .sage jsou pÅ™edformátovány preparserem, soubory .py ne. Koncovku .sage a .py můžete vynechat. Soubory mohou nahrávat další soubory.Můžete použít "save obj1 obj2 ..." a "load obj1 obj2 ...". Tím umožníte pÅ™enos objektů z jednoho zápisníku do druhého a uložení objektů pro pozdÄ›jší další použití.Můžete použít "save_session('name')" pro uložení vÅ¡ech promÄ›nných. Můžete použít "load_session('name')" pro pÅ™ihrání vÅ¡ech uložených promÄ›nných do aktuálního sezení.Používejte vÄ›tÅ¡inu matematických programů pomocí SageSage můžete použít pro studium matematické analýzy, elementární i pokroÄilé teorie Äísel, kryptografie, komutativních algeber, teorie grup, teorie grafů, klasické i numerické lineární algebry a dalších oborů.Používejte rozšířený programovací jazykUse a challenge for account registrationPoužívejte volnÄ› Å¡iÅ™itelnou alternativuMůžete použít menu Data pro uložení obrázků a jiných souborů a pro vytvoÅ™ení souborů, které mohou být sdíleny mezi zápisníky. PromÄ›nná DATA obsahuje cestu k tÄ›mto souborům. Například pro otevÅ™ení souboru v tomto adresáři můžete použít "open(DATA+'soubor')". Pokus nahrajete soubor foo.sage, můžete použít "load foo.sage"; pokud nahrajete soubor foo.py jazyka Python, můžete jej zaÄlenit pomocí "import foo".UžiteÄné tipyUživatelUživatel "%s" nemá oprávnÄ›ní pro vstup do adresářů uživatele "%s".Správa uživatelůUživatelské jménoChyba v uživatelském jménÄ›Toto uživatelské jméno je již zaregistrovánoUživatelské jméno není v systémuUživatelské jméno obdrženoUživateléVerzeProhlédnout podrobnou referenÄní příruÄku programu SageProhlížet historii Zobrazit zmÄ›ny v zápisníku a umožnit návrat k dřívÄ›jší verziTextová verze zápisníkuZobrazení textové verze zápisníkuVítejte v Sage! Můžete vytvoÅ™it nový zápisník, prohlédnout si zveÅ™ejnÄ›né zápisníky, nebo pÅ™eÄíst dokumentaci.Vítejte!Jak se má zápisník jmenovat (pokud chcete mÄ›nit jméno)Kolik je 2 plus 3?Kolik je tÅ™i krát osm?Jaký je nejvÄ›tší dÄ›litel Äísla 15?V prostÅ™edí Sage Notebook může každý tvoÅ™it, sdílet a vystavovat interaktivní zápisníky. V zápisnících je možno použít kód v jazycích Sage, Pyhton a dalších programů, zaÄlenÄ›ných do Sage.Pracovní adresářZápisníkZápisník je zamÄený pro zmÄ›ny. Není možno vložit buňky.Zápisník je veÅ™ejnÄ› přístupný na %(u)sWorksheet process limitsWorksheet process users (comma-separated list)Å patné hesloAnoNemáte oprávnÄ›ní pro pÅ™esun "%s"Nejste pÅ™ihlášen(-a) nebo nemáte oprávnÄ›ní pro přístup k zápisníku "%s".Svůj zápisník můžete zveÅ™ejnit na Internetu. Každý si jej bude moci prohlédnout online.Můžete pÅ™edat nebo odstranit spolupracovníky (uživatelská jména oddÄ›lujte Äárkami).Můžete stáhnout %(f)s nebo vytvoÅ™it kopii tohoto zápisníkuPro editaci zápisníku se musíte pÅ™ihlásit.Pro hodnocení zápisníku se musíte nejprve pÅ™ihlásit.Z nÄ›jakého důvodu server nereagoval na žádost o vyhodnocení buňky.V Sage pracujete s kvalitním skriptovacím jazykem Python. Můžete psát programy, které kombinují vysokou matematiku s Äímkoliv jiným.Vámi použitá kombinace operaÄního systému a prohlížeÄe není podporována.\nPoužijte prosím prohlížeÄe Firefox nebo Opera v operaÄních systémech Linux a Windows. V Mac OS X použijte Safari.Pro obnovu hesla musíte poskytnout e-mailovou adresu. Na tuto adresu pÅ™ijde potvrzovací odkaz.VaÅ¡e nové heslo je %s Příhlaste se na %s://%s:%s/ Po pÅ™ihlášení si prosím změňte heslo (odkaz "Nastavení" vpravo nahoÅ™e ).Heslo musí mít alespoň 4 znaky a nejvíce 32 znaků. Heslo nesmí obsahovat uživatelské jméno ani mezery.Uživatelské jméno musí zaÄínat písmenem, musí mít nejménÄ› 3 a nejvíce 64 znaků. Můžete použít pouze písmena, Äísla, podtržítko, zavinÃ¡Ä a teÄku.Váš zápisník obdrží jedineÄnou internetovou adresu (URL), kterou můžete poslat svým známým a spolupracovníkům.prohlížet adresářnení možno vyhodnotit buňky v zápisníkuÄeÅ¡tina (ÄŒeská republika)Deutsch (Österreich)English (United States)español (España)vyhodnotitfrançais (France)poslední zmÄ›na %(t)s, uživatel %(le)snahrávání...volitelnénebo vymazat %(f)s.português (Brasil)zveÅ™ejnÄ›noreCAPTCHA private keyreCAPTCHA public keyруÑÑкий (РоÑÑиÑ)spuÅ¡tÄ›nýs (ruší se následující kontroly aktualizace)vyberte zápisníkукраїнÑька (Україна)netiskne sea|anosagenb-1.0.1/sagenb/translations/cs_CZ/LC_MESSAGES/messages.po000066400000000000000000002317431311436262400237010ustar00rootroot00000000000000# translation of sagenb.po to # Robert Marik , 2010. # Czech translation for Sage (www.sagemath.org) # The Czech translation is supported by Grant FRVS 131/2010 # (www.frvs.cz) msgid "" msgstr "" "Project-Id-Version: sagenb\n" "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" "POT-Creation-Date: 2011-06-13 12:49-0700\n" "PO-Revision-Date: 2011-06-13 12:55-0800\n" "Last-Translator: Mike Hansen \n" "Language-Team: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Generated-By: Babel 0.9.5\n" "X-Generator: KBabel 1.11.4\n" "Plural-Forms: nplurals=3; plural=n==1 ? 0 : n>=2 && n<=4 ? 1 : 2;\n" msgid "cs_CZ" msgstr "ÄeÅ¡tina (ÄŒeská republika)" msgid "de_AT" msgstr "Deutsch (Österreich)" msgid "en_US" msgstr "English (United States)" msgid "es_ES" msgstr "español (España)" msgid "pt_BR" msgstr "português (Brasil)" msgid "ru_RU" msgstr "руÑÑкий (РоÑÑиÑ)" msgid "fr_FR" msgstr "français (France)" msgid "uk_UA" msgstr "українÑька (Україна)" #: data/sage/html/base.html:31 #: data/sage/html/login.html:35 msgid "The Sage Notebook" msgstr "ProstÅ™edí Sage Notebook" #: data/sage/html/base.html:33 msgid "Searching for Sage server..." msgstr "Vyhledávání Sage serveru..." #: data/sage/html/base.html:35 msgid "Version" msgstr "Verze" #: data/sage/html/base_authenticated.html:7 msgid "Please log in to the Sage notebook" msgstr "PÅ™ihlaste se prosím do prostÅ™edí Sage Notebook" #: data/sage/html/base_authenticated.html:7 msgid "Log in" msgstr "PÅ™ihlášení" #: data/sage/html/base_authenticated.html:9 msgid "Toggle the top bar" msgstr "PÅ™epnout horní panel" #: data/sage/html/base_authenticated.html:9 #: data/sage/html/test_report.html:123 msgid "Toggle" msgstr "PÅ™epnout" #: data/sage/html/base_authenticated.html:10 msgid "Back to your personal worksheet list" msgstr "ZpÄ›t na seznam zápisníků" #: data/sage/html/base_authenticated.html:10 msgid "Home" msgstr "Domů" #: data/sage/html/base_authenticated.html:12 #: data/sage/html/base_authenticated.html:14 msgid "Published" msgstr "ZveÅ™ejnÄ›né" #: data/sage/html/base_authenticated.html:14 msgid "Browse the published worksheets" msgstr "Prohlížet zveÅ™ejnÄ›né zápisníky" #: data/sage/html/base_authenticated.html:15 msgid "View a log of recent computations" msgstr "Prohlížet historii " #: data/sage/html/base_authenticated.html:15 msgid "Log" msgstr "Log" #: data/sage/html/base_authenticated.html:17 msgid "Change account settings including password" msgstr "ZmÄ›na nastavení úÄtu a hesla" #: data/sage/html/base_authenticated.html:17 msgid "Settings" msgstr "Nastavení" #: data/sage/html/base_authenticated.html:18 msgid "Documentation" msgstr "Dokumentace" #: data/sage/html/base_authenticated.html:18 msgid "Help" msgstr "NápovÄ›da" #: data/sage/html/base_authenticated.html:19 msgid "Report a problem or submit a bug to improve Sage" msgstr "Ohlásit problém nebo chybu pro zlepÅ¡ení Sage" #: data/sage/html/base_authenticated.html:19 msgid "Report a Problem" msgstr "Nahlásit chybu" #: data/sage/html/base_authenticated.html:20 msgid "Log out of the Sage notebook" msgstr "Odhlásit z prostÅ™edí programu Sage" #: data/sage/html/base_authenticated.html:20 msgid "Sign out" msgstr "Odhlásit" #: data/sage/html/docs.html:3 msgid "Sage Documentation" msgstr "Dokumentace programu Sage" #: data/sage/html/docs.html:15 msgid "To quickly try out Sage start here" msgstr "Pro rychlé vyzkouÅ¡ení Sage zaÄnÄ›te zde" #: data/sage/html/docs.html:15 msgid "Tutorial" msgstr "Tutoriál (angl.)" #: data/sage/html/docs.html:16 msgid "View a 4000+ page reference manual about Sage" msgstr "Prohlédnout podrobnou referenÄní příruÄku programu Sage" #: data/sage/html/docs.html:16 msgid "Reference Manual" msgstr "ReferenÄní příruÄka" #: data/sage/html/docs.html:17 msgid "Learn to write Sage programs" msgstr "NauÄte se psát programy pro Sage" #: data/sage/html/docs.html:17 msgid "Developer Guide" msgstr "Průvodce vývojáře" #: data/sage/html/docs.html:18 msgid "How do I construct ... in Sage?" msgstr "Jak udÄ›lám ... v Sage?" #: data/sage/html/docs.html:18 msgid "Constructions" msgstr "NÄ›které programové konstrukce" #: data/sage/html/docs.html:21 msgid "Static version..." msgstr "Statická verze..." #: data/sage/html/docs.html:21 msgid "Fast Static Versions of the Documentation" msgstr "Dokumentace (rychlá statická verze)" #: data/sage/html/docs.html:22 msgid "Help via Internet Chat (IRC)" msgstr "Pomoc na kanálu IRC (Internet Chat)" #: data/sage/html/docs.html:28 msgid "How to use the Sage Notebook" msgstr "Návod k použití prostÅ™edí Sage Notebook" #: data/sage/html/docs.html:30 msgid "A worksheet is an ordered list of Sage calculations with output." msgstr "Zápisník je uspořádaný seznam bunÄ›k a výstupů programu Sage" #: data/sage/html/docs.html:31 msgid "A session is a worksheet and a set of variables in some state." msgstr "Sezení je zápisník a množina promÄ›nných v nÄ›jakých definovaných stavech." #: data/sage/html/docs.html:32 msgid "The Sage notebook is a collection of worksheets, saved objects, and user information." msgstr "Sage notebook je kolekce zápisníků, uložených objektů a uživatelských informací." #: data/sage/html/docs.html:45 msgid "The Sage Notebook was primarily written by William Stein with substantial contributions from Tom Boothby, Timothy Clemans, Alex Clemesha, Mike Hansen, Bobby Moretti, Yi Qiang, and Dorian Raymer." msgstr "Původním autorem programu Sage Notebook je William Stein, dalšími autory jsou Tom Boothby, Timothy Clemans, Alex Clemesha, Mike Hansen, Bobby Moretti, Yi Qiang, Dorian Raymer a další." #: data/sage/html/error_message.html:4 #: data/sage/html/login.html:63 #: data/sage/html/login.html:70 #: data/sage/html/login.html:98 #: data/sage/html/login.html:100 #: data/sage/html/recaptcha.html:27 #: data/sage/html/test_report.html:112 #: data/sage/html/test_report.html:131 #: data/sage/html/accounts/registration.html:20 #: data/sage/html/accounts/registration.html:23 #: data/sage/html/accounts/registration.html:26 #: data/sage/html/accounts/registration.html:36 #: data/sage/html/accounts/registration.html:39 #: data/sage/html/accounts/registration.html:46 #: data/sage/html/accounts/registration.html:57 #: data/sage/html/accounts/registration.html:60 #: data/sage/html/accounts/registration.html:69 #: data/sage/html/accounts/registration.html:72 #: data/sage/html/settings/admin_add_user.html:17 #: data/sage/html/settings/admin_add_user.html:19 #: data/sage/js/translated-messages.js:17 msgid "Error" msgstr "Chyba" #: data/sage/html/error_message.html:19 msgid "Continue" msgstr "PokraÄovat" #: data/sage/html/history.html:3 #, python-format msgid "Sage: History for %(u)s" msgstr "Sage: Historie pro %(u)s" #: data/sage/html/history.html:13 msgid "Click here to turn the above into a Sage worksheet" msgstr "KliknÄ›te zde pro pÅ™evod na zápisník programu Sage" #: data/sage/html/history.html:13 msgid "Create a new Sage worksheet version of the last 100 commands in the above log." msgstr "VytvoÅ™it zápisník s posledními 100 příkazy" #: data/sage/html/login.html:12 #, fuzzy msgid "username" msgstr "Uživatelské jméno" #: data/sage/html/login.html:13 msgid "Select an OpenID provider" msgstr "" #: data/sage/html/login.html:14 #, fuzzy msgid "Send" msgstr "Zakázat" #: data/sage/html/login.html:22 #: data/sage/html/login.html:78 msgid "Sign in" msgstr "PÅ™ihlásit" #: data/sage/html/login.html:28 #, python-format msgid "Congratulations %(u)s! You can now sign into the Sage Notebook." msgstr "Gratulujeme %(u)s! Nyní se můžete pÅ™ihlásit do prostÅ™edí Sage Notebook." #: data/sage/html/login.html:32 msgid "Welcome!" msgstr "Vítejte!" #: data/sage/html/login.html:33 msgid "Sage is a different approach to mathematics software." msgstr "Sage pÅ™edstavuje jiný přístup k matematickým programům." #: data/sage/html/login.html:36 msgid "With the Sage Notebook anyone can create, collaborate on, and publish interactive worksheets. In a worksheet, one can write code using Sage, Python, and other software included in Sage." msgstr "V prostÅ™edí Sage Notebook může každý tvoÅ™it, sdílet a vystavovat interaktivní zápisníky. V zápisnících je možno použít kód v jazycích Sage, Pyhton a dalších programů, zaÄlenÄ›ných do Sage." #: data/sage/html/login.html:39 msgid "General and Advanced Pure and Applied Mathematics" msgstr "Obecná, Äistá a aplikovaná matematika" #: data/sage/html/login.html:40 msgid "Use Sage for studying calculus, elementary to very advanced number theory, cryptography, commutative algebra, group theory, graph theory, numerical and exact linear algebra, and more." msgstr "Sage můžete použít pro studium matematické analýzy, elementární i pokroÄilé teorie Äísel, kryptografie, komutativních algeber, teorie grup, teorie grafů, klasické i numerické lineární algebry a dalších oborů." #: data/sage/html/login.html:43 msgid "Use an Open Source Alternative" msgstr "Používejte volnÄ› Å¡iÅ™itelnou alternativu" #: data/sage/html/login.html:44 msgid "By using Sage you help to support a viable open source alternative to Magma, Maple, Mathematica, and MATLAB. Sage includes many high-quality open source math packages." msgstr "Použitím Sage pomáháte podporovat životaschopnou alternativu k programům Magma, Maple, Mathematica a MATLAB. Sage obsahuje mnoho kvalitních volnÄ› Å¡iÅ™itelných matematických programů a knihoven." #: data/sage/html/login.html:47 msgid "Use Most Mathematics Software from Within Sage" msgstr "Používejte vÄ›tÅ¡inu matematických programů pomocí Sage" #: data/sage/html/login.html:48 msgid "Sage makes it easy for you to use most mathematics software together. Sage includes GAP, GP/PARI, Maxima, and Singular, and dozens of other open packages." msgstr "Sage umožňuje používat mnoho programů z jednotného prostÅ™edí. Sage obsahuje programy GAP, GP/PARI, Maxima, Singular a mnoho dalších." #: data/sage/html/login.html:51 msgid "Use a Mainstream Programming Language" msgstr "Používejte rozšířený programovací jazyk" #: data/sage/html/login.html:52 msgid "You work with Sage using the highly regarded scripting language Python. You can write programs that combine serious mathematics with anything else." msgstr "V Sage pracujete s kvalitním skriptovacím jazykem Python. Můžete psát programy, které kombinují vysokou matematiku s Äímkoliv jiným." #: data/sage/html/login.html:60 #: data/sage/html/accounts/account_recovery.html:13 msgid "Username" msgstr "Uživatelské jméno" #: data/sage/html/login.html:63 msgid "Username is not in the system" msgstr "Uživatelské jméno není v systému" #: data/sage/html/login.html:67 #: data/sage/html/settings/user_management.html:13 msgid "Password" msgstr "Heslo" #: data/sage/html/login.html:70 msgid "Wrong password" msgstr "Å patné heslo" #: data/sage/html/login.html:74 msgid "Remember me" msgstr "Zapamatovat si mÄ›" #: data/sage/html/login.html:83 msgid "Sign up for a new Sage Notebook account" msgstr "VytvoÅ™it nový uživatelský úÄet pro prostÅ™edí Sage Notebook" #: data/sage/html/login.html:87 msgid "Browse published Sage worksheets
    (no login required)" msgstr "Prohlížet zveřejněné zápisníky
    (není nutné pÅ™ihlášení)" #: data/sage/html/login.html:91 msgid "Forgot password" msgstr "ZapomnÄ›l(-a) jsem heslo" #: data/sage/html/login.html:98 msgid "Creating new users is disabled by the administrator." msgstr "" #: data/sage/html/login.html:100 msgid "Javascript must be enabled in order to use the Sage Notebook." msgstr "" #: data/sage/html/source_code.html:3 #: notebook/tutorial.py:358 msgid "Source Code" msgstr "Zdrojový kód" #: data/sage/html/source_code.html:13 msgid "Sage Source Browser" msgstr "ProhlížeÄ zdrojového kódu" #: data/sage/html/source_code.html:14 msgid "browse directory" msgstr "prohlížet adresář" #: data/sage/html/test_report.html:79 msgid "Sage Notebook version" msgstr "Sage Notebook verze" #: data/sage/html/test_report.html:85 msgid "Sage version" msgstr "Sage verze " #: data/sage/html/test_report.html:91 msgid "Environment" msgstr "ProstÅ™edí" #: data/sage/html/test_report.html:96 msgid "Start" msgstr "Start" #: data/sage/html/test_report.html:100 #: data/sage/html/worksheet_listing.html:73 msgid "Stop" msgstr "Zastavit" #: data/sage/html/test_report.html:104 msgid "Elapsed" msgstr "Uplynulo" #: data/sage/html/test_report.html:108 msgid "Status" msgstr "Status" #: data/sage/html/test_report.html:110 #: data/sage/html/test_report.html:129 msgid "Pass" msgstr "Vynechat" #: data/sage/html/test_report.html:111 #: data/sage/html/test_report.html:130 msgid "Fail" msgstr "Selhání" #: data/sage/html/test_report.html:113 msgid "Total" msgstr "Celkem" #: data/sage/html/test_report.html:121 msgid "Hide" msgstr "Skrýt" #: data/sage/html/test_report.html:122 msgid "Show" msgstr "Ukázat" #: data/sage/html/test_report.html:128 msgid "Cases / Tests" msgstr "Testy" #: data/sage/html/test_report.html:132 msgid "Count" msgstr "PoÄet" #: data/sage/html/test_report.html:141 msgid "Totals" msgstr "Celkem" #: data/sage/html/upload.html:10 msgid "Upload worksheet (an sws or txt file) to the Sage Notebook" msgstr "Nahrát zápisník (sws nebo txt soubor) do prostÅ™edí Sage Notebook" #: data/sage/html/upload.html:14 msgid "Browse your computer to select a worksheet file to upload:" msgstr "NajdÄ›te soubor na lokálním poÄítaÄi" #: data/sage/html/upload.html:18 msgid "Or enter the URL of a worksheet file on the web:" msgstr "Nebo zadejte URL zápisníku vystaveného na Internetu" #: data/sage/html/upload.html:22 #: data/sage/html/notebook/upload_data_window.html:27 msgid "What do you want to call it? (if different than the original name)" msgstr "Jak se má zápisník jmenovat (pokud chcete mÄ›nit jméno)" #: data/sage/html/upload.html:25 msgid "Upload Worksheet" msgstr "Nahrát zápisník" #: data/sage/html/worksheet_listing.html:9 msgid "Published Worksheets" msgstr "ZveÅ™ejnÄ›né zápisníky" #: data/sage/html/worksheet_listing.html:11 msgid "Deleted Worksheets" msgstr "Smazané zápisníky" #: data/sage/html/worksheet_listing.html:13 msgid "Active Worksheets" msgstr "Aktivní zápisníky" #: data/sage/html/worksheet_listing.html:15 msgid "Archived Worksheets" msgstr "Archivované zápisníky" #: data/sage/html/worksheet_listing.html:45 msgid "New Worksheet" msgstr "Nový zápisník" #: data/sage/html/worksheet_listing.html:46 msgid "Upload" msgstr "Vložit zápisník ze souboru" #: data/sage/html/worksheet_listing.html:47 msgid "Download All Active" msgstr "Uložit vÅ¡echny aktivní zápisníky" #: data/sage/html/worksheet_listing.html:54 msgid "Search Worksheets" msgstr "Hledat" #: data/sage/html/worksheet_listing.html:62 msgid "Unarchive selected worksheets so it appears in the default worksheet list" msgstr "Odstranit vybrané zápisníky z archivu (objeví se ve výchozím seznamu zápisníků)" #: data/sage/html/worksheet_listing.html:62 msgid "Unarchive" msgstr "ZruÅ¡it archivaci" #: data/sage/html/worksheet_listing.html:64 msgid "Archive selected worksheets so they do not appear in the default worksheet list" msgstr "Archivovat vybrané zápisníky tak, aby se neobjevovaly ve výchozím seznamu zápisníků" #: data/sage/html/worksheet_listing.html:64 msgid "Archive" msgstr "Archivovat" #: data/sage/html/worksheet_listing.html:68 msgid "Move the selected worksheets to the trash" msgstr "PÅ™esunout vybrané zápisníky do koÅ¡e" #: data/sage/html/worksheet_listing.html:68 msgid "Delete" msgstr "Smazat" #: data/sage/html/worksheet_listing.html:70 msgid "Move the selected worksheets out of the trash" msgstr "PÅ™esunout vybrané zápisníky z koÅ¡e do výchozího seznamu" #: data/sage/html/worksheet_listing.html:70 msgid "Undelete" msgstr "Obnovit" #: data/sage/html/worksheet_listing.html:73 msgid "Stop selected worksheets" msgstr "Pozastavit vybrané zápisníky" #: data/sage/html/worksheet_listing.html:75 msgid "Download selected worksheets" msgstr "Stáhnout vybrané zápisníky" #: data/sage/html/worksheet_listing.html:75 msgid "Download" msgstr "Stáhnout" #: data/sage/html/worksheet_listing.html:79 msgid "Current Folder" msgstr "Složky" #: data/sage/html/worksheet_listing.html:80 msgid "Active" msgstr "Aktivní" #: data/sage/html/worksheet_listing.html:81 msgid "Archived" msgstr "Archivované" #: data/sage/html/worksheet_listing.html:82 msgid "Trash" msgstr "KoÅ¡" #: data/sage/html/worksheet_listing.html:86 msgid "Empty Trash" msgstr "Vysypat koÅ¡" #: data/sage/html/worksheet_listing.html:101 #: data/sage/html/worksheet/ratings_info.html:9 msgid "Rating" msgstr "Hodnocení" #: data/sage/html/worksheet_listing.html:112 msgid "Owner" msgstr "Majitel" #: data/sage/html/worksheet_listing.html:112 msgid "Collaborators" msgstr "Spolupracovníci" #: data/sage/html/worksheet_listing.html:118 #: data/sage/html/notebook/worksheet_revision_list.html:16 msgid "Last Edited" msgstr "Naposledy upraveno" #: data/sage/html/worksheet_listing.html:128 msgid "There are no published worksheets." msgstr "Nejsou zveÅ™ejnÄ›ny žádné zápisníky" #: data/sage/html/worksheet_listing.html:134 msgid "Welcome to Sage! You can create a new worksheet, view published worksheets, or read the documentation." msgstr "Vítejte v Sage! Můžete vytvoÅ™it nový zápisník, prohlédnout si zveÅ™ejnÄ›né zápisníky, nebo pÅ™eÄíst dokumentaci." #: data/sage/html/worksheet_listing.html:176 msgid "running" msgstr "spuÅ¡tÄ›ný" #: data/sage/html/worksheet_listing.html:209 msgid "Add or Delete" msgstr "PÅ™idat nebo vymazat" #: data/sage/html/worksheet_listing.html:211 msgid "Share now" msgstr "Sdílet" #: data/sage/html/worksheet_listing.html:216 msgid "published" msgstr "zveÅ™ejnÄ›no" #: data/sage/html/accounts/account_recovery.html:3 #: data/sage/html/accounts/account_recovery.html:8 msgid "Account Recovery" msgstr "Obnova uživatelského úÄtu" #: data/sage/html/accounts/account_recovery.html:9 msgid "A new password will be emailed to the email address connected to your account. However if you didn't confirm your email address you will be unable to recover your account." msgstr "Nové heslo Vám bude zasláno na emailovou adresu spojenou s vaším úÄtem. Pokud nepotvrdíte správnÄ› VaÅ¡i mailovou adresu, nebudete mít k obnovÄ› úÄtu přístup." #: data/sage/html/accounts/account_recovery.html:17 msgid "Submit" msgstr "Odeslat" #: data/sage/html/accounts/account_recovery.html:17 #: data/sage/html/accounts/registration.html:78 #: data/sage/html/notebook/download_or_delete_datafile.html:54 #: data/sage/html/notebook/edit_window.html:12 #: data/sage/html/settings/account_settings.html:10 #: data/sage/html/settings/account_settings.html:67 #: data/sage/html/settings/admin_add_user.html:26 #: data/sage/html/settings/notebook_settings.html:20 #: data/sage/html/settings/notebook_settings.html:27 msgid "Cancel" msgstr "ZruÅ¡it" #: data/sage/html/accounts/registration.html:3 msgid "Sign up" msgstr "PÅ™ihlásit" #: data/sage/html/accounts/registration.html:9 msgid "Sign up for a Sage Notebook account" msgstr "Založení nového úÄtu pro prostÅ™edí Sage Notebook" #: data/sage/html/accounts/registration.html:11 msgid "Errors found" msgstr "Byly nalezeny chyby" #: data/sage/html/accounts/registration.html:11 msgid "Error found" msgstr "Nalezena chyba" #: data/sage/html/accounts/registration.html:16 msgid "Create a username" msgstr "Zvolte si uživatelské jméno" #: data/sage/html/accounts/registration.html:17 msgid "Your username must start with a letter and be between 3 and 64 characters long. You may only use letters, numbers, underscores, @, and dots." msgstr "Uživatelské jméno musí zaÄínat písmenem, musí mít nejménÄ› 3 a nejvíce 64 znaků. Můžete použít pouze písmena, Äísla, podtržítko, zavinÃ¡Ä a teÄku." #: data/sage/html/accounts/registration.html:20 msgid "No username given" msgstr "Nebylo zadáno uživatelské jméno" #: data/sage/html/accounts/registration.html:23 msgid "Username already in use" msgstr "Toto uživatelské jméno je již zaregistrováno" #: data/sage/html/accounts/registration.html:26 msgid "Bad username" msgstr "Neplatné uživatelské jméno" #: data/sage/html/accounts/registration.html:30 msgid "Create a good password" msgstr "VytvoÅ™te si silné heslo" #: data/sage/html/accounts/registration.html:32 msgid "Your password must be between 4 and 32 characters long. Your password can not contain your username nor spaces." msgstr "Heslo musí mít alespoň 4 znaky a nejvíce 32 znaků. Heslo nesmí obsahovat uživatelské jméno ani mezery." #: data/sage/html/accounts/registration.html:36 msgid "No password given" msgstr "Nebylo zadáno heslo." #: data/sage/html/accounts/registration.html:39 msgid "Bad password" msgstr "Chybné heslo" #: data/sage/html/accounts/registration.html:43 msgid "Re-type your password" msgstr "Zadejte heslo jeÅ¡tÄ› jednou" #: data/sage/html/accounts/registration.html:46 msgid "Passwords didn't match" msgstr "Hesla se neshodují" #: data/sage/html/accounts/registration.html:51 msgid "Enter your email address" msgstr "Zadejte svoji emailovou adresu" #: data/sage/html/accounts/registration.html:53 msgid "Your email address is required for account confirmation and recovery. You will be emailed a confirmation link right after you successfully sign up." msgstr "Pro obnovu hesla musíte poskytnout e-mailovou adresu. Na tuto adresu pÅ™ijde potvrzovací odkaz." #: data/sage/html/accounts/registration.html:57 msgid "No email address given" msgstr "Není zadána emailová adresa" #: data/sage/html/accounts/registration.html:60 msgid "Invalid email address" msgstr "Neplatná emailová adresa" #: data/sage/html/accounts/registration.html:66 msgid "Answer a challenge" msgstr "ZodpovÄ›zte úkol" #: data/sage/html/accounts/registration.html:69 msgid "No challenge response given" msgstr "Nebyla zadána odpovÄ›Ä" #: data/sage/html/accounts/registration.html:72 msgid "Invalid challenge response" msgstr "Å patná odpovÄ›Ä" #: data/sage/html/accounts/registration.html:77 msgid "Create account" msgstr "VytvoÅ™it uživatelský úÄet" #: data/sage/html/notebook/afterpublish_window.html:8 #, python-format msgid "Worksheet is publicly viewable at %(u)s" msgstr "Zápisník je veÅ™ejnÄ› přístupný na %(u)s" #: data/sage/html/notebook/afterpublish_window.html:9 #, python-format msgid "Published on %(t)s" msgstr "ZveÅ™ejnÄ›no dne %(t)s" #: data/sage/html/notebook/afterpublish_window.html:11 msgid "Re-publish worksheet" msgstr "Aktualizovat zveÅ™ejnÄ›nou verzi zápisníku" #: data/sage/html/notebook/afterpublish_window.html:12 msgid "Stop publishing" msgstr "Pozastavit zveÅ™ejnÄ›ní" #: data/sage/html/notebook/afterpublish_window.html:14 #: data/sage/html/notebook/beforepublish_window.html:18 msgid "Automatically re-publish when changes are made" msgstr "Po zmÄ›nách aktualizovat automaticky i zveÅ™ejnÄ›nou verzi" #: data/sage/html/notebook/base.html:74 msgid "Click to rename this worksheet" msgstr "KliknÄ›te pro pÅ™ejmenování zápisníku" #: data/sage/html/notebook/base.html:79 msgid "Someone else is viewing this worksheet" msgstr "Další uživatel si prohlíží tento zápisník" #: data/sage/html/notebook/base.html:84 #: data/sage/html/notebook/text_cell.html:46 msgid "Save changes" msgstr "Uložit zmÄ›ny" #: data/sage/html/notebook/base.html:84 #: data/sage/html/settings/account_settings.html:9 #: data/sage/html/settings/account_settings.html:66 #: data/sage/html/settings/notebook_settings.html:19 #: data/sage/html/settings/notebook_settings.html:26 msgid "Save" msgstr "Uložit" #: data/sage/html/notebook/base.html:84 msgid "Save changes and close window" msgstr "Uložit zmÄ›ny a zavřít okno" #: data/sage/html/notebook/base.html:84 msgid "Save & quit" msgstr "Uložit a zavřít" #: data/sage/html/notebook/base.html:84 msgid "Discard changes to this worksheet" msgstr "Zahodit zmÄ›ny v tomto zápisníku" #: data/sage/html/notebook/base.html:84 msgid "Discard & quit" msgstr "Zavřít bez uložení" #: data/sage/html/notebook/base.html:90 msgid "Select a file related function" msgstr "Vyberte funkci pro práci se souborem" #: data/sage/html/notebook/base.html:90 msgid "File..." msgstr "Soubor..." #: data/sage/html/notebook/base.html:91 msgid "Load a new worksheet stored in a file" msgstr "Nahrát nový zápisník ze souboru" #: data/sage/html/notebook/base.html:91 msgid "Load worksheet from a file..." msgstr "Nahrát zápisník ze souboru" #: data/sage/html/notebook/base.html:92 msgid "Create a new worksheet" msgstr "VytvoÅ™it nový zápisník" #: data/sage/html/notebook/base.html:92 msgid "New worksheet" msgstr "Nový zápisník" #: data/sage/html/notebook/base.html:93 msgid "Save this worksheet to an sws file" msgstr "Uložit zápisník jako sws soubor" #: data/sage/html/notebook/base.html:93 msgid "Save worksheet to a file..." msgstr "Uložit zápisník do souboru" #: data/sage/html/notebook/base.html:94 #: data/sage/html/notebook/base.html:143 msgid "Print this worksheet" msgstr "Vytisknout tento zápisník" #: data/sage/html/notebook/base.html:94 #: data/sage/html/notebook/base.html:143 msgid "Print" msgstr "Tisk" #: data/sage/html/notebook/base.html:95 msgid "Rename this worksheet" msgstr "PÅ™ejmenovat tento zápisník" #: data/sage/html/notebook/base.html:95 #: data/sage/js/translated-messages.js:11 msgid "Rename worksheet" msgstr "PÅ™ejmenovat zápisník" #: data/sage/html/notebook/base.html:96 msgid "Copy this worksheet" msgstr "Zkopírovat tento zápisník" #: data/sage/html/notebook/base.html:96 msgid "Copy worksheet" msgstr "Zkopírovat zápisník" #: data/sage/html/notebook/base.html:97 msgid "Move this worksheet to the trash" msgstr "PÅ™esunout zápisník do odpadkového koÅ¡e" #: data/sage/html/notebook/base.html:97 msgid "Delete worksheet" msgstr "Vymazat zápisník" #: data/sage/html/notebook/base.html:101 msgid "Select a worksheet function" msgstr "Vyberte funkci pro práci se zápisníkem" #: data/sage/html/notebook/base.html:101 msgid "Action..." msgstr "Akce..." #: data/sage/html/notebook/base.html:102 msgid "Interrupt currently running calculations, if possible" msgstr "Pozastavit bežící výpoÄet, je-li to možné" #: data/sage/html/notebook/base.html:102 msgid "Interrupt" msgstr "PÅ™eruÅ¡it" #: data/sage/html/notebook/base.html:103 msgid "Restart the worksheet process" msgstr "Restartovat proces zápisníku" #: data/sage/html/notebook/base.html:103 msgid "Restart worksheet" msgstr "Restartovat zápisník" #: data/sage/html/notebook/base.html:104 msgid "Quit the worksheet process" msgstr "UkonÄit proces náležící zápisníku" #: data/sage/html/notebook/base.html:104 msgid "Save and quit worksheet" msgstr "Uložit a ukonÄit" #: data/sage/html/notebook/base.html:106 msgid "Evaluate all input cells in the worksheet" msgstr "Vyhodnotit vÅ¡echny vstupní buňky" #: data/sage/html/notebook/base.html:106 msgid "Evaluate All" msgstr "Vyhodnotit vÅ¡e" #: data/sage/html/notebook/base.html:107 msgid "Hide all output" msgstr "Ukrýt vÅ¡echny výstupy" #: data/sage/html/notebook/base.html:107 msgid "Hide All Output" msgstr "Ukrýt vÅ¡echny výstupy" #: data/sage/html/notebook/base.html:108 msgid "Show all output" msgstr "Zobrazit vÅ¡echny výstupy" #: data/sage/html/notebook/base.html:108 msgid "Show All Output" msgstr "Zobrazit vÅ¡echny výstupy" #: data/sage/html/notebook/base.html:109 msgid "Delete all output" msgstr "Vymazat vÅ¡echny výstupy" #: data/sage/html/notebook/base.html:109 msgid "Delete All Output" msgstr "Vymazat vÅ¡echny výstupy" #: data/sage/html/notebook/base.html:111 msgid "Switch to single-cell mode" msgstr "PÅ™epnout do módu s jednou vstupní buňkou" #: data/sage/html/notebook/base.html:111 msgid "One Cell Mode" msgstr "Režim s jednou vstupní buňkou" #: data/sage/html/notebook/base.html:112 msgid "Switch to multi-cell mode" msgstr "PÅ™epnout do módu s více vstupními buňkami" #: data/sage/html/notebook/base.html:112 msgid "Multi Cell Mode" msgstr "Režim s více vstupními buňkami" #: data/sage/html/notebook/base.html:115 msgid "Select an attached file" msgstr "Vyberte pÅ™ipojený soubor" #: data/sage/html/notebook/base.html:115 msgid "Data..." msgstr "Data..." #: data/sage/html/notebook/base.html:116 msgid "Upload or create a data file in a wide range of formats" msgstr "Můžete nahrát nebo vytvoÅ™it soubor s daty v Å¡iroké Å¡kále formátů" #: data/sage/html/notebook/base.html:116 msgid "Upload or create file..." msgstr "Nahrát nebo vytvoÅ™it soubor" #: data/sage/html/notebook/base.html:126 #, python-format msgid "Evaluate all input cells using %(i)s" msgstr "Vyhodnotit vÅ¡echny buňky pomocí %(i)s" #: data/sage/html/notebook/base.html:132 msgid "Enable/disable pretty_printing" msgstr "Povolit/zakázat pretty_printing (pÄ›kné formátování matematických výrazů)" #: data/sage/html/notebook/base.html:144 msgid "Interactively use this worksheet" msgstr "Interaktivní práce se zápisníkem" #: data/sage/html/notebook/base.html:144 msgid "Worksheet" msgstr "Zápisník" #: data/sage/html/notebook/base.html:145 msgid "Edit text version of this worksheet" msgstr "Editace textové verze zápisníku" #: data/sage/html/notebook/base.html:145 msgid "Edit" msgstr "Editovat" #: data/sage/html/notebook/base.html:146 msgid "View plain text version of this worksheet" msgstr "Zobrazení textové verze zápisníku" #: data/sage/html/notebook/base.html:146 msgid "Text" msgstr "Text" #: data/sage/html/notebook/base.html:147 msgid "View changes to this worksheet over time" msgstr "Zobrazit zmÄ›ny v zápisníku a umožnit návrat k dřívÄ›jší verzi" #: data/sage/html/notebook/base.html:147 msgid "Undo" msgstr "Historie" #: data/sage/html/notebook/base.html:148 msgid "Let others edit this worksheet" msgstr "Povolit ostatním prohlížet a editovat tento zápisník" #: data/sage/html/notebook/base.html:148 msgid "Share" msgstr "Sdílet" #: data/sage/html/notebook/base.html:149 msgid "Make this worksheet publicly viewable" msgstr "ZveÅ™ejnit tento zápisník" #: data/sage/html/notebook/base.html:149 msgid "Publish" msgstr "ZveÅ™ejnit" #: data/sage/html/notebook/base.html:157 msgid "Exit" msgstr "Konec" #: data/sage/html/notebook/beforepublish_window.html:5 msgid "You can publish your worksheet to the Internet, where anyone will be able to access and view it online." msgstr "Svůj zápisník můžete zveÅ™ejnit na Internetu. Každý si jej bude moci prohlédnout online." #: data/sage/html/notebook/beforepublish_window.html:7 msgid "Your worksheet will be assigned a unique address (URL) that you can send to your friends and colleagues." msgstr "Váš zápisník obdrží jedineÄnou internetovou adresu (URL), kterou můžete poslat svým známým a spolupracovníkům." #: data/sage/html/notebook/beforepublish_window.html:9 msgid "Do you want to publish this worksheet?" msgstr "Chcete zveÅ™ejnit tento zápisník?" #: data/sage/html/notebook/beforepublish_window.html:14 msgid "Yes" msgstr "Ano" #: data/sage/html/notebook/beforepublish_window.html:15 msgid "No" msgstr "Ne" #: data/sage/html/notebook/cell.html:63 msgid "Click here or press shift-return to evaluate" msgstr "KliknÄ›te sem nebo stisknÄ›te shift+enter pro spuÅ¡tÄ›ní výpoÄtu" #: data/sage/html/notebook/cell.html:64 msgid "evaluate" msgstr "vyhodnotit" #: data/sage/html/notebook/download_or_delete_datafile.html:35 msgid "Data file" msgstr "Datový soubor" #: data/sage/html/notebook/download_or_delete_datafile.html:39 #, python-format msgid "You may download %(f)s or create a linked copy to the worksheet" msgstr "Můžete stáhnout %(f)s nebo vytvoÅ™it kopii tohoto zápisníku" #: data/sage/html/notebook/download_or_delete_datafile.html:40 msgid "select worksheet" msgstr "vyberte zápisník" #: data/sage/html/notebook/download_or_delete_datafile.html:44 #, python-format msgid "or delete %(f)s." msgstr "nebo vymazat %(f)s." #: data/sage/html/notebook/download_or_delete_datafile.html:46 #, python-format msgid "Access %(f)s in this worksheet by typing DATA+'%(f)s'. Here DATA is a special variable that gives the exact path to all data files uploaded to this worksheet." msgstr "Soubor %(f)s v tomto zápisníku zpřístupníte pomocí DATA+'%(f)s'. Speciální promÄ›nná DATA obsahuje cestu ke vÅ¡em datům, která byla nahrána k tomuto zápisníku." #: data/sage/html/notebook/download_or_delete_datafile.html:54 #: data/sage/html/notebook/edit_window.html:11 msgid "Save Changes" msgstr "Uložit zmÄ›ny" #: data/sage/html/notebook/edit_window.html:10 msgid "Edit plain text" msgstr "Editovat textovou verzi" #: data/sage/html/notebook/guest_worksheet_page.html:14 msgid "Edit this." msgstr "Editovat zde." #: data/sage/html/notebook/guest_worksheet_page.html:16 msgid "Log in to edit a copy." msgstr "PÅ™ihlásit se a editovat kopii." #: data/sage/html/notebook/guest_worksheet_page.html:19 msgid "Edit a copy." msgstr "Editovat kopii." #: data/sage/html/notebook/guest_worksheet_page.html:28 msgid "Download." msgstr "Stáhnout." #: data/sage/html/notebook/guest_worksheet_page.html:34 #, python-format msgid "This page is rated %(wr).1f." msgstr "Tato stránka má hodnocení %(wr).1f." #: data/sage/html/notebook/guest_worksheet_page.html:39 #, fuzzy msgid "Rerate" msgstr "ZmÄ›nit hodnocení:" #: data/sage/html/notebook/guest_worksheet_page.html:39 #, fuzzy msgid "Rate" msgstr "Ohodnotit:" #: data/sage/html/notebook/guest_worksheet_page.html:49 msgid "Other published documents..." msgstr "Jiné zveÅ™ejnÄ›né zápisníky..." #: data/sage/html/notebook/plain_text_window.html:4 msgid "View plain text" msgstr "Textová verze zápisníku" #: data/sage/html/notebook/specific_revision.html:5 #, python-format msgid "Revision from %(ta)s ago" msgstr "Verze uložená pÅ™ed %(ta)s" #: data/sage/html/notebook/specific_revision.html:5 msgid "Revision List" msgstr "Seznam verzí" #: data/sage/html/notebook/specific_revision.html:12 msgid "Older" msgstr "Starší" #: data/sage/html/notebook/specific_revision.html:14 msgid "Oldest" msgstr "Nejstarší" #: data/sage/html/notebook/specific_revision.html:18 msgid "Newer" msgstr "NovÄ›jší" #: data/sage/html/notebook/specific_revision.html:20 msgid "Newest" msgstr "NejnovÄ›jší" #: data/sage/html/notebook/specific_revision.html:23 msgid "Revert to this one" msgstr "Vrátit na tuto verzi" #: data/sage/html/notebook/specific_revision.html:23 msgid "(note that images are not recorded)" msgstr "(obrázky nejsou uloženy)" #: data/sage/html/notebook/specific_revision.html:24 msgid "Publish this one" msgstr "ZveÅ™ejnit tohle" #: data/sage/html/notebook/text_cell.html:47 msgid "Cancel changes" msgstr "ZruÅ¡it zmÄ›ny" #: data/sage/html/notebook/upload_data_window.html:7 #, python-format msgid "Upload or Create Data File to attach to worksheet \"%(wn)s\"" msgstr "Nahrát nebo vytvoÅ™it datový soubor pÅ™ipojený k zápisníku \"%(wn)s\"" #: data/sage/html/notebook/upload_data_window.html:15 msgid "Browse your computer to select a file to upload:" msgstr "Vyberte soubor pro uložení na server" #: data/sage/html/notebook/upload_data_window.html:19 msgid "Or enter the URL of a file on the web:" msgstr "Nebo zadejte URL souboru na internetu" #: data/sage/html/notebook/upload_data_window.html:23 msgid "Or enter the name of a new file, which will be created:" msgstr "Nebo můžete zadat jméno nového souboru, který chcete vytvoÅ™it:" #: data/sage/html/notebook/upload_data_window.html:30 msgid "Upload or Create Data File" msgstr "Nahrát nebo vytvoÅ™it soubor" #: data/sage/html/notebook/worksheet_page.html:27 #: notebook/twist.py:413 #: notebook/twist.py:2217 #: notebook/worksheet.py:703 #: notebook/worksheet.py:723 #: notebook/worksheet.py:4079 msgid "Untitled" msgstr "Bezejména" #: data/sage/html/notebook/worksheet_revision_list.html:6 msgid "Revision History" msgstr "Historie zmÄ›n" #: data/sage/html/notebook/worksheet_revision_list.html:15 msgid "Revision" msgstr "Verze" #: data/sage/html/notebook/worksheet_revision_list.html:22 #, python-format msgid "Revision %(lr)s" msgstr "Verze %(lr)s" #: data/sage/html/notebook/worksheet_share.html:10 msgid "Share this document" msgstr "Sdílet dokument" #: data/sage/html/notebook/worksheet_share.html:17 msgid "Only the owner of a worksheet is allowed to share it. You can do whatever you want if you make your own copy." msgstr "Pouze majitel zápisníku jej může sdílet. Pro vlastní úpravy si můžete udÄ›lat vlastní kopii zápisníku." #: data/sage/html/notebook/worksheet_share.html:19 msgid "This Sage Worksheet is currently shared with the people listed in the box below." msgstr "Tento zápisník v souÄasnosti sdílí níže uvedení uživatelé." #: data/sage/html/notebook/worksheet_share.html:20 msgid "You may add or remove collaborators (separate user names by commas)." msgstr "Můžete pÅ™edat nebo odstranit spolupracovníky (uživatelská jména oddÄ›lujte Äárkami)." #: data/sage/html/notebook/worksheet_share.html:24 msgid "Give access to your worksheet to the above collaborators" msgstr "Zpřístupnit zápisník následujícím spolupracovníkům" #: data/sage/html/notebook/worksheet_share.html:24 msgid "Invite Collaborators" msgstr "PÅ™izvat spolupracovníky" #: data/sage/html/notebook/worksheet_share.html:28 msgid "Sage Users:" msgstr "Uživatelé:" #: data/sage/html/settings/account_settings.html:3 #: data/sage/html/settings/base.html:13 msgid "Account Settings" msgstr "Nastavení úÄtu" #: data/sage/html/settings/account_settings.html:13 msgid "Change Auto-Save Interval" msgstr "ZmÄ›nit interval pro automatické ukládání" #: data/sage/html/settings/account_settings.html:15 #, fuzzy msgid "Minutes" msgstr "Minuty:" #: data/sage/html/settings/account_settings.html:24 msgid "Change Password" msgstr "ZmÄ›na hesla" #: data/sage/html/settings/account_settings.html:30 msgid "Old password" msgstr "Staré heslo" #: data/sage/html/settings/account_settings.html:34 msgid "New password" msgstr "Nové heslo" #: data/sage/html/settings/account_settings.html:38 msgid "Retype new password" msgstr "Znovu zadejte nové heslo" #: data/sage/html/settings/account_settings.html:46 msgid "Change E-mail Address" msgstr "ZmÄ›nit e-mailovou adresu" #: data/sage/html/settings/account_settings.html:50 msgid "Current e-mail" msgstr "SouÄasný e-mail" #: data/sage/html/settings/account_settings.html:54 msgid "New e-mail" msgstr "Nový e-mail" #: data/sage/html/settings/admin_add_user.html:2 #: data/sage/html/settings/admin_add_user.html:6 msgid "Add New User" msgstr "PÅ™idat nového uživatele" #: data/sage/html/settings/admin_add_user.html:8 msgid "Username Error" msgstr "Chyba v uživatelském jménÄ›" #: data/sage/html/settings/admin_add_user.html:12 msgid "Pick a username" msgstr "Vyberte uživatelské jméno" #: data/sage/html/settings/admin_add_user.html:13 msgid "The username must start with a letter and be between 4 and 32 characters long. It can only consist of letters, numbers, underscores, and one dot (.)." msgstr "Uživatelské jméno musí zaÄínat písmenem a musí být alespoň 4 a nejvýše 32 znaků dlouhé. Může obsahovat pouze písmena, Äísla, podtržítka a jednu teÄku (.)." #: data/sage/html/settings/admin_add_user.html:17 msgid "Invalid username" msgstr "Chybné uživatelské jméno" #: data/sage/html/settings/admin_add_user.html:19 msgid "Username taken" msgstr "Uživatelské jméno obdrženo" #: data/sage/html/settings/admin_add_user.html:25 msgid "Create Account" msgstr "VytvoÅ™it úÄet" #: data/sage/html/settings/base.html:10 msgid "Manage Users" msgstr "Správa uživatelů" #: data/sage/html/settings/base.html:11 #: data/sage/html/settings/notebook_settings.html:2 msgid "Notebook Settings" msgstr "Nastavení Notebooku" #: data/sage/html/settings/user_management.html:3 #: data/sage/html/settings/user_management.html:13 msgid "Users" msgstr "Uživatelé" #: data/sage/html/settings/user_management.html:7 msgid "User Management" msgstr "Správa uživatelů" #: data/sage/html/settings/user_management.html:8 msgid "Add User" msgstr "PÅ™idat uživatele" #: data/sage/html/settings/user_management.html:10 #, python-format msgid "The password for the user %(u)s has been reset to %(p)s" msgstr "Heslo pro uživatele %(u)s bylo nastaveno na %(p)s" #: data/sage/html/settings/user_management.html:13 msgid "Suspension" msgstr "Pozastavení" #: data/sage/html/settings/user_management.html:16 msgid "Reset" msgstr "Resetovat" #: data/sage/html/settings/user_management.html:16 msgid "Unsuspend" msgstr "Povolit" #: data/sage/html/settings/user_management.html:16 msgid "Suspend" msgstr "Zakázat" #: data/sage/html/worksheet/ratings_info.html:3 #: data/sage/html/worksheet/ratings_info.html:6 #, python-format msgid "Ratings for %(wn)s" msgstr "Hodnocení pro %(wn)s" #: data/sage/html/worksheet/ratings_info.html:7 msgid "Go to the worksheet." msgstr "PÅ™ejít na zápisník." #: data/sage/html/worksheet/ratings_info.html:9 msgid "User" msgstr "Uživatel" #: data/sage/html/worksheet/ratings_info.html:9 msgid "Comment" msgstr "Komentář" #: data/sage/html/worksheet/time_last_edited.html:6 #, python-format msgid "last edited on %(t)s by %(le)s" msgstr "poslední zmÄ›na %(t)s, uživatel %(le)s" #: data/sage/html/worksheet/time_since_last_edited.html:6 #: notebook/worksheet.py:2009 #, python-format msgid "%(t)s ago by %(le)s" msgstr "pÅ™ed %(t)s, autor %(le)s" #: data/sage/js/translated-messages.js:4 msgid "Click to download and install tex fonts." msgstr "Kliknutím spustíte stažení a instalaci TeXovských fontů." #: data/sage/js/translated-messages.js:5 msgid "" "Your browser / OS combination is not supported.\\n" "Please use Firefox or Opera under Linux, Windows, or Mac OS X, or Safari." msgstr "" "Vámi použitá kombinace operaÄního systému a prohlížeÄe není podporována.\\n" "Použijte prosím prohlížeÄe Firefox nebo Opera v operaÄních systémech Linux a Windows. V Mac OS X použijte Safari." #: data/sage/js/translated-messages.js:6 msgid "Java Applet Hidden" msgstr "Skrytý Java applet" #: data/sage/js/translated-messages.js:7 msgid "Click here to pop out" msgstr "KliknÄ›te sem pro vložení do samostatného okna" #: data/sage/js/translated-messages.js:8 msgid "Error applying function to worksheet(s)." msgstr "Chyby pÅ™i použití funkce na zápisník(y)." #: data/sage/js/translated-messages.js:9 msgid "Title of saved worksheet" msgstr "Název ukládaného zápisníku" #: data/sage/js/translated-messages.js:10 msgid "Failed to save worksheet." msgstr "Uložení zápisníku se nezdaÅ™ilo." #: data/sage/js/translated-messages.js:12 msgid "Please enter a name for this worksheet." msgstr "Prosím, zadejte název zápisníku." #: data/sage/js/translated-messages.js:13 msgid "Rename" msgstr "PÅ™ejmenovat" #: data/sage/js/translated-messages.js:14 msgid "Possible failure deleting worksheet." msgstr "PravdÄ›podobnÄ› nastala chyba pÅ™i mazání souboru" #: data/sage/js/translated-messages.js:15 msgid "unprinted" msgstr "netiskne se" #: data/sage/js/translated-messages.js:16 msgid "You requested to evaluate a cell that, for some reason, the server is unaware of." msgstr "Z nÄ›jakého důvodu server nereagoval na žádost o vyhodnocení buňky." #: data/sage/js/translated-messages.js:18 msgid "This worksheet is read only. Please make a copy or contact the owner to change it." msgstr "Tento zápisník je pouze ke Ätení. Prosím udÄ›lejte si kopii nebo kontaktujte majitele pro zmÄ›nu nastavení." #: data/sage/js/translated-messages.js:19 msgid "loading..." msgstr "nahrávání..." #: data/sage/js/translated-messages.js:20 msgid "Error updating cell output after " msgstr "Chyba pÅ™i aktualizaci buňky po " #: data/sage/js/translated-messages.js:21 msgid "s (canceling further update checks)." msgstr "s (ruší se následující kontroly aktualizace)" #: data/sage/js/translated-messages.js:22 msgid "Problem inserting new input cell after current input cell.\\n" msgstr "NepodaÅ™ilo se vložit novou buňku za buňku souÄasnou.\\n" #: data/sage/js/translated-messages.js:23 msgid "Worksheet is locked. Cannot insert cells." msgstr "Zápisník je zamÄený pro zmÄ›ny. Není možno vložit buňky." #: data/sage/js/translated-messages.js:24 msgid "Unable to interrupt calculation." msgstr "PÅ™eruÅ¡ení výpoÄtu se nezdaÅ™ilo." #: data/sage/js/translated-messages.js:25 msgid "Close this box to stop trying." msgstr "ZavÅ™ete rámeÄek pro konec pokusů." #: data/sage/js/translated-messages.js:26 msgid "Interrupt attempt" msgstr "Pokus o pÅ™eruÅ¡ení" #: data/sage/js/translated-messages.js:27 msgid "Restart, instead?" msgstr "Restartovat?" #: data/sage/js/translated-messages.js:28 msgid "Emptying the trash will permanently delete all items in the trash. Continue?" msgstr "Vysypání koÅ¡e definitivnÄ› odstraní vÅ¡echny položky,které v koÅ¡i jsou. PokraÄovat?" #: data/sage/js/translated-messages.js:29 msgid "Get Image" msgstr "Uložit obrázek" #: data/sage/js/translated-messages.js:30 msgid "Jmol Image" msgstr "Obrázek programu Jmoll" #: data/sage/js/translated-messages.js:31 msgid "To save this image, you can try right-clicking on the image to copy it or save it to a file, or you may be able to just drag the image to your desktop." msgstr "Obrázek můžete uložit do souboru pomocí pravého tlaÄítka myÅ¡i. V nÄ›kterých prostÅ™edích je možno obrázek přímo pÅ™etáhnout na plochu." #: data/sage/js/translated-messages.js:32 msgid "Sorry, but you need a browser that supports the <canvas> tag." msgstr "Litujeme, musíte použít prohlížeÄ, který podporuje tag <canvas>." #: data/sage/js/translated-messages.js:33 #, python-format msgid "Trying again in %(num)d second..." msgid_plural "Trying again in %(num)d seconds..." msgstr[0] "Nový pokus za %(num)d sekundu..." msgstr[1] "Nový pokus za %(num)d sekund..." msgstr[2] "Nový pokus za %(num)d sekund..." #: notebook/challenge.py:179 msgid "Please ask the server administrator to configure a challenge!" msgstr "Požádejte administrátora serveru o konfiguraci kontrolních otázek!" #: notebook/challenge.py:217 msgid "Is pi > e?" msgstr "Je pi>e?" #: notebook/challenge.py:217 msgid "y|yes" msgstr "a|ano" #: notebook/challenge.py:218 msgid "What is 3 times 8?" msgstr "Kolik je tÅ™i krát osm?" #: notebook/challenge.py:218 msgid "24|twenty-four" msgstr "24|dvacet ÄtyÅ™i" #: notebook/challenge.py:219 msgid "What is 2 plus 3?" msgstr "Kolik je 2 plus 3?" #: notebook/challenge.py:219 #: notebook/challenge.py:221 msgid "5|five" msgstr "5|pÄ›t" #: notebook/challenge.py:220 msgid "How many bits are in one byte?" msgstr "Kolik bitů je v jednom bajtu? " #: notebook/challenge.py:220 msgid "8|eight" msgstr "8|osm" #: notebook/challenge.py:221 msgid "What is the largest prime factor of 15?" msgstr "Jaký je nejvÄ›tší dÄ›litel Äísla 15?" #: notebook/conf.py:120 msgid "Updated" msgstr "Aktualizováno" #: notebook/notebook.py:169 msgid "optional" msgstr "volitelné" #: notebook/register.py:19 #: notebook/register.py:26 #, python-format msgid "" "Hi %s!\n" "\n" msgstr "" "Ahoj %s!\n" "\n" #: notebook/register.py:20 #, python-format msgid "" "Thank you for registering for the Sage notebook. To complete your registration, copy and paste the following link into your browser:\n" "\n" "%s://%s:%s/confirm?key=%s\n" "\n" "You will be taken to a page which will confirm that you have indeed registered." msgstr "" "DÄ›kujeme za registraci. Pro dokonÄení registrace zkopírujte následující odkaz do VaÅ¡eho internetového prohlížeÄe:\n" "\n" "%s://%s:%s/confirm?key=%s\n" "\n" "Budete pÅ™esmÄ›rováni na stránku, kde budete moci dokonÄit registraci." #: notebook/register.py:27 #, python-format msgid "" "Your new password is %s\n" "\n" "Sign in at %s://%s:%s/\n" "\n" "Make sure to reset your password by going to Settings in the upper right bar." msgstr "" "VaÅ¡e nové heslo je %s\n" "\n" "Příhlaste se na %s://%s:%s/\n" "\n" "Po pÅ™ihlášení si prosím změňte heslo (odkaz \"Nastavení\" vpravo nahoÅ™e )." #: notebook/server_conf.py:42 #: notebook/user_conf.py:24 msgid "Appearance" msgstr "Vzhled" #: notebook/server_conf.py:43 msgid "Authentication" msgstr "Autentizace" #: notebook/server_conf.py:44 msgid "Server" msgstr "Server" #: notebook/server_conf.py:49 msgid "Number of word-wrap columns" msgstr "PoÄet znaků na řádek" #: notebook/server_conf.py:55 msgid "Maximum history length" msgstr "Maximální délka historie" #: notebook/server_conf.py:61 msgid "Idle timeout (seconds)" msgstr "Idle timeout (seconds)" #: notebook/server_conf.py:67 msgid "Idle check interval (seconds)" msgstr "Idle check interval (seconds)" #: notebook/server_conf.py:73 msgid "Save interval (seconds)" msgstr "Interval ukládání (sekundy)" #: notebook/server_conf.py:79 msgid "Doc pool size" msgstr "Doc pool size" #: notebook/server_conf.py:85 msgid "Worksheet process users (comma-separated list)" msgstr "Worksheet process users (comma-separated list)" #: notebook/server_conf.py:91 msgid "Default system" msgstr "Default system" #: notebook/server_conf.py:97 msgid "Pretty print (typeset) output" msgstr "Vykreslovat matematické výrazy" #: notebook/server_conf.py:103 msgid "Worksheet process limits" msgstr "Worksheet process limits" #: notebook/server_conf.py:109 msgid "Require e-mail for account registration" msgstr "Require e-mail for account registration" #: notebook/server_conf.py:115 msgid "Enable user registration" msgstr "Umožnit registraci dalších uživatelů" #: notebook/server_conf.py:121 msgid "Use a challenge for account registration" msgstr "Use a challenge for account registration" #: notebook/server_conf.py:127 msgid "Type of challenge" msgstr "Type of challenge" #: notebook/server_conf.py:134 msgid "reCAPTCHA public key" msgstr "reCAPTCHA public key" #: notebook/server_conf.py:140 msgid "reCAPTCHA private key" msgstr "reCAPTCHA private key" #: notebook/server_conf.py:146 msgid "Default Language" msgstr "PÅ™ednastavený jazyk" #: notebook/template.py:68 #, python-format msgid "%(num)d second" msgid_plural "%(num)d seconds" msgstr[0] "%(num)d sekundou" msgstr[1] "%(num)d sekundami" msgstr[2] "%(num)d sekundami" #: notebook/template.py:71 #, fuzzy, python-format msgid "%(num)d minute" msgid_plural "%(num)d minutes" msgstr[0] "%d minutou" msgstr[1] "%d minutami" msgstr[2] "%d minutami" #: notebook/template.py:74 #, fuzzy, python-format msgid "%(num)d hour" msgid_plural "%(num)d hours" msgstr[0] "%d hodinou" msgstr[1] "%d hodinami" msgstr[2] "%d hodinami" #: notebook/template.py:76 #, fuzzy, python-format msgid "%(num)d day" msgid_plural "%(num)d days" msgstr[0] "%d dnem" msgstr[1] "%d dny" msgstr[2] "%d dny" #: notebook/template.py:135 msgid "Sage Notebook" msgstr "Sage Notebook" #: notebook/tutorial.py:354 msgid "Find Help and Documentation" msgstr "NápovÄ›da a dokumentace" #: notebook/tutorial.py:355 msgid "Get Started with Sage" msgstr "První kroky s programem Sage" #: notebook/tutorial.py:355 msgid "Work through the tutorial (if you have trouble with it, view the static version)." msgstr "Anglický tutoriál (pokud pÅ™i práci máte problémy, použijte statickou verzi)." #: notebook/tutorial.py:356 msgid "Help About" msgstr "Kontextová nápovÄ›da" #: notebook/tutorial.py:357 msgid "Type ? immediately after the object or function and press tab or shift-enter (shift-enter overwrites output and saves to worksheet)." msgstr "ZapiÅ¡te ? bezprostÅ™ednÄ› za objekt nebo funkci a stisknÄ›te tab nebo shift-enter (shift-enter pÅ™epíše výstup buňky v zápisníku)." #: notebook/tutorial.py:359 msgid "Put ?? after the object and press tab or shift-enter (shift-enter overwrites output and saves to worksheet)." msgstr "ZapiÅ¡te ?? bezprostÅ™ednÄ› za objekt a stisknÄ›te tab nebo shift-enter (shift-enter pÅ™epíše výstup buňky v zápisníku)." #: notebook/tutorial.py:360 msgid "Full Text Search of Docs and Source" msgstr "Fulltextové prohledávání dokumentace a zdrojových kódů" #: notebook/tutorial.py:361 msgid "Search the SAGE documentation by typing
    search_doc(\"my query\")
    in an input cell and press shift-enter. Search the source code of SAGE by typing
    search_src(\"my query\")
    and pressing shift-enter. Arbitrary regular expressions are allowed as queries." msgstr "Dokumentaci programu SAGE můžete prohledávat pomocí příkazu
    search_doc(\"dotaz\")
    ve vstupním poli a následně stiskem shift-enter. Zdrojové kódy je možno prohledávat pomocí
    search_src(\"dotaz\")
    . Jako dotaz může sloužit libovolný regulární výraz." #: notebook/tutorial.py:365 msgid "Key and Mouse Bindings" msgstr "Klávesové povely a povely myší" #: notebook/tutorial.py:366 msgid "Evaluate Input" msgstr "Vyhodnocení vstupu" #: notebook/tutorial.py:367 msgid "Press shift-enter. You can start several calculations at once. If you press alt-enter instead, then a new cell is created after the current one. If you press ctrl-enter then the cell is split and both pieces are evaluated separately." msgstr "StisknÄ›te shift-enter. Můžete spustit i více výpoÄtů souÄasnÄ›. Stiskem kombinace alt-enter se navíc za aktuální vstupní buňku vloží další, prázdná. Stiskem ctrl-enter dojde k rozdÄ›lení buňky v místÄ› kurzoru na dvÄ› a obÄ› nové buňky jsou vyhodnoceny nezávisle na sobÄ›." #: notebook/tutorial.py:368 msgid "Tab Completion" msgstr "Doplňování pomocí tabelátoru" #: notebook/tutorial.py:369 msgid "Press tab while the cursor is on an identifier. On some web browsers (e.g., Opera) you must use control-space instead of tab." msgstr "StisknÄ›te tab když je kurzor na identifikátoru.V nÄ›kterých prohlížeÄích (napÅ™. Opera) musíte místo tabelátoru použít control-mezerník." #: notebook/tutorial.py:370 msgid "Insert New Cell" msgstr "Vložení nové vstupní buňky" #: notebook/tutorial.py:371 msgid "Put the mouse between an output and input until the horizontal line appears and click. If you press Alt-Enter in a cell, the cell is evaluated and a new cell is inserted after it." msgstr "UmístÄ›te ukazatel myÅ¡i mezi vstupní a výstupní buňku, dokud se neobjeví vodorovná linka a na tuto linku kliknÄ›te. Stiskem Alt-Enter v buňce je obsah této buňky zpracován a nová buňka je vložena za ni." #: notebook/tutorial.py:372 msgid "Delete Cell" msgstr "Výmaz vstupní buňky" #: notebook/tutorial.py:373 msgid "Delete all cell contents, then press backspace." msgstr "Vymažte celý obsah a stisknÄ›te backspace." #: notebook/tutorial.py:374 msgid "Split and Join Cells" msgstr "RozdÄ›lení a spojení bunÄ›k" #: notebook/tutorial.py:375 msgid "Press ctrl-; in a cell to split it into two cells, and ctrl-backspace to join them. Press ctrl-enter to split a cell and evaluate both pieces." msgstr "StisknÄ›te ctrl-; v buňce pro rozdÄ›lení na dvÄ› buňky a ctrl-backspace pro slouÄení bunÄ›k. Použijte ctrl-enter pro rozdÄ›lení buňky na dvÄ› a vyhodnocení obsahů obou tÄ›chto bunÄ›k. " #: notebook/tutorial.py:376 msgid "Insert New Text Cell" msgstr "Vložení nové buňky s textem" #: notebook/tutorial.py:377 msgid "Move the mouse between cells until a blue bar appears. Shift-click on the blue bar to create a new text cell. Double click on existing text to edit it. Use $...$ and $$...$$ to include typeset math in the text block." msgstr "PÅ™emisÅ¥ujte ukazatel myÅ¡i mezi buňkami, dokud se neobjeví modrá linka. Shift-click na modré lince vytvoří novou textovou buňku. Pro editaci existující textové buňky na tuto buňku kliknÄ›te dvakrát.Pro formátování matematických výrazů použijte $...$ a $$...$$. Výraz mezi dolary zapiÅ¡te pomocí jazyka LaTeX." #: notebook/tutorial.py:378 msgid "Hide/Show Output" msgstr "Skrýt/ukázat výstup" #: notebook/tutorial.py:379 msgid "Click on the left side of output to toggle between hidden, shown with word wrap, and shown without word wrap." msgstr "KliknÄ›te na levou stranu výstupem pro pÅ™epnutí mezi skrytím, zobrazením se řádkovým zlomem a zobrazením bez řádkového zlomu." #: notebook/tutorial.py:380 msgid "Indenting Blocks" msgstr "Odsazení bloků" #: notebook/tutorial.py:381 msgid "Highlight text and press > to indent it all and < to unindent it all (works in Safari and Firefox). In Firefox you can also press tab and shift-tab." msgstr "OznaÄte text a stisknÄ›te > pro odsazení a < pro zruÅ¡ení odsazení (funguje v prohlížeÄích Safari a Firefox). Ve Firefoxu můžete použít i tab a shift-tab." #: notebook/tutorial.py:382 msgid "Comment/Uncomment Blocks" msgstr "Zakomentování a odkomentování bloků" #: notebook/tutorial.py:383 msgid "Highlight text and press ctrl-. to comment it and ctrl-, to uncomment it. Alternatively, use ctrl-3 and ctrl-4." msgstr "OznaÄený text můžete zakomentovat pomocí ctrl-. a zruÅ¡it zakomentování pomocí ctrl-,. Můžete též použit ctrl-3 a ctrl-4." #: notebook/tutorial.py:384 msgid "Paren matching" msgstr "Párovost závorek" #: notebook/tutorial.py:384 msgid "To fix unmatched or mis-matched parentheses, braces or brackets, press ctrl-0. Parentheses before the cursor will be matched, minding strings and (Python) comments." msgstr "Pro opravení párovosti závorek můžete použít ctrl-0. Bude nalezena párová závorka k závorce pÅ™ed kurzorem." #: notebook/tutorial.py:388 msgid "Interrupt and Restart Sessions" msgstr "PÅ™eruÅ¡ení a restartování sezení" #: notebook/tutorial.py:389 msgid "Interrupt Running Calculations" msgstr "PÅ™eruÅ¡ení bežícího výpoÄtu" #: notebook/tutorial.py:390 msgid "Click Interrupt or press escape in any input cell. This will (attempt) to interrupt SAGE by sending many interrupt signals." msgstr "StisknÄ›te PÅ™eruÅ¡it nebo stisknÄ›te escape v libovolné vstupní buňce. Sage zaÅ¡le signál k pÅ™eruÅ¡ení vÅ¡em běžícím podprocesům." #: notebook/tutorial.py:391 msgid "Restart" msgstr "Restartovat" #: notebook/tutorial.py:392 msgid "Type \"restart\" to restart the SAGE interpreter for a given worksheet. (You have to interrupt first.)" msgstr "Použijte příkaz \"restart\" pro restartování Sage interpretru pro souÄasný zápisník. (Musíte nejprve pÅ™eruÅ¡it výpoÄty.)" #: notebook/tutorial.py:394 msgid "Special Cell Blocks" msgstr "Speciální vstupní buňky" #: notebook/tutorial.py:395 msgid "Evaluate Cell using GAP, Singular, etc." msgstr "Vyhodnocení pomocí programů GAP, Singular, atd." #: notebook/tutorial.py:396 #, python-format msgid "Put \"%gap\", \"%singular\", etc. as the first input line of a cell; the rest of the cell is evaluated in that system." msgstr "ZapiÅ¡te \"%gap\", \"%singular\", atd. na první řádek vstupní buňky; další řádky buňky budou zpracovány přísluÅ¡ným programem." #: notebook/tutorial.py:397 msgid "Shell Scripts" msgstr "Příkazy shellu" #: notebook/tutorial.py:398 #, python-format msgid "Begin a block with %sh to have the rest of the block evaluated as a shell script. The current working directory is maintained." msgstr "Použijte %sh na zaÄátku buňky a zbytek buňky bude vyhodnocen linuxovým shellem. Pracovní adresář zůstane zachován." #: notebook/tutorial.py:399 msgid "Interactive Dynamic Widgets" msgstr "Interaktivní objekty" #: notebook/tutorial.py:400 msgid "Put @interact on the line before a function definition. Type interact? for more details." msgstr "Vložte @interact na řádek pÅ™ed definici funkce. Použijte interact? pro nápovÄ›du a ukázky." #: notebook/tutorial.py:401 msgid "Autoevaluate Cells on Load" msgstr "Automatické vyhodnocení bunÄ›k pÅ™i startu" #: notebook/tutorial.py:402 msgid "Any cells with \"#auto\" in the input is automatically evaluated when the worksheet is first opened." msgstr "Každá buňka s Å™etÄ›zcem \"#auto\" na vstupu je automaticky zpracována pÅ™i prvním otevÅ™ení zápisníku." #: notebook/tutorial.py:403 msgid "Time" msgstr "ÄŒas výpoÄtu" #: notebook/tutorial.py:404 msgid "Type \"%time\" at the beginning of the cell." msgstr "Použijte \"%time\" na zaÄátku buňky." #: notebook/tutorial.py:406 msgid "Useful Tips" msgstr "UžiteÄné tipy" #: notebook/tutorial.py:407 msgid "Input Rules" msgstr "Vstupní pravidla" #: notebook/tutorial.py:408 msgid "Code is evaluated by exec'ing (after preparsing). Only the output of the last line of the cell is implicitly printed. If any line starts with \"sage:\" or \">>>\" the entire block is assumed to contain text and examples, so only lines that begin with a prompt are executed. Thus you can paste in complete examples from the docs without any editing, and you can write input cells that contains non-evaluated plain text mixed with examples by starting the block with \">>>\" or including an example." msgstr "Kód je spouÅ¡tÄ›n po pÅ™edformátování. ImplicitnÄ› je vytiÅ¡tÄ›n je pouze výstup posledního řádku. Pokud libovolný řádek zaÄíná Å™etÄ›zcem \"sage:\" nebo \">>>\", potom se pÅ™edpokládá, že celý blok obsahuje ukázky a příklady a vyhodnoceny jsou pouze řádky s tÄ›mito Å™etÄ›zci. Můžete tedy zkopírovat úplné příklady z dokumentace bez dodateÄných úprav. Můžete také používat vstupní buňky, kde jsou kombinovány textové komentáře s příkazy uvozenými \">>>\"." #: notebook/tutorial.py:409 msgid "History" msgstr "Historie" #: notebook/tutorial.py:410 msgid "Click log commands you have entered in any worksheet of this notebook." msgstr "Použijte odkaz log pro zobrazení vaÅ¡ich posledních příkazů použitých v libovolném zápisníku." #: notebook/tutorial.py:411 msgid "Typesetting All Output" msgstr "Sazba vzorců na výstupu" #: notebook/tutorial.py:412 msgid "Type pretty_print_default() in an input cell and press shift-enter. All future output will be typeset automatically." msgstr "SpusÅ¥te pretty_print_default() ve vstupní buňce (zapiÅ¡te a stisknÄ›te shift-enter). Následující výstupy budou automaticky pÄ›knÄ› formátovány." #: notebook/tutorial.py:416 msgid "Files and Scripts" msgstr "Soubory a skripty" #: notebook/tutorial.py:417 msgid "Loading SAGE/Python Scripts" msgstr "Nahrávání skriptů Sage/Python" #: notebook/tutorial.py:418 msgid "Use \"load filename.sage\" and \"load filename.py\". Load is relative to the path you started the notebook in. The .sage files are preparsed and .py files are not. You may omit the .sage or .py extension. Files may load other files." msgstr "Použijte \"load filename.sage\" a \"load filename.py\". Nahrávání je vzhledem k cestÄ›, odkud je spuÅ¡tÄ›n zápisník. Sobory .sage jsou pÅ™edformátovány preparserem, soubory .py ne. Koncovku .sage a .py můžete vynechat. Soubory mohou nahrávat další soubory." #: notebook/tutorial.py:419 msgid "Attaching Scripts" msgstr "PÅ™ipojení skriptů" #: notebook/tutorial.py:420 msgid "Use \"attach filename.sage\" or \"attach filename.py\". Attached files are automatically reloaded when the file changes. The file $HOME/.sage/init.sage is attached on startup if it exists." msgstr "Použijte \"attach filename.sage\" nebo \"attach filename.py\". PÅ™ipojené skripty jsou pÅ™i zmÄ›nách automaticky opÄ›tovnÄ› nahrány. Pokud v systému existuje soubor $HOME/.sage/init.sage, je tento soubor pÅ™ipojen pÅ™i startu." #: notebook/tutorial.py:421 msgid "Working Directory" msgstr "Pracovní adresář" #: notebook/tutorial.py:422 msgid "Each block of code is run from its own directory. If any images are created as a side effect, they will automatically be displayed." msgstr "Každá vstupní buňka je spouÅ¡tÄ›na ve vlastním adresáři. Pokud jsou bÄ›hem výpoÄtu vytvoÅ™eny obrázky, jsou tyto obrázky automaticky zobrazeny." #: notebook/tutorial.py:423 msgid "DIR Variable" msgstr "PromÄ›nná DIR" #: notebook/tutorial.py:424 msgid "The variable DIR contains the directory from which you started the SAGE notebook. For example, to open a file in that directory, do \"open(DIR+'filename')\"." msgstr "PromÄ›nná DIR obsahuje jméno adresáře, odkud byl spuÅ¡tÄ›n program Sage Notebook. Například pro otevÅ™ení souboru v tomto adresáři můžete použít příkaz \"open(DIR+'soubor')\"." #: notebook/tutorial.py:425 msgid "DATA Variable" msgstr "PromÄ›nná DATA" #: notebook/tutorial.py:426 msgid "Use the Data menu to upload images and other files, and create new files that can be shared between worksheets. The DATA variable contains the path to the data files. For example, to open a file in that directory, do \"open(DATA+'filename')\". If foo.sage is a Sage file that you uploaded, type \"load foo.sage\"; if foo.py is a Python file, you can import it by typing \"import foo\"." msgstr "Můžete použít menu Data pro uložení obrázků a jiných souborů a pro vytvoÅ™ení souborů, které mohou být sdíleny mezi zápisníky. PromÄ›nná DATA obsahuje cestu k tÄ›mto souborům. Například pro otevÅ™ení souboru v tomto adresáři můžete použít \"open(DATA+'soubor')\". Pokus nahrajete soubor foo.sage, můžete použít \"load foo.sage\"; pokud nahrajete soubor foo.py jazyka Python, můžete jej zaÄlenit pomocí \"import foo\"." #: notebook/tutorial.py:427 msgid "Loading and Saving Objects" msgstr "Ukládání a Ätení objektů" #: notebook/tutorial.py:428 msgid "Use \"save obj1 obj2 ...\" and \"load obj1 obj2 ...\". This allows for easy moving of objects from one worksheet to another, and saving of objects for later use." msgstr "Můžete použít \"save obj1 obj2 ...\" a \"load obj1 obj2 ...\". Tím umožníte pÅ™enos objektů z jednoho zápisníku do druhého a uložení objektů pro pozdÄ›jší další použití." #: notebook/tutorial.py:429 msgid "Loading and Saving Sessions" msgstr "Uložení a obnovení sezení" #: notebook/tutorial.py:430 msgid "Use \"save_session('name')\" to save all variables to an object. Use \"load_session('name')\" to merge in all variables from a saved session." msgstr "Můžete použít \"save_session('name')\" pro uložení vÅ¡ech promÄ›nných. Můžete použít \"load_session('name')\" pro pÅ™ihrání vÅ¡ech uložených promÄ›nných do aktuálního sezení." #: notebook/tutorial.py:431 msgid "Customizing the Notebook CSS" msgstr "Úprava CSS" #: notebook/tutorial.py:432 msgid "If you create a file $HOME/.sage/notebook.css then it will get applied when rendering the notebook. See " msgstr "Pokud existuje soubor $HOME/.sage/notebook.css je tento soubor použit pÅ™i formátování zápisníku. Viz" #: notebook/twist.py:448 #, python-format msgid "Please specify a worksheet to load.%s" msgstr "Vyberte zápisník pro nahrání.%s" #: notebook/twist.py:486 #, python-format msgid "There was an error uploading the worksheet. It could be an old unsupported format or worse. If you desperately need its contents contact the sage-support group and post a link to your worksheet. Alternatively, an sws file is just a bzip2 tarball; take a look inside!%s" msgstr "Nahrávání zápisníku skonÄilo chybou. Může být ve starém nebo nepodporovaném formátu. Pokud nutnÄ› potÅ™ebujete přístup k tomuto zápisníku, kontaktujte sage-support group a poÅ¡lete sem odkaz na Váš soubor (jedná se o anglicky mluvící diskusní skupinu). Můžete se také pokusit sws soubor rozbalit, jedná se o balíÄek zabalený pomocí tar a bzip2!%s" #: notebook/twist.py:515 #: notebook/twist.py:645 #, python-format msgid "There was an error uploading \"%s\" (please recheck the URL).%s" msgstr "Chyba pÅ™i nahrávání \"%s\" (zkontrolujte prosím URL).%s" #: notebook/twist.py:597 #, python-format msgid "Return to Upload or Create Data File or %s." msgstr "ZpÄ›t na Nahrát nebo vytvoÅ™it datový soubor nebo %s." #: notebook/twist.py:601 #, python-format msgid "Error uploading file (missing fileField file).%s" msgstr "Chyba pÅ™i nahrávání souboru (missing fileField file).%s" #: notebook/twist.py:606 #, python-format msgid "Error uploading file (missing %s arg).%s" msgstr "Chyba pÅ™i nahrávání souboru (missing %s arg).%s" #: notebook/twist.py:623 #, python-format msgid "Error uploading file (missing filename).%s" msgstr "Chyba pÅ™i nahrávání soubodu (chybÄ›jící jméno souboru).%s" #: notebook/twist.py:627 #, python-format msgid "Suspicious filename \"%s\" encountered uploading file.%s" msgstr "Nekorektní jméno souboru \"%s\" pÅ™i nahrávání.%s" #: notebook/twist.py:674 #, python-format msgid "Successfully deleted \"%s\"" msgstr "Soubor \"%s\" úspěšnÄ› smazán." #: notebook/twist.py:691 msgid "No data files" msgstr "Nejsou datové soubor" #: notebook/twist.py:770 msgid "Error in introspection -- invalid cell id." msgstr "Chyba -- Å¡patné id u buňky." #: notebook/twist.py:824 msgid "You must login first in order to edit this worksheet." msgstr "Pro editaci zápisníku se musíte pÅ™ihlásit." #: notebook/twist.py:998 msgid "Old password not given" msgstr "Staré heslo nebylo zadáno" #: notebook/twist.py:1000 msgid "Incorrect password given" msgstr "Neplatné heslo" #: notebook/twist.py:1002 msgid "New password not given" msgstr "Nebylo zadáno nové heslo" #: notebook/twist.py:1004 msgid "Please type in new password again." msgstr "Prosím, zadejte nové heslo jeÅ¡tÄ› jednou." #: notebook/twist.py:1006 msgid "The passwords you entered do not match." msgstr "Zadaná hesla se neshodují." #: notebook/twist.py:1039 msgid "Confirmed" msgstr "Potvrzeno" #: notebook/twist.py:1041 msgid "Not confirmed" msgstr "Nepotvrzeno" #: notebook/twist.py:1294 msgid "can't evaluate worksheet cells" msgstr "není možno vyhodnotit buňky v zápisníku" #: notebook/twist.py:1391 msgid "You must login first in order to rate this worksheet." msgstr "Pro hodnocení zápisníku se musíte nejprve pÅ™ihlásit." #: notebook/twist.py:1395 msgid "Gees -- You can't fool the rating system that easily!" msgstr "Fujtajbl -- Systém hodnocení nemůžete ošálit tak snadno!" #: notebook/twist.py:1398 #, python-format msgid "Thank you for rating the worksheet %s! You can see all ratings of this worksheet." msgstr "DÄ›kujeme za zadání hodnocení pro zápisník %s! Můžete si prohlédnout vÅ¡echna hodnocení tohoto zápisníku." #: notebook/twist.py:1398 msgid "Rating Accepted" msgstr "Hodnocení uloženo" #: notebook/twist.py:1415 msgid "No such worksheet." msgstr "Takový zápisník neexistuje." #: notebook/twist.py:1521 #, python-format msgid "The worksheet operation \"%s\" is not defined." msgstr "Operace \"%s\" se zápisníkem není definována." #: notebook/twist.py:1618 #, python-format msgid "User \"%s\" does not have permission to view the home page of \"%s\"." msgstr "Uživatel \"%s\" nemá oprávnÄ›ní pro vstup do adresářů uživatele \"%s\"." #: notebook/twist.py:1629 #, python-format msgid "The user \"%s\" has no worksheet \"%s\"." msgstr "Uživatel \"%s\" nemá vytvoÅ™en zápisník \"%s\"." #: notebook/twist.py:1632 #, python-format msgid "There is no published worksheet with name \"%s\". Redirecting to the index of published worksheets in 10 seconds...

    " msgstr "Zápisník se jménem \"%s\" není zveřejněn. Během 10 vteřin budete přesměrováni na seznam zveřejněných zápisníků...

    " #: notebook/twist.py:1637 #, python-format msgid "You are not logged in or do not have access to the worksheet \"%s\"." msgstr "Nejste přihlášen(-a) nebo nemáte oprávnění pro přístup k zápisníku \"%s\"." #: notebook/twist.py:1662 msgid "This url can only be accessed through a POST request." msgstr "Toto URL je přístupné pouze metodou POST." #: notebook/twist.py:1712 #, python-format msgid "You are not authorized to move \"%s\"" msgstr "Nemáte oprávnění pro přesun \"%s\"" #: notebook/twist.py:1781 msgid "Please request a specific worksheet" msgstr "Požadujte konkrétní zápisník." #: notebook/twist.py:2022 msgid "The confirmation system is not active." msgstr "Systém potvrzování není aktivní." #: notebook/twist.py:2024 msgid "

    Invalid confirmation key

    You are reporting a confirmation key that has not been assigned by this server. Please register with the server.

    " msgstr "

    Chybný potvrzovací kód

    Používáte jiný potvrzovací kód než ten, který byl vystaven tímto serverem. Registrujte se prosím na serveru.

    " #: notebook/twist.py:2033 #, python-format msgid "

    Email address confirmed for user %s

    " msgstr "

    Emailová adresa uživatele %s potvrzena

    " #: notebook/twist.py:2035 msgid "Email Confirmed" msgstr "Email potvrzen" #: notebook/user_conf.py:23 msgid "Language" msgstr "PÅ™ednastavený jazyk" #: notebook/wiki2html.py:647 #, python-format msgid "Expected \"%(wanted)s\" after \"%(key)s\", got \"%(token)s\"" msgstr "OÄekáváváno \"%(wanted)s\" po \"%(key)s\", obdrženo \"%(token)s\"" #: notebook/wiki2html.py:653 #, python-format msgid "Expected an integer \"%(key)s\" before \"%(token)s\"" msgstr "OÄekáváno celé Äíslo \"%(key)s\" pÅ™ed \"%(token)s\"" #: notebook/wiki2html.py:663 #: notebook/wiki2html.py:673 #, python-format msgid "Expected an integer \"%(arg)s\" after \"%(key)s\"" msgstr "OÄekáváno celé Äíslo \"%(arg)s\" po \"%(key)s\"" #: notebook/wiki2html.py:699 #, python-format msgid "Expected a color value \"%(arg)s\" after \"%(key)s\"" msgstr "OÄekávána barva \"%(arg)s\" po \"%(key)s\"" #: notebook/worksheet.py:2014 #, python-format msgid "%(seconds)s ago" msgstr "" #: notebook/worksheet.py:4155 msgid "January" msgstr "" #: notebook/worksheet.py:4156 msgid "February" msgstr "" #: notebook/worksheet.py:4157 msgid "March" msgstr "" #: notebook/worksheet.py:4158 msgid "April" msgstr "" #: notebook/worksheet.py:4159 msgid "May" msgstr "" #: notebook/worksheet.py:4160 msgid "June" msgstr "" #: notebook/worksheet.py:4161 msgid "July" msgstr "" #: notebook/worksheet.py:4162 msgid "August" msgstr "" #: notebook/worksheet.py:4163 #, fuzzy msgid "September" msgstr "Zapamatovat si mÄ›" #: notebook/worksheet.py:4164 msgid "October" msgstr "" #: notebook/worksheet.py:4165 #, fuzzy msgid "November" msgstr "NovÄ›jší" #: notebook/worksheet.py:4166 #, fuzzy msgid "December" msgstr "Zapamatovat si mÄ›" #~ msgid "Sign into the Sage Notebook v%(v)s" #~ msgstr "PÅ™ihlášení do prostÅ™edí Sage Notebook v%(v)s" #~ msgid "Problem inserting new text cell before current input cell." #~ msgstr "NepodaÅ™ilo se vložit novou textovou buňku pÅ™ed buňku aktuální." #~ msgid "Problem inserting new input cell before current input cell." #~ msgstr "NepodaÅ™ilo se vložit novou buňku pÅ™ed buňku aktuální." #~ msgid "simple" #~ msgstr "simple" #~ msgid "recaptcha" #~ msgstr "recaptcha" #~ msgid "Sage Notebook Registration" #~ msgstr "Registrace programu Sage Notebook" #~ msgid "The account recovery system is not active." #~ msgstr "Systém obnovy úÄtů není aktivní." #~ msgid "Username is invalid." #~ msgstr "Neplatné uživatelské jméno" #~ msgid "The e-mail address hasn't been confirmed." #~ msgstr "Emailová adresa nebyla potvrzena." #~ msgid "Sage Notebook Account Recovery" #~ msgstr "Obnova úÄtu pro prostÅ™edí Sage Notebook" #~ msgid "The new password couldn't be sent to %s." #~ msgstr "Není možno nastavit nové heslo na %s." #~ msgid "A new password has been sent to your e-mail address." #~ msgstr "Nové heslo bylo zasláno na VaÅ¡i adresu." #~ msgid "The temporary password for the new user %s is %s" #~ msgstr "DoÄasné heslo uživatele %s je %s" #~ msgid "This is an invalid page." #~ msgstr "Toto je neplatná stránka." #~ msgid " You might have to login to view this page." #~ msgstr "Pro prohlížení této stránky může být vyžadováno pÅ™ihlášení." #~ msgid "unauthorized request" #~ msgstr "neautorizovaný přístup" #~ msgid "Your account is currently suspended." #~ msgstr "Váš úÄet je pozastaven" #~ msgid "" #~ "Please enable cookies or delete all Sage cookies and localhost cookies in " #~ "your browser and try again." #~ msgstr "" #~ "Povolte cookies nebo smažte vÅ¡echny cookies pro Sage a localhost ve vaÅ¡em " #~ "prohlížeÄi a pokuste se pÅ™ihlásit znovu." #~ msgid "%s ago" #~ msgstr "pÅ™ed %s" sagenb-1.0.1/sagenb/translations/de_AT/000077500000000000000000000000001311436262400177065ustar00rootroot00000000000000sagenb-1.0.1/sagenb/translations/de_AT/LC_MESSAGES/000077500000000000000000000000001311436262400214735ustar00rootroot00000000000000sagenb-1.0.1/sagenb/translations/de_AT/LC_MESSAGES/messages.mo000066400000000000000000001520331311436262400236430ustar00rootroot00000000000000Þ•öÌ|}–±Ðïÿ# 7 F M «U :!,:T:e: z:…::= : Þ:é:î:ó: ; ;;<;%[;;Ÿ;»;Ö;ò;ö;ý;<%1< W<d<j<<…<ìŽ<-{=)©= Ó=ô= > > >*> A>O>U>\>_> {>‰> >²>Å> ×>å>÷>?? $?1?H?N? U?€c?&ä?0 @7<@t@‘@—@¦@«@´@Ë@=Û@'A"AA#dA%ˆA"®A$ÑAÂöA¹BŽÙChD†DŒD<¡DÞDæD ÷DEEr)ElœEY F´cFG3Gc\ckcqc-yc!§c(Écòc)d¹,dædBïd2eDe'We¹e9f Kf)UfZfÚf.óf"g1g#5gBYggœgDhSIhEhEãhQ)i“{izj“Šj~kokŒ lhšlmm3m9m?mEmKmTmZm ym„mMmÛm ámëmnnn$$nInZn `njnmpnÞo÷op 5pVpfp6}p´pÆpÎpÁÕpA—q3ÙqÑ rIßrc)sZs½èsÛ¦t‚u™u ¬u·u½uÔuïuv vl?v¬v½vÃvtËv@wIwcwwˆw'šw4Âw3÷w+xBxŽ]xNìx2;yInyO¸yÂz ËzÕz ëz0öz'{>{4O{ž„{®#|<Ò|%}<5}}r}Cð},4~;a~|~  &50 fKq½ Ì×ô ‚‚!‚Y@‚š‚·‚Ï‚Kß‚+ƒAƒ)Qƒ {ƒ ‰ƒ –ƒ¢ƒ«ƒ´ƒ̃äƒíƒ„V„j„„—„²„Ì„,â„0…@… `… n…|…*—…Â…‹Ñ… ]†h†z†,ކ »†džÙ†ë†dý†%b‡)ˆ‡!²‡Ô‡݇Mä‡2ˆ9Bˆ2|ˆ:¯ˆ>êˆ8)‰b‰r‰7‚‰º‰3͉7Š 9ŠDCŠ*ˆŠ*³Š+ÞŠ ‹(‹.:‹i‹q‹z‹ •‹¶‹+É‹Iõ‹??Œ ŒŠŒ>¢ŒáŒþŒ& A MWo‡ê£»ŽŽJ R`~œ4¸&í–² ÅÓè+‘(.‘ W‘"d‘&‡‘®‘;Ä‘+’,’F’_’ t’‚’‰’>¡’ à’ê’ï’ô’““&)“4P“/…“µ“Õ“ õ“” 4” >”1H”z”0š”˔ޔ䔕•F•5U–:‹–1Æ–ø–— —'—6—U—h—o—w—/|—¬—Ê—é—$˜&˜ B˜O˜f˜o˜Œ˜”˜£˜˜ʘÓ˜­â˜3™;Ä™Iš$Jš oš{š –š¢š&«šÒšFèš9/›+i›3•›0É›/ú›2*œñ]œ3O¬ƒž0ŸPŸXŸTtŸÉŸÚŸòŸ  # „< ¥Á ug¡èݡƢ 㢠í¢÷¢£$*£#O£s£„£ ž£©£È£à£0ï£= ¤^¤ q¤ ¤ ‹¤¬¤úŤ À¥ ᥦ ¦¦2¦G¦_¦ u¦ƒ¦™¦°¦­¿¦ m§z§ “§§³§%ɧï§ ¨1&¨0X¨(‰¨²¨ÐΨŸ©!´©%Ö©!ü©ª ;ªEª Lª Zªdªtª Žªœª¥ª¼ªÓªܪåª(îª'«3?«[s« ϫ٫𫬬+¬3¬<¬%W¬ }¬ˆ¬£¬«¬C´¬ø¬­5­R­˜W­'ð­o¯ ˆ¯Ä–¯([°T„°>Ù°-±©F±²ð±2£²2Ö² ³^™³©ø³d¢µ(¶C0¶†t¶û¶%·É&·1ð·Â"¸å¸î¸¹ ¹ ¹N"¹q¹*z¹‡¥¹º-º躙»š»*¯»Ú»|ð»m¼ м —¼ ¢¼ ¬¼ ¹¼ü$Ú¼Oÿ¼>O½!޽=°½Úî½ýɾ¸Ç¿º€ÀN;ÁØŠÁ-cÂ6‘Â!ÈÂêÂþÄÅHÅaÅ tÅÅ›Å)·ÅáÅùÅÆ; Æ+FÆJrƽÆ.ÏÆÝþÆ ÜÇHèÇ1ÈCÈ'TÈö|ÈsÉ †É;“ÉiÏÉ-9Ê<gʤʶÊ.¹ÊJèÊq3ËU¥ËiûË^eÌXÄÌbͰ€Í›1ζÍγ„Ït8Ф­ÐwRÑÊÑ(âÑ Ò)Ò?ÒWÒ jÒtÒ&‡Ò®Ò¶ÒQ¿ÒÓ%Ó5Ó"SÓvÓ”Ó0œÓÍÓ%åÓ ÔÔ%(num)d day%(num)d days%(num)d hour%(num)d hours%(num)d minute%(num)d minutes%(num)d second%(num)d seconds%(seconds)s ago%(t)s ago by %(le)s(note that images are not recorded)24|twenty-four5|five8|eightWork through the tutorial (if you have trouble with it, view the static version).Restart, instead?

    Email address confirmed for user %s

    Invalid confirmation key

    You are reporting a confirmation key that has not been assigned by this server. Please register with the server.

    Sage is a different approach to mathematics software.A session is a worksheet and a set of variables in some state.A worksheet is an ordered list of Sage calculations with output.A new password will be emailed to the email address connected to your account. However if you didn't confirm your email address you will be unable to recover your account.Access %(f)s in this worksheet by typing DATA+'%(f)s'. Here DATA is a special variable that gives the exact path to all data files uploaded to this worksheet.Account RecoveryAccount SettingsAction...ActiveActive WorksheetsAdd New UserAdd UserAdd or DeleteAnswer a challengeAny cells with "#auto" in the input is automatically evaluated when the worksheet is first opened.AppearanceAprilArchiveArchive selected worksheets so they do not appear in the default worksheet listArchivedArchived WorksheetsAttaching ScriptsAugustAuthenticationAutoevaluate Cells on LoadAutomatically re-publish when changes are madeBack to your personal worksheet listBad passwordBad usernameBegin a block with %sh to have the rest of the block evaluated as a shell script. The current working directory is maintained.Browse published Sage worksheets
    (no login required)Browse the published worksheetsBrowse your computer to select a file to upload:Browse your computer to select a worksheet file to upload:By using Sage you help to support a viable open source alternative to Magma, Maple, Mathematica, and MATLAB. Sage includes many high-quality open source math packages.CancelCancel changesCases / TestsChange Auto-Save IntervalChange E-mail AddressChange PasswordChange account settings including passwordClick log commands you have entered in any worksheet of this notebook.Click Interrupt or press escape in any input cell. This will (attempt) to interrupt SAGE by sending many interrupt signals.Click here or press shift-return to evaluateClick here to pop outClick here to turn the above into a Sage worksheetClick on the left side of output to toggle between hidden, shown with word wrap, and shown without word wrap.Click to download and install tex fonts.Click to rename this worksheetClose this box to stop trying.Code is evaluated by exec'ing (after preparsing). Only the output of the last line of the cell is implicitly printed. If any line starts with "sage:" or ">>>" the entire block is assumed to contain text and examples, so only lines that begin with a prompt are executed. Thus you can paste in complete examples from the docs without any editing, and you can write input cells that contains non-evaluated plain text mixed with examples by starting the block with ">>>" or including an example.CollaboratorsCommentComment/Uncomment BlocksConfirmedCongratulations %(u)s! You can now sign into the Sage Notebook.ConstructionsContinueCopy this worksheetCopy worksheetCountCreate AccountCreate a good passwordCreate a new Sage worksheet version of the last 100 commands in the above log.Create a new worksheetCreate a usernameCreate accountCreating new users is disabled by the administrator.Current FolderCurrent e-mailCustomizing the Notebook CSSDATA VariableDIR VariableData fileData...DecemberDefault LanguageDefault systemDeleteDelete All OutputDelete CellDelete all cell contents, then press backspace.Delete all outputDelete worksheetDeleted WorksheetsDeveloper GuideDiscard & quitDiscard changes to this worksheetDo you want to publish this worksheet?Doc pool sizeDocumentationDownloadDownload All ActiveDownload selected worksheetsDownload.Each block of code is run from its own directory. If any images are created as a side effect, they will automatically be displayed.EditEdit a copy.Edit plain textEdit text version of this worksheetEdit this.ElapsedEmail ConfirmedEmpty TrashEmptying the trash will permanently delete all items in the trash. Continue?Enable user registrationEnable/disable pretty_printingEnter your email addressEnvironmentErrorError applying function to worksheet(s).Error foundError in introspection -- invalid cell id.Error updating cell output after Error uploading file (missing %s arg).%sError uploading file (missing fileField file).%sError uploading file (missing filename).%sErrors foundEvaluate AllEvaluate Cell using GAP, Singular, etc.Evaluate InputEvaluate all input cells in the worksheetEvaluate all input cells using %(i)sExitExpected "%(wanted)s" after "%(key)s", got "%(token)s"Expected a color value "%(arg)s" after "%(key)s"Expected an integer "%(arg)s" after "%(key)s"Expected an integer "%(key)s" before "%(token)s"FailFailed to save worksheet.Fast Static Versions of the DocumentationFebruaryFile...Files and ScriptsFind Help and DocumentationForgot passwordFull Text Search of Docs and SourceGees -- You can't fool the rating system that easily!General and Advanced Pure and Applied MathematicsGet ImageGet Started with SageGive access to your worksheet to the above collaboratorsGo to the worksheet.HelpHelp AboutHelp via Internet Chat (IRC)Hi %s! HideHide All OutputHide all outputHide/Show OutputHighlight text and press ctrl-. to comment it and ctrl-, to uncomment it. Alternatively, use ctrl-3 and ctrl-4.Highlight text and press > to indent it all and < to unindent it all (works in Safari and Firefox). In Firefox you can also press tab and shift-tab.HistoryHomeHow do I construct ... in Sage?How many bits are in one byte?How to use the Sage NotebookIdle check interval (seconds)Idle timeout (seconds)If you create a file $HOME/.sage/notebook.css then it will get applied when rendering the notebook. See Incorrect password givenIndenting BlocksInput RulesInsert New CellInsert New Text CellInteractive Dynamic WidgetsInteractively use this worksheetInterruptInterrupt Running CalculationsInterrupt and Restart SessionsInterrupt attemptInterrupt currently running calculations, if possibleInvalid challenge responseInvalid email addressInvalid usernameInvite CollaboratorsIs pi > e?JanuaryJava Applet HiddenJavascript must be enabled in order to use the Sage Notebook.Jmol ImageJulyJuneKey and Mouse BindingsLanguageLast EditedLearn to write Sage programsLet others edit this worksheetLoad a new worksheet stored in a fileLoad worksheet from a file...Loading SAGE/Python ScriptsLoading and Saving ObjectsLoading and Saving SessionsLogLog inLog in to edit a copy.Log out of the Sage notebookMake this worksheet publicly viewableManage UsersMarchMaximum history lengthMayMinutes:Move the mouse between cells until a blue bar appears. Shift-click on the blue bar to create a new text cell. Double click on existing text to edit it. Use $...$ and $$...$$ to include typeset math in the text block.Move the selected worksheets out of the trashMove the selected worksheets to the trashMove this worksheet to the trashMulti Cell ModeNew WorksheetNew e-mailNew passwordNew password not givenNew worksheetNewerNewestNoNo challenge response givenNo data filesNo email address givenNo password givenNo such worksheet.No username givenNot confirmedNotebook SettingsNovemberNumber of word-wrap columnsOctoberOld passwordOld password not givenOlderOldestOne Cell ModeOnly the owner of a worksheet is allowed to share it. You can do whatever you want if you make your own copy.Or enter the URL of a file on the web:Or enter the URL of a worksheet file on the web:Or enter the name of a new file, which will be created:Other published documents...OwnerParen matchingPassPasswordPasswords didn't matchPick a usernamePlease ask the server administrator to configure a challenge!Please enter a name for this worksheet.Please log in to the Sage notebookPlease request a specific worksheetPlease specify a worksheet to load.%sPlease type in new password again.Possible failure deleting worksheet.Press ctrl-; in a cell to split it into two cells, and ctrl-backspace to join them. Press ctrl-enter to split a cell and evaluate both pieces.Press shift-enter. You can start several calculations at once. If you press alt-enter instead, then a new cell is created after the current one. If you press ctrl-enter then the cell is split and both pieces are evaluated separately.Press tab while the cursor is on an identifier. On some web browsers (e.g., Opera) you must use control-space instead of tab.Pretty print (typeset) outputPrintPrint this worksheetProblem inserting new input cell after current input cell.\nPublishPublish this onePublishedPublished WorksheetsPublished on %(t)sPut "%gap", "%singular", etc. as the first input line of a cell; the rest of the cell is evaluated in that system.Put ?? after the object and press tab or shift-enter (shift-enter overwrites output and saves to worksheet).Put @interact on the line before a function definition. Type interact? for more details.Put the mouse between an output and input until the horizontal line appears and click. If you press Alt-Enter in a cell, the cell is evaluated and a new cell is inserted after it.Quit the worksheet processRate it:RatingRating AcceptedRatings for %(wn)sRe-publish worksheetRe-type your passwordReference ManualRemember meRenameRename this worksheetRename worksheetReport a ProblemReport a problem or submit a bug to improve SageRequire e-mail for account registrationRerate it:ResetRestartRestart the worksheet processRestart worksheetReturn to Upload or Create Data File or %s.Retype new passwordRevert to this oneRevisionRevision %(lr)sRevision HistoryRevision ListRevision from %(ta)s agoSage DocumentationSage NotebookSage Notebook versionSage Source BrowserSage Users:Sage makes it easy for you to use most mathematics software together. Sage includes GAP, GP/PARI, Maxima, and Singular, and dozens of other open packages.Sage versionSage: History for %(u)sSaveSave & quitSave ChangesSave and quit worksheetSave changesSave changes and close windowSave interval (seconds)Save this worksheet to an sws fileSave worksheet to a file...Search WorksheetsSearch the SAGE documentation by typing
    search_doc("my query")
    in an input cell and press shift-enter. Search the source code of SAGE by typing
    search_src("my query")
    and pressing shift-enter. Arbitrary regular expressions are allowed as queries.Searching for Sage server...Select a file related functionSelect a worksheet functionSelect an OpenID providerSelect an attached fileSeptemberServerSettingsShareShare nowShare this documentShell ScriptsShowShow All OutputShow all outputSign inSign outSign upSign up for a Sage Notebook accountSign up for a new Sage Notebook accountSomeone else is viewing this worksheetSorry, but you need a browser that supports the <canvas> tag.Source CodeSpecial Cell BlocksSplit and Join CellsStartStatic version...StatusStopStop publishingStop selected worksheetsSubmitSuccessfully deleted "%s"SuspendSuspensionSuspicious filename "%s" encountered uploading file.%sSwitch to multi-cell modeSwitch to single-cell modeTab CompletionTextThank you for rating the worksheet %s! You can see all ratings of this worksheet.Thank you for registering for the Sage notebook. To complete your registration, copy and paste the following link into your browser: %s://%s:%s/confirm?key=%s You will be taken to a page which will confirm that you have indeed registered.The Sage notebook is a collection of worksheets, saved objects, and user information.The Sage NotebookThe Sage Notebook was primarily written by William Stein with substantial contributions from Tom Boothby, Timothy Clemans, Alex Clemesha, Mike Hansen, Bobby Moretti, Yi Qiang, and Dorian Raymer.The confirmation system is not active.The password for the user %(u)s has been reset to %(p)sThe passwords you entered do not match.The user "%s" has no worksheet "%s".The username must start with a letter and be between 4 and 32 characters long. It can only consist of letters, numbers, underscores, and one dot (.).The variable DIR contains the directory from which you started the SAGE notebook. For example, to open a file in that directory, do "open(DIR+'filename')".The worksheet operation "%s" is not defined.There are no published worksheets.There is no published worksheet with name "%s". Redirecting to the index of published worksheets in 10 seconds...

    There was an error uploading "%s" (please recheck the URL).%sThere was an error uploading the worksheet. It could be an old unsupported format or worse. If you desperately need its contents contact the sage-support group and post a link to your worksheet. Alternatively, an sws file is just a bzip2 tarball; take a look inside!%sThis Sage Worksheet is currently shared with the people listed in the box below.This page is rated %(wr).1f.This url can only be accessed through a POST request.This worksheet is read only. Please make a copy or contact the owner to change it.TimeTitle of saved worksheetTo fix unmatched or mis-matched parentheses, braces or brackets, press ctrl-0. Parentheses before the cursor will be matched, minding strings and (Python) comments.To quickly try out Sage start hereTo save this image, you can try right-clicking on the image to copy it or save it to a file, or you may be able to just drag the image to your desktop.ToggleToggle the top barTotalTotalsTrashTrying again in %(num)d second...Trying again in %(num)d seconds...TutorialType "%time" at the beginning of the cell.Type "restart" to restart the SAGE interpreter for a given worksheet. (You have to interrupt first.)Type ? immediately after the object or function and press tab or shift-enter (shift-enter overwrites output and saves to worksheet).Type of challengeType pretty_print_default() in an input cell and press shift-enter. All future output will be typeset automatically.Typesetting All OutputUnable to interrupt calculation.UnarchiveUnarchive selected worksheets so it appears in the default worksheet listUndeleteUndoUnsuspendUntitledUpdatedUploadUpload WorksheetUpload or Create Data FileUpload or Create Data File to attach to worksheet "%(wn)s"Upload or create a data file in a wide range of formatsUpload or create file...Upload worksheet (an sws or txt file) to the Sage NotebookUse "attach filename.sage" or "attach filename.py". Attached files are automatically reloaded when the file changes. The file $HOME/.sage/init.sage is attached on startup if it exists.Use "load filename.sage" and "load filename.py". Load is relative to the path you started the notebook in. The .sage files are preparsed and .py files are not. You may omit the .sage or .py extension. Files may load other files.Use "save obj1 obj2 ..." and "load obj1 obj2 ...". This allows for easy moving of objects from one worksheet to another, and saving of objects for later use.Use "save_session('name')" to save all variables to an object. Use "load_session('name')" to merge in all variables from a saved session.Use Most Mathematics Software from Within SageUse Sage for studying calculus, elementary to very advanced number theory, cryptography, commutative algebra, group theory, graph theory, numerical and exact linear algebra, and more.Use a Mainstream Programming LanguageUse a challenge for account registrationUse an Open Source AlternativeUse the Data menu to upload images and other files, and create new files that can be shared between worksheets. The DATA variable contains the path to the data files. For example, to open a file in that directory, do "open(DATA+'filename')". If foo.sage is a Sage file that you uploaded, type "load foo.sage"; if foo.py is a Python file, you can import it by typing "import foo".Useful TipsUserUser "%s" does not have permission to view the home page of "%s".User ManagementUsernameUsername ErrorUsername already in useUsername is not in the systemUsername takenUsersVersionView a 4000+ page reference manual about SageView a log of recent computationsView changes to this worksheet over timeView plain textView plain text version of this worksheetWelcome to Sage! You can create a new worksheet, view published worksheets, or read the documentation.Welcome!What do you want to call it? (if different than the original name)What is 2 plus 3?What is 3 times 8?What is the largest prime factor of 15?With the Sage Notebook anyone can create, collaborate on, and publish interactive worksheets. In a worksheet, one can write code using Sage, Python, and other software included in Sage.Working DirectoryWorksheetWorksheet is locked. Cannot insert cells.Worksheet is publicly viewable at %(u)sWorksheet process limitsWorksheet process users (comma-separated list)Wrong passwordYesYou are not authorized to move "%s"You are not logged in or do not have access to the worksheet "%s".You can publish your worksheet to the Internet, where anyone will be able to access and view it online.You may add or remove collaborators (separate user names by commas).You may download %(f)s or create a linked copy to the worksheetYou must login first in order to edit this worksheet.You must login first in order to rate this worksheet.You requested to evaluate a cell that, for some reason, the server is unaware of.You work with Sage using the highly regarded scripting language Python. You can write programs that combine serious mathematics with anything else.Your browser / OS combination is not supported.\nPlease use Firefox or Opera under Linux, Windows, or Mac OS X, or Safari.Your email address is required for account confirmation and recovery. You will be emailed a confirmation link right after you successfully sign up.Your new password is %s Sign in at %s://%s:%s/ Make sure to reset your password by going to Settings in the upper right bar.Your password must be between 4 and 32 characters long. Your password can not contain your username nor spaces.Your username must start with a letter and be between 3 and 64 characters long. You may only use letters, numbers, underscores, @, and dots.Your worksheet will be assigned a unique address (URL) that you can send to your friends and colleagues.browse directorycan't evaluate worksheet cellscs_CZde_ATen_USes_ESevaluatefr_FRlast edited on %(t)s by %(le)sloading...optionalor delete %(f)s.pt_BRpublishedreCAPTCHA private keyreCAPTCHA public keyru_RUrunnings (canceling further update checks).select worksheetuk_UAunprintedy|yesProject-Id-Version: Sage Notebook 0.8 Report-Msgid-Bugs-To: EMAIL@ADDRESS POT-Creation-Date: 2011-06-18 15:38-0300 PO-Revision-Date: 2011-06-18 20:43-0300 Last-Translator: Achim Faßbender Language-Team: Achim Faßbender MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit Generated-By: Babel 1.3 %(num)d Tag%(num)d Tage%(num)d Stunde%(num)d Stunden%(num)d Minute%(num)d Minuten%(num)d Sekunde%(num)d Sekundenvor %(seconds)svor %(t)s durch %(le)s(beachten Sie, dass Bilder nicht aufgezeichnet werden)24|vierundzwanzig5|fünf8|achtDen Lehrpfad durcharbeiten (wenn Sie Schwierigkeiten damit haben, sehen Sie die statische Fassung ein).Stattdessen neu starten?

    E-Mail-Adresse bestätigt für Benutzer %s

    Ungültiger Bestätigungsschlüssel

    Sie bringen einen Bestätigungsschlüssel mit, der nicht von diesem Server ausgestellt wurde. Bitte registrieren Sie sich beim Server.

    Sage ist ein alternativer Ansatz mathematischer SoftwareEine Sitzung ist ein Arbeitsblatt mit einer Menge von Variablen in einem gewissen Zustand.Ein Arbeitsblatt ist eine geordnete Liste von Berechnungen in Sage samt Ausgaben.Ein neues Passwort wird an die mit Ihrem Konto verbundene E-Mail-Adresse gesendet. Falls Sie Ihre E-Mail-Adresse jedoch nicht bestätigt haben, können Sie Ihr Konto nicht wiederherstellen.Durch Eingabe von DATA+'%(f)s' erhalten Sie Zugriff auf %(f)s in diesem Arbeitsblatt. DATA ist hier eine spezielle Variable, die den genauen Pfad aller in dieses Arbeitsblatt hochgeladenen Daten-Dateien angibt.KontowiederherstellungKontoeinstellungenVorgang...AktivAktive ArbeitsblätterNeuen Benutzer hinzufügenBenutzer hinzufügenHinzufügen oder löschenEine Herausforderung beantwortenAlle Zellen mit "#auto" in der Eingabe werden beim ersten Öffnen des Arbeitsblatts automatisch ausgewertet.ErscheinungsbildAprilAblegenAusgewählte Arbeitsblätter ablegen, so dass sie nicht in der vorausgewählten Liste der Arbeitsblätter erscheinenAbgelegtAbgelegte ArbeitsblätterAnhängen von ScriptenAugustEchtheitsnachweisZellen beim Laden automatisch auswertenNach Änderungen automatisch erneut veröffentlichenZurück zur persönlichen Liste der ArbeitsblätterUnzulässiges PasswortUnzulässiger BenutzernameBeginnen Sie einen Block mit %sh, so wird der Rest des Blocks als Shell-Script ausgewertet. Das aktuelle Arbeitsverzeichnis wird beibehalten.Veröffentlichte Sage-Arbeitsblätter durchsuchen
    (kein Login erforderlich)Alle veröffentlichten Arbeitsblätter durchsuchenDurchsuchen Sie Ihren Computer, um eine Datei zum Hochladen auszuwählen:Durchsuchen Sie Ihren Computer, um ein Arbeitsblatt zum Hochladen auszuwählen:Indem Sie Sage nutzen, helfen Sie, eine respektable freie alternative zu Magma, Maple, Mathematica und MATLAB zu unterstützen. Sage umfasst viele qualitativ hochwertige freie Mathematik-Pakete.AbbrechenÄnderungen verwerfenTestfälleIntervall für automatisches Speichern abändernE-Mail-Adresse ändernPasswort ändernKontoeinstellungen ändern, einschließlich PasswortKlicken Sie auf Protokoll, um alle Befehle anzuzeigen, die Sie bisher in beliebigen Arbeitsblättern dieses Notebooks eingegeben haben.Klicken Sie auf Unterbrechen oder drücken Sie Escape in einer beliebigen Zelle. Dadurch werden viele Interrupt-Signale gesendet, die SAGE (versuchen zu) unterbrechen.Zum Auswerten klicken Sie hier oder drücken Sie Shift+EnterKlicken Sie hier, um herauszuspringenHier klicken, um Obiges in ein Sage Arbeitsblatt umzuwandelnKlicken Sie links der Ausgabe, um zwischen verborgen, sichtbar mit Zeilenumbruch und sichtbar ohne Zeilenumbruch zu wechseln.Klicken, um die Tex-Schriftart herunterzuladen und zu installieren.Klicken, um dieses Arbeitsblatt umzubenennenSchließen Sie diesen Kasten, um die Versuche einzustellen.Code wird durch Ausführen (nach dem Vorparsen) ausgewertet. Nur die Ausgabe der letzten Zeile einer Zelle wird implizit gedruckt. Wann immer eine Zeile mit "sage:" oder ">>>" beginnt, wird davon ausgegangen, dass der gesamte Block Text und Beispiele enthält und folglich nur solche Zeilen ausgeführt, die mit einer Eingabeaufforderung beginnen. Daher können Sie vollständige Beispiele aus der Dokumentation ohne irgendwelche Anpassungen einfügen. Und Sie können Eingabezellen schreiben, die unausgewerteten Klartext, gemischt mit Beispielen, enthalten, indem Sie den Block mit ">>>" beginnen oder ein Beispiel einschließen.MitarbeiterKommentarKommentieren / Entfernen von Kommentaren von BlöckenBestätigtHerzlichen Glückwunsch! Sie können sich jetzt bei Sage Notebook anmelden.KonstruktionenFortsetzenDieses Arbeitsblatt kopierenArbeitsblatt kopierenAnzahlKonto erstellenZulässiges Passwort erstellenNeue Sage-Arbeitsblatt-Fassung aus den letzten 100 Befehlen im obigen Protokoll erzeugen.Neues Arbeitsblatt erstellenBenutzernamen erstellenKonto erstellenDie Funktion, neue Benutzer anzulegen, wurde vom Administrator deaktiviert.Aktuelles VerzeichnisAktuelle E-mailPersönliche Anpassungen des Notebook-CSSDATA-VariableDIR-VariableDaten-DateiDaten...DezemberVorausgewählte SpracheVorausgewähltes SystemLöschenAlle Ausgaben löschenZelle löschenLöschen Sie den gesamten Zellinhalt und drücken Sie dann Backspace.Alle Ausgaben löschenArbeitsblatt löschenGelöschte ArbeitsblätterAnleitung für EntwicklerVerwerfen & verlassenÄnderungen an diesem Arbeitsblatt verwerfenWollen Sie dieses Arbeitsblatt veröffentlichen?Größe des DokumentenspeichersDokumentationHerunterladenAlle aktiven herunterladenAusgewählte Arbeitsblätter herunterladenHerunterladen.Jeder Code-Block wird in seinem eigenen Verzeichnis ausgeführt. Eventuell als Nebeneffekt erzeugte Bilder werden automatisch dargestellt.BearbeitenKopie bearbeiten.Klartext bearbeitenText-Fassung dieses Arbeitsblatts bearbeitenBearbeiten.Verstrichene ZeitE-Mail bestätigtMülleimer leerenBeim Leeren des Mülleimers werden alle darin befindlichen Objekte entgültig gelöscht. Fortsetzen?Registierung von Benutzern aktivierenEdle Druckausgabe aktivieren/deaktivierenGeben Sie Ihre E-Mail-Adresse einUmgebungFehlerFehler beim Anwenden der Funktion auf das Arbeitsblatt / die Arbeitsblätter.Fehler gefundenFehler bei der Selbstüberprüfung -- ungültige Zell-ID.Fehler beim Aktualisieren der Zell-Ausgabe hinter Fehler beim Hochladen der Datei (fehlendes %s-Argument).%sFehler beim Hochladen der Datei (fehlendes Dateifeld Datei).%sFehler beim Hochladen der Datei (fehlender Dateiname).%sFehler gefundenAlles auswertenZelle auswerten unter Verwendung von GAP, Singular usw.Eingaben auswertenAlle Eingabezellen in diesem Arbeitsblatt auswertenAlle Eingabezellen unter Verwendung von %(i)s auswertenVerlassen"%(wanted)s" erwartet hinter "%(key)s", aber "%(token)s" vorgefundenFarbwert "%(arg)s" nach "%(key)s" erwartetGanzzahl "%(arg)s" nach "%(key)s" erwartetGanzzahl "%(key)s" vor "%(token)s" erwartetFehlerFehler beim Speichern des Arbeitsblatts.Schnelle statische Fassungen der DokumentationFebruarDatei...Dateien und ScripteHilfe und Dokumentation beziehenPasswort vergessenVolltextsuche nach Dokumenten und QuelltextÄtsch! -- So einfach lässt sich das Bewertungssystem nicht überlisten!Allgemeine und Fortgeschrittene Reine und Angewandte MathematikBild holenErste Schritte mit SageDen obigen Mitarbeitern Zugang zu Ihrem Arbeitsblatt gewährenZum Arbeitsblatt navigieren.HilfeKontextbezogene HilfeHilfe per Internet-Chat beziehen (IRC)Hallo %s! VerbergenAlle Ausgaben verbergenAlle Ausgaben verbergenAusgaben verbergen/anzeigenHeben Sie Text hervor und drücken Sie Ctrl+., um ihn zu kommentieren und Ctrl+,, um einen Kommentar zu entfernen. Alternativ können Sie Ctrl+3 und Ctrl+4 verwenden.Heben Sie Text hervor und drücken Sie >, um alles einzurücken und <, um alles auszurücken (funktioniert in Safari und Firefox). In Firefox können Sie auch Tab und Shift+Tab drücken.VerlaufAusgangspunktWie erstelle ich ... in Sage?Wie viele Bits sind ein Byte?Benutzung von Sage NotebookIntervall für Überprüfung auf Leerlauf (Sekunden)Beenden nach Leerlaufdauer in SekundenWenn Sie eine Datei $HOME/.sage/notebook.css erstellen, dann wird sie beim Rendern des Notebooks angewandt. Sehen Sie Falsches Passwort angegebenBlöcke einrückenEingaberegelnNeue Zelle einfügenNeue Text-Zelle einfügenInteraktive dynamische FenstererweiterungenDieses Arbeitsblatt interaktiv verwendenUnterbrechenLaufende Berechnungen unterbrechenSitzungen unterbrechen und neu startenUnterbrechungsversuchAktuell laufende Berechnungen unterbrechen, sofern möglichUngültige Anfrage auf eine HerausforderungUngültige E-Mail-AdresseUngültiger BenutzernameMitarbeiter einladenGilt pi > e ?JanuarVerborgenes Java-AppletUm Sage Notebook zu benutzen, muss Javascript muss aktiv sein.Jmol-BildJuliJuniTastatur- und MausanbindungSpracheLetzte ÄnderungLernen Sie Sage-Programme zu schreibenZulassen, dass andere dieses Arbeitsblatt bearbeitenIn Datei gespeichertes neues Arbeitsblatt ladenArbeitsblatt aus Datei laden...Lade SAGE/Python-ScripteLaden und Speichern von ObjektenSitzungen laden und speichernProtokollEinloggenLoggen Sie sich ein, um eine Kopie zu bearbeiten.Aus dem Sage-Notebook ausloggenDieses Arbeitsblatt öffentlich einsehbar machenBenutzer verwaltenMärzMaximale Länge des VerlaufsMaiMinuten:Bewegen Sie den Mauszeiger zwischen Zellen bis ein blauer Balken erscheint. Mit Shift+Klick auf dem blauen Balken können Sie eine neue Textzelle erstellen. Doppelklicken Sie vorhandenen Text, um ihn zu bearbeiten. Verwenden Sie $...$ und $$...$$, um mathematische Formeln in den Textblock einzuschließen.Ausgewählte Arbeitsblätter aus dem Mülleimer holenAusgewählte Arbeitsblätter in den Mülleimer verschiebenDieses Arbeitsblatt in den Mülleimer verschiebenMehr-Zell-ModusNeues ArbeitsblattNeue E-MailNeues PasswortNeues Passwort nicht angegebenNeues ArbeitsblattNeuereNeuesteNeinKeine Antwort auf die Herausforderung angegebenKeine Daten-Dateien vorhandenKeine E-Mail-Adresse angegebenKein Passwort angegebenKein solches Arbeitsblatt vorhanden.Kein Benutzername angegebenUnbestätigtNotebook-EinstellungenNovemberAnzahl der Spalten pro ZeileOktoberAltes PasswortAltes Passwort nicht angegebenÄltereÄltesteEin-Zell-ModusNur der Eigentümer eines Arbeitsblatts ist zu dessen Freigabe berechtigt. Sie können tun, was immer Sie möchten, wenn Sie Ihre eigene Kopie anfertigen.Oder geben Sie den URL einer Datei im Internet ein:Oder geben Sie den URL eines Arbeitsblatts im Internet ein:Oder geben Sie den Namen einer neuen Datei ein, die erstellt werden soll:Andere veröffentlichte Dokumente...EigentümerKorrektheit der KlammerungDurchlaufenPasswortDie Passwörter stimmen nicht übereinBenutzernamen wählenBitte, bitten Sie den Administrator eine Herausforderung einzurichten!Bitte geben Sie einen Namen ein für dieses Arbeitsblatt.Bitte loggen Sie sich ins Sage-Notebook einBitte fragen Sie nach einem bestimmten ArbeitsblattBitte geben Sie ein Arbeitsblatt zum Laden an.%sBitte geben Sie das neue Passwort nochmals ein.Möglicher Fehler beim Löschen des Arbeitsblatts.Drücken Sie Ctrl+; in einer Zelle, um sie in zwei Zellen zu spalten und Ctrl+Backspace, um sie zu vereinigen. Drücken Sie Ctrl+Enter, um eine Zelle zu spalten und beide Teile auszuwerten.Drücken Sie Shift+Enter, um mehrere Berechnungen auf einmal zu starten. Wenn Sie stattdessen Alt+Enter drücken, wird eine neue Zelle hinter der aktuellen erzeugt. Drücken Sie Ctrl+Enter, so wird die Zelle gespalten und beide Teile getrennt ausgewertet.Drücken Sie Tab während der Cursor auf einem Bezeichner steht. Bei einigen Internetbrowsern (z.B. Opera) müssen Sie Ctrl+Leertaste benutzen anstatt Tab.Edle Druckausgabe (Schriftsatz)DruckenDieses Arbeitsblatt druckenProblem beim Einfügen einer neuen Eingabezelle hinter der aktuellen Eingabezelle.\nVeröffentlichenDieses veröffentlichenVeröffentlichtVeröffentlichte ArbeitsblätterVeröffentlicht am %(t)sSetzen Sie "%gap", "%singular" usw. als erste Eingabezeile einer Zelle, so wird der Rest der Zelle im jeweiligen System ausgewertet.Geben Sie ?? unmittelbar hinter dem Objekt und drücken Sie Tab oder Shift+Enter (die Kombination Shift+Enter überschreibt Ausgaben und speichert ins Arbeitsblatt).Setzen Sie @interact in die Zeile vor einer Funktionsdefinition. Geben Sie interact? ein für nähere Informationen.Bringen Sie den Mauszeiger zwischen eine Ausgabe und eine Eingabe bis die waagerechte Linie erscheint und klicken dann. Wenn Sie in einer Zelle Alt+Enter drücken, wird sie ausgewertet und eine neue Zelle wird hinter ihr eingefügt.Arbeitsblatt-Prozess beendenBewerten:BewertungBewertung entgegengenommenBewertungen für %(wn)sArbeitsblatt erneut veröffentlichenGeben Sie Ihr Passwort nochmals einReferenzhandbuchMeine Anmeldedaten merkenUmbenennenDieses Arbeitsblatt umbenennenArbeitsblatt umbenennenProblem meldenProblem melden oder auf Fehler aufmerksam machenZur Konto-Registrierung die Angabe der E-Mail-Adresse fordernNochmals bewerten:ZurücksetzenNeu startenArbeitsblatt-Prozess neu startenArbeitsblatt neu startenZurück zu Hochladen oder Erstellen einer Daten-Datei oder %s.Neues Passwort nochmals eingebenAuf diese Revision zurücksetzenRevisionRevision %(lr)sVerlauf der RevisionenListe der RevisionenRevision von vor %(ta)sDokumentation zu SageSage NotebookSage Notebook VersionSage Quelltext-BrowserSage-Benutzer:Sage macht es Ihnen leicht, einen Großteil der Mathematik-Software gemeinsam zu benutzen. Sage beinhaltet GAP, GP/PARI, Maxima, Singular und Dutzende anderer freier Pakete.Sage VersionSage: Verlauf für %(u)sSpeichernSpeichern & verlassenÄnderungen speichernSpeichern und Arbeitsblatt schließenÄnderungen speichernSpeichern und Fenster schließenIntervall für automatisches Speichern (Sekunden)Dieses Arbeitsblatt in einer sws-Datei speichernArbeitsblatt in einer Datei speichern...Arbeitsblätter durchsuchenDurchsuchen Sie die Dokumentation von Sage, indem Sie
    search_doc("meine Anfrage")
    in eine Input-Zelle eingeben und Shift+Enter drücken. Beliebige reguläre Ausdrücke sind als Anfragen zulässig.Suche Sage-Server...Dateibezogene Funktion auswählenEine Arbeitsblatt-Funktion auswählenWählen Sie einen OpenID-AnbieterAngehängte Datei auswählenSeptemberServerEinstellungenFreigebenJetzt freigebenDieses Dokument freigebenShell-ScripteAnzeigenAlle Ausgaben anzeigenAlle Ausgaben anzeigenAnmeldenAbmeldenAnmeldenAnmelden für ein Konto in Sage NotebookAnmelden für neues Sage-Notebook-KontoJemand anderes sieht gerade dieses Arbeitsblatt einEntschuldigung, aber Sie benötigen einen Browser, der den <canvas>-Tag unterstützt.QuellcodeSpezielle Zell-BlöckeZellen spalten und vereinigenStartenStatische Fassung...ZustandAnhaltenVeröffentlichen anhalten.Ausgewählte Arbeitsblätter anhaltenAbschicken"%s" erfolgreich gelöschtSperrenSperrungVerdächtigen Dateinamen "%s" beim Hochladen der Datei .%s gefundenAuf Mehr-Zell-Modus umschaltenAuf Ein-Zell-Modus umschaltenTabulator-VervollständigungTextDanke, dass Sie das Arbeitsblatt bewertet haben %s! Sie können alle Bewertungen zu diesem Arbeitsblatt ansehen.Danke, dass Sie sich bei Sage-Notebook registriert haben. Um die Registrierung abzuschließen, kopieren sie bitte den folgenden Link und fügen ihn in Ihren Browser ein: %s://%s:%s/confirm?key=%s Sie werden auf eine Seite geleitet, die bestätigt, dass Sie sich tatsächlich registriert haben.Sage Notebook ist eine Sammlung von Arbeitsblättern, gespeicherten Objekten und BenutzerinformationenSage NotebookSage Notebook wurde ursprünglich geschrieben von William Stein mit wesentlichen Beiträgen von Tom Boothby, Timothy Clemans, Alex Clemesha, Mike Hansen, Bobby Moretti, Yi Qiang und Dorian Raymer.Das Bestätigungssystem ist nicht aktiv.Das Passwort für den Benutzer %(u)s wurde zurückgesetzt auf %(p)sDie von Ihnen eingegebenen Passwörter stimmen nicht überein.Der Benutzer "%s" hat kein Arbeitsblatt "%s".Der Benutzername muss mit einem Buchstaben beginnen und zwischen 4 und 32 Zeichen lang sein. Er darf nur Buchstaben, Zahlen, Unterstrich sowie einen Punkt (.) enthalten.Die DIR-Variable enthält das Verzeichnis, von dem aus SAGE-Notebook gestartet wurde. Um z.B. eine Datei in diesem Verzeichnis zu öffnen, verwenden Sie "open(DIR+'Dateiname')".Der Arbeitsblatt-Vorgang "%s" ist nicht definiert.Keine veröffentlichten Arbeitsblätter vorhanden.Es gibt kein veröffentlichtes Arbeitsblatt namens "%s". Umleitung zum Verzeichnis veröffentlichter Arbeitsblätter in 10 Sekunden...

    Beim Hochladen von "%s" ist ein Fehler aufgetreten (bitte überprüfen Sie den URL nochmal).%sBeim Hochladen des Arbeitsblatts ist ein Fehler aufgetreten. Es könnte sich um ein altes, nicht unterstütztes Format handeln oder Schlimmeres. Wenn Sie unbedingt dessen Inhalt benötigen, kontaktieren Sie die Sage-Support-Gruppe und posten einen Link auf Ihr Arbeitsblatt. Alternativ: eine sws-Datei ist nur ein bzip2-tar-Archiv; werfen Sie einen Blick hinein!%sDieses Sage-Arbeitsblatt ist zur Zeit freigegeben für die im unteren Kasten aufgelisteten Personen.Diese Seite wurde mit %(wr).1f bewertet.Auf diesen URL kann nur über eine POST-Anfrage zugegriffen werden.Dieses Arbeitsblatt kann nur gelesen werden. Bitte fertigen Sie eine Kopie davon an oder bitten Sie den Eigentümer es zu abzuändern.ZeitTitel des gespeicherten ArbeitsblattsZur Korrektur unpaariger oder fehlgepaarter Klammern drücken Sie Ctrl+0. Klammern vor dem Cursor werden gepaart unter Beachtung von Zeichenfolgenkonstanten und (Python-) Kommentaren.Starten Sie hier, um Sage mal eben auszuprobierenMit einem Rechts-Klick auf dieses Bild können sie versuchen, es zu speichern. Sie können es kopieren oder in einer Datei abspeichern. Oder Sie könnten das Bild einfach auf Ihr Desktop ziehen.WechselnDie Kopfleiste wechselnGesamtInsgesamtMülleimerErneuter Versuch in %(num)d Sekunde...Erneuter Versuch in %(num)d Sekunden...LehrpfadGeben Sie "%time" am Anfang der Zelle ein.Geben Sie "restart" ein, um den SAGE-Interpreter für ein gegebenes Arbeitsblatt neu zu starten. (Sie müssen zunächst unterbrechen.)Geben Sie ? unmittelbar hinter dem Objekt oder der Funktion ein und drücken Sie Tab oder Shift+Enter (die Kombination Shift+Enter überschreibt Ausgaben und speichert ins Arbeitsblatt).Art der HerausforderungGeben Sie pretty_print_default() in eine Eingabezelle ein und drücken Sie Shift+Enter. Der Schriftsatz aller zukünftiger Ausgaben erfolgt automatisch.Alle Ausgaben setzenBerechnung kann nicht unterbrochen werden.Von der Ablage nehmenAusgewählte Arbeitsblätter von der Ablage nehmen, so dass sie in der vorausgewählten Liste der Arbeitsblätter erscheinenLöschen rückgängig machenRückgängigEntsperrenUnbenanntAktualisiertHochladenArbeitsblatt hochladenDaten-Datei hochladen oder erstellenAn das Arbeitsblatt "%(wn)s" anzuhängende Daten-Datei hochladen oder erstellenDaten-Datei nahezu beliebigen Formats hochladen oder erstellenDatei hochladen oder erstellen...Arbeitsblatt in Sage Notebook hochladen (sws- oder txt-Datei)Verwenden Sie "attach Dateiname.sage" oder "attach Dateiname.py". Angehängte Dateien werden nach Änderungen automatisch neu geladen. Die Datei $HOME/.sage/init.sage wird beim Start angehängt, sofern sie existiert.Verwenden Sie "load Dateiname.sage" und "load Dateiname.py". Das Laden erfolgt relativ zu dem Verzeichnis, in dem Sie das Notebook gestartet haben. Die .sage-Dateien werden vorgeparst, .py-Dateien hingegen nicht. Dateien dürfen andere Dateien laden.Verwenden Sie "save obj1 obj2 ..." und "load obj1 obj2 ...". Das macht es leicht, Objekte von einem Arbeitsblatt zu einem anderen zu bewegen oder zur späteren Verwendung zu speichern.Verwenden Sie "save_session('Name')", um alle Variablen in ein Objekt zu speichern. Verwenden Sie "load_session('Name')", um alle Variablen einer gespeicherten Sitzung einzulesen.Greifen Sie innerhalb Sage auf einen Großteil mathematischer Software zurückVerwenden Sie Sage zum Studium der Algebra, elementaren bis sehr fortgeschrittenen Zahlentheorie, Kryptografie, kommutativen Algebra, Gruppentheorie, Graphentheorie, numerischen und exakten linearen Algebra und mehr.Benutzen Sie eine gängige ProgrammierspracheEine Herausforderung zur Konto-Registrierung verwendenNutzen Sie eine freie AlternativeVerwenden Sie das Datenmenü, um Bilder und andere Dateien hochzuladen sowie neue Dateien zu erstellen, auf die von mehreren Arbeitsblättern aus zugegriffen werden kann. Die DATA-Variable enthält den Pfad zu den Daten-Dateien. Um z.B. eine Datei in diesem Verzeichnis zu öffnen, verwenden Sie "open(DATA+'Dateiname')". Wenn Beispiel.sage eine von Ihnen hochgeladene SAGE-Datei ist, geben Sie "load Beispiel.sage" ein. Wenn Beispiel.py eine Python-Datei ist, können Sie sie importieren, indem Sie "import Beispiel" eingeben.Nützliche TippsBenutzerDer Benutzer "%s" ist nicht berechtigt die Homepage von "%s" anzuzeigen.BenutzerverwaltungBenutzernameFehlerhafter BenutzernameBenutzername bereits belegtDer Benutzername ist dem System unbekanntGewählter BenutzernameBenutzerVersionMehr als 4000 Seiten des Referenzhandbuchs zu Sage anzeigenProtokoll der letzten Berechnungen anzeigenIm Laufe der Zeit an diesem Arbeitsblatt vorgenommene Änderungen anzeigenKlartext anzeigenKlartext-Fassung dieses Arbeitsblatts anzeigenWillkommen bei Sage! Sie können ein neues Arbeitsblatt erstellen, veröffentlichte Arbeitsblätter anzeigen oder die Dokumentation lesen.Willkommen!Wie möchten Sie es nennen? (falls abweichend vom ursprünglichen Namen)Was ist 2 plus 3?Was ist 3 mal 8?Was ist der größte Primfaktor von 15?Mit Sage Notebook kann jeder interaktive Arbeitsblätter erstellen, gemeinsam mit anderen bearbeiten und veröffentlichen. In einem Arbeitsblatt kann man Code schreiben unter Verwendung von Sage, Python sowie anderer in Sage enthaltener Software.ArbeitsverzeichnisArbeitsblattDas Arbeitsblatt ist gesperrt. Kann keine Zellen einfügen.Das Arbeitsblatt ist öffentlich einsehbar unter %(u)sBeschränkungen für den Arbeitsblatt-ProzessBenutzer des Arbeitsblatt-Prozesses (Komma-separierte Liste)Falsches PasswortJaSie sind nicht berechtigt, "%s" zu verschiebenSie sind nicht eingeloggt oder haben keinen Zugriff das Arbeitsblatt "%s".Sie können Ihr Arbeitsblatt im Internet veröffentlichen, wo jeder darauf zugreifen und es online einsehen kann.Sie können Mitarbeiter hinzufügen oder entfernen (Trennen der Namen durch Kommata).Sie können eine verlinkte Kopie des Arbeitsblatts herunterladen %(f)s oder erstellenSie müssen sich erst einloggen, um dieses Arbeitsblatt bearbeiten zu können.Sie müssen angemeldet sein, um dieses Arbeitsblatt bewerten zu können.Sie haben die Auswertung einer Zelle angefragt, die der Server aus irgendeinem Grunde nicht kennt.Sie verwenden beim Arbeiten mit Sage die hoch angesehene Skriptsprache Python. Sie können Programme schreiben, die ernste Mathematik mit beliebigen anderen Dingen verknüpfen.Ihre Kombination von Browser und Betriebssystem wird nicht unterstützt.\nBitte benutzen Sie Firefox oder Opera unter Linux, Mac OS X, Safari oder Windows.Zur Bestätigung sowie ggf. Wiederherstellung des Kontos wird Ihre E-Mail-Adresse benötigt. Unmittelbar nach erfolgreicher Anmeldung erhalten Sie einen Bestätigungslink per E-Mail.Ihr neues Passwort lautet: %s Melden Sie sich an bei: %s://%s:%s/ Vergewissern Sie sich, Ihr Passwort zurückzusetzen. Gehen Sie dazu auf Einstellungen im rechten oberen Balken.Ihr Passwort muss zwischen 4 und 32 Zeichen lang sein. Es darf weder Ihren Benutzernamen noch Leerzeichen enthalten.Ihr Benutzername muss mit einem Buchstaben beginnen und zwischen 3 und 64 Zeichen lang sein. Sie dürfen nur Buchstaben, Zahlen, Unterstrich, @ und Punkt verwenden.Ihrem Arbeitsblatt wird eine eindeutige Adresse (URL) zugeordnet, die Sie Ihren Freunden und Kollegen schicken können.Verzeichnis durchsuchenkann Arbeitsblatt-Zellen nicht auswertenÄeÅ¡tina (ÄŒeská republika)Deutsch (Österreich)English (United States)español (España)auswertenfrançais (France)letzte Änderung am %(t)s durch %(le)slade...optionaloder löschen %(f)s.português (Brasil)veröffentlichtreCAPTCHA privater SchlüsselreCAPTCHA öffentlicher SchlüsselруÑÑкий (РоÑÑиÑ)laufends (breche weitere Aktualisierungsprüfungen ab).Arbeitsblatt auswählenукраїнÑька (Україна)ungedrucktj|jasagenb-1.0.1/sagenb/translations/de_AT/LC_MESSAGES/messages.po000066400000000000000000002364331311436262400236550ustar00rootroot00000000000000# Translations template for SAGE Notebook. # Copyright (C) 2011 SAGE # This file is distributed under the same license as the SAGE project. # FIRST AUTHOR bla@achfa.de, 2011. # msgid "" msgstr "" "Project-Id-Version: Sage Notebook 0.8\n" "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" "POT-Creation-Date: 2011-06-18 15:38-0300\n" "PO-Revision-Date: 2011-06-18 20:43-0300\n" "Last-Translator: Achim Faßbender \n" "Language-Team: Achim Faßbender \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Generated-By: Babel 0.9.5\n" "Plural-Forms: nplurals=2; plural=n>1;\n" "X-Poedit-Language: German\n" "X-Poedit-Country: GERMANY\n" "X-Poedit-SourceCharset: utf-8\n" msgid "cs_CZ" msgstr "ÄeÅ¡tina (ÄŒeská republika)" msgid "de_AT" msgstr "Deutsch (Österreich)" msgid "en_US" msgstr "English (United States)" msgid "es_ES" msgstr "español (España)" msgid "pt_BR" msgstr "português (Brasil)" msgid "ru_RU" msgstr "руÑÑкий (РоÑÑиÑ)" msgid "fr_FR" msgstr "français (France)" msgid "uk_UA" msgstr "українÑька (Україна)" #: data/sage/html/base.html:31 #: data/sage/html/login.html:35 msgid "The Sage Notebook" msgstr "Sage Notebook" #: data/sage/html/base.html:33 msgid "Searching for Sage server..." msgstr "Suche Sage-Server..." #: data/sage/html/base.html:35 msgid "Version" msgstr "Version" #: data/sage/html/base_authenticated.html:7 msgid "Please log in to the Sage notebook" msgstr "Bitte loggen Sie sich ins Sage-Notebook ein" #: data/sage/html/base_authenticated.html:7 msgid "Log in" msgstr "Einloggen" #: data/sage/html/base_authenticated.html:9 msgid "Toggle the top bar" msgstr "Die Kopfleiste wechseln" #: data/sage/html/base_authenticated.html:9 #: data/sage/html/test_report.html:123 msgid "Toggle" msgstr "Wechseln" #: data/sage/html/base_authenticated.html:10 msgid "Back to your personal worksheet list" msgstr "Zurück zur persönlichen Liste der Arbeitsblätter" #: data/sage/html/base_authenticated.html:10 msgid "Home" msgstr "Ausgangspunkt" #: data/sage/html/base_authenticated.html:12 #: data/sage/html/base_authenticated.html:14 msgid "Published" msgstr "Veröffentlicht" #: data/sage/html/base_authenticated.html:14 msgid "Browse the published worksheets" msgstr "Alle veröffentlichten Arbeitsblätter durchsuchen" #: data/sage/html/base_authenticated.html:15 msgid "View a log of recent computations" msgstr "Protokoll der letzten Berechnungen anzeigen" #: data/sage/html/base_authenticated.html:15 msgid "Log" msgstr "Protokoll" #: data/sage/html/base_authenticated.html:17 msgid "Change account settings including password" msgstr "Kontoeinstellungen ändern, einschließlich Passwort" #: data/sage/html/base_authenticated.html:17 msgid "Settings" msgstr "Einstellungen" #: data/sage/html/base_authenticated.html:18 msgid "Documentation" msgstr "Dokumentation" #: data/sage/html/base_authenticated.html:18 msgid "Help" msgstr "Hilfe" #: data/sage/html/base_authenticated.html:19 msgid "Report a problem or submit a bug to improve Sage" msgstr "Problem melden oder auf Fehler aufmerksam machen" #: data/sage/html/base_authenticated.html:19 msgid "Report a Problem" msgstr "Problem melden" #: data/sage/html/base_authenticated.html:20 msgid "Log out of the Sage notebook" msgstr "Aus dem Sage-Notebook ausloggen" #: data/sage/html/base_authenticated.html:20 msgid "Sign out" msgstr "Abmelden" #: data/sage/html/docs.html:3 msgid "Sage Documentation" msgstr "Dokumentation zu Sage" #: data/sage/html/docs.html:15 msgid "To quickly try out Sage start here" msgstr "Starten Sie hier, um Sage mal eben auszuprobieren" #: data/sage/html/docs.html:15 msgid "Tutorial" msgstr "Lehrpfad" #: data/sage/html/docs.html:16 msgid "View a 4000+ page reference manual about Sage" msgstr "Mehr als 4000 Seiten des Referenzhandbuchs zu Sage anzeigen" #: data/sage/html/docs.html:16 msgid "Reference Manual" msgstr "Referenzhandbuch" #: data/sage/html/docs.html:17 msgid "Learn to write Sage programs" msgstr "Lernen Sie Sage-Programme zu schreiben" #: data/sage/html/docs.html:17 msgid "Developer Guide" msgstr "Anleitung für Entwickler" #: data/sage/html/docs.html:18 msgid "How do I construct ... in Sage?" msgstr "Wie erstelle ich ... in Sage?" #: data/sage/html/docs.html:18 msgid "Constructions" msgstr "Konstruktionen" #: data/sage/html/docs.html:21 msgid "Static version..." msgstr "Statische Fassung..." #: data/sage/html/docs.html:21 msgid "Fast Static Versions of the Documentation" msgstr "Schnelle statische Fassungen der Dokumentation" #: data/sage/html/docs.html:22 msgid "Help via Internet Chat (IRC)" msgstr "Hilfe per Internet-Chat beziehen (IRC)" #: data/sage/html/docs.html:28 msgid "How to use the Sage Notebook" msgstr "Benutzung von Sage Notebook" #: data/sage/html/docs.html:30 msgid "A worksheet is an ordered list of Sage calculations with output." msgstr "Ein Arbeitsblatt ist eine geordnete Liste von Berechnungen in Sage samt Ausgaben." #: data/sage/html/docs.html:31 msgid "A session is a worksheet and a set of variables in some state." msgstr "Eine Sitzung ist ein Arbeitsblatt mit einer Menge von Variablen in einem gewissen Zustand." #: data/sage/html/docs.html:32 msgid "The Sage notebook is a collection of worksheets, saved objects, and user information." msgstr "Sage Notebook ist eine Sammlung von Arbeitsblättern, gespeicherten Objekten und Benutzerinformationen" #: data/sage/html/docs.html:45 msgid "The Sage Notebook was primarily written by William Stein with substantial contributions from Tom Boothby, Timothy Clemans, Alex Clemesha, Mike Hansen, Bobby Moretti, Yi Qiang, and Dorian Raymer." msgstr "Sage Notebook wurde ursprünglich geschrieben von William Stein mit wesentlichen Beiträgen von Tom Boothby, Timothy Clemans, Alex Clemesha, Mike Hansen, Bobby Moretti, Yi Qiang und Dorian Raymer." #: data/sage/html/error_message.html:4 #: data/sage/html/login.html:63 #: data/sage/html/login.html:70 #: data/sage/html/login.html:98 #: data/sage/html/login.html:100 #: data/sage/html/recaptcha.html:27 #: data/sage/html/test_report.html:112 #: data/sage/html/test_report.html:131 #: data/sage/html/accounts/registration.html:20 #: data/sage/html/accounts/registration.html:23 #: data/sage/html/accounts/registration.html:26 #: data/sage/html/accounts/registration.html:36 #: data/sage/html/accounts/registration.html:39 #: data/sage/html/accounts/registration.html:46 #: data/sage/html/accounts/registration.html:57 #: data/sage/html/accounts/registration.html:60 #: data/sage/html/accounts/registration.html:69 #: data/sage/html/accounts/registration.html:72 #: data/sage/html/settings/admin_add_user.html:17 #: data/sage/html/settings/admin_add_user.html:19 #: data/sage/js/translated-messages.js:17 msgid "Error" msgstr "Fehler" #: data/sage/html/error_message.html:19 msgid "Continue" msgstr "Fortsetzen" #: data/sage/html/history.html:3 #, python-format msgid "Sage: History for %(u)s" msgstr "Sage: Verlauf für %(u)s" #: data/sage/html/history.html:13 msgid "Click here to turn the above into a Sage worksheet" msgstr "Hier klicken, um Obiges in ein Sage Arbeitsblatt umzuwandeln" #: data/sage/html/history.html:13 msgid "Create a new Sage worksheet version of the last 100 commands in the above log." msgstr "Neue Sage-Arbeitsblatt-Fassung aus den letzten 100 Befehlen im obigen Protokoll erzeugen." #: data/sage/html/login.html:12 #, fuzzy msgid "username" msgstr "Benutzername" #: data/sage/html/login.html:13 msgid "Select an OpenID provider" msgstr "Wählen Sie einen OpenID-Anbieter" #: data/sage/html/login.html:14 #, fuzzy msgid "Send" msgstr "Abschicken" #: data/sage/html/login.html:22 #: data/sage/html/login.html:78 msgid "Sign in" msgstr "Anmelden" #: data/sage/html/login.html:28 #, python-format msgid "Congratulations %(u)s! You can now sign into the Sage Notebook." msgstr "Herzlichen Glückwunsch! Sie können sich jetzt bei Sage Notebook anmelden." #: data/sage/html/login.html:32 msgid "Welcome!" msgstr "Willkommen!" #: data/sage/html/login.html:33 msgid "Sage is a different approach to mathematics software." msgstr "Sage ist ein alternativer Ansatz mathematischer Software" #: data/sage/html/login.html:36 msgid "With the Sage Notebook anyone can create, collaborate on, and publish interactive worksheets. In a worksheet, one can write code using Sage, Python, and other software included in Sage." msgstr "Mit Sage Notebook kann jeder interaktive Arbeitsblätter erstellen, gemeinsam mit anderen bearbeiten und veröffentlichen. In einem Arbeitsblatt kann man Code schreiben unter Verwendung von Sage, Python sowie anderer in Sage enthaltener Software." #: data/sage/html/login.html:39 msgid "General and Advanced Pure and Applied Mathematics" msgstr "Allgemeine und Fortgeschrittene Reine und Angewandte Mathematik" #: data/sage/html/login.html:40 msgid "Use Sage for studying calculus, elementary to very advanced number theory, cryptography, commutative algebra, group theory, graph theory, numerical and exact linear algebra, and more." msgstr "Verwenden Sie Sage zum Studium der Algebra, elementaren bis sehr fortgeschrittenen Zahlentheorie, Kryptografie, kommutativen Algebra, Gruppentheorie, Graphentheorie, numerischen und exakten linearen Algebra und mehr." #: data/sage/html/login.html:43 msgid "Use an Open Source Alternative" msgstr "Nutzen Sie eine freie Alternative" #: data/sage/html/login.html:44 msgid "By using Sage you help to support a viable open source alternative to Magma, Maple, Mathematica, and MATLAB. Sage includes many high-quality open source math packages." msgstr "Indem Sie Sage nutzen, helfen Sie, eine respektable freie alternative zu Magma, Maple, Mathematica und MATLAB zu unterstützen. Sage umfasst viele qualitativ hochwertige freie Mathematik-Pakete." #: data/sage/html/login.html:47 msgid "Use Most Mathematics Software from Within Sage" msgstr "Greifen Sie innerhalb Sage auf einen Großteil mathematischer Software zurück" #: data/sage/html/login.html:48 msgid "Sage makes it easy for you to use most mathematics software together. Sage includes GAP, GP/PARI, Maxima, and Singular, and dozens of other open packages." msgstr "Sage macht es Ihnen leicht, einen Großteil der Mathematik-Software gemeinsam zu benutzen. Sage beinhaltet GAP, GP/PARI, Maxima, Singular und Dutzende anderer freier Pakete." #: data/sage/html/login.html:51 msgid "Use a Mainstream Programming Language" msgstr "Benutzen Sie eine gängige Programmiersprache" #: data/sage/html/login.html:52 msgid "You work with Sage using the highly regarded scripting language Python. You can write programs that combine serious mathematics with anything else." msgstr "Sie verwenden beim Arbeiten mit Sage die hoch angesehene Skriptsprache Python. Sie können Programme schreiben, die ernste Mathematik mit beliebigen anderen Dingen verknüpfen." #: data/sage/html/login.html:60 #: data/sage/html/accounts/account_recovery.html:13 msgid "Username" msgstr "Benutzername" #: data/sage/html/login.html:63 msgid "Username is not in the system" msgstr "Der Benutzername ist dem System unbekannt" #: data/sage/html/login.html:67 #: data/sage/html/settings/user_management.html:13 msgid "Password" msgstr "Passwort" #: data/sage/html/login.html:70 msgid "Wrong password" msgstr "Falsches Passwort" #: data/sage/html/login.html:74 msgid "Remember me" msgstr "Meine Anmeldedaten merken" #: data/sage/html/login.html:83 msgid "Sign up for a new Sage Notebook account" msgstr "Anmelden für neues Sage-Notebook-Konto" #: data/sage/html/login.html:87 msgid "Browse published Sage worksheets
    (no login required)" msgstr "Veröffentlichte Sage-Arbeitsblätter durchsuchen
    (kein Login erforderlich)" #: data/sage/html/login.html:91 msgid "Forgot password" msgstr "Passwort vergessen" #: data/sage/html/login.html:98 msgid "Creating new users is disabled by the administrator." msgstr "Die Funktion, neue Benutzer anzulegen, wurde vom Administrator deaktiviert." #: data/sage/html/login.html:100 msgid "Javascript must be enabled in order to use the Sage Notebook." msgstr "Um Sage Notebook zu benutzen, muss Javascript muss aktiv sein." #: data/sage/html/source_code.html:3 #: notebook/tutorial.py:358 msgid "Source Code" msgstr "Quellcode" #: data/sage/html/source_code.html:13 msgid "Sage Source Browser" msgstr "Sage Quelltext-Browser" #: data/sage/html/source_code.html:14 msgid "browse directory" msgstr "Verzeichnis durchsuchen" #: data/sage/html/test_report.html:79 msgid "Sage Notebook version" msgstr "Sage Notebook Version" #: data/sage/html/test_report.html:85 msgid "Sage version" msgstr "Sage Version" #: data/sage/html/test_report.html:91 msgid "Environment" msgstr "Umgebung" #: data/sage/html/test_report.html:96 msgid "Start" msgstr "Starten" #: data/sage/html/test_report.html:100 #: data/sage/html/worksheet_listing.html:73 msgid "Stop" msgstr "Anhalten" #: data/sage/html/test_report.html:104 msgid "Elapsed" msgstr "Verstrichene Zeit" #: data/sage/html/test_report.html:108 msgid "Status" msgstr "Zustand" #: data/sage/html/test_report.html:110 #: data/sage/html/test_report.html:129 msgid "Pass" msgstr "Durchlaufen" #: data/sage/html/test_report.html:111 #: data/sage/html/test_report.html:130 msgid "Fail" msgstr "Fehler" #: data/sage/html/test_report.html:113 msgid "Total" msgstr "Gesamt" #: data/sage/html/test_report.html:121 msgid "Hide" msgstr "Verbergen" #: data/sage/html/test_report.html:122 msgid "Show" msgstr "Anzeigen" #: data/sage/html/test_report.html:128 msgid "Cases / Tests" msgstr "Testfälle" #: data/sage/html/test_report.html:132 msgid "Count" msgstr "Anzahl" #: data/sage/html/test_report.html:141 msgid "Totals" msgstr "Insgesamt" #: data/sage/html/upload.html:10 msgid "Upload worksheet (an sws or txt file) to the Sage Notebook" msgstr "Arbeitsblatt in Sage Notebook hochladen (sws- oder txt-Datei)" #: data/sage/html/upload.html:14 msgid "Browse your computer to select a worksheet file to upload:" msgstr "Durchsuchen Sie Ihren Computer, um ein Arbeitsblatt zum Hochladen auszuwählen:" #: data/sage/html/upload.html:18 msgid "Or enter the URL of a worksheet file on the web:" msgstr "Oder geben Sie den URL eines Arbeitsblatts im Internet ein:" #: data/sage/html/upload.html:22 #: data/sage/html/notebook/upload_data_window.html:27 msgid "What do you want to call it? (if different than the original name)" msgstr "Wie möchten Sie es nennen? (falls abweichend vom ursprünglichen Namen)" #: data/sage/html/upload.html:25 msgid "Upload Worksheet" msgstr "Arbeitsblatt hochladen" #: data/sage/html/worksheet_listing.html:9 msgid "Published Worksheets" msgstr "Veröffentlichte Arbeitsblätter" #: data/sage/html/worksheet_listing.html:11 msgid "Deleted Worksheets" msgstr "Gelöschte Arbeitsblätter" #: data/sage/html/worksheet_listing.html:13 msgid "Active Worksheets" msgstr "Aktive Arbeitsblätter" #: data/sage/html/worksheet_listing.html:15 msgid "Archived Worksheets" msgstr "Abgelegte Arbeitsblätter" #: data/sage/html/worksheet_listing.html:45 msgid "New Worksheet" msgstr "Neues Arbeitsblatt" #: data/sage/html/worksheet_listing.html:46 msgid "Upload" msgstr "Hochladen" #: data/sage/html/worksheet_listing.html:47 msgid "Download All Active" msgstr "Alle aktiven herunterladen" #: data/sage/html/worksheet_listing.html:54 msgid "Search Worksheets" msgstr "Arbeitsblätter durchsuchen" #: data/sage/html/worksheet_listing.html:62 msgid "Unarchive selected worksheets so it appears in the default worksheet list" msgstr "Ausgewählte Arbeitsblätter von der Ablage nehmen, so dass sie in der vorausgewählten Liste der Arbeitsblätter erscheinen" #: data/sage/html/worksheet_listing.html:62 msgid "Unarchive" msgstr "Von der Ablage nehmen" #: data/sage/html/worksheet_listing.html:64 msgid "Archive selected worksheets so they do not appear in the default worksheet list" msgstr "Ausgewählte Arbeitsblätter ablegen, so dass sie nicht in der vorausgewählten Liste der Arbeitsblätter erscheinen" #: data/sage/html/worksheet_listing.html:64 msgid "Archive" msgstr "Ablegen" #: data/sage/html/worksheet_listing.html:68 msgid "Move the selected worksheets to the trash" msgstr "Ausgewählte Arbeitsblätter in den Mülleimer verschieben" #: data/sage/html/worksheet_listing.html:68 msgid "Delete" msgstr "Löschen" #: data/sage/html/worksheet_listing.html:70 msgid "Move the selected worksheets out of the trash" msgstr "Ausgewählte Arbeitsblätter aus dem Mülleimer holen" #: data/sage/html/worksheet_listing.html:70 msgid "Undelete" msgstr "Löschen rückgängig machen" #: data/sage/html/worksheet_listing.html:73 msgid "Stop selected worksheets" msgstr "Ausgewählte Arbeitsblätter anhalten" #: data/sage/html/worksheet_listing.html:75 msgid "Download selected worksheets" msgstr "Ausgewählte Arbeitsblätter herunterladen" #: data/sage/html/worksheet_listing.html:75 msgid "Download" msgstr "Herunterladen" #: data/sage/html/worksheet_listing.html:79 msgid "Current Folder" msgstr "Aktuelles Verzeichnis" #: data/sage/html/worksheet_listing.html:80 msgid "Active" msgstr "Aktiv" #: data/sage/html/worksheet_listing.html:81 msgid "Archived" msgstr "Abgelegt" #: data/sage/html/worksheet_listing.html:82 msgid "Trash" msgstr "Mülleimer" #: data/sage/html/worksheet_listing.html:86 msgid "Empty Trash" msgstr "Mülleimer leeren" #: data/sage/html/worksheet_listing.html:101 #: data/sage/html/worksheet/ratings_info.html:9 msgid "Rating" msgstr "Bewertung" #: data/sage/html/worksheet_listing.html:112 msgid "Owner" msgstr "Eigentümer" #: data/sage/html/worksheet_listing.html:112 msgid "Collaborators" msgstr "Mitarbeiter" #: data/sage/html/worksheet_listing.html:118 #: data/sage/html/notebook/worksheet_revision_list.html:16 msgid "Last Edited" msgstr "Letzte Änderung" #: data/sage/html/worksheet_listing.html:128 msgid "There are no published worksheets." msgstr "Keine veröffentlichten Arbeitsblätter vorhanden." #: data/sage/html/worksheet_listing.html:134 msgid "Welcome to Sage! You can create a new worksheet, view published worksheets, or read the documentation." msgstr "Willkommen bei Sage! Sie können ein neues Arbeitsblatt erstellen, veröffentlichte Arbeitsblätter anzeigen oder die Dokumentation lesen." #: data/sage/html/worksheet_listing.html:176 msgid "running" msgstr "laufend" #: data/sage/html/worksheet_listing.html:209 msgid "Add or Delete" msgstr "Hinzufügen oder löschen" #: data/sage/html/worksheet_listing.html:211 msgid "Share now" msgstr "Jetzt freigeben" #: data/sage/html/worksheet_listing.html:216 msgid "published" msgstr "veröffentlicht" #: data/sage/html/accounts/account_recovery.html:3 #: data/sage/html/accounts/account_recovery.html:8 msgid "Account Recovery" msgstr "Kontowiederherstellung" #: data/sage/html/accounts/account_recovery.html:9 msgid "A new password will be emailed to the email address connected to your account. However if you didn't confirm your email address you will be unable to recover your account." msgstr "Ein neues Passwort wird an die mit Ihrem Konto verbundene E-Mail-Adresse gesendet. Falls Sie Ihre E-Mail-Adresse jedoch nicht bestätigt haben, können Sie Ihr Konto nicht wiederherstellen." #: data/sage/html/accounts/account_recovery.html:17 msgid "Submit" msgstr "Abschicken" #: data/sage/html/accounts/account_recovery.html:17 #: data/sage/html/accounts/registration.html:78 #: data/sage/html/notebook/download_or_delete_datafile.html:54 #: data/sage/html/notebook/edit_window.html:12 #: data/sage/html/settings/account_settings.html:10 #: data/sage/html/settings/account_settings.html:67 #: data/sage/html/settings/admin_add_user.html:26 #: data/sage/html/settings/notebook_settings.html:20 #: data/sage/html/settings/notebook_settings.html:27 msgid "Cancel" msgstr "Abbrechen" #: data/sage/html/accounts/registration.html:3 msgid "Sign up" msgstr "Anmelden" #: data/sage/html/accounts/registration.html:9 msgid "Sign up for a Sage Notebook account" msgstr "Anmelden für ein Konto in Sage Notebook" #: data/sage/html/accounts/registration.html:11 msgid "Errors found" msgstr "Fehler gefunden" #: data/sage/html/accounts/registration.html:11 msgid "Error found" msgstr "Fehler gefunden" #: data/sage/html/accounts/registration.html:16 msgid "Create a username" msgstr "Benutzernamen erstellen" #: data/sage/html/accounts/registration.html:17 msgid "Your username must start with a letter and be between 3 and 64 characters long. You may only use letters, numbers, underscores, @, and dots." msgstr "Ihr Benutzername muss mit einem Buchstaben beginnen und zwischen 3 und 64 Zeichen lang sein. Sie dürfen nur Buchstaben, Zahlen, Unterstrich, @ und Punkt verwenden." #: data/sage/html/accounts/registration.html:20 msgid "No username given" msgstr "Kein Benutzername angegeben" #: data/sage/html/accounts/registration.html:23 msgid "Username already in use" msgstr "Benutzername bereits belegt" #: data/sage/html/accounts/registration.html:26 msgid "Bad username" msgstr "Unzulässiger Benutzername" #: data/sage/html/accounts/registration.html:30 msgid "Create a good password" msgstr "Zulässiges Passwort erstellen" #: data/sage/html/accounts/registration.html:32 msgid "Your password must be between 4 and 32 characters long. Your password can not contain your username nor spaces." msgstr "Ihr Passwort muss zwischen 4 und 32 Zeichen lang sein. Es darf weder Ihren Benutzernamen noch Leerzeichen enthalten." #: data/sage/html/accounts/registration.html:36 msgid "No password given" msgstr "Kein Passwort angegeben" #: data/sage/html/accounts/registration.html:39 msgid "Bad password" msgstr "Unzulässiges Passwort" #: data/sage/html/accounts/registration.html:43 msgid "Re-type your password" msgstr "Geben Sie Ihr Passwort nochmals ein" #: data/sage/html/accounts/registration.html:46 msgid "Passwords didn't match" msgstr "Die Passwörter stimmen nicht überein" #: data/sage/html/accounts/registration.html:51 msgid "Enter your email address" msgstr "Geben Sie Ihre E-Mail-Adresse ein" #: data/sage/html/accounts/registration.html:53 msgid "Your email address is required for account confirmation and recovery. You will be emailed a confirmation link right after you successfully sign up." msgstr "Zur Bestätigung sowie ggf. Wiederherstellung des Kontos wird Ihre E-Mail-Adresse benötigt. Unmittelbar nach erfolgreicher Anmeldung erhalten Sie einen Bestätigungslink per E-Mail." #: data/sage/html/accounts/registration.html:57 msgid "No email address given" msgstr "Keine E-Mail-Adresse angegeben" #: data/sage/html/accounts/registration.html:60 msgid "Invalid email address" msgstr "Ungültige E-Mail-Adresse" #: data/sage/html/accounts/registration.html:66 msgid "Answer a challenge" msgstr "Eine Herausforderung beantworten" #: data/sage/html/accounts/registration.html:69 msgid "No challenge response given" msgstr "Keine Antwort auf die Herausforderung angegeben" #: data/sage/html/accounts/registration.html:72 msgid "Invalid challenge response" msgstr "Ungültige Anfrage auf eine Herausforderung" #: data/sage/html/accounts/registration.html:77 msgid "Create account" msgstr "Konto erstellen" #: data/sage/html/notebook/afterpublish_window.html:8 #, python-format msgid "Worksheet is publicly viewable at %(u)s" msgstr "Das Arbeitsblatt ist öffentlich einsehbar unter %(u)s" #: data/sage/html/notebook/afterpublish_window.html:9 #, python-format msgid "Published on %(t)s" msgstr "Veröffentlicht am %(t)s" #: data/sage/html/notebook/afterpublish_window.html:11 msgid "Re-publish worksheet" msgstr "Arbeitsblatt erneut veröffentlichen" #: data/sage/html/notebook/afterpublish_window.html:12 msgid "Stop publishing" msgstr "Veröffentlichen anhalten." #: data/sage/html/notebook/afterpublish_window.html:14 #: data/sage/html/notebook/beforepublish_window.html:18 msgid "Automatically re-publish when changes are made" msgstr "Nach Änderungen automatisch erneut veröffentlichen" #: data/sage/html/notebook/base.html:74 msgid "Click to rename this worksheet" msgstr "Klicken, um dieses Arbeitsblatt umzubenennen" #: data/sage/html/notebook/base.html:79 msgid "Someone else is viewing this worksheet" msgstr "Jemand anderes sieht gerade dieses Arbeitsblatt ein" #: data/sage/html/notebook/base.html:84 #: data/sage/html/notebook/text_cell.html:46 msgid "Save changes" msgstr "Änderungen speichern" #: data/sage/html/notebook/base.html:84 #: data/sage/html/settings/account_settings.html:9 #: data/sage/html/settings/account_settings.html:66 #: data/sage/html/settings/notebook_settings.html:19 #: data/sage/html/settings/notebook_settings.html:26 msgid "Save" msgstr "Speichern" #: data/sage/html/notebook/base.html:84 msgid "Save changes and close window" msgstr "Speichern und Fenster schließen" #: data/sage/html/notebook/base.html:84 msgid "Save & quit" msgstr "Speichern & verlassen" #: data/sage/html/notebook/base.html:84 msgid "Discard changes to this worksheet" msgstr "Änderungen an diesem Arbeitsblatt verwerfen" #: data/sage/html/notebook/base.html:84 msgid "Discard & quit" msgstr "Verwerfen & verlassen" #: data/sage/html/notebook/base.html:90 msgid "Select a file related function" msgstr "Dateibezogene Funktion auswählen" #: data/sage/html/notebook/base.html:90 msgid "File..." msgstr "Datei..." #: data/sage/html/notebook/base.html:91 msgid "Load a new worksheet stored in a file" msgstr "In Datei gespeichertes neues Arbeitsblatt laden" #: data/sage/html/notebook/base.html:91 msgid "Load worksheet from a file..." msgstr "Arbeitsblatt aus Datei laden..." #: data/sage/html/notebook/base.html:92 msgid "Create a new worksheet" msgstr "Neues Arbeitsblatt erstellen" #: data/sage/html/notebook/base.html:92 msgid "New worksheet" msgstr "Neues Arbeitsblatt" #: data/sage/html/notebook/base.html:93 msgid "Save this worksheet to an sws file" msgstr "Dieses Arbeitsblatt in einer sws-Datei speichern" #: data/sage/html/notebook/base.html:93 msgid "Save worksheet to a file..." msgstr "Arbeitsblatt in einer Datei speichern..." #: data/sage/html/notebook/base.html:94 #: data/sage/html/notebook/base.html:143 msgid "Print this worksheet" msgstr "Dieses Arbeitsblatt drucken" #: data/sage/html/notebook/base.html:94 #: data/sage/html/notebook/base.html:143 msgid "Print" msgstr "Drucken" #: data/sage/html/notebook/base.html:95 msgid "Rename this worksheet" msgstr "Dieses Arbeitsblatt umbenennen" #: data/sage/html/notebook/base.html:95 #: data/sage/js/translated-messages.js:11 msgid "Rename worksheet" msgstr "Arbeitsblatt umbenennen" #: data/sage/html/notebook/base.html:96 msgid "Copy this worksheet" msgstr "Dieses Arbeitsblatt kopieren" #: data/sage/html/notebook/base.html:96 msgid "Copy worksheet" msgstr "Arbeitsblatt kopieren" #: data/sage/html/notebook/base.html:97 msgid "Move this worksheet to the trash" msgstr "Dieses Arbeitsblatt in den Mülleimer verschieben" #: data/sage/html/notebook/base.html:97 msgid "Delete worksheet" msgstr "Arbeitsblatt löschen" #: data/sage/html/notebook/base.html:101 msgid "Select a worksheet function" msgstr "Eine Arbeitsblatt-Funktion auswählen" #: data/sage/html/notebook/base.html:101 msgid "Action..." msgstr "Vorgang..." #: data/sage/html/notebook/base.html:102 msgid "Interrupt currently running calculations, if possible" msgstr "Aktuell laufende Berechnungen unterbrechen, sofern möglich" #: data/sage/html/notebook/base.html:102 msgid "Interrupt" msgstr "Unterbrechen" #: data/sage/html/notebook/base.html:103 msgid "Restart the worksheet process" msgstr "Arbeitsblatt-Prozess neu starten" #: data/sage/html/notebook/base.html:103 msgid "Restart worksheet" msgstr "Arbeitsblatt neu starten" #: data/sage/html/notebook/base.html:104 msgid "Quit the worksheet process" msgstr "Arbeitsblatt-Prozess beenden" #: data/sage/html/notebook/base.html:104 msgid "Save and quit worksheet" msgstr "Speichern und Arbeitsblatt schließen" #: data/sage/html/notebook/base.html:106 msgid "Evaluate all input cells in the worksheet" msgstr "Alle Eingabezellen in diesem Arbeitsblatt auswerten" #: data/sage/html/notebook/base.html:106 msgid "Evaluate All" msgstr "Alles auswerten" #: data/sage/html/notebook/base.html:107 msgid "Hide all output" msgstr "Alle Ausgaben verbergen" #: data/sage/html/notebook/base.html:107 msgid "Hide All Output" msgstr "Alle Ausgaben verbergen" #: data/sage/html/notebook/base.html:108 msgid "Show all output" msgstr "Alle Ausgaben anzeigen" #: data/sage/html/notebook/base.html:108 msgid "Show All Output" msgstr "Alle Ausgaben anzeigen" #: data/sage/html/notebook/base.html:109 msgid "Delete all output" msgstr "Alle Ausgaben löschen" #: data/sage/html/notebook/base.html:109 msgid "Delete All Output" msgstr "Alle Ausgaben löschen" #: data/sage/html/notebook/base.html:111 msgid "Switch to single-cell mode" msgstr "Auf Ein-Zell-Modus umschalten" #: data/sage/html/notebook/base.html:111 msgid "One Cell Mode" msgstr "Ein-Zell-Modus" #: data/sage/html/notebook/base.html:112 msgid "Switch to multi-cell mode" msgstr "Auf Mehr-Zell-Modus umschalten" #: data/sage/html/notebook/base.html:112 msgid "Multi Cell Mode" msgstr "Mehr-Zell-Modus" #: data/sage/html/notebook/base.html:115 msgid "Select an attached file" msgstr "Angehängte Datei auswählen" #: data/sage/html/notebook/base.html:115 msgid "Data..." msgstr "Daten..." #: data/sage/html/notebook/base.html:116 msgid "Upload or create a data file in a wide range of formats" msgstr "Daten-Datei nahezu beliebigen Formats hochladen oder erstellen" #: data/sage/html/notebook/base.html:116 msgid "Upload or create file..." msgstr "Datei hochladen oder erstellen..." #: data/sage/html/notebook/base.html:126 #, python-format msgid "Evaluate all input cells using %(i)s" msgstr "Alle Eingabezellen unter Verwendung von %(i)s auswerten" #: data/sage/html/notebook/base.html:132 msgid "Enable/disable pretty_printing" msgstr "Edle Druckausgabe aktivieren/deaktivieren" #: data/sage/html/notebook/base.html:144 msgid "Interactively use this worksheet" msgstr "Dieses Arbeitsblatt interaktiv verwenden" #: data/sage/html/notebook/base.html:144 msgid "Worksheet" msgstr "Arbeitsblatt" #: data/sage/html/notebook/base.html:145 msgid "Edit text version of this worksheet" msgstr "Text-Fassung dieses Arbeitsblatts bearbeiten" #: data/sage/html/notebook/base.html:145 msgid "Edit" msgstr "Bearbeiten" #: data/sage/html/notebook/base.html:146 msgid "View plain text version of this worksheet" msgstr "Klartext-Fassung dieses Arbeitsblatts anzeigen" #: data/sage/html/notebook/base.html:146 msgid "Text" msgstr "Text" #: data/sage/html/notebook/base.html:147 msgid "View changes to this worksheet over time" msgstr "Im Laufe der Zeit an diesem Arbeitsblatt vorgenommene Änderungen anzeigen" #: data/sage/html/notebook/base.html:147 msgid "Undo" msgstr "Rückgängig" #: data/sage/html/notebook/base.html:148 msgid "Let others edit this worksheet" msgstr "Zulassen, dass andere dieses Arbeitsblatt bearbeiten" #: data/sage/html/notebook/base.html:148 msgid "Share" msgstr "Freigeben" #: data/sage/html/notebook/base.html:149 msgid "Make this worksheet publicly viewable" msgstr "Dieses Arbeitsblatt öffentlich einsehbar machen" #: data/sage/html/notebook/base.html:149 msgid "Publish" msgstr "Veröffentlichen" #: data/sage/html/notebook/base.html:157 msgid "Exit" msgstr "Verlassen" #: data/sage/html/notebook/beforepublish_window.html:5 msgid "You can publish your worksheet to the Internet, where anyone will be able to access and view it online." msgstr "Sie können Ihr Arbeitsblatt im Internet veröffentlichen, wo jeder darauf zugreifen und es online einsehen kann." #: data/sage/html/notebook/beforepublish_window.html:7 msgid "Your worksheet will be assigned a unique address (URL) that you can send to your friends and colleagues." msgstr "Ihrem Arbeitsblatt wird eine eindeutige Adresse (URL) zugeordnet, die Sie Ihren Freunden und Kollegen schicken können." #: data/sage/html/notebook/beforepublish_window.html:9 msgid "Do you want to publish this worksheet?" msgstr "Wollen Sie dieses Arbeitsblatt veröffentlichen?" #: data/sage/html/notebook/beforepublish_window.html:14 msgid "Yes" msgstr "Ja" #: data/sage/html/notebook/beforepublish_window.html:15 msgid "No" msgstr "Nein" #: data/sage/html/notebook/cell.html:63 msgid "Click here or press shift-return to evaluate" msgstr "Zum Auswerten klicken Sie hier oder drücken Sie Shift+Enter" #: data/sage/html/notebook/cell.html:64 msgid "evaluate" msgstr "auswerten" #: data/sage/html/notebook/download_or_delete_datafile.html:35 msgid "Data file" msgstr "Daten-Datei" #: data/sage/html/notebook/download_or_delete_datafile.html:39 #, python-format msgid "You may download %(f)s or create a linked copy to the worksheet" msgstr "Sie können eine verlinkte Kopie des Arbeitsblatts herunterladen %(f)s oder erstellen" #: data/sage/html/notebook/download_or_delete_datafile.html:40 msgid "select worksheet" msgstr "Arbeitsblatt auswählen" #: data/sage/html/notebook/download_or_delete_datafile.html:44 #, python-format msgid "or delete %(f)s." msgstr "oder löschen %(f)s." #: data/sage/html/notebook/download_or_delete_datafile.html:46 #, python-format msgid "Access %(f)s in this worksheet by typing DATA+'%(f)s'. Here DATA is a special variable that gives the exact path to all data files uploaded to this worksheet." msgstr "Durch Eingabe von DATA+'%(f)s' erhalten Sie Zugriff auf %(f)s in diesem Arbeitsblatt. DATA ist hier eine spezielle Variable, die den genauen Pfad aller in dieses Arbeitsblatt hochgeladenen Daten-Dateien angibt." #: data/sage/html/notebook/download_or_delete_datafile.html:54 #: data/sage/html/notebook/edit_window.html:11 msgid "Save Changes" msgstr "Änderungen speichern" #: data/sage/html/notebook/edit_window.html:10 msgid "Edit plain text" msgstr "Klartext bearbeiten" #: data/sage/html/notebook/guest_worksheet_page.html:14 msgid "Edit this." msgstr "Bearbeiten." #: data/sage/html/notebook/guest_worksheet_page.html:16 msgid "Log in to edit a copy." msgstr "Loggen Sie sich ein, um eine Kopie zu bearbeiten." #: data/sage/html/notebook/guest_worksheet_page.html:19 msgid "Edit a copy." msgstr "Kopie bearbeiten." #: data/sage/html/notebook/guest_worksheet_page.html:28 msgid "Download." msgstr "Herunterladen." #: data/sage/html/notebook/guest_worksheet_page.html:34 #, python-format msgid "This page is rated %(wr).1f." msgstr "Diese Seite wurde mit %(wr).1f bewertet." #: data/sage/html/notebook/guest_worksheet_page.html:39 msgid "Rerate it:" msgstr "Nochmals bewerten:" #: data/sage/html/notebook/guest_worksheet_page.html:39 msgid "Rate it:" msgstr "Bewerten:" #: data/sage/html/notebook/guest_worksheet_page.html:49 msgid "Other published documents..." msgstr "Andere veröffentlichte Dokumente..." #: data/sage/html/notebook/plain_text_window.html:4 msgid "View plain text" msgstr "Klartext anzeigen" #: data/sage/html/notebook/specific_revision.html:5 #, python-format msgid "Revision from %(ta)s ago" msgstr "Revision von vor %(ta)s" #: data/sage/html/notebook/specific_revision.html:5 msgid "Revision List" msgstr "Liste der Revisionen" #: data/sage/html/notebook/specific_revision.html:12 msgid "Older" msgstr "Ältere" #: data/sage/html/notebook/specific_revision.html:14 msgid "Oldest" msgstr "Älteste" #: data/sage/html/notebook/specific_revision.html:18 msgid "Newer" msgstr "Neuere" #: data/sage/html/notebook/specific_revision.html:20 msgid "Newest" msgstr "Neueste" #: data/sage/html/notebook/specific_revision.html:23 msgid "Revert to this one" msgstr "Auf diese Revision zurücksetzen" #: data/sage/html/notebook/specific_revision.html:23 msgid "(note that images are not recorded)" msgstr "(beachten Sie, dass Bilder nicht aufgezeichnet werden)" #: data/sage/html/notebook/specific_revision.html:24 msgid "Publish this one" msgstr "Dieses veröffentlichen" #: data/sage/html/notebook/text_cell.html:47 msgid "Cancel changes" msgstr "Änderungen verwerfen" #: data/sage/html/notebook/upload_data_window.html:7 #, python-format msgid "Upload or Create Data File to attach to worksheet \"%(wn)s\"" msgstr "An das Arbeitsblatt \"%(wn)s\" anzuhängende Daten-Datei hochladen oder erstellen" #: data/sage/html/notebook/upload_data_window.html:15 msgid "Browse your computer to select a file to upload:" msgstr "Durchsuchen Sie Ihren Computer, um eine Datei zum Hochladen auszuwählen:" #: data/sage/html/notebook/upload_data_window.html:19 msgid "Or enter the URL of a file on the web:" msgstr "Oder geben Sie den URL einer Datei im Internet ein:" #: data/sage/html/notebook/upload_data_window.html:23 msgid "Or enter the name of a new file, which will be created:" msgstr "Oder geben Sie den Namen einer neuen Datei ein, die erstellt werden soll:" #: data/sage/html/notebook/upload_data_window.html:30 msgid "Upload or Create Data File" msgstr "Daten-Datei hochladen oder erstellen" #: data/sage/html/notebook/worksheet_page.html:27 #: notebook/twist.py:413 #: notebook/twist.py:2217 #: notebook/worksheet.py:703 #: notebook/worksheet.py:723 #: notebook/worksheet.py:4079 msgid "Untitled" msgstr "Unbenannt" #: data/sage/html/notebook/worksheet_revision_list.html:6 msgid "Revision History" msgstr "Verlauf der Revisionen" #: data/sage/html/notebook/worksheet_revision_list.html:15 msgid "Revision" msgstr "Revision" #: data/sage/html/notebook/worksheet_revision_list.html:22 #, python-format msgid "Revision %(lr)s" msgstr "Revision %(lr)s" #: data/sage/html/notebook/worksheet_share.html:10 msgid "Share this document" msgstr "Dieses Dokument freigeben" #: data/sage/html/notebook/worksheet_share.html:17 msgid "Only the owner of a worksheet is allowed to share it. You can do whatever you want if you make your own copy." msgstr "Nur der Eigentümer eines Arbeitsblatts ist zu dessen Freigabe berechtigt. Sie können tun, was immer Sie möchten, wenn Sie Ihre eigene Kopie anfertigen." #: data/sage/html/notebook/worksheet_share.html:19 msgid "This Sage Worksheet is currently shared with the people listed in the box below." msgstr "Dieses Sage-Arbeitsblatt ist zur Zeit freigegeben für die im unteren Kasten aufgelisteten Personen." #: data/sage/html/notebook/worksheet_share.html:20 msgid "You may add or remove collaborators (separate user names by commas)." msgstr "Sie können Mitarbeiter hinzufügen oder entfernen (Trennen der Namen durch Kommata)." #: data/sage/html/notebook/worksheet_share.html:24 msgid "Give access to your worksheet to the above collaborators" msgstr "Den obigen Mitarbeitern Zugang zu Ihrem Arbeitsblatt gewähren" #: data/sage/html/notebook/worksheet_share.html:24 msgid "Invite Collaborators" msgstr "Mitarbeiter einladen" #: data/sage/html/notebook/worksheet_share.html:28 msgid "Sage Users:" msgstr "Sage-Benutzer:" #: data/sage/html/settings/account_settings.html:3 #: data/sage/html/settings/base.html:13 msgid "Account Settings" msgstr "Kontoeinstellungen" #: data/sage/html/settings/account_settings.html:13 msgid "Change Auto-Save Interval" msgstr "Intervall für automatisches Speichern abändern" #: data/sage/html/settings/account_settings.html:15 msgid "Minutes:" msgstr "Minuten:" #: data/sage/html/settings/account_settings.html:24 msgid "Change Password" msgstr "Passwort ändern" #: data/sage/html/settings/account_settings.html:30 msgid "Old password" msgstr "Altes Passwort" #: data/sage/html/settings/account_settings.html:34 msgid "New password" msgstr "Neues Passwort" #: data/sage/html/settings/account_settings.html:38 msgid "Retype new password" msgstr "Neues Passwort nochmals eingeben" #: data/sage/html/settings/account_settings.html:46 msgid "Change E-mail Address" msgstr "E-Mail-Adresse ändern" #: data/sage/html/settings/account_settings.html:50 msgid "Current e-mail" msgstr "Aktuelle E-mail" #: data/sage/html/settings/account_settings.html:54 msgid "New e-mail" msgstr "Neue E-Mail" #: data/sage/html/settings/admin_add_user.html:2 #: data/sage/html/settings/admin_add_user.html:6 msgid "Add New User" msgstr "Neuen Benutzer hinzufügen" #: data/sage/html/settings/admin_add_user.html:8 msgid "Username Error" msgstr "Fehlerhafter Benutzername" #: data/sage/html/settings/admin_add_user.html:12 msgid "Pick a username" msgstr "Benutzernamen wählen" #: data/sage/html/settings/admin_add_user.html:13 msgid "The username must start with a letter and be between 4 and 32 characters long. It can only consist of letters, numbers, underscores, and one dot (.)." msgstr "Der Benutzername muss mit einem Buchstaben beginnen und zwischen 4 und 32 Zeichen lang sein. Er darf nur Buchstaben, Zahlen, Unterstrich sowie einen Punkt (.) enthalten." #: data/sage/html/settings/admin_add_user.html:17 msgid "Invalid username" msgstr "Ungültiger Benutzername" #: data/sage/html/settings/admin_add_user.html:19 msgid "Username taken" msgstr "Gewählter Benutzername" #: data/sage/html/settings/admin_add_user.html:25 msgid "Create Account" msgstr "Konto erstellen" #: data/sage/html/settings/base.html:10 msgid "Manage Users" msgstr "Benutzer verwalten" #: data/sage/html/settings/base.html:11 #: data/sage/html/settings/notebook_settings.html:2 msgid "Notebook Settings" msgstr "Notebook-Einstellungen" #: data/sage/html/settings/user_management.html:3 #: data/sage/html/settings/user_management.html:13 msgid "Users" msgstr "Benutzer" #: data/sage/html/settings/user_management.html:7 msgid "User Management" msgstr "Benutzerverwaltung" #: data/sage/html/settings/user_management.html:8 msgid "Add User" msgstr "Benutzer hinzufügen" #: data/sage/html/settings/user_management.html:10 #, python-format msgid "The password for the user %(u)s has been reset to %(p)s" msgstr "Das Passwort für den Benutzer %(u)s wurde zurückgesetzt auf %(p)s" #: data/sage/html/settings/user_management.html:13 msgid "Suspension" msgstr "Sperrung" #: data/sage/html/settings/user_management.html:16 msgid "Reset" msgstr "Zurücksetzen" #: data/sage/html/settings/user_management.html:16 msgid "Unsuspend" msgstr "Entsperren" #: data/sage/html/settings/user_management.html:16 msgid "Suspend" msgstr "Sperren" #: data/sage/html/worksheet/ratings_info.html:3 #: data/sage/html/worksheet/ratings_info.html:6 #, python-format msgid "Ratings for %(wn)s" msgstr "Bewertungen für %(wn)s" #: data/sage/html/worksheet/ratings_info.html:7 msgid "Go to the worksheet." msgstr "Zum Arbeitsblatt navigieren." #: data/sage/html/worksheet/ratings_info.html:9 msgid "User" msgstr "Benutzer" #: data/sage/html/worksheet/ratings_info.html:9 msgid "Comment" msgstr "Kommentar" #: data/sage/html/worksheet/time_last_edited.html:6 #, python-format msgid "last edited on %(t)s by %(le)s" msgstr "letzte Änderung am %(t)s durch %(le)s" #: data/sage/html/worksheet/time_since_last_edited.html:6 #: notebook/worksheet.py:2009 #, python-format msgid "%(t)s ago by %(le)s" msgstr "vor %(t)s durch %(le)s" #: data/sage/js/translated-messages.js:4 msgid "Click to download and install tex fonts." msgstr "Klicken, um die Tex-Schriftart herunterzuladen und zu installieren." #: data/sage/js/translated-messages.js:5 msgid "" "Your browser / OS combination is not supported.\\n" "Please use Firefox or Opera under Linux, Windows, or Mac OS X, or Safari." msgstr "" "Ihre Kombination von Browser und Betriebssystem wird nicht unterstützt.\\n" "Bitte benutzen Sie Firefox oder Opera unter Linux, Mac OS X, Safari oder Windows." #: data/sage/js/translated-messages.js:6 msgid "Java Applet Hidden" msgstr "Verborgenes Java-Applet" #: data/sage/js/translated-messages.js:7 msgid "Click here to pop out" msgstr "Klicken Sie hier, um herauszuspringen" #: data/sage/js/translated-messages.js:8 msgid "Error applying function to worksheet(s)." msgstr "Fehler beim Anwenden der Funktion auf das Arbeitsblatt / die Arbeitsblätter." #: data/sage/js/translated-messages.js:9 msgid "Title of saved worksheet" msgstr "Titel des gespeicherten Arbeitsblatts" #: data/sage/js/translated-messages.js:10 msgid "Failed to save worksheet." msgstr "Fehler beim Speichern des Arbeitsblatts." #: data/sage/js/translated-messages.js:12 msgid "Please enter a name for this worksheet." msgstr "Bitte geben Sie einen Namen ein für dieses Arbeitsblatt." #: data/sage/js/translated-messages.js:13 msgid "Rename" msgstr "Umbenennen" #: data/sage/js/translated-messages.js:14 msgid "Possible failure deleting worksheet." msgstr "Möglicher Fehler beim Löschen des Arbeitsblatts." #: data/sage/js/translated-messages.js:15 msgid "unprinted" msgstr "ungedruckt" #: data/sage/js/translated-messages.js:16 msgid "You requested to evaluate a cell that, for some reason, the server is unaware of." msgstr "Sie haben die Auswertung einer Zelle angefragt, die der Server aus irgendeinem Grunde nicht kennt." #: data/sage/js/translated-messages.js:18 msgid "This worksheet is read only. Please make a copy or contact the owner to change it." msgstr "Dieses Arbeitsblatt kann nur gelesen werden. Bitte fertigen Sie eine Kopie davon an oder bitten Sie den Eigentümer es zu abzuändern." #: data/sage/js/translated-messages.js:19 msgid "loading..." msgstr "lade..." #: data/sage/js/translated-messages.js:20 msgid "Error updating cell output after " msgstr "Fehler beim Aktualisieren der Zell-Ausgabe hinter " #: data/sage/js/translated-messages.js:21 msgid "s (canceling further update checks)." msgstr "s (breche weitere Aktualisierungsprüfungen ab)." #: data/sage/js/translated-messages.js:22 msgid "Problem inserting new input cell after current input cell.\\n" msgstr "Problem beim Einfügen einer neuen Eingabezelle hinter der aktuellen Eingabezelle.\\n" #: data/sage/js/translated-messages.js:23 msgid "Worksheet is locked. Cannot insert cells." msgstr "Das Arbeitsblatt ist gesperrt. Kann keine Zellen einfügen." #: data/sage/js/translated-messages.js:24 msgid "Unable to interrupt calculation." msgstr "Berechnung kann nicht unterbrochen werden." #: data/sage/js/translated-messages.js:25 msgid "Close this box to stop trying." msgstr "Schließen Sie diesen Kasten, um die Versuche einzustellen." #: data/sage/js/translated-messages.js:26 msgid "Interrupt attempt" msgstr "Unterbrechungsversuch" #: data/sage/js/translated-messages.js:27 msgid "Restart, instead?" msgstr "Stattdessen neu starten?" #: data/sage/js/translated-messages.js:28 msgid "Emptying the trash will permanently delete all items in the trash. Continue?" msgstr "Beim Leeren des Mülleimers werden alle darin befindlichen Objekte entgültig gelöscht. Fortsetzen?" #: data/sage/js/translated-messages.js:29 msgid "Get Image" msgstr "Bild holen" #: data/sage/js/translated-messages.js:30 msgid "Jmol Image" msgstr "Jmol-Bild" #: data/sage/js/translated-messages.js:31 msgid "To save this image, you can try right-clicking on the image to copy it or save it to a file, or you may be able to just drag the image to your desktop." msgstr "Mit einem Rechts-Klick auf dieses Bild können sie versuchen, es zu speichern. Sie können es kopieren oder in einer Datei abspeichern. Oder Sie könnten das Bild einfach auf Ihr Desktop ziehen." #: data/sage/js/translated-messages.js:32 msgid "Sorry, but you need a browser that supports the <canvas> tag." msgstr "Entschuldigung, aber Sie benötigen einen Browser, der den <canvas>-Tag unterstützt." #: data/sage/js/translated-messages.js:33 #, python-format msgid "Trying again in %(num)d second..." msgid_plural "Trying again in %(num)d seconds..." msgstr[0] "Erneuter Versuch in %(num)d Sekunde..." msgstr[1] "Erneuter Versuch in %(num)d Sekunden..." #: notebook/challenge.py:179 msgid "Please ask the server administrator to configure a challenge!" msgstr "Bitte, bitten Sie den Administrator eine Herausforderung einzurichten!" #: notebook/challenge.py:217 msgid "Is pi > e?" msgstr "Gilt pi > e ?" #: notebook/challenge.py:217 msgid "y|yes" msgstr "j|ja" #: notebook/challenge.py:218 msgid "What is 3 times 8?" msgstr "Was ist 3 mal 8?" #: notebook/challenge.py:218 msgid "24|twenty-four" msgstr "24|vierundzwanzig" #: notebook/challenge.py:219 msgid "What is 2 plus 3?" msgstr "Was ist 2 plus 3?" #: notebook/challenge.py:219 #: notebook/challenge.py:221 msgid "5|five" msgstr "5|fünf" #: notebook/challenge.py:220 msgid "How many bits are in one byte?" msgstr "Wie viele Bits sind ein Byte?" #: notebook/challenge.py:220 msgid "8|eight" msgstr "8|acht" #: notebook/challenge.py:221 msgid "What is the largest prime factor of 15?" msgstr "Was ist der größte Primfaktor von 15?" #: notebook/conf.py:120 msgid "Updated" msgstr "Aktualisiert" #: notebook/notebook.py:169 msgid "optional" msgstr "optional" #: notebook/register.py:19 #: notebook/register.py:26 #, python-format msgid "" "Hi %s!\n" "\n" msgstr "" "Hallo %s!\n" "\n" #: notebook/register.py:20 #, python-format msgid "" "Thank you for registering for the Sage notebook. To complete your registration, copy and paste the following link into your browser:\n" "\n" "%s://%s:%s/confirm?key=%s\n" "\n" "You will be taken to a page which will confirm that you have indeed registered." msgstr "" "Danke, dass Sie sich bei Sage-Notebook registriert haben. Um die Registrierung abzuschließen, kopieren sie bitte den folgenden Link und fügen ihn in Ihren Browser ein:\n" "\n" "%s://%s:%s/confirm?key=%s\n" "\n" "Sie werden auf eine Seite geleitet, die bestätigt, dass Sie sich tatsächlich registriert haben." #: notebook/register.py:27 #, python-format msgid "" "Your new password is %s\n" "\n" "Sign in at %s://%s:%s/\n" "\n" "Make sure to reset your password by going to Settings in the upper right bar." msgstr "" "Ihr neues Passwort lautet: %s\n" "\n" "Melden Sie sich an bei: %s://%s:%s/\n" "\n" "Vergewissern Sie sich, Ihr Passwort zurückzusetzen. Gehen Sie dazu auf Einstellungen im rechten oberen Balken." #: notebook/server_conf.py:42 #: notebook/user_conf.py:24 msgid "Appearance" msgstr "Erscheinungsbild" #: notebook/server_conf.py:43 msgid "Authentication" msgstr "Echtheitsnachweis" #: notebook/server_conf.py:44 msgid "Server" msgstr "Server" #: notebook/server_conf.py:49 msgid "Number of word-wrap columns" msgstr "Anzahl der Spalten pro Zeile" #: notebook/server_conf.py:55 msgid "Maximum history length" msgstr "Maximale Länge des Verlaufs" #: notebook/server_conf.py:61 msgid "Idle timeout (seconds)" msgstr "Beenden nach Leerlaufdauer in Sekunden" #: notebook/server_conf.py:67 msgid "Idle check interval (seconds)" msgstr "Intervall für Überprüfung auf Leerlauf (Sekunden)" #: notebook/server_conf.py:73 msgid "Save interval (seconds)" msgstr "Intervall für automatisches Speichern (Sekunden)" #: notebook/server_conf.py:79 msgid "Doc pool size" msgstr "Größe des Dokumentenspeichers" #: notebook/server_conf.py:85 msgid "Worksheet process users (comma-separated list)" msgstr "Benutzer des Arbeitsblatt-Prozesses (Komma-separierte Liste)" #: notebook/server_conf.py:91 msgid "Default system" msgstr "Vorausgewähltes System" #: notebook/server_conf.py:97 msgid "Pretty print (typeset) output" msgstr "Edle Druckausgabe (Schriftsatz)" #: notebook/server_conf.py:103 msgid "Worksheet process limits" msgstr "Beschränkungen für den Arbeitsblatt-Prozess" #: notebook/server_conf.py:109 msgid "Require e-mail for account registration" msgstr "Zur Konto-Registrierung die Angabe der E-Mail-Adresse fordern" #: notebook/server_conf.py:115 msgid "Enable user registration" msgstr "Registierung von Benutzern aktivieren" #: notebook/server_conf.py:121 msgid "Use a challenge for account registration" msgstr "Eine Herausforderung zur Konto-Registrierung verwenden" #: notebook/server_conf.py:127 msgid "Type of challenge" msgstr "Art der Herausforderung" #: notebook/server_conf.py:134 msgid "reCAPTCHA public key" msgstr "reCAPTCHA öffentlicher Schlüssel" #: notebook/server_conf.py:140 msgid "reCAPTCHA private key" msgstr "reCAPTCHA privater Schlüssel" #: notebook/server_conf.py:146 msgid "Default Language" msgstr "Vorausgewählte Sprache" #: notebook/template.py:68 #, python-format msgid "%(num)d second" msgid_plural "%(num)d seconds" msgstr[0] "%(num)d Sekunde" msgstr[1] "%(num)d Sekunden" #: notebook/template.py:71 #, python-format msgid "%(num)d minute" msgid_plural "%(num)d minutes" msgstr[0] "%(num)d Minute" msgstr[1] "%(num)d Minuten" #: notebook/template.py:74 #, python-format msgid "%(num)d hour" msgid_plural "%(num)d hours" msgstr[0] "%(num)d Stunde" msgstr[1] "%(num)d Stunden" #: notebook/template.py:76 #, python-format msgid "%(num)d day" msgid_plural "%(num)d days" msgstr[0] "%(num)d Tag" msgstr[1] "%(num)d Tage" #: notebook/template.py:135 msgid "Sage Notebook" msgstr "Sage Notebook" #: notebook/tutorial.py:354 msgid "Find Help and Documentation" msgstr "Hilfe und Dokumentation beziehen" #: notebook/tutorial.py:355 msgid "Get Started with Sage" msgstr "Erste Schritte mit Sage" #: notebook/tutorial.py:355 msgid "Work through the tutorial (if you have trouble with it, view the static version)." msgstr "Den Lehrpfad durcharbeiten (wenn Sie Schwierigkeiten damit haben, sehen Sie die statische Fassung ein)." #: notebook/tutorial.py:356 msgid "Help About" msgstr "Kontextbezogene Hilfe" #: notebook/tutorial.py:357 msgid "Type ? immediately after the object or function and press tab or shift-enter (shift-enter overwrites output and saves to worksheet)." msgstr "Geben Sie ? unmittelbar hinter dem Objekt oder der Funktion ein und drücken Sie Tab oder Shift+Enter (die Kombination Shift+Enter überschreibt Ausgaben und speichert ins Arbeitsblatt)." #: notebook/tutorial.py:359 msgid "Put ?? after the object and press tab or shift-enter (shift-enter overwrites output and saves to worksheet)." msgstr "Geben Sie ?? unmittelbar hinter dem Objekt und drücken Sie Tab oder Shift+Enter (die Kombination Shift+Enter überschreibt Ausgaben und speichert ins Arbeitsblatt)." #: notebook/tutorial.py:360 msgid "Full Text Search of Docs and Source" msgstr "Volltextsuche nach Dokumenten und Quelltext" #: notebook/tutorial.py:361 msgid "Search the SAGE documentation by typing
    search_doc(\"my query\")
    in an input cell and press shift-enter. Search the source code of SAGE by typing
    search_src(\"my query\")
    and pressing shift-enter. Arbitrary regular expressions are allowed as queries." msgstr "Durchsuchen Sie die Dokumentation von Sage, indem Sie
    search_doc(\"meine Anfrage\")
    in eine Input-Zelle eingeben und Shift+Enter drücken. Beliebige reguläre Ausdrücke sind als Anfragen zulässig." #: notebook/tutorial.py:365 msgid "Key and Mouse Bindings" msgstr "Tastatur- und Mausanbindung" #: notebook/tutorial.py:366 msgid "Evaluate Input" msgstr "Eingaben auswerten" #: notebook/tutorial.py:367 msgid "Press shift-enter. You can start several calculations at once. If you press alt-enter instead, then a new cell is created after the current one. If you press ctrl-enter then the cell is split and both pieces are evaluated separately." msgstr "Drücken Sie Shift+Enter, um mehrere Berechnungen auf einmal zu starten. Wenn Sie stattdessen Alt+Enter drücken, wird eine neue Zelle hinter der aktuellen erzeugt. Drücken Sie Ctrl+Enter, so wird die Zelle gespalten und beide Teile getrennt ausgewertet." #: notebook/tutorial.py:368 msgid "Tab Completion" msgstr "Tabulator-Vervollständigung" #: notebook/tutorial.py:369 msgid "Press tab while the cursor is on an identifier. On some web browsers (e.g., Opera) you must use control-space instead of tab." msgstr "Drücken Sie Tab während der Cursor auf einem Bezeichner steht. Bei einigen Internetbrowsern (z.B. Opera) müssen Sie Ctrl+Leertaste benutzen anstatt Tab." #: notebook/tutorial.py:370 msgid "Insert New Cell" msgstr "Neue Zelle einfügen" #: notebook/tutorial.py:371 msgid "Put the mouse between an output and input until the horizontal line appears and click. If you press Alt-Enter in a cell, the cell is evaluated and a new cell is inserted after it." msgstr "Bringen Sie den Mauszeiger zwischen eine Ausgabe und eine Eingabe bis die waagerechte Linie erscheint und klicken dann. Wenn Sie in einer Zelle Alt+Enter drücken, wird sie ausgewertet und eine neue Zelle wird hinter ihr eingefügt." #: notebook/tutorial.py:372 msgid "Delete Cell" msgstr "Zelle löschen" #: notebook/tutorial.py:373 msgid "Delete all cell contents, then press backspace." msgstr "Löschen Sie den gesamten Zellinhalt und drücken Sie dann Backspace." #: notebook/tutorial.py:374 msgid "Split and Join Cells" msgstr "Zellen spalten und vereinigen" #: notebook/tutorial.py:375 msgid "Press ctrl-; in a cell to split it into two cells, and ctrl-backspace to join them. Press ctrl-enter to split a cell and evaluate both pieces." msgstr "Drücken Sie Ctrl+; in einer Zelle, um sie in zwei Zellen zu spalten und Ctrl+Backspace, um sie zu vereinigen. Drücken Sie Ctrl+Enter, um eine Zelle zu spalten und beide Teile auszuwerten." #: notebook/tutorial.py:376 msgid "Insert New Text Cell" msgstr "Neue Text-Zelle einfügen" #: notebook/tutorial.py:377 msgid "Move the mouse between cells until a blue bar appears. Shift-click on the blue bar to create a new text cell. Double click on existing text to edit it. Use $...$ and $$...$$ to include typeset math in the text block." msgstr "Bewegen Sie den Mauszeiger zwischen Zellen bis ein blauer Balken erscheint. Mit Shift+Klick auf dem blauen Balken können Sie eine neue Textzelle erstellen. Doppelklicken Sie vorhandenen Text, um ihn zu bearbeiten. Verwenden Sie $...$ und $$...$$, um mathematische Formeln in den Textblock einzuschließen." #: notebook/tutorial.py:378 msgid "Hide/Show Output" msgstr "Ausgaben verbergen/anzeigen" #: notebook/tutorial.py:379 msgid "Click on the left side of output to toggle between hidden, shown with word wrap, and shown without word wrap." msgstr "Klicken Sie links der Ausgabe, um zwischen verborgen, sichtbar mit Zeilenumbruch und sichtbar ohne Zeilenumbruch zu wechseln." #: notebook/tutorial.py:380 msgid "Indenting Blocks" msgstr "Blöcke einrücken" #: notebook/tutorial.py:381 msgid "Highlight text and press > to indent it all and < to unindent it all (works in Safari and Firefox). In Firefox you can also press tab and shift-tab." msgstr "Heben Sie Text hervor und drücken Sie >, um alles einzurücken und <, um alles auszurücken (funktioniert in Safari und Firefox). In Firefox können Sie auch Tab und Shift+Tab drücken." #: notebook/tutorial.py:382 msgid "Comment/Uncomment Blocks" msgstr "Kommentieren / Entfernen von Kommentaren von Blöcken" #: notebook/tutorial.py:383 msgid "Highlight text and press ctrl-. to comment it and ctrl-, to uncomment it. Alternatively, use ctrl-3 and ctrl-4." msgstr "Heben Sie Text hervor und drücken Sie Ctrl+., um ihn zu kommentieren und Ctrl+,, um einen Kommentar zu entfernen. Alternativ können Sie Ctrl+3 und Ctrl+4 verwenden." #: notebook/tutorial.py:384 msgid "Paren matching" msgstr "Korrektheit der Klammerung" #: notebook/tutorial.py:384 msgid "To fix unmatched or mis-matched parentheses, braces or brackets, press ctrl-0. Parentheses before the cursor will be matched, minding strings and (Python) comments." msgstr "Zur Korrektur unpaariger oder fehlgepaarter Klammern drücken Sie Ctrl+0. Klammern vor dem Cursor werden gepaart unter Beachtung von Zeichenfolgenkonstanten und (Python-) Kommentaren." #: notebook/tutorial.py:388 msgid "Interrupt and Restart Sessions" msgstr "Sitzungen unterbrechen und neu starten" #: notebook/tutorial.py:389 msgid "Interrupt Running Calculations" msgstr "Laufende Berechnungen unterbrechen" #: notebook/tutorial.py:390 msgid "Click Interrupt or press escape in any input cell. This will (attempt) to interrupt SAGE by sending many interrupt signals." msgstr "Klicken Sie auf Unterbrechen oder drücken Sie Escape in einer beliebigen Zelle. Dadurch werden viele Interrupt-Signale gesendet, die SAGE (versuchen zu) unterbrechen." #: notebook/tutorial.py:391 msgid "Restart" msgstr "Neu starten" #: notebook/tutorial.py:392 msgid "Type \"restart\" to restart the SAGE interpreter for a given worksheet. (You have to interrupt first.)" msgstr "Geben Sie \"restart\" ein, um den SAGE-Interpreter für ein gegebenes Arbeitsblatt neu zu starten. (Sie müssen zunächst unterbrechen.)" #: notebook/tutorial.py:394 msgid "Special Cell Blocks" msgstr "Spezielle Zell-Blöcke" #: notebook/tutorial.py:395 msgid "Evaluate Cell using GAP, Singular, etc." msgstr "Zelle auswerten unter Verwendung von GAP, Singular usw." #: notebook/tutorial.py:396 #, python-format msgid "Put \"%gap\", \"%singular\", etc. as the first input line of a cell; the rest of the cell is evaluated in that system." msgstr "Setzen Sie \"%gap\", \"%singular\" usw. als erste Eingabezeile einer Zelle, so wird der Rest der Zelle im jeweiligen System ausgewertet." #: notebook/tutorial.py:397 msgid "Shell Scripts" msgstr "Shell-Scripte" #: notebook/tutorial.py:398 #, python-format msgid "Begin a block with %sh to have the rest of the block evaluated as a shell script. The current working directory is maintained." msgstr "Beginnen Sie einen Block mit %sh, so wird der Rest des Blocks als Shell-Script ausgewertet. Das aktuelle Arbeitsverzeichnis wird beibehalten." #: notebook/tutorial.py:399 msgid "Interactive Dynamic Widgets" msgstr "Interaktive dynamische Fenstererweiterungen" #: notebook/tutorial.py:400 msgid "Put @interact on the line before a function definition. Type interact? for more details." msgstr "Setzen Sie @interact in die Zeile vor einer Funktionsdefinition. Geben Sie interact? ein für nähere Informationen." #: notebook/tutorial.py:401 msgid "Autoevaluate Cells on Load" msgstr "Zellen beim Laden automatisch auswerten" #: notebook/tutorial.py:402 msgid "Any cells with \"#auto\" in the input is automatically evaluated when the worksheet is first opened." msgstr "Alle Zellen mit \"#auto\" in der Eingabe werden beim ersten Öffnen des Arbeitsblatts automatisch ausgewertet." #: notebook/tutorial.py:403 msgid "Time" msgstr "Zeit" #: notebook/tutorial.py:404 msgid "Type \"%time\" at the beginning of the cell." msgstr "Geben Sie \"%time\" am Anfang der Zelle ein." #: notebook/tutorial.py:406 msgid "Useful Tips" msgstr "Nützliche Tipps" #: notebook/tutorial.py:407 msgid "Input Rules" msgstr "Eingaberegeln" #: notebook/tutorial.py:408 msgid "Code is evaluated by exec'ing (after preparsing). Only the output of the last line of the cell is implicitly printed. If any line starts with \"sage:\" or \">>>\" the entire block is assumed to contain text and examples, so only lines that begin with a prompt are executed. Thus you can paste in complete examples from the docs without any editing, and you can write input cells that contains non-evaluated plain text mixed with examples by starting the block with \">>>\" or including an example." msgstr "Code wird durch Ausführen (nach dem Vorparsen) ausgewertet. Nur die Ausgabe der letzten Zeile einer Zelle wird implizit gedruckt. Wann immer eine Zeile mit \"sage:\" oder \">>>\" beginnt, wird davon ausgegangen, dass der gesamte Block Text und Beispiele enthält und folglich nur solche Zeilen ausgeführt, die mit einer Eingabeaufforderung beginnen. Daher können Sie vollständige Beispiele aus der Dokumentation ohne irgendwelche Anpassungen einfügen. Und Sie können Eingabezellen schreiben, die unausgewerteten Klartext, gemischt mit Beispielen, enthalten, indem Sie den Block mit \">>>\" beginnen oder ein Beispiel einschließen." #: notebook/tutorial.py:409 msgid "History" msgstr "Verlauf" #: notebook/tutorial.py:410 msgid "Click log commands you have entered in any worksheet of this notebook." msgstr "Klicken Sie auf Protokoll, um alle Befehle anzuzeigen, die Sie bisher in beliebigen Arbeitsblättern dieses Notebooks eingegeben haben." #: notebook/tutorial.py:411 msgid "Typesetting All Output" msgstr "Alle Ausgaben setzen" #: notebook/tutorial.py:412 msgid "Type pretty_print_default() in an input cell and press shift-enter. All future output will be typeset automatically." msgstr "Geben Sie pretty_print_default() in eine Eingabezelle ein und drücken Sie Shift+Enter. Der Schriftsatz aller zukünftiger Ausgaben erfolgt automatisch." #: notebook/tutorial.py:416 msgid "Files and Scripts" msgstr "Dateien und Scripte" #: notebook/tutorial.py:417 msgid "Loading SAGE/Python Scripts" msgstr "Lade SAGE/Python-Scripte" #: notebook/tutorial.py:418 msgid "Use \"load filename.sage\" and \"load filename.py\". Load is relative to the path you started the notebook in. The .sage files are preparsed and .py files are not. You may omit the .sage or .py extension. Files may load other files." msgstr "Verwenden Sie \"load Dateiname.sage\" und \"load Dateiname.py\". Das Laden erfolgt relativ zu dem Verzeichnis, in dem Sie das Notebook gestartet haben. Die .sage-Dateien werden vorgeparst, .py-Dateien hingegen nicht. Dateien dürfen andere Dateien laden." #: notebook/tutorial.py:419 msgid "Attaching Scripts" msgstr "Anhängen von Scripten" #: notebook/tutorial.py:420 msgid "Use \"attach filename.sage\" or \"attach filename.py\". Attached files are automatically reloaded when the file changes. The file $HOME/.sage/init.sage is attached on startup if it exists." msgstr "Verwenden Sie \"attach Dateiname.sage\" oder \"attach Dateiname.py\". Angehängte Dateien werden nach Änderungen automatisch neu geladen. Die Datei $HOME/.sage/init.sage wird beim Start angehängt, sofern sie existiert." #: notebook/tutorial.py:421 msgid "Working Directory" msgstr "Arbeitsverzeichnis" #: notebook/tutorial.py:422 msgid "Each block of code is run from its own directory. If any images are created as a side effect, they will automatically be displayed." msgstr "Jeder Code-Block wird in seinem eigenen Verzeichnis ausgeführt. Eventuell als Nebeneffekt erzeugte Bilder werden automatisch dargestellt." #: notebook/tutorial.py:423 msgid "DIR Variable" msgstr "DIR-Variable" #: notebook/tutorial.py:424 msgid "The variable DIR contains the directory from which you started the SAGE notebook. For example, to open a file in that directory, do \"open(DIR+'filename')\"." msgstr "Die DIR-Variable enthält das Verzeichnis, von dem aus SAGE-Notebook gestartet wurde. Um z.B. eine Datei in diesem Verzeichnis zu öffnen, verwenden Sie \"open(DIR+'Dateiname')\"." #: notebook/tutorial.py:425 msgid "DATA Variable" msgstr "DATA-Variable" #: notebook/tutorial.py:426 msgid "Use the Data menu to upload images and other files, and create new files that can be shared between worksheets. The DATA variable contains the path to the data files. For example, to open a file in that directory, do \"open(DATA+'filename')\". If foo.sage is a Sage file that you uploaded, type \"load foo.sage\"; if foo.py is a Python file, you can import it by typing \"import foo\"." msgstr "Verwenden Sie das Datenmenü, um Bilder und andere Dateien hochzuladen sowie neue Dateien zu erstellen, auf die von mehreren Arbeitsblättern aus zugegriffen werden kann. Die DATA-Variable enthält den Pfad zu den Daten-Dateien. Um z.B. eine Datei in diesem Verzeichnis zu öffnen, verwenden Sie \"open(DATA+'Dateiname')\". Wenn Beispiel.sage eine von Ihnen hochgeladene SAGE-Datei ist, geben Sie \"load Beispiel.sage\" ein. Wenn Beispiel.py eine Python-Datei ist, können Sie sie importieren, indem Sie \"import Beispiel\" eingeben." #: notebook/tutorial.py:427 msgid "Loading and Saving Objects" msgstr "Laden und Speichern von Objekten" #: notebook/tutorial.py:428 msgid "Use \"save obj1 obj2 ...\" and \"load obj1 obj2 ...\". This allows for easy moving of objects from one worksheet to another, and saving of objects for later use." msgstr "Verwenden Sie \"save obj1 obj2 ...\" und \"load obj1 obj2 ...\". Das macht es leicht, Objekte von einem Arbeitsblatt zu einem anderen zu bewegen oder zur späteren Verwendung zu speichern." #: notebook/tutorial.py:429 msgid "Loading and Saving Sessions" msgstr "Sitzungen laden und speichern" #: notebook/tutorial.py:430 msgid "Use \"save_session('name')\" to save all variables to an object. Use \"load_session('name')\" to merge in all variables from a saved session." msgstr "Verwenden Sie \"save_session('Name')\", um alle Variablen in ein Objekt zu speichern. Verwenden Sie \"load_session('Name')\", um alle Variablen einer gespeicherten Sitzung einzulesen." #: notebook/tutorial.py:431 msgid "Customizing the Notebook CSS" msgstr "Persönliche Anpassungen des Notebook-CSS" #: notebook/tutorial.py:432 msgid "If you create a file $HOME/.sage/notebook.css then it will get applied when rendering the notebook. See " msgstr "Wenn Sie eine Datei $HOME/.sage/notebook.css erstellen, dann wird sie beim Rendern des Notebooks angewandt. Sehen Sie " #: notebook/twist.py:448 #, python-format msgid "Please specify a worksheet to load.%s" msgstr "Bitte geben Sie ein Arbeitsblatt zum Laden an.%s" #: notebook/twist.py:486 #, python-format msgid "There was an error uploading the worksheet. It could be an old unsupported format or worse. If you desperately need its contents contact the sage-support group and post a link to your worksheet. Alternatively, an sws file is just a bzip2 tarball; take a look inside!%s" msgstr "Beim Hochladen des Arbeitsblatts ist ein Fehler aufgetreten. Es könnte sich um ein altes, nicht unterstütztes Format handeln oder Schlimmeres. Wenn Sie unbedingt dessen Inhalt benötigen, kontaktieren Sie die Sage-Support-Gruppe und posten einen Link auf Ihr Arbeitsblatt. Alternativ: eine sws-Datei ist nur ein bzip2-tar-Archiv; werfen Sie einen Blick hinein!%s" #: notebook/twist.py:515 #: notebook/twist.py:645 #, python-format msgid "There was an error uploading \"%s\" (please recheck the URL).%s" msgstr "Beim Hochladen von \"%s\" ist ein Fehler aufgetreten (bitte überprüfen Sie den URL nochmal).%s" #: notebook/twist.py:597 #, python-format msgid "Return to Upload or Create Data File or %s." msgstr "Zurück zu Hochladen oder Erstellen einer Daten-Datei oder %s." #: notebook/twist.py:601 #, python-format msgid "Error uploading file (missing fileField file).%s" msgstr "Fehler beim Hochladen der Datei (fehlendes Dateifeld Datei).%s" #: notebook/twist.py:606 #, python-format msgid "Error uploading file (missing %s arg).%s" msgstr "Fehler beim Hochladen der Datei (fehlendes %s-Argument).%s" #: notebook/twist.py:623 #, python-format msgid "Error uploading file (missing filename).%s" msgstr "Fehler beim Hochladen der Datei (fehlender Dateiname).%s" #: notebook/twist.py:627 #, python-format msgid "Suspicious filename \"%s\" encountered uploading file.%s" msgstr "Verdächtigen Dateinamen \"%s\" beim Hochladen der Datei .%s gefunden" #: notebook/twist.py:674 #, python-format msgid "Successfully deleted \"%s\"" msgstr "\"%s\" erfolgreich gelöscht" #: notebook/twist.py:691 msgid "No data files" msgstr "Keine Daten-Dateien vorhanden" #: notebook/twist.py:770 msgid "Error in introspection -- invalid cell id." msgstr "Fehler bei der Selbstüberprüfung -- ungültige Zell-ID." #: notebook/twist.py:824 msgid "You must login first in order to edit this worksheet." msgstr "Sie müssen sich erst einloggen, um dieses Arbeitsblatt bearbeiten zu können." #: notebook/twist.py:998 msgid "Old password not given" msgstr "Altes Passwort nicht angegeben" #: notebook/twist.py:1000 msgid "Incorrect password given" msgstr "Falsches Passwort angegeben" #: notebook/twist.py:1002 msgid "New password not given" msgstr "Neues Passwort nicht angegeben" #: notebook/twist.py:1004 msgid "Please type in new password again." msgstr "Bitte geben Sie das neue Passwort nochmals ein." #: notebook/twist.py:1006 msgid "The passwords you entered do not match." msgstr "Die von Ihnen eingegebenen Passwörter stimmen nicht überein." #: notebook/twist.py:1039 msgid "Confirmed" msgstr "Bestätigt" #: notebook/twist.py:1041 msgid "Not confirmed" msgstr "Unbestätigt" #: notebook/twist.py:1294 msgid "can't evaluate worksheet cells" msgstr "kann Arbeitsblatt-Zellen nicht auswerten" #: notebook/twist.py:1391 msgid "You must login first in order to rate this worksheet." msgstr "Sie müssen angemeldet sein, um dieses Arbeitsblatt bewerten zu können." #: notebook/twist.py:1395 msgid "Gees -- You can't fool the rating system that easily!" msgstr "Ätsch! -- So einfach lässt sich das Bewertungssystem nicht überlisten!" #: notebook/twist.py:1398 #, python-format msgid "Thank you for rating the worksheet %s! You can see all ratings of this worksheet." msgstr "Danke, dass Sie das Arbeitsblatt bewertet haben %s! Sie können alle Bewertungen zu diesem Arbeitsblatt ansehen." #: notebook/twist.py:1398 msgid "Rating Accepted" msgstr "Bewertung entgegengenommen" #: notebook/twist.py:1415 msgid "No such worksheet." msgstr "Kein solches Arbeitsblatt vorhanden." #: notebook/twist.py:1521 #, python-format msgid "The worksheet operation \"%s\" is not defined." msgstr "Der Arbeitsblatt-Vorgang \"%s\" ist nicht definiert." #: notebook/twist.py:1618 #, python-format msgid "User \"%s\" does not have permission to view the home page of \"%s\"." msgstr "Der Benutzer \"%s\" ist nicht berechtigt die Homepage von \"%s\" anzuzeigen." #: notebook/twist.py:1629 #, python-format msgid "The user \"%s\" has no worksheet \"%s\"." msgstr "Der Benutzer \"%s\" hat kein Arbeitsblatt \"%s\"." #: notebook/twist.py:1632 #, python-format msgid "There is no published worksheet with name \"%s\". Redirecting to the index of published worksheets in 10 seconds...

    " msgstr "Es gibt kein veröffentlichtes Arbeitsblatt namens \"%s\". Umleitung zum Verzeichnis veröffentlichter Arbeitsblätter in 10 Sekunden...

    " #: notebook/twist.py:1637 #, python-format msgid "You are not logged in or do not have access to the worksheet \"%s\"." msgstr "Sie sind nicht eingeloggt oder haben keinen Zugriff das Arbeitsblatt \"%s\"." #: notebook/twist.py:1662 msgid "This url can only be accessed through a POST request." msgstr "Auf diesen URL kann nur über eine POST-Anfrage zugegriffen werden." #: notebook/twist.py:1712 #, python-format msgid "You are not authorized to move \"%s\"" msgstr "Sie sind nicht berechtigt, \"%s\" zu verschieben" #: notebook/twist.py:1781 msgid "Please request a specific worksheet" msgstr "Bitte fragen Sie nach einem bestimmten Arbeitsblatt" #: notebook/twist.py:2022 msgid "The confirmation system is not active." msgstr "Das Bestätigungssystem ist nicht aktiv." #: notebook/twist.py:2024 msgid "

    Invalid confirmation key

    You are reporting a confirmation key that has not been assigned by this server. Please register with the server.

    " msgstr "

    Ungültiger Bestätigungsschlüssel

    Sie bringen einen Bestätigungsschlüssel mit, der nicht von diesem Server ausgestellt wurde. Bitte registrieren Sie sich beim Server.

    " #: notebook/twist.py:2033 #, python-format msgid "

    Email address confirmed for user %s

    " msgstr "

    E-Mail-Adresse bestätigt für Benutzer %s

    " #: notebook/twist.py:2035 msgid "Email Confirmed" msgstr "E-Mail bestätigt" #: notebook/user_conf.py:23 msgid "Language" msgstr "Sprache" #: notebook/wiki2html.py:647 #, python-format msgid "Expected \"%(wanted)s\" after \"%(key)s\", got \"%(token)s\"" msgstr "\"%(wanted)s\" erwartet hinter \"%(key)s\", aber \"%(token)s\" vorgefunden" #: notebook/wiki2html.py:653 #, python-format msgid "Expected an integer \"%(key)s\" before \"%(token)s\"" msgstr "Ganzzahl \"%(key)s\" vor \"%(token)s\" erwartet" #: notebook/wiki2html.py:663 #: notebook/wiki2html.py:673 #, python-format msgid "Expected an integer \"%(arg)s\" after \"%(key)s\"" msgstr "Ganzzahl \"%(arg)s\" nach \"%(key)s\" erwartet" #: notebook/wiki2html.py:699 #, python-format msgid "Expected a color value \"%(arg)s\" after \"%(key)s\"" msgstr "Farbwert \"%(arg)s\" nach \"%(key)s\" erwartet" #: notebook/worksheet.py:2014 #, python-format msgid "%(seconds)s ago" msgstr "vor %(seconds)s" #: notebook/worksheet.py:4155 msgid "January" msgstr "Januar" #: notebook/worksheet.py:4156 msgid "February" msgstr "Februar" #: notebook/worksheet.py:4157 msgid "March" msgstr "März" #: notebook/worksheet.py:4158 msgid "April" msgstr "April" #: notebook/worksheet.py:4159 msgid "May" msgstr "Mai" #: notebook/worksheet.py:4160 msgid "June" msgstr "Juni" #: notebook/worksheet.py:4161 msgid "July" msgstr "Juli" #: notebook/worksheet.py:4162 msgid "August" msgstr "August" #: notebook/worksheet.py:4163 msgid "September" msgstr "September" #: notebook/worksheet.py:4164 msgid "October" msgstr "Oktober" #: notebook/worksheet.py:4165 msgid "November" msgstr "November" #: notebook/worksheet.py:4166 msgid "December" msgstr "Dezember" #~ msgid "Sign into the Sage Notebook v%(v)s" #~ msgstr "Im Sage-Notebook anmelden v%(v)s" #~ msgid "Problem inserting new input cell before current input cell." #~ msgstr "Problem beim Einfügen einer neuen Eingabezelle vor der aktuellen Eingabezelle." #~ msgid "Problem inserting new text cell before current input cell." #~ msgstr "" #~ "Problem beim Einfügen einer neuen Text-Zelle vor der aktuellen Eingabezelle." #~ msgid "simple" #~ msgstr "einfach" #~ msgid "recaptcha" #~ msgstr "recaptcha" #~ msgid "Sage Notebook Registration" #~ msgstr "Sage-Notebook-Registrierung" #~ msgid "The account recovery system is not active." #~ msgstr "Das Kontowiederherstellungssystem ist nicht aktiv." #~ msgid "Username is invalid." #~ msgstr "Ungültiger Benutzername." #~ msgid "The e-mail address hasn't been confirmed." #~ msgstr "Die E-Mail-Adresse wurde nicht unbestätigt." #~ msgid "Sage Notebook Account Recovery" #~ msgstr "Sage-Notebook-Kontowiederherstellung" #~ msgid "The new password couldn't be sent to %s." #~ msgstr "Das neue Passwort konnte nicht an %s gesendet werden." #~ msgid "A new password has been sent to your e-mail address." #~ msgstr "Ein neues Passwort wurde an Ihre E-Mail-Adresse gesendet." #~ msgid "The temporary password for the new user %s is %s" #~ msgstr "Das vorläufige Passwort für den neuen Benutzer %s lautet %s" #~ msgid "This is an invalid page." #~ msgstr "Diese Seite ist ungültig." #~ msgid " You might have to login to view this page." #~ msgstr " Möglicherweise müssen Sie sich einloggen, um diese Seite anzeigen zu können." #~ msgid "unauthorized request" #~ msgstr "unberechtigte Anfrage" #~ msgid "Your account is currently suspended." #~ msgstr "Ihr Konto ist zur Zeit gesperrt." #~ msgid "" #~ "Please enable cookies or delete all Sage cookies and localhost cookies in " #~ "your browser and try again." #~ msgstr "" #~ "Bitte aktivieren Sie Cookies oder löschen Sie alle Cookies mit Bezug zu " #~ "Sage oder localhost in Ihrem Browser und versuchen es erneut." #~ msgid "%s ago" #~ msgstr "vor %s" #~ msgid "No data file (%s)" #~ msgstr "Keine Daten-Datei (%s)" #~ msgid "ago by %s" #~ msgstr "durch %s" sagenb-1.0.1/sagenb/translations/en_US/000077500000000000000000000000001311436262400177435ustar00rootroot00000000000000sagenb-1.0.1/sagenb/translations/en_US/LC_MESSAGES/000077500000000000000000000000001311436262400215305ustar00rootroot00000000000000sagenb-1.0.1/sagenb/translations/en_US/LC_MESSAGES/messages.mo000066400000000000000000000014541311436262400237000ustar00rootroot00000000000000Þ• d¬­³¹¿ÅËÑׄÝb€–®ÁÔè%cs_CZde_ATen_USes_ESfr_FRpt_BRru_RUuk_UAProject-Id-Version: Sage Notebook 0.9.2 Report-Msgid-Bugs-To: migeruhito@gmail.com POT-Creation-Date: 2012-03-18 08:47+0400 PO-Revision-Date: 2013-02-18 10:24+0100 Last-Translator: J. Miguel Farto Language-Team: J. Miguel Farto MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit Generated-By: Babel 1.3 ÄeÅ¡tina (ÄŒeská republika)Deutsch (Österreich)English (United States)español (España)français (France)português (Brasil)руÑÑкий (РоÑÑиÑ)українÑька (Україна)sagenb-1.0.1/sagenb/translations/en_US/LC_MESSAGES/messages.po000066400000000000000000000021141311436262400236750ustar00rootroot00000000000000# Translations template for SAGE Notebook. # Copyright (C) 2014 SAGE # This file is distributed under the same license as the SAGE project. # FIRST AUTHOR J. Miguel Farto , 2014. # #, fuzzy msgid "" msgstr "" "Project-Id-Version: Sage Notebook 0.9.2\n" "Report-Msgid-Bugs-To: migeruhito@gmail.com\n" "POT-Creation-Date: 2012-03-18 08:47+0400\n" "PO-Revision-Date: 2013-02-18 10:24+0100\n" "Last-Translator: J. Miguel Farto \n" "Language-Team: J. Miguel Farto \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" "Generated-By: Babel 0.9.6\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" msgid "cs_CZ" msgstr "ÄeÅ¡tina (ÄŒeská republika)" msgid "de_AT" msgstr "Deutsch (Österreich)" msgid "en_US" msgstr "English (United States)" msgid "es_ES" msgstr "español (España)" msgid "pt_BR" msgstr "português (Brasil)" msgid "ru_RU" msgstr "руÑÑкий (РоÑÑиÑ)" msgid "fr_FR" msgstr "français (France)" msgid "uk_UA" msgstr "українÑька (Україна)" sagenb-1.0.1/sagenb/translations/es_ES/000077500000000000000000000000001311436262400177305ustar00rootroot00000000000000sagenb-1.0.1/sagenb/translations/es_ES/LC_MESSAGES/000077500000000000000000000000001311436262400215155ustar00rootroot00000000000000sagenb-1.0.1/sagenb/translations/es_ES/LC_MESSAGES/messages.mo000066400000000000000000001717261311436262400236770ustar00rootroot00000000000000Þ•;ôÌ#—Í#Âe$(%,&E&`&&ž&®&Â&;Ò&#(2(XA(š(¡(«©(:U)6)FÇ)G*IV*4 *«Õ*§+),:,K,Eh,®, ¾,È,Ï, á,î, ÷,-8 -D-bW- º-Å-Ë-OÓ-#.,.@.R.Y.h.8ƒ.$¼. á. î.û.€/„/ Œ/7š/Ò/0ò/§#0Ë0Ò0 á0ï0 11*/1]Z1‚¸1,;2h22~2m±2!3#A3e3„3ï£3 “5¡5©5 Â5?Ì5 66#676F6L6[6Nr6Á6Ø6ê64ù6.7=7L7 i7 w7 „7Ž7–7Ÿ7°7¿7Æ7 Ø7@ä7%878H8[8k8!z8&œ8Ã8Û8 ô8)9,959I9 f9„p9õ9ú9 ::#&: J:U:]: m:Ly:Æ:?á:!;:;Y; r;~;(„;#­;!Ñ;:ó;:.<5i<1Ÿ<6Ñ< ='===)L=$v=›=6 =0×=->06>=g>¥>ª>)Ä>î>÷>ÿ>?-?#=?5a?1—? É?Ó?8é?"@7@=@ B@M@j@}@‚@’@¢@Ô³@•ˆAB&B+BKBjB‡B-¥B,ÓBsCtCC žCªCºCÏC ëC DD5DTD5fDœDµDËDãDþDE,ELE ]EhEpE=ƒE ÁEÌEÑEÖEíEòEûE FF-FLF _FAmF%¯FÕFóFG*GFGJGQGhG%…G «G¸G¾GÕGÙG áG.ïG-I)LI vI—I§I °I ¾I ÉIÖI íIûIJJ J 'J5JLJ^JqJ ƒJ‘J£J¬JÈJ ÐJÝJôJúJ K€K°K&AL7hL L½LÃLÒL×LWàL8MOM=_MeM'N"+N1NN"€N$£NÂÈN>‹OŽÊPYQwQ}Q<’Q=ÏQ: R<HR…RR žR¨R½RtÐR«ESYñSÓKTU7URUWU^UnUU–U¬U½UÄUÚUëU0üU)-V'WVV†VŒV”V²VXÄVW1WDWMW%]W ƒW‘W ªW´W»W ÎWÜWûWX,Xš@X ÛXèXY Y YY 6YCYaY"yYœY¸YÊYÙZöZ[1[K[c[3h[ œ[¦[­[¶[ ¼[Æ[ Ú[è[í[ý[ \"\8\A\#I\'m\&•\C¼\ ] ] ]5];]M]T]Y]i]‚]#‰]­]Å] Í]KØ]$^>^Y^h^ m^^{_Ú_ì_Âÿa*Âb&íbrc)‡c.±cHàc')dVQd•¨dœ>eÛeøe" fU.fP„g±Õg‡hR¤h÷hüh¶i"Ìi—ïi‡jŽj¡j§j®jD´jùj+ke.k”kWluilßlçl5þl4m GmFhm ¯mI¹mn/ n t ½uÉuMÎuv,v65vlv{v“v¨vÆvÕvÛv-ãv!w(3w\w)lw¹–wPxBYxœx®x'Áx¹éx£y µy)¿yZéyDz.]zŒz›zgŸz2{3:{Dn{V³{Q |“\|#ð|z}“}›#~e¿~Œ%h²û€!(?JŠ›¡§­³¼ Øä ôÿ‚M‚¤f‚ ƒ ƒƒ1ƒ FƒPƒVƒ$^ƒƒƒ”ƒ´›ƒP„ V„`„i„„o„”ô…܉†f‡ˆšˆµˆ Ôˆõˆ‰‰v-‰/¤ŠÔŠVäŠ;‹C‹«J‹<ö‹E3ŒSyŒNÍŒL>i–¨´?ŽôŽ (JG’ ¢­ µÃÙéúGHWY ±¼ÂNË ‘%‘6‘G‘N‘_‘H}‘#Ƒꑒ’’œ’¤’;µ’ñ’2“ÀA“” ” ”%*”P”p”A‡”pÉ”±:•6ì•#–;=–ty–0î–.—N—,n—›— ™ «™¶™ Ô™<ß™š +š5š FšRš [šhšR…šØšíš þš@ ›L› [›i› „› ’›Ÿ›°› ¹›ÛÖ›ê›ñ› œSœdœ €œŒœœµœ"Çœêœ%-E;T š!¬ ΉÙcžjž„ž •ž(¢ž Ëž מäžöžBŸIŸRgŸ ºŸ&ÛŸ" % - &3 "Z 9} F· @þ B?¡.‚¡>±¡ ð¡)ý¡'¢.D¢4s¢¨¢F®¢=õ¢43£4h£K£é£ï£) ¤3¤ ;¤G¤ Z¤{¤6’¤Aɤ/ ¥;¥J¥3]¥ ‘¥ž¥§¥­¥¼¥Ë¥â¥ê¥ý¥¦ï5¦¢%§ ȧÒ§Ù§ø§¨54¨Ej¨<°¨eí¨,S©€©©¢©!·©Ù©&ù© ª,ª Bªcª0|ª­ªͪ骫&%«L«+l«˜« ««µ«»«9Ϋ ¬¬¬ ¬0¬5¬>¬E¬%M¬#s¬—¬­¬I½¬+­3­M­m­Š­ §­±­¸­Õ­1í­®4®:®Y®^®f®—z®,°,?°l°‹° œ° ª° µ°°)Ô° þ° ± ±!±,$±Q±/j±&š±Á±!Ô± ö±² ²,*²W²_²+t² ²©²¹²„βßS³,3´<`´´ ¼´È´â´ ç´uó´iµ‡µA˜µtÚµ/O¶$¶=¤¶3â¶ ·¼7·Hô·˜=¹Ö¹ë¹ô¹YºVaºR¸ºT »`» i» w»‚»“»v¦»ø¼[½êr½+]¾‰¾ ¦¾ ²¾¾¾Ó¾ë¾"ý¾ ¿ 5¿?¿^¿m¿;…¿$Á¿+æ¿ À À 'À1ÀQÀU`À(¶ÀßÀ ïÀùÀ6 ÁAÁUÁ qÁ|Á„Á ›Á-©Á×Á÷Á¨2ÂÛÂìÂÃÃÃ/ÃDÃTà mÃ#ŽÃ"²Ã ÕÃ<âÃÅ$<Å ałŠſÅ<ÆÅ ÆÆÆ &Æ 0Æ:ÆSÆdÆlÆÆœÆ £ÆÄÆ ÊÆ+ÖÆ-Ç#0Ç@TǕǤÇÁÇ×ÇßÇõÇüÇÈÈ2È'9ÈaÈ €È ŠÈ^–ÈõÈÉ/ÉAÉúGÉbBÊ ¥Ê-³ÊÄáÌ7¦Í-ÞÍp Î,}Î7ªÎNâÎ*1Ï_\ψ¼Ï§EÐíÐÿÐш-ÑV¶Òº Ó+ÈÓeôÓZÔaÔ¿Ô.?Õ¨nÕÖ!'ÖIÖOÖUÖZ^Ö¹Ö'ÂÖ‡êÖr× ŠØ™—Ø1Ù%FÙ9lÙ¦ÙÂÙqâÙ TÚSaÚ µÚ2¿Ú òÚ þÚ Û #Û/Û 5Û CÛNÛ?mÛ8­ÛæÛÿÛÜC!Ý­eÞÂß'Öß7þßÚ6à2á,Dá)qá›á:®ážéáˆããR¥ãøãä6äSädä#|ä! äÂäÑäÚä8ãä'å%Då jå*tå·Ÿå WæJeæ°æÇæ'Ýæ·ç½çÓç5Øç^è#mèI‘èÛèðèjôè5_é2•éFÈéVêBfê“©ê-=ë€kë±ì둞ìl0íí\+îˆî ¤ï.²ïYáï;ðJðhð~ð–ð©ð±ðÄðãðëð ÿð ññL%ñ˜rñ ò ò*ò@ò Uò_ò }ò<ˆòÅòÖòºÝò%˜ó ¾óÉóÑó Thank you for rating the worksheet %(worksheet_name)s! You can see all ratings of this worksheet.

    Invalid confirmation key

    You are reporting a confirmation key that has not been assigned by this server. Please register with the server.

    Return to Upload or Create Data File or %(worksheet_name)s.%(num)d day%(num)d days%(num)d hour%(num)d hours%(num)d minute%(num)d minutes%(num)d second%(num)d seconds%(seconds)s ago%(t)s ago by %(le)s%(t)s by %(le)s(Currently no different from "load", see bug report) Use "attach filename.sage" or "attach filename.py". Attached files are automatically reloaded when the file changes. The file $HOME/.sage/init.sage is attached on startup if it exists.(note that images are not recorded)24|twenty-four500: Internal server error. An e-mail has been sent to the administrator(s).5|five8|eightWork through the tutorial (if you have trouble with it, view the static version).Restart, instead?

    Email address confirmed for user %(username)s

    Sage is a different approach to mathematics software.A session is a worksheet and a set of variables in some state.A worksheet is an ordered list of Sage calculations with output.A new password has been sent to your e-mail address.A new password will be emailed to the email address connected to your account. However if you didn't confirm your email address you will be unable to recover your account.Access %(f)s in this worksheet by typing DATA+'%(f)s'. Here DATA is a special variable that gives the exact path to all data files uploaded to this worksheet.Account RecoveryAccount SettingsAccount is in read-only modeAccount is read only. You may download or delete worksheets or data.AcknowledgementAction...ActiveActive WorksheetsAdd New UserAdd UserAdd or DeleteAdminAllow OpenID authentication (requires python ssl module)Answer a challengeAny cells with "#auto" in the input is automatically evaluated when the worksheet is first opened.AppearanceAprilArchiveArchive selected worksheets so they do not appear in the default worksheet listArchivedArchived WorksheetsAttaching ScriptsAugustAuthenticationAutoevaluate Cells on LoadAutomatically re-publish when changes are made and savedBack to your personal worksheet listBad passwordBad usernameBase DNBegin a block with %%sh to have the rest of the block evaluated as a shell script. The current working directory is maintained.Bind DNBind PasswordBrowse published Sage worksheets
    (no login required)Browse the published worksheetsBrowse your computer to select a file to upload:By using Sage you help to support a viable open source alternative to Magma, Maple, Mathematica, and MATLAB. Sage includes many high-quality open source math packages.CancelCancel changesCases / TestsChange Auto-Save IntervalChange E-mail AddressChange PasswordChange account settings including passwordClick log commands you have entered in any worksheet of this notebook.Click Interrupt or press escape in any input cell. This will (attempt) to interrupt SAGE by sending many interrupt signals.Click here or press shift-return to evaluateClick here to pop outClick here to turn the above into a Sage worksheetClick on the left side of output to toggle between hidden, shown with word wrap, and shown without word wrap.Click to insert new compute cell.Click to insert new rich-text cell.Click to rename this worksheetClose this box to stop trying.Code is evaluated by exec'ing (after preparsing). Only the output of the last line of the cell is implicitly printed. If any line starts with "sage:" or ">>>" the entire block is assumed to contain text and examples, so only lines that begin with a prompt are executed. Thus you can paste in complete examples from the docs without any editing, and you can write input cells that contains non-evaluated plain text mixed with examples by starting the block with ">>>" or including an example.CollaboratorsCommentComment/Uncomment BlocksConfirmedCongratulations %(u)s! You can now sign into the Sage Notebook.ConstructionsContinueCopy this worksheetCopy worksheetCountCreate AccountCreate a good passwordCreate a new Sage worksheet version of the last 100 commands in the above log.Create a new worksheetCreate a usernameCreate accountCreating new users is disabled by the administrator.Current FolderCurrent e-mailCustomizing the Notebook CSSDATA VariableDIR VariableData fileData...DecemberDefault LanguageDefault systemDeleteDelete All OutputDelete CellDelete all cell contents, then press backspace.Delete all outputDelete worksheetDeleted WorksheetsDeveloper GuideDiscard & quitDiscard changes to this worksheetDo you want to publish this worksheet?Doc worksheet pool sizeDocument does not exist.DocumentationDouble click on existing text to edit it.DownloadDownload All ActiveDownload selected worksheetsDownload.Each block of code is run from its own directory. If any images are created as a side effect, they will automatically be displayed.EditEdit Text CellEdit a copy.Edit plain textEdit text version of this worksheetEdit this.ElapsedEmail ConfirmedEmpty TrashEmptying the trash will permanently delete all items in the trash. Continue?Enable LDAP AuthenticationEnable published interacts (EXPERIMENTAL; USE AT YOUR OWN RISK)Enable user registrationEnable/disable pretty_printingEnter your email addressEnvironmentErrorError applying function to worksheet(s).Error displaying worksheet listing.Error updating cell output after Error uploading file (missing %(field)s arg).%(backlinks)sError uploading file (missing field "file"). %(backlinks)sError uploading file (missing filename).%(backlinks)sError uploading worksheet '%(msg)s'.%(backlinks)sError: can't add more than 500 collaborators at a timeEvaluate AllEvaluate Cell using GAP, Singular, etc.Evaluate InputEvaluate all input cells in the worksheetEvaluate all input cells using %(i)sExitExpected "%(wanted)s" after "%(key)s", got "%(token)s"Expected a color value "%(arg)s" after "%(key)s"Expected an integer "%(arg)s" after "%(key)s"Expected an integer "%(key)s" before "%(token)s"Explore a collection of in-depth tutorials on specific topicsFailFailed to save worksheet.Fast Static Versions of the DocumentationFebruaryFile...Files and ScriptsFind Help and DocumentationForgot passwordFull Text Search of Docs and SourceGees -- You can't fool the rating system that easily!General and Advanced Pure and Applied MathematicsGet ImageGet Started with SageGive access to your worksheet to the above collaboratorsGo to the worksheet.GrantHelpHelp AboutHelp via Internet Chat (IRC)Hi %(username)s! HideHide All OutputHide all outputHide/Show OutputHighlight text and press ctrl-. to comment it and ctrl-, to uncomment it. As an alternative (necessary in some browsers), use ctrl-3 and ctrl-4.Highlight text and press > to indent it all and < to unindent it all (works in Safari and Firefox). In Firefox you can also press tab and shift-tab.HistoryHomeHow do I construct ... in Sage?How many bits are in one byte?How to use the Sage NotebookIdle check interval (seconds)Idle timeout for live documentation (seconds)Idle timeout for normal worksheets (seconds)If you create a file $HOME/.sage/notebook.css then it will get applied when rendering the notebook. See Incorrect password givenIndenting BlocksInput RulesInsert New CellInsert New Text CellInteractive Dynamic WidgetsInteractively use this worksheetInterruptInterrupt Running CalculationsInterrupt and Restart SessionsInterrupt attemptInterrupt currently running calculations, if possibleInvalid JSmol encoding: Invalid JSmol query: Invalid JSmol request: Invalid challenge responseInvalid e-mail address.Invalid email addressInvalid filename. %(backlinks)sInvalid usernameIs pi > e?JanuaryJava Applet HiddenJavascript must be enabled in order to use the Sage Notebook.Jmol ImageJulyJuneKey and Mouse BindingsLDAPLDAP URILanguageLast EditedLearn to write Sage programsLet others edit this worksheetLive DocumentationLoad 3-D LiveLoad 3-D Live. Not recommended for worksheets with > 2 3-D Plots.Load a new worksheet stored in a fileLoad worksheet from a file...Loading SAGE/Python ScriptsLoading and Saving ObjectsLoading and Saving SessionsLogLog inLog in to edit a copy.Log out of the Sage notebookMake this worksheet publicly viewableManage UsersMarchMaximum history lengthMayMinutesModel VersionMove the mouse between cells until a blue bar appears. Shift-click on the blue bar, or click on the text bubble icon, to create a new text cell. Use $...$ and $$...$$ to include typeset math in the text block. Click the button to save changes, or press shift-enter.Move the selected worksheets out of the trashMove the selected worksheets to the trashMove this worksheet to the trashMulti Cell ModeNew UserNew WorksheetNew e-mailNew passwordNew password not givenNew worksheetNewerNewestNoNo challenge response givenNo data filesNo email address givenNo password givenNo such worksheet.No username givenNot confirmedNotebook SettingsNovemberNumber of word-wrap columnsOctoberOld passwordOld password not givenOlderOldestOne Cell ModeOnly the owner of a worksheet is allowed to share it. You can do whatever you want if you make your own copy.Or enter the URL of a file on the web. This can be a direct link to any of the above kinds of files, or the URL of any HTML page that supports "linked worksheet autodiscovery".Or enter the URL of a file on the web:Or enter the name of a new file, which will be created:Other published documents...OwnerParen matchingPassPasswordPassword not acceptable. Must be 4 to 32 characters and not contain spaces or username.Passwords didn't matchPick a usernamePlease ask the server administrator to configure a challenge!Please enable cookies or delete all Sage cookies and localhost cookies in your browser and try again.Please enter a name for this worksheet.Please log in to the Sage notebookPlease specify a worksheet to load. %(backlinks)sPlease type in new password again.Possible failure deleting worksheet.Press ctrl-; in a cell to split it into two cells, and ctrl-backspace to join them. Press ctrl-enter to split a cell and evaluate both pieces.Press shift-enter or click the "evaluate" button. You can start several calculations at once. If you press alt-enter instead, then a new cell is created after the current one. If you press ctrl-enter then the cell is split and both pieces are evaluated separately.Press tab while the cursor is on an identifier. On some web browsers (e.g., Opera) you must use control-space instead of tab.Pretty print (typeset) outputPrintPrint this worksheetProblem inserting new input cell after current input cell.\nProblem inserting new input cell before current input cell.\nProblem inserting new text cell before current input cell.Problem inserting new text cell before current input cell.\nPublishPublish this onePublishedPublished WorksheetsPublished on %(t)sPut "%%gap", "%%singular", etc. as the first input line of a cell; the rest of the cell is evaluated in that system.Put ?? after the object and press tab or shift-enter (shift-enter overwrites output and saves to worksheet). Doing this twice or more toggles with just the documentation.Put @interact on the line before a function definition. Type interact? for more details.Put the mouse between an output and input until the blue horizontal line appears and click, or click the "plus" icon. If you press Alt-Enter in a cell, the cell is evaluated and a new cell is inserted after it.Query timeout (seconds)Quit the worksheet processRateRatingRating AcceptedRatings for %(wn)sRe-publish worksheetRe-type your passwordReference ManualRenameRename this worksheetRename worksheetReport a ProblemReport a problem or submit a bug to improve SageRequested public worksheet does not existRequire e-mail for account registrationRerateResetRestartRestart the worksheet processRestart worksheetReturn to Upload File.Retype new passwordRevert to this oneRevisionRevision %(lr)sRevision History -- List of SnapshotsRevision ListRevision from %(ta)s agoRevisionsRevokeSage DocumentationSage NotebookSage Notebook Account RecoverySage Notebook RegistrationSage Notebook versionSage Source BrowserSage makes it easy for you to use most mathematics software together. Sage includes GAP, GP/PARI, Maxima, and Singular, and dozens of other open packages.Sage versionSage: History for %(u)sSaveSave & quitSave ChangesSave and quit worksheetSave changesSave changes and close windowSave interval (seconds)Save this worksheet to an sws fileSave worksheet to a file...Search WorksheetsSearch the SAGE documentation by typing
    search_doc("my query")
    in an input cell and press shift-enter. Search the source code of SAGE by typing
    search_src("my query")
    and pressing shift-enter. Arbitrary regular expressions are allowed as queries.Searching for Sage server...Select a file related functionSelect a worksheet functionSelect an OpenID providerSelect an attached fileSendSend notification e-mails to (comma-separated list)SeptemberServerSettingsShareShare nowShare this documentShell ScriptsShowShow All OutputShow all outputSign inSign into the Sage Notebook v%(v)sSign outSign upSign up for a Sage Notebook accountSign up for a new Sage Notebook accountSomeone else is viewing this worksheetSorry, but you need a browser that supports the <canvas> tag.Source CodeSpecial Cell BlocksSplit and Join CellsStartStatic version...StatusStopStop publishingStop selected worksheetsSubmitSuccessfully deleted '%(filename)s'Supported file formats:SuspendSuspensionSuspicious filename "%(filename)s" encountered uploading file.%(backlinks)sSwitch to multi-cell modeSwitch to single-cell modeTab CompletionTextThank you for registering for the Sage notebook. To complete your registration, copy and paste the following link into your browser: %(url_prefix)s://%(addr)s:%(port)s/confirm?key=%(key)s You will be taken to a page which will confirm that you have indeed registered.The Sage notebook is a collection of worksheets, saved objects, and user information.The Sage NotebookThe Sage Notebook is based upon work supported by the National Science Foundation under grants DMS-0821725, DMS-1020378, DMS-0713225, DMS-0555776, DMS-0545904, DMS-0838212, DMS-0757627, DUE-1020378, DUE-1022574, DMS-1015114, etc. Any opinions, findings, and conclusions or recommendations expressed in this material are those of the author(s) and do not necessarily reflect the views of the National Science Foundation. See also http://sagemath.org/development-ack.html.The Sage Notebook was primarily written by William Stein with substantial contributions from Tom Boothby, Timothy Clemans, Alex Clemesha, Mike Hansen, Bobby Moretti, Yi Qiang, and Dorian Raymer.The account recovery system is not active.The confirmation system is not active.The data filename already exists in other worksheet Delete the file in the other worksheet before creating a link.The e-mail address hasn't been confirmed.The new password couldn't be sent to %(dest)s.The password for the user %(u)s has been reset to %(p)sThe passwords you entered do not match.The temporary password for the new user %(username)s is %(password)sThe username must start with a letter and be between 4 and 32 characters long. It can only consist of letters, numbers, underscores, and one dot (.).The variable DIR contains the directory from which you started the SAGE notebook. For example, to open a file in that directory, do "open(DIR+'filename')".The worksheet does not existThematic TutorialsThere are no published worksheets.There was an error uploading the worksheet. It could be an old unsupported format or worse. If you desperately need its contents contact the sage-support group and post a link to your worksheet. Alternatively, an sws file is just a bzip2 tarball; take a look inside! %(backlinks)sThis Sage Worksheet is currently shared with the people listed in the box below.This Sage notebook is not configured to load worksheets from 'https' URLs. Try a different URL or download the worksheet and upload it directly from your computer. %(backlinks)sThis page is rated %(wr).1f.This worksheet is read only. Please make a copy or contact the owner to change it.TimeTitle of saved worksheetTo fix unmatched or mis-matched parentheses, braces or brackets, press ctrl-0. Parentheses before the cursor will be matched, minding strings and (Python) comments.To quickly try out Sage start hereTo save this image, you can try right-clicking on the image to copy it or save it to a file, or you may be able to just drag the image to your desktop.ToggleToggle the top barTotalTotalsTrashTrying again in %(num)d second...Trying again in %(num)d seconds...TutorialType "%%time" at the beginning of the cell.Type "restart" to restart the SAGE interpreter for a given worksheet. (You have to interrupt first.)Type ? immediately after the object or function and press tab or shift-enter (shift-enter overwrites output and saves to worksheet). Doing this twice or more toggles with formatted source code.Type of challengeType pretty_print_default() in an input cell and press shift-enter. All future output will be typeset automatically.TypesetTypesetting All OutputURL must start with http, https, or ftp.%(backlinks)sURL of file on webUnable to interrupt calculation.Unable to load file URL's when not running on localhost. %(backlinks)sUnarchiveUnarchive selected worksheets so it appears in the default worksheet listUndeleteUnknown worksheet extension: %(ext)s. %(links)sUnsuspendUntitledUpdate CollaboratorsUpdatedUploadUpload FileUpload WorksheetUpload or Create Data FileUpload or Create Data File to attach to worksheet "%(wn)s"Upload or create a data file in a wide range of formatsUpload or create file...Upload worksheet to the Sage NotebookUse "load filename.sage" and "load filename.py". Load is relative to the path you started the notebook in. The .sage files are preparsed and .py files are not. You may omit the .sage or .py extension. Files may load other files.Use "save(obj1,DATA+'foo')" to save an object to the data directory of a worksheet, and "obj1 = load(DATA+'foo')" to load it again. To use such objects between worksheets, you may save to any filename (given as a string) Sage can write to on your system.Use "save_session('name')" to save all variables to an object. Use "load_session('name')" to merge in all variables from a saved session.Use live documentation to try out the full Sage documentation "live". (Only new compute cells allowed, click the icon.)Use GSSAPI instead of Bind DN/PasswordUse Most Mathematics Software from Within SageUse Sage for studying calculus, elementary to very advanced number theory, cryptography, commutative algebra, group theory, graph theory, numerical and exact linear algebra, and more.Use a Mainstream Programming LanguageUse a challenge for account registrationUse an Open Source AlternativeUse java for 3-DUse java for 3-D. Only applies to this running of worksheet.Use the Data menu to upload images and other files, and create new files that can be shared between worksheets. The DATA variable contains the path to the data files. For example, to open a file in that directory, do "open(DATA+'filename')". If foo.sage is a Sage file that you uploaded, type "load foo.sage"; if foo.py is a Python file, you can import it by typing "import foo".Useful TipsUserUser '%(user)s' does not have permission to view the home page of '%(name)s'.User ManagementUsernameUsername Attribute (i.e. cn, uid or userPrincipalName)Username ErrorUsername already in useUsername is invalid.Username is not in the systemUsername takenUsersVersionView a 4000+ page reference manual about SageView a log of recent computationsView changes to this worksheet over timeView plain textView plain text version of this worksheetWelcome to Sage! You can create a new worksheet, view published worksheets, or read the documentation.Welcome!What do you want to call it? (if different than the original name)What is 2 plus 3?What is 3 times 8?What is the largest prime factor of 15?With the Sage Notebook anyone can create, collaborate on, and publish interactive worksheets. In a worksheet, one can write code using Sage, Python, and other software included in Sage.Working DirectoryWorksheetWorksheet is locked. Cannot insert cells.Worksheet is publicly viewable at %(u)sWorksheet process limitsWorksheet process users (comma-separated list)Wrong passwordYesYou can publish your worksheet to the Internet, where anyone will be able to access and view it online.You do not have permission to access this locationYou do not have permission to access this worksheetYou may add or remove collaborators (separate user names by commas).You may download %(f)s or create a link to this file in worksheet You requested to evaluate a cell that, for some reason, the server is unaware of.You work with Sage using the highly regarded scripting language Python. You can write programs that combine serious mathematics with anything else.Your account is currently suspendedYour browser / OS combination is not supported.\nPlease use Firefox or Opera under Linux, Windows, or Mac OS X, or Safari.Your email address is required for account confirmation and recovery. You will be emailed a confirmation link right after you successfully sign up.Your new password is %(key)s Sign in at %(url_prefix)s://%(addr)s:%(port)s/ Make sure to reset your password by going to Settings in the upper right bar.Your password must have at least 4 characters. Your password can not contain your username or spaces.Your username must start with a letter and be between 3 and 64 characters long. You may only use letters, numbers, underscores, @, and dots.Your worksheet will be assigned a unique address (URL) that you can send to your friends and colleagues.a ReStructuredText file (Add ".. escape-backslashes" as a line in the file if you want backslashes to be escaped. Put latex code inside backticks "`" or dollar signs "$" or "$$". Math role is not supported for now.)a Sage worksheeta zip archive of any of the abovean HTML page generated by docutils from a ReStructuredText filebrowse directorycs_CZde_ATen_USes_ESevaluatefr_FRillegal link attempt!last editedleave a commentloading...nothing to see.optionalor delete %(f)s.or .txt - a worksheet text file with html code and cells surrounded by {{{ and }}} that defines a worksheetpt_BRpublishedreCAPTCHA private keyreCAPTCHA public keyrecaptcharu_RUrunnings (canceling further update checks).select worksheetsimplethe URL of a page of the Sage Documentation, for example the URL of this pageuk_UAunprintedusernamey|yesProject-Id-Version: Sage Notebook 0.9.2 Report-Msgid-Bugs-To: migeruhito@gmail.com POT-Creation-Date: 2014-12-19 22:07+0100 PO-Revision-Date: 2013-02-18 10:24+0100 Last-Translator: J. Miguel Farto Language-Team: J. Miguel Farto MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit Generated-By: Babel 1.3 Gracias por puntuar la hoja %(worksheet_name)s! Puede ver todas las puntuaciones de esta hoja.

    Contraseña de confirmación inválida

    Usted ha proporcionado una contraseña de confirmación no asignada por este servidor. Por favor regístrese en el servidor.

    Vuelva a Subir o Crear Archivo de Datos o %(worksheet_name)s.%(num)d día%(num)d días%(num)d hora%(num)d horas%(num)d minuto%(num)d minutos%(num)d segundo%(num)d segundoshace %(seconds)shace %(t)s por %(le)s%(t)s por %(le)s(Actualmente "attach" funciona como "load", ver informe de errores) Utilice "attach filename.sage" o "attach filename.py". Los archivos adjuntos se recargarán automáticamente cuando se produzcan cambios en ellos. El archivo $HOME/.sage/init.sage, si existe, se adjunta automáticamente al inicio.(observar que las imágenes no se han guardado)24|veinticuatro500: Error interno del servidor. Se ha enviado un e-mail al administrador.5|cinco8|ochoTutorial interactivo (si tiene problemas con él, utilice la versión estática).¿Reiniciar, si no?

    Dirección de e-mail confirmada para el usuario %(username)s

    Sage presenta un enfoque diferente del software para matemáticas.Una sesión es una hoja y un conjunto de variables con algún estado.Una hoja es una lista ordenada de cálculos en Sage con resultados.Se ha enviado una nueva contraseña a su dirección de e-mail.Se le enviará una nueva contraseña a su dirección de e-mail. Sin embargo no podrá recuperar su cuenta si no ha confirmado su dirección de e-mail.Acceda a %(f)s en esta hoja escribiendo DATA+'%(f)s'. Aquí DATA es una variable especial que proporciona la ruta exacta a todos los archivos de datos subidos a esta hoja.Recuperación de CuentaConfigurar CuentaLa cuenta está en modo de sólo lecturaLa cuenta es de sólo lectura. Se pueden descargar o borrar hojas o datos.AgradecimientosAcción...ActivasHojas activasAñadir Usuario NuevoAñadir UsuarioAñadir o BorrarAdminPermitir autentificación OpenID (se requiere el módulo ssl de python)Conteste un retoTodas las celdas que contengan "#auto" se evaluarán automáticamente al abrir la hoja.AparienciaAbrilArchivarArchivar hojas seleccionadas para que no aparezcan en la lista normal de hojasArchivadasHojas ArchivadasAdjuntar ScriptsAgostoAutentificaciónAuto-evaluar Celdas al CargarRe-publicar automáticamente cuando se realicen cambios y sean guardadosVolver a su lista personal de hojasContraseña incorrectaUsuario incorrectoBase DNComience un bloque con %%sh para que el resto se evalúe como un script de shell. Se mantiene el directorio por defecto actual.Bind DNContraseña BindVer las hojas de Sage publicadas
    (no se requiere entrar)Revisar las hojas publicadasSeleccionar un archivo para subir en su ordenador:Cuando utiliza Sage, ayuda a mantener una alternativa viable de fuente abierta a Magma, Maple, Mathematica y MATLAB. Sage incluye muchos paquetes matemáticos de fuente abierta y alta calidad.CancelarCancelar cambiosCasos / TestsCambiar el intervalo de auto-guardadoCambiar la dirección de e-mailCambiar la ContraseñaCambiar la configuración de la cuenta, incluyendo la contraseñaPulse historial para ver los comandos que ha tecleado en cualquier hoja de este notebook.Pulse Interrupt o pulse escape en cualquier celda de entrada. Esto interrumpirá (o al menos intentará interrumpir) a SAGE enviando múltiples señales de interrupción.Pulsar aquí o teclear mayúsculas-entrar para evaluarPulsar aquí para activarPulsar aquí para convertir lo anterior en una hoja de SagePulse en el lado izquierdo para cambiar entre ocultar, mostrar con ajuste de línea, y mostrar sin ajuste de línea.Pulsar para insertar un nueva celda de cálculo.Pulsar para insertar una nueva celda de texto.Pulsar para renombrar esta hojaCerrar este cuadro para dejar de intentarlo.El código se evalúa mediante ejecución (después de un preprocesado). Sólo se muestra la salida de la última línea. Si alguna línea comienza por "sage:" o ">>>" se asume que todo el bloque contiene texto y ejemplos, por lo que solo se ejecutan las líneas que comiencen por un inductor. Así, se pueden pegar ejemplos completos de la documentación sin necesidad de editarlos y se puede escribir texto sin evaluar en las celdas mezclado con ejemplos, comenzando el bloque con ">>>" o incluyendo un ejemplo.ColaboradoresComentarioComentar/Des-comentar bloquesConfirmado¡Enhorabuena %(u)s! Ahora puede entrar en el Notebook Sage.ConstruccionesContinuarCopiar esta hojaCopiar hojaContadorCrear CuentaCree una contraseña robustaCrear una hoja de Sage nueva con los 100 últimos comandos del historial anterior.Crear una hoja nuevaCrear un usuarioCrear cuentaEl administrador ha desactivado la creación de usuarios nuevos.Carpeta actualE-mail actualPersonalizando el NotebookVariable DATAVariable DIRArchivo de datosDatos...DiciembreIdioma por defectoSistema por defectoBorrarBorrar ResultadosBorrar CeldaBorrar todo el contenido de una celda y después pulsar retroceso.Borrar todos los resultadosBorrar hojaHojas EliminadasGuía del desarrolladorDescartar y SalirDescartar los cambios en esta hoja¿Quiere publicar esta hoja?Espacio para hojas de documentación No existe el documento.DocumentaciónHaga doble click sobre el texto preexistente para editarlo.DescargarDescargar activasDescargar las hojas seleccionadasDescargar.Cada bloque de código se ejecuta en su propio directorio. Si se crea alguna imagen como efecto colateral, se mostrará automáticamente.EditarEditar una celda de textoEditar una copiaEditar textoEditar la versión de texto de esta hojaEditar estoTranscurridoE-mail confirmadoVaciar PapeleraVaciar la papelera borrará permanente sus elementos. ¿Continuar?Activar Autentificación LDAPActivar interacciones en hojas publicadas (EXPERIMENTAL; UTILÃZELO A SU CRITERIO)Permitir el registro de usuariosActivar/desactivar impresión avanzadaIntroduzca su dirección de e-mailEntornoErrorError al aplicar función a la hoja(s)Error al mostrar la lista de hojasError al actualizar el resultado de la celda después de Error subiendo archivo (falta el argumento de %(field)s).%(backlinks)sError subiendo archivo (falta el campo "archivo"). %(backlinks)sError subiendo archivo (falta el nombre del archivo).%(backlinks)sError subiendo la hoja '%(msg)s'.%(backlinks)sError: No se pueden añadir más de 500 colaboradores a la vezEvaluar todoEvaluar celdas usando GAP, Singular, etc.Evaluar una celda de entradaEvaluar todas las celdas de entrada de la hojaEvaluar todas las celdas de entrada utilizando %(i)sSalirSe esperaba "%(wanted)s" después de "%(key)s" y se obtuvo "%(token)s"Se esperaba un valor de color "%(arg)s" después de "%(key)s"Se esperaba un entero"%(arg)s" después de "%(key)s"Se esperaba un entero "%(key)s" antes de "%(token)s"Explorar una colección de tutoriales avanzados sobre materias específicasFalloFallo al guardar la hoja.Versiones estáticas de la documentaciónFebreroArchivos...Archivos y ScriptsEncontrar Ayuda y DocumentaciónOlvidar la contraseñaBúsqueda a Texto Completo en Documentación y Fuentes¡No se puede engañar tan fácilmente al sistema de puntuación!Matemática General y Avanzada, Pura y AplicadaObtener ImagenEmpezando con SageDar acceso a su hoja a los colaboradores anterioresIr a la hojaPermitirAyudaAyuda sobre...Ayuda vía IRC¡Hola %(username)s! OcultarOcultar ResultadosOcultar todos los resultadosOcultar/Mostrar ResultadosSeleccione un texto y pulse ctrl-. para comentarlo y ctrl-, para quitar los comentarios. También se puede usar ctrl-3 y ctrl-4 (esto es necesario en algunos navegadores).Seleccione un texto y pulse > para sangrarlo < para reducir la sangría (funciona en Safari y Firefox). En Firefox también se puede pulsar tab y mayúsculas-tab.HistorialInicio¿Cómo construir ... en Sage?¿Cuántos bits hay en un byte?Cómo usar el Notebook SageComprobación del intervalo de inactividad (segundos)Tiempo de espera inactivo para la documentación dinámica (segundos)Tiempo de espera inactivo para las hojas normales (segundos)Si crea un archivo $HOME/.sage/notebook.css, se aplicará cuando se muestre el notebook. VerSe ha introducido una contraseña incorrectaSangrar bloquesReglas de EntradaInsertar Celda NuevaInsertar una celda de texto nuevaWidgets Dinámicas InteractivasUtilizar esta hoja en modo interactivoInterrumpirInterrumpir CálculosInterrumpir y Reiniciar SesionesIntento de interrupciónInterrumpir los cálculos en curso si es posibleCodificación JSmol inválida: Petición JSmol inválida: Petición JSmol inválida: Contestación al reto inválidaLa dirección de e-mail no es válida.Dirección de e-mail no válidaNombre de archivo no válido. %(backlinks)sUsuario no válido¿pi > e?EneroApplet Java OcultaPara utilizar el Notebook Sage se debe activar JavascriptImagen JmolJulioJunioTeclas RápidasLDAPLDAP URIIdiomaEditadaAprender a escribir programas en SagePermitir que otros editen esta hojaDocumentación activaCargar 3-D LiveCargar 3-D Live. No se recomienda para hojas con más de 2 gráficas 3-D.Carga una hoja nueva guardada en un archivoCargar hoja de archivo...Cargando Scripts de SAGE/PythonCargando y Guardando ObjetosCargando y Salvando sesionesHistorialEntrarEntrar para editar una copiaSalir del Notebook SagePermitir que esta hoja se pueda ver públicamenteAdministrar UsuariosMarzoLongitud máxima del historialMayoMinutosVersión del ModeloMueva el ratón entre celdas hasta que aparezca una barra horizontal. Pinche mientras mantiene pulsada la tecla Mayúsculas en la barra horizontal, o bien pinche en el icono de texto para crear una celda de texto nueva. Utilice $...$ y $$...$$ para incluir tipografía matemática en el bloque de texto. Pinche el botón para guardar los cambios o pulse Mayúsculas-Entrar.Sacar las hojas seleccionadas de la papeleraEnviar las hojas seleccionadas a la papeleraEnviar esta hoja a la papeleraModo Multi-CeldaNuevo usuarioHoja NuevaNuevo e-mailContraseña NuevaNo se ha introducido la nueva contraseñaHoja nuevaPosteriorLa más nuevaNoNo se ha proporcionado contestación al retoNo hay archivos de datosNo se ha proporcionado una dirección de e-mailNo se ha proporcionado una contraseñaNo existe la hoja.No se ha proporcionado un usuarioNo confirmadoConfiguración del NotebookNoviembreNúmero de columnas para el ajuste de líneaOctubreContraseña anteriorNo se ha introducido la contraseña antiguaAnteriorLa más antiguaModo de Celda ÚnicaSólo se permite compartir una hoja a su propietario. Usted podrá hacer lo que desee si realiza su propia copia.O introducir el URL de un archivo de la web. Puede ser un enlace directo a cualquiera de las clases anteriores de archivos, o el URL de cualquier página HTML que soporte la característica "linked worksheet autodiscovery".O introducir el URL de un archivo en la web:O introducir el nombre de un archivo nuevo que será creado:Otros documentos publicados...PropietarioEmparejado de ParéntesisPasaContraseñaSu contraseña no es aceptable. Debe tener al menos 4 caracteres y no debe contener espacios ni su nombre de usuario.Las contraseñas no coincidenElija un usuario¡Por favor consulte al administrador para que configure un reto!Por favor, active las cookies o borre todas las cookies de Sage y de localhost de su navegador e inténtelo de nuevoPor favor, introduzca un nombre para esta hoja.Por favor entre en el Notebook Sage Por favor, especifique una hoja para recuperar. %(backlinks)sVuelva a introducir la nueva contraseña, por favorPosible fallo al borrar la hoja.Pulse ctrl-; en una celda para dividirla en dos, y ctrl-retroceso para unirlas. Pulse ctrl-entrar para dividir una celda y evaluar ambas.Pulse mayúsculas-entrar o pinche en el botón "evaluar". Se pueden iniciar varios cálculos a la vez. Si en lugar de ello, pulsa alt-entrar, se crea una celda nueva después de la actual. Si pulsa ctrl-entrar, la celda se divide en dos y se evalúan ambas partes por separado.Pulse tab cuando el cursor está sobre un identificador. En algunos navegadores (e.g., Opera) se debe usar control-space en vez de tab.Typografía avanzadaImprimirImprimir esta hojaProblema al insertar una celda de entrada nueva después de la celda de entrada actual.\nProblema al insertar una celda de entrada nueva antes de la celda de entrada actual.\nProblema al insertar una celda de texto nueva antes de la celda de entrada actual.Problema al insertar una celda de texto nueva antes de la celda de entrada actual.\nPublicarPublicar estaPublicadasHojas PublicadasPublicado en %(t)sEscriba "%%gap", "%%singular", etc. como primera línea de la celda; el resto de la celda se evaluará en ese sistema.Teclee ?? después del objeto y pulse tab o mayúsculas-entrar (mayúsculas-entrar sobrescribe la salida de la hoja con el código fuente en la propia hoja). Realizar esta acción dos o más veces cambia entre el código fuente y la documentación.Escriba @interact en una línea antes de una función. Teclee interact? para más detalles.Sitúe el ratón entre un cuadro de salida y uno de entrada hasta que aparezca una línea horizontal y pinche, o bien pinche en el icono "más". Si pulsa Alt-Enter en una celda, ésta se evalúa y se inserta una nueva a continuación.Tiempo de espera para peticiones (segundos)Salir del proceso de la hojaPuntuaciónPuntuaciónPuntuación aceptadaPuntuación para %(wn)sHoja re-publicadaVuelva a introducir su contraseñaManual de ReferenciaRenombrarCambiar el nombre de esta hojaRenombrar hojaInformar de un problemaInformar de un problema o enviar un error para mejorar SageLa hoja pública requerida no existeRequerir e-mail para el registro de cuentasRe-puntuarReiniciarReiniciarReiniciar el proceso de la hojaReiniciar hojaVuelva a Subir Archivo.Volver a introducir la nueva contraseñaRevertir a estaRevisiónRevisión %(lr)sHistorial de revisiones -- Lista de sesiones guardadasLista de RevisionesRevisión desde hace %(ta)sRevisionesRevocarDocumentación de SageNotebook SageRecuperación de cuentas del Notebook de SageRegistro en el Notebook de SageVersión del Notebook SageVisualizador de Fuentes de SageCon Sage usted puede utilizar fácilmente la mayoría del software matemático. Sage incluye GAP, GP/PARI, Maxima y Singular, y otros muchos paquetes de fuente abierta.Versión de SageSage: Historial para %(u)sGuardarGuardar y salirGuardar CambiosSalir y guardar hojaGuardar cambiosGuardar cambios y cerrarIntervalo de guardado (segundos)Guardar esta hoja en un archivo swsGuardar esta hoja en un archivo...Buscar hojasBusque en la documentación de SAGE escribiendo
    search_doc("mi búsqueda")
    en una celda de entrada y pulse mayúsculas-entrar. Busque en el código fuente de SAGE tecleando
    search_src("mi búsqueda")
    y pulsando mayúsculas-entrar. Se admiten expresiones regulares arbitrarias en las búsquedas.Buscando el servidor Sage...Seleccionar una función de archivosSeleccionar una función de hojaElegir un proveedor de OpenIDSeleccionar un archivo adjuntoEnviarEnviar e-mails de notificación a (lista separada por comas)SeptiembreServidorConfiguraciónCompartirCompartirCompartir este documentoScripts de ShellMostrarMostrar ResultadosMostrar todos los resultadosEntrarEntra en el notebook Sage v%(v)sSalirRegistrarseRegistrase para una cuenta de Notebook SageAbrir una cuenta nueva en el Notebook de SageAlguien más está viendo esta hojaLo siento, pero necesita un navegador que soporte <canvas>Código FuenteBloques de Celdas EspecialesDividir y Unir CeldasIniciarVersión estática...EstadoPararDejar de publicarParar las hojas seleccionadasEnviar'%(filename)s' Se ha borrado con éxitoFormatos de archivo soportadosSuspenderSuspensiónSe ha encontrado un nombre de archivo "%(filename)s" sospechoso subiendo archivo.%(backlinks)sCambiar a modo multi-celdaCambiar a modo de celda únicaCompletar con TabTextoGracias por registrarse en el Notebook Sage. Para completar su registro copie y pegue el siguiente enlace en su navegador: %(url_prefix)s://%(addr)s:%(port)s/confirm?key=%(key)s Será conducido a una página que le confirmará que se ha registrado.El Notebook sage es una colección de hojas, objetos grabados e información del usuario.Notebook SageEl Notebook Sage está basado en trabajos financiados por The National Science Foundation bajo los proyectos DMS-0821725, DMS-1020378, DMS-0713225, DMS-0555776, DMS-0545904, DMS-0838212, DMS-0757627, DUE-1020378, DUE-1022574, DMS-1015114, etc. Cualesquiera opiniones, investigaciones, y conclusiones o recomendaciones expresadas en este material son del autor(es), no reflejan necesariamente los puntos de vista de The National Science Foundation. Ver también http://sagemath.org/development-ack.html.El Notebook Sage fue escrito principalmente por William Stein con contribuciones sustanciales de Tom Boothby, Timothy Clemans, Alex Clemesha, Mike Hansen, Bobby Moretti, Yi Qiang, y Dorian Raymer.El sistema de recuperación de cuentas no está activo.El sistema de confirmación está desactivadoEl nombre del archivo de datos ya existe en otra hoja Borre el archivo en la otra hoja antes de crear el enlace.No se ha confirmado la dirección de e-mail.No se ha podido enviar la nueva contraseña a %(dest)s.La contraseña para el usuario %(u)s se ha reiniciado a %(p)sLas contraseñas introducidas no coincidenLa contraseña provisional para el nuevo usuario %(username)s es %(password)sEl usuario debe comenzar por una letra y tener entre 4 y 32 caracteres. Sólo puede contener letras, números, guiones bajos y un punto.La variable DIR contiene el directorio desde el que se inicio el notebook de SAGE. Por ejemplo, para abrir un archivo en ese directorio, teclee "open(DIR+'filename')".La hoja no existeTutoriales temáticosNo hay hojas publicadasOcurrió un error al subir la hoja. Pudiera estar en un formato antiguo no soportado o peor aún. Si necesita sus contenidos desesperadamente contacte con el grupo sage-support y envíe un enlace a su hoja. Alternativamente, un archivo sws simplemente es un tarball comprimido con bzip2; ¡Eche un vistazo dentro de él! %(backlinks)sSe ha compartido la hoja de Sage con los usuarios que figuran en el recuadro de abajo.Este notebook Sage no está configurado para recuperar hojas desde URLs 'https'. Pruebe con un URL diferente, o descargue la hoja y súbala directamente desde su ordenador. %(backlinks)sEsta página tiene la puntuación %(wr).1f.Esta hoja es de sólo lectura. Por favor haga una copia o contacte con el propietario para cambiarlo.TiempoTítulo de la hojas guardadasPara emparejar paréntesis, llaves o corchetes, pulse ctrl-0. Se emparejarán los paréntesis que estén antes del cursor, teniendo en cuenta strings y comentarios de Python.Comenzar aquí para probar Sage inmediatamentePara guardar esta imagen, puede intentar pulsar el botón derecho sobre ella y copiarla o guardarla en un archivo, o puede intentar arrastrar la imagen a su escritorio.Ocultar/MostrarOcultar/Mostrar la barra superiorTotalTotalPapeleraSe intentará de nuevo en %(num)d segundo...Se intentará de nuevo en %(num)d segundos...TutorialEscriba "%%time" al inicio de la celda.Teclee "restart" para reiniciar el intérprete de SAGE para una determinada hoja. (Primero hay que interrumpir los cálculos en curso).Teclee ? inmediatamente después del objeto o función y presione tab o mayúsculas-entrar (mayúsculas-entrar sobrescribe la salida de la celda con la ayuda en la propia hoja). Realizar esta acción dos o más veces cambia entre la documentación y el código fuente formateado.Tipo de retoTeclee pretty_print_default() en una celda de entrada y pulse mayúsculas-entrar. Toda la salida a partir de ahora se mostrará con tipografía avanzada.Tipografía avanzadaUtilizar siempre tipografía avanzadaEl URL debe comenzar con http, https, o ftp.%(backlinks)sURL de un archivo de la webImposible interrumpir cálculo.No se pueden cargar URL de archivos cuando no está ejecutando la aplicación en la máquina local. %(backlinks)sDes-archivarDes-archivar las hojas seleccionadas para que aparezcan en la lista normal de hojasRecuperarExtensión de hoja desconocida: %(ext)s. %(links)sRestablecerSin títuloActualizar colaboradoresActualizadoSubirSubir ficheroSubir HojaSubir o Crear Archivo de DatosSubir o Crear Archivo de datos para adjuntar a la hoja "%(wn)s"Subir o crear un archivo de datos en múltiples formatosSubir o crear archivo...Subir una hoja al Notebook SageUtilice "load filename.sage" y "load filename.py". La ruta será relativa a la del directorio donde inició el notebook. Los archivos .sage son preprocesados y los .py no. Se puede omitir la extensión .sage o .py. Los archivos pueden cargar otros archivos.Utilice "save(obj1, DATA + 'foo') para guardar un objeto en el directorio de datos de una hoja, y "obj1 = load(DATA + 'foo')" para cargarlo de nuevo. Para utilizar tales objetos entre distintas hojas, se pueden guardar en cualquier archivo (cuyo nombre se da en forma de cadena de caracteres) en el que Sage pueda escribir.Utilice "save_session('name')" para guardar todas las variables en un objeto. Utilice "load_session('name')" para mezclar todas las variables de una sesión guardada.Utilice la documentación activa para obtener toda la documentación de Sage en forma "activa". (Sólo se permiten celdas de cálculo nuevas, pulsar el icono.)Utilizar GSSAPI en vez de Bind DN/claveUtilice la mayoría del Software Matemático desde SageUtilice Sage para estudiar cálculo infinitesimal, teoría de números desde elemental a muy avanzada, criptografía, álgebra conmutativa, teoría de grupos, teoría de grafos, álgebra lineal numérica y exacta, etc.Utilice un Lenguaje de Programación de uso ComúnUtilizar un reto para el registro de cuentasUtilice una Alternativa de Fuente AbiertaUsar java para 3-DUsar java para 3-D. Sólo para esta ejecución de la hoja.Utilice el menú Datos para subir imágenes y otros archivos, y crear nuevos archivos que se puedan compartir entre hojas. La variable DATA contiene la ruta a los archivos de datos. Por ejemplo, para abrir un archivo de ese directorio, escribir "open(DATA+'filename')". Si usted ha subido el archivo foo.sage, podrá cargarlo con "load foo.sage"; Si foo.py es un archivo Python, podrá importarlo con "import foo".Indicaciones ÚtilesUsuarioEl usuario '%(user)s' no tiene permiso para ver la página personal de '%(name)s'.Administración de UsuariosUsuarioAtributo de usuario (i.e. cn, uid o userPrincipalName)Error de UsuarioEl usuario está en usoEl nombre de usuario no es válido.El usuario no está en el sistemaUsuario en usoUsuariosVersiónVer un manual de referencia sobre Sage de 4000+ páginasVer un historial de cálculos recientesVer historial de cambios de esta hojaVer textoVer la versión en modo texto de esta hoja¡Bienvenido a Sage! Puede crear una hoja nueva, ver las hojas publicadas, o leer la documentación.¡Bienvenido!¿Cómo quiere llamarlo? (en caso de que sea diferente al nombre original)¿Cuánto es 2 más 3?¿Cuánto es 3 por 8?¿Cuál es el mayor factor primo de 15?Con el Notebook Sage, cualquiera puede crear, colaborar en, y publicar hojas interactivas. En una hoja se puede escribir código de Sage, de Python y de otro software incluido en SageDirectorio de TrabajoHojaLa hoja está bloqueada. No se pueden insertar celdasLa hoja se puede ver públicamente en %(u)sLímites para el procesado de hojasUsuarios del sistema para el procesado de hojas (lista separada por coma)Contraseña erróneaSíPuede publicar su hoja en Internet de modo que cualquiera pueda acceder a ella y visualizarla remotamente.Usted no está autorizado para acceder a esta páginaUsted no está autorizado para acceder a esta hojaPuede añadir o eliminar colaboradores (separe los usuarios con comas)Puede descargar %(f)s o crear un enlace a este archivo en la hoja El servidor no puede evaluar la celda solicitada por alguna razónTrabaje con Sage utilizando el muy reputado lenguaje Python. Podrá escribir programas que combinen matemáticas de verdad con cualquier otra cosa.Su cuenta se encuentra suspendida actualmenteSu combinación navegador / OS no está soportada.\nPor favor, utilice Firefox u Opera bajo Linux, Windows o Mac OS X, o Safari.Se requiere su dirección de e-mail para la confirmación de su cuenta y su recuperación. Le será enviado un e-mail con un enlace de confirmación después de que se registre.Su nueva contraseña es %(key)s Entre en %(url_prefix)s://%(addr)s:%(port)s/ Asegúrese de reiniciar su contraseña entrando en Configuración.Su contraseña debe tener al menos 4 caracteres. Su contraseña no puede contener ni su usuario ni espacios.Su usuario debe comenzar con una letra y tener entre 3 y 64 caracteres. Sólo se puede utilizar letras, números, guiones bajos, @, y puntos.Se asignará una dirección única a su hoja (URL) que podrá enviar a sus amigos y colegas.un archivo en formato ReStructuredText (Añadir ".. escape-backslashes" al archivo para que "\" sea un carácter de escape. Poner el código de latex entre acentos graves "`" o dólares "$" o "$$". El modo matemático no esta soportado por ahora.)una hoja Sageun archivo zip de cualquiera de los anterioresuna página HTML generada por docutils a partir de un archivo en formato ReStructuredTextVer directorioÄeÅ¡tina (ÄŒeská republika)Deutsch (Österreich)English (United States)español (España)evaluarfrançais (France)Intento no permitido de enlaceeditadodejar un comentariocargando...nada que mostraropcionalo borrar %(f)s.o .txt - una hoja en un archivo de texto con html y celdas entre {{{ y }}} que definan una hojaportuguês (Brasil)publicadasreCAPTCHA private keyreCAPTCHA public keyrecaptchaруÑÑкий (РоÑÑиÑ)ejecutandos (cancelando comprobaciones de actualización posteriores).seleccionar hojasimpleel URL de una página de Documentación de Sage, por ejemplo el URL de esta páginaукраїнÑька (Україна)no impresausuarios|sisagenb-1.0.1/sagenb/translations/es_ES/LC_MESSAGES/messages.po000066400000000000000000002745161311436262400237030ustar00rootroot00000000000000# Spanish (Spain) translations for SAGE Notebook. # Copyright (C) 2013 SAGE # This file is distributed under the same license as the SAGE project. # FIRST AUTHOR J. Miguel Farto , 2013, 2014. # #, fuzzy msgid "" msgstr "" "Project-Id-Version: Sage Notebook 0.9.2\n" "Report-Msgid-Bugs-To: migeruhito@gmail.com\n" "POT-Creation-Date: 2014-12-19 22:07+0100\n" "PO-Revision-Date: 2013-02-18 10:24+0100\n" "Last-Translator: J. Miguel Farto \n" "Language-Team: J. Miguel Farto \n" "Plural-Forms: nplurals=2; plural=n != 1\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" "Generated-By: Babel 1.3\n" msgid "ru_RU" msgstr "руÑÑкий (РоÑÑиÑ)" msgid "pt_BR" msgstr "português (Brasil)" msgid "en_US" msgstr "English (United States)" msgid "cs_CZ" msgstr "ÄeÅ¡tina (ÄŒeská republika)" msgid "de_AT" msgstr "Deutsch (Österreich)" msgid "es_ES" msgstr "español (España)" msgid "fr_FR" msgstr "français (France)" msgid "uk_UA" msgstr "українÑька (Україна)" #: sagenb/data/sage/html/accounts/account_recovery.html:3 #: sagenb/data/sage/html/accounts/account_recovery.html:8 msgid "Account Recovery" msgstr "Recuperación de Cuenta" #: sagenb/data/sage/html/accounts/account_recovery.html:9 msgid "" "A new password will be emailed to the email address connected to your " "account. However if you didn't confirm your email address you will be " "unable to recover your account." msgstr "" "Se le enviará una nueva contraseña a su dirección de e-mail. Sin embargo " "no podrá recuperar su cuenta si no ha confirmado su dirección de e-mail." #: sagenb/data/sage/html/accounts/account_recovery.html:16 msgid "Submit" msgstr "Enviar" #: sagenb/data/sage/html/accounts/account_recovery.html:19 #: sagenb/data/sage/html/accounts/registration.html:83 #: sagenb/data/sage/html/notebook/download_or_delete_datafile.html:54 #: sagenb/data/sage/html/notebook/edit_window.html:12 #: sagenb/data/sage/html/settings/account_settings.html:10 #: sagenb/data/sage/html/settings/account_settings.html:67 #: sagenb/data/sage/html/settings/admin_add_user.html:25 #: sagenb/data/sage/html/settings/notebook_settings.html:20 #: sagenb/data/sage/html/settings/notebook_settings.html:27 msgid "Cancel" msgstr "Cancelar" #: sagenb/data/sage/html/accounts/registration.html:3 msgid "Sign up" msgstr "Registrarse" #: sagenb/data/sage/html/accounts/registration.html:9 msgid "Sign up for a Sage Notebook account" msgstr "Registrase para una cuenta de Notebook Sage" #: sagenb/data/sage/html/accounts/registration.html:16 msgid "Create a username" msgstr "Crear un usuario" #: sagenb/data/sage/html/accounts/registration.html:17 msgid "" "Your username must start with a letter and be between 3 and 64 characters" " long. You may only use letters, numbers, underscores, @, and dots." msgstr "" "Su usuario debe comenzar con una letra y tener entre 3 y 64 caracteres. " "Sólo se puede utilizar letras, números, guiones bajos, @, y puntos." #: sagenb/data/sage/html/accounts/registration.html:22 msgid "No username given" msgstr "No se ha proporcionado un usuario" #: sagenb/data/sage/html/accounts/registration.html:25 msgid "Username already in use" msgstr "El usuario está en uso" #: sagenb/data/sage/html/accounts/registration.html:28 msgid "Bad username" msgstr "Usuario incorrecto" #: sagenb/data/sage/html/accounts/registration.html:32 msgid "Create a good password" msgstr "Cree una contraseña robusta" #: sagenb/data/sage/html/accounts/registration.html:34 msgid "" "Your password must have at least 4 characters. Your password can not " "contain your username or spaces." msgstr "" "Su contraseña debe tener al menos 4 caracteres. Su contraseña no puede " "contener ni su usuario ni espacios." #: sagenb/data/sage/html/accounts/registration.html:39 msgid "No password given" msgstr "No se ha proporcionado una contraseña" #: sagenb/data/sage/html/accounts/registration.html:42 msgid "Bad password" msgstr "Contraseña incorrecta" #: sagenb/data/sage/html/accounts/registration.html:46 msgid "Re-type your password" msgstr "Vuelva a introducir su contraseña" #: sagenb/data/sage/html/accounts/registration.html:49 msgid "Passwords didn't match" msgstr "Las contraseñas no coinciden" #: sagenb/data/sage/html/accounts/registration.html:54 msgid "Enter your email address" msgstr "Introduzca su dirección de e-mail" #: sagenb/data/sage/html/accounts/registration.html:56 msgid "" "Your email address is required for account confirmation and recovery. You" " will be emailed a confirmation link right after you successfully sign " "up." msgstr "" "Se requiere su dirección de e-mail para la confirmación de su cuenta y su" " recuperación. Le será enviado un e-mail con un enlace de confirmación " "después de que se registre." #: sagenb/data/sage/html/accounts/registration.html:62 msgid "No email address given" msgstr "No se ha proporcionado una dirección de e-mail" #: sagenb/data/sage/html/accounts/registration.html:65 msgid "Invalid email address" msgstr "Dirección de e-mail no válida" #: sagenb/data/sage/html/accounts/registration.html:71 msgid "Answer a challenge" msgstr "Conteste un reto" #: sagenb/data/sage/html/accounts/registration.html:74 msgid "No challenge response given" msgstr "No se ha proporcionado contestación al reto" #: sagenb/data/sage/html/accounts/registration.html:77 msgid "Invalid challenge response" msgstr "Contestación al reto inválida" #: sagenb/data/sage/html/accounts/registration.html:82 msgid "Create account" msgstr "Crear cuenta" #: sagenb/data/sage/html/base.html:33 sagenb/data/sage/html/login.html:35 msgid "The Sage Notebook" msgstr "Notebook Sage" #: sagenb/data/sage/html/base.html:35 msgid "Searching for Sage server..." msgstr "Buscando el servidor Sage..." #: sagenb/data/sage/html/base.html:37 msgid "Version" msgstr "Versión" #: sagenb/data/sage/html/base_authenticated.html:7 msgid "Please log in to the Sage notebook" msgstr "Por favor entre en el Notebook Sage " #: sagenb/data/sage/html/base_authenticated.html:7 msgid "Log in" msgstr "Entrar" #: sagenb/data/sage/html/base_authenticated.html:9 msgid "Toggle the top bar" msgstr "Ocultar/Mostrar la barra superior" #: sagenb/data/sage/html/base_authenticated.html:9 #: sagenb/data/sage/html/test_report.html:123 msgid "Toggle" msgstr "Ocultar/Mostrar" #: sagenb/data/sage/html/base_authenticated.html:10 msgid "Back to your personal worksheet list" msgstr "Volver a su lista personal de hojas" #: sagenb/data/sage/html/base_authenticated.html:10 msgid "Home" msgstr "Inicio" #: sagenb/data/sage/html/base_authenticated.html:12 #: sagenb/data/sage/html/base_authenticated.html:14 msgid "Published" msgstr "Publicadas" #: sagenb/data/sage/html/base_authenticated.html:14 msgid "Browse the published worksheets" msgstr "Revisar las hojas publicadas" #: sagenb/data/sage/html/base_authenticated.html:15 msgid "View a log of recent computations" msgstr "Ver un historial de cálculos recientes" #: sagenb/data/sage/html/base_authenticated.html:15 #: sagenb/flask_version/base.py:214 msgid "Log" msgstr "Historial" #: sagenb/data/sage/html/base_authenticated.html:17 msgid "Change account settings including password" msgstr "Cambiar la configuración de la cuenta, incluyendo la contraseña" #: sagenb/data/sage/html/base_authenticated.html:17 msgid "Settings" msgstr "Configuración" #: sagenb/data/sage/html/base_authenticated.html:18 msgid "Documentation" msgstr "Documentación" #: sagenb/data/sage/html/base_authenticated.html:18 msgid "Help" msgstr "Ayuda" #: sagenb/data/sage/html/base_authenticated.html:19 msgid "Report a problem or submit a bug to improve Sage" msgstr "Informar de un problema o enviar un error para mejorar Sage" #: sagenb/data/sage/html/base_authenticated.html:19 msgid "Report a Problem" msgstr "Informar de un problema" #: sagenb/data/sage/html/base_authenticated.html:20 msgid "Log out of the Sage notebook" msgstr "Salir del Notebook Sage" #: sagenb/data/sage/html/base_authenticated.html:20 msgid "Sign out" msgstr "Salir" #: sagenb/data/sage/html/docs.html:3 msgid "Sage Documentation" msgstr "Documentación de Sage" #: sagenb/data/sage/html/docs.html:15 msgid "To quickly try out Sage start here" msgstr "Comenzar aquí para probar Sage inmediatamente" #: sagenb/data/sage/html/docs.html:15 msgid "Tutorial" msgstr "Tutorial" #: sagenb/data/sage/html/docs.html:16 msgid "Explore a collection of in-depth tutorials on specific topics" msgstr "Explorar una colección de tutoriales avanzados sobre materias específicas" #: sagenb/data/sage/html/docs.html:16 msgid "Thematic Tutorials" msgstr "Tutoriales temáticos" #: sagenb/data/sage/html/docs.html:17 msgid "View a 4000+ page reference manual about Sage" msgstr "Ver un manual de referencia sobre Sage de 4000+ páginas" #: sagenb/data/sage/html/docs.html:17 msgid "Reference Manual" msgstr "Manual de Referencia" #: sagenb/data/sage/html/docs.html:18 msgid "Learn to write Sage programs" msgstr "Aprender a escribir programas en Sage" #: sagenb/data/sage/html/docs.html:18 msgid "Developer Guide" msgstr "Guía del desarrollador" #: sagenb/data/sage/html/docs.html:19 msgid "How do I construct ... in Sage?" msgstr "¿Cómo construir ... en Sage?" #: sagenb/data/sage/html/docs.html:19 msgid "Constructions" msgstr "Construcciones" #: sagenb/data/sage/html/docs.html:22 msgid "Static version..." msgstr "Versión estática..." #: sagenb/data/sage/html/docs.html:22 msgid "Fast Static Versions of the Documentation" msgstr "Versiones estáticas de la documentación" #: sagenb/data/sage/html/docs.html:23 msgid "Help via Internet Chat (IRC)" msgstr "Ayuda vía IRC" #: sagenb/data/sage/html/docs.html:29 msgid "How to use the Sage Notebook" msgstr "Cómo usar el Notebook Sage" #: sagenb/data/sage/html/docs.html:31 msgid "A worksheet is an ordered list of Sage calculations with output." msgstr "" "Una hoja es una lista ordenada de cálculos en Sage con " "resultados." #: sagenb/data/sage/html/docs.html:32 msgid "A session is a worksheet and a set of variables in some state." msgstr "" "Una sesión es una hoja y un conjunto de variables con algún " "estado." #: sagenb/data/sage/html/docs.html:33 msgid "" "The Sage notebook is a collection of worksheets, saved objects, " "and user information." msgstr "" "El Notebook sage es una colección de hojas, objetos grabados e " "información del usuario." #: sagenb/data/sage/html/docs.html:46 msgid "" "The Sage Notebook was primarily written by William Stein with substantial" " contributions from Tom Boothby, Timothy Clemans, Alex Clemesha, Mike " "Hansen, Bobby Moretti, Yi Qiang, and Dorian Raymer." msgstr "" "El Notebook Sage fue escrito principalmente por William Stein con " "contribuciones sustanciales de Tom Boothby, Timothy Clemans, Alex " "Clemesha, Mike Hansen, Bobby Moretti, Yi Qiang, y Dorian Raymer." #: sagenb/data/sage/html/error_message.html:4 #: sagenb/data/sage/html/login.html:69 sagenb/data/sage/html/login.html:76 #: sagenb/data/sage/html/login.html:108 sagenb/data/sage/html/login.html:110 #: sagenb/data/sage/html/recaptcha.html:27 #: sagenb/data/sage/html/test_report.html:112 #: sagenb/data/sage/html/test_report.html:131 #: sagenb/data/sage/html/accounts/registration.html:22 #: sagenb/data/sage/html/accounts/registration.html:25 #: sagenb/data/sage/html/accounts/registration.html:28 #: sagenb/data/sage/html/accounts/registration.html:39 #: sagenb/data/sage/html/accounts/registration.html:42 #: sagenb/data/sage/html/accounts/registration.html:49 #: sagenb/data/sage/html/accounts/registration.html:62 #: sagenb/data/sage/html/accounts/registration.html:65 #: sagenb/data/sage/html/accounts/registration.html:74 #: sagenb/data/sage/html/accounts/registration.html:77 #: sagenb/data/sage/html/settings/admin_add_user.html:14 #: sagenb/data/sage/html/settings/admin_add_user.html:16 #: sagenb/data/sage/html/settings/admin_add_user.html:18 #: sagenb/data/sage/js/localization.js:21 #: sagenb/flask_version/worksheet.py:640 msgid "Error" msgstr "Error" #: sagenb/data/sage/html/error_message.html:19 msgid "Continue" msgstr "Continuar" #: sagenb/data/sage/html/history.html:3 #, python-format msgid "Sage: History for %(u)s" msgstr "Sage: Historial para %(u)s" #: sagenb/data/sage/html/history.html:13 msgid "Click here to turn the above into a Sage worksheet" msgstr "Pulsar aquí para convertir lo anterior en una hoja de Sage" #: sagenb/data/sage/html/history.html:13 msgid "" "Create a new Sage worksheet version of the last 100 commands in the above" " log." msgstr "" "Crear una hoja de Sage nueva con los 100 últimos comandos del historial " "anterior." #: sagenb/data/sage/html/login.html:12 msgid "username" msgstr "usuario" #: sagenb/data/sage/html/login.html:13 msgid "Select an OpenID provider" msgstr "Elegir un proveedor de OpenID" #: sagenb/data/sage/html/login.html:14 msgid "Send" msgstr "Enviar" #: sagenb/data/sage/html/login.html:22 sagenb/data/sage/html/login.html:81 msgid "Sign in" msgstr "Entrar" #: sagenb/data/sage/html/login.html:28 #, python-format msgid "Congratulations %(u)s! You can now sign into the Sage Notebook." msgstr "¡Enhorabuena %(u)s! Ahora puede entrar en el Notebook Sage." #: sagenb/data/sage/html/login.html:32 msgid "Welcome!" msgstr "¡Bienvenido!" #: sagenb/data/sage/html/login.html:33 msgid "Sage is a different approach to mathematics software." msgstr "" "Sage presenta un enfoque diferente del software para " "matemáticas." #: sagenb/data/sage/html/login.html:36 msgid "" "With the Sage Notebook anyone can create, collaborate on, and publish " "interactive worksheets. In a worksheet, one can write code using Sage, " "Python, and other software included in Sage." msgstr "" "Con el Notebook Sage, cualquiera puede crear, colaborar en, y publicar " "hojas interactivas. En una hoja se puede escribir código de Sage, de " "Python y de otro software incluido en Sage" #: sagenb/data/sage/html/login.html:39 msgid "General and Advanced Pure and Applied Mathematics" msgstr "Matemática General y Avanzada, Pura y Aplicada" #: sagenb/data/sage/html/login.html:40 msgid "" "Use Sage for studying calculus, elementary to very advanced number " "theory, cryptography, commutative algebra, group theory, graph theory, " "numerical and exact linear algebra, and more." msgstr "" "Utilice Sage para estudiar cálculo infinitesimal, teoría de números desde" " elemental a muy avanzada, criptografía, álgebra conmutativa, teoría de " "grupos, teoría de grafos, álgebra lineal numérica y exacta, etc." #: sagenb/data/sage/html/login.html:43 msgid "Use an Open Source Alternative" msgstr "Utilice una Alternativa de Fuente Abierta" #: sagenb/data/sage/html/login.html:44 msgid "" "By using Sage you help to support a viable open source alternative to " "Magma, Maple, Mathematica, and MATLAB. Sage includes many high-quality " "open source math packages." msgstr "" "Cuando utiliza Sage, ayuda a mantener una alternativa viable de fuente " "abierta a Magma, Maple, Mathematica y MATLAB. Sage incluye muchos " "paquetes matemáticos de fuente abierta y alta calidad." #: sagenb/data/sage/html/login.html:47 msgid "Use Most Mathematics Software from Within Sage" msgstr "Utilice la mayoría del Software Matemático desde Sage" #: sagenb/data/sage/html/login.html:48 msgid "" "Sage makes it easy for you to use most mathematics software together. " "Sage includes GAP, GP/PARI, Maxima, and Singular, and dozens of other " "open packages." msgstr "" "Con Sage usted puede utilizar fácilmente la mayoría del software " "matemático. Sage incluye GAP, GP/PARI, Maxima y Singular, y otros muchos " "paquetes de fuente abierta." #: sagenb/data/sage/html/login.html:51 msgid "Use a Mainstream Programming Language" msgstr "Utilice un Lenguaje de Programación de uso Común" #: sagenb/data/sage/html/login.html:52 msgid "" "You work with Sage using the highly regarded scripting language Python. " "You can write programs that combine serious mathematics with anything " "else." msgstr "" "Trabaje con Sage utilizando el muy reputado lenguaje Python. Podrá " "escribir programas que combinen matemáticas de verdad con cualquier otra " "cosa." #: sagenb/data/sage/html/login.html:55 msgid "Acknowledgement" msgstr "Agradecimientos" #: sagenb/data/sage/html/login.html:56 msgid "" "The Sage Notebook is based upon work supported by the National Science " "Foundation under grants DMS-0821725, DMS-1020378, DMS-0713225, " "DMS-0555776, DMS-0545904, DMS-0838212, DMS-0757627, DUE-1020378, " "DUE-1022574, DMS-1015114, etc. Any opinions, findings, and conclusions" " or recommendations expressed in this material are those of the author(s)" " and do not necessarily reflect the views of the National Science " "Foundation. See also http://sagemath.org/development-ack.html." msgstr "" "El Notebook Sage está basado en trabajos financiados por The National " "Science Foundation bajo los proyectos DMS-0821725, DMS-1020378, " "DMS-0713225, DMS-0555776, DMS-0545904, DMS-0838212, DMS-0757627, " "DUE-1020378, DUE-1022574, DMS-1015114, etc. Cualesquiera opiniones, " "investigaciones, y conclusiones o recomendaciones expresadas en este " "material son del autor(es), no reflejan necesariamente los puntos de " "vista de The National Science Foundation. Ver también http://sagemath.org" "/development-ack.html." #: sagenb/data/sage/html/login.html:63 #, python-format msgid "Sign into the Sage Notebook v%(v)s" msgstr "Entra en el notebook Sage v%(v)s" #: sagenb/data/sage/html/login.html:66 #: sagenb/data/sage/html/accounts/account_recovery.html:13 msgid "Username" msgstr "Usuario" #: sagenb/data/sage/html/login.html:69 msgid "Username is not in the system" msgstr "El usuario no está en el sistema" #: sagenb/data/sage/html/login.html:73 #: sagenb/data/sage/html/settings/user_management.html:15 msgid "Password" msgstr "Contraseña" #: sagenb/data/sage/html/login.html:76 msgid "Wrong password" msgstr "Contraseña errónea" #: sagenb/data/sage/html/login.html:86 msgid "Sign up for a new Sage Notebook account" msgstr "Abrir una cuenta nueva en el Notebook de Sage" #: sagenb/data/sage/html/login.html:90 msgid "Browse published Sage worksheets
    (no login required)" msgstr "Ver las hojas de Sage publicadas
    (no se requiere entrar)" #: sagenb/data/sage/html/login.html:94 msgid "Forgot password" msgstr "Olvidar la contraseña" #: sagenb/data/sage/html/login.html:108 msgid "Creating new users is disabled by the administrator." msgstr "El administrador ha desactivado la creación de usuarios nuevos." #: sagenb/data/sage/html/login.html:110 msgid "Javascript must be enabled in order to use the Sage Notebook." msgstr "Para utilizar el Notebook Sage se debe activar Javascript" #: sagenb/data/sage/html/notebook/afterpublish_window.html:8 #, python-format msgid "" "Worksheet is publicly viewable at %(u)s" msgstr "" "La hoja se puede ver públicamente en %(u)s" #: sagenb/data/sage/html/notebook/afterpublish_window.html:9 #, python-format msgid "Published on %(t)s" msgstr "Publicado en %(t)s" #: sagenb/data/sage/html/notebook/afterpublish_window.html:11 msgid "Re-publish worksheet" msgstr "Hoja re-publicada" #: sagenb/data/sage/html/notebook/afterpublish_window.html:12 msgid "Stop publishing" msgstr "Dejar de publicar" #: sagenb/data/sage/html/notebook/afterpublish_window.html:14 #: sagenb/data/sage/html/notebook/beforepublish_window.html:18 msgid "Automatically re-publish when changes are made and saved" msgstr "Re-publicar automáticamente cuando se realicen cambios y sean " "guardados" #: sagenb/data/sage/html/notebook/base.html:82 msgid "Click to rename this worksheet" msgstr "Pulsar para renombrar esta hoja" #: sagenb/data/sage/html/notebook/base.html:85 msgid "last edited" msgstr "editado" #: sagenb/data/sage/html/notebook/base.html:87 msgid "Someone else is viewing this worksheet" msgstr "Alguien más está viendo esta hoja" #: sagenb/data/sage/html/notebook/base.html:92 msgid "Save changes and close window" msgstr "Guardar cambios y cerrar" #: sagenb/data/sage/html/notebook/base.html:92 msgid "Save & quit" msgstr "Guardar y salir" #: sagenb/data/sage/html/notebook/base.html:92 msgid "Discard changes to this worksheet" msgstr "Descartar los cambios en esta hoja" #: sagenb/data/sage/html/notebook/base.html:92 msgid "Discard & quit" msgstr "Descartar y Salir" #: sagenb/data/sage/html/notebook/base.html:92 #: sagenb/data/sage/html/notebook/text_cell.html:56 msgid "Save changes" msgstr "Guardar cambios" #: sagenb/data/sage/html/notebook/base.html:92 #: sagenb/data/sage/html/settings/account_settings.html:9 #: sagenb/data/sage/html/settings/account_settings.html:66 #: sagenb/data/sage/html/settings/notebook_settings.html:19 #: sagenb/data/sage/html/settings/notebook_settings.html:26 msgid "Save" msgstr "Guardar" #: sagenb/data/sage/html/notebook/base.html:99 msgid "Select a file related function" msgstr "Seleccionar una función de archivos" #: sagenb/data/sage/html/notebook/base.html:99 msgid "File..." msgstr "Archivos..." #: sagenb/data/sage/html/notebook/base.html:100 msgid "Load a new worksheet stored in a file" msgstr "Carga una hoja nueva guardada en un archivo" #: sagenb/data/sage/html/notebook/base.html:100 msgid "Load worksheet from a file..." msgstr "Cargar hoja de archivo..." #: sagenb/data/sage/html/notebook/base.html:101 msgid "Create a new worksheet" msgstr "Crear una hoja nueva" #: sagenb/data/sage/html/notebook/base.html:101 msgid "New worksheet" msgstr "Hoja nueva" #: sagenb/data/sage/html/notebook/base.html:102 msgid "Save this worksheet to an sws file" msgstr "Guardar esta hoja en un archivo sws" #: sagenb/data/sage/html/notebook/base.html:102 msgid "Save worksheet to a file..." msgstr "Guardar esta hoja en un archivo..." #: sagenb/data/sage/html/notebook/base.html:103 #: sagenb/data/sage/html/notebook/base.html:158 msgid "Print this worksheet" msgstr "Imprimir esta hoja" #: sagenb/data/sage/html/notebook/base.html:103 #: sagenb/data/sage/html/notebook/base.html:158 msgid "Print" msgstr "Imprimir" #: sagenb/data/sage/html/notebook/base.html:104 msgid "Rename this worksheet" msgstr "Cambiar el nombre de esta hoja" #: sagenb/data/sage/html/notebook/base.html:104 #: sagenb/data/sage/js/localization.js:15 msgid "Rename worksheet" msgstr "Renombrar hoja" #: sagenb/data/sage/html/notebook/base.html:105 msgid "Copy this worksheet" msgstr "Copiar esta hoja" #: sagenb/data/sage/html/notebook/base.html:105 msgid "Copy worksheet" msgstr "Copiar hoja" #: sagenb/data/sage/html/notebook/base.html:106 msgid "Move this worksheet to the trash" msgstr "Enviar esta hoja a la papelera" #: sagenb/data/sage/html/notebook/base.html:106 msgid "Delete worksheet" msgstr "Borrar hoja" #: sagenb/data/sage/html/notebook/base.html:110 msgid "Select a worksheet function" msgstr "Seleccionar una función de hoja" #: sagenb/data/sage/html/notebook/base.html:110 msgid "Action..." msgstr "Acción..." #: sagenb/data/sage/html/notebook/base.html:111 msgid "Interrupt currently running calculations, if possible" msgstr "Interrumpir los cálculos en curso si es posible" #: sagenb/data/sage/html/notebook/base.html:111 msgid "Interrupt" msgstr "Interrumpir" #: sagenb/data/sage/html/notebook/base.html:112 msgid "Restart the worksheet process" msgstr "Reiniciar el proceso de la hoja" #: sagenb/data/sage/html/notebook/base.html:112 msgid "Restart worksheet" msgstr "Reiniciar hoja" #: sagenb/data/sage/html/notebook/base.html:113 msgid "Quit the worksheet process" msgstr "Salir del proceso de la hoja" #: sagenb/data/sage/html/notebook/base.html:113 msgid "Save and quit worksheet" msgstr "Salir y guardar hoja" #: sagenb/data/sage/html/notebook/base.html:115 msgid "Evaluate all input cells in the worksheet" msgstr "Evaluar todas las celdas de entrada de la hoja" #: sagenb/data/sage/html/notebook/base.html:115 msgid "Evaluate All" msgstr "Evaluar todo" #: sagenb/data/sage/html/notebook/base.html:116 msgid "Hide all output" msgstr "Ocultar todos los resultados" #: sagenb/data/sage/html/notebook/base.html:116 msgid "Hide All Output" msgstr "Ocultar Resultados" #: sagenb/data/sage/html/notebook/base.html:117 msgid "Show all output" msgstr "Mostrar todos los resultados" #: sagenb/data/sage/html/notebook/base.html:117 msgid "Show All Output" msgstr "Mostrar Resultados" #: sagenb/data/sage/html/notebook/base.html:118 msgid "Delete all output" msgstr "Borrar todos los resultados" #: sagenb/data/sage/html/notebook/base.html:118 msgid "Delete All Output" msgstr "Borrar Resultados" #: sagenb/data/sage/html/notebook/base.html:120 msgid "Switch to single-cell mode" msgstr "Cambiar a modo de celda única" #: sagenb/data/sage/html/notebook/base.html:120 msgid "One Cell Mode" msgstr "Modo de Celda Única" #: sagenb/data/sage/html/notebook/base.html:121 msgid "Switch to multi-cell mode" msgstr "Cambiar a modo multi-celda" #: sagenb/data/sage/html/notebook/base.html:121 msgid "Multi Cell Mode" msgstr "Modo Multi-Celda" #: sagenb/data/sage/html/notebook/base.html:124 msgid "Select an attached file" msgstr "Seleccionar un archivo adjunto" #: sagenb/data/sage/html/notebook/base.html:124 msgid "Data..." msgstr "Datos..." #: sagenb/data/sage/html/notebook/base.html:125 msgid "Upload or create a data file in a wide range of formats" msgstr "Subir o crear un archivo de datos en múltiples formatos" #: sagenb/data/sage/html/notebook/base.html:125 msgid "Upload or create file..." msgstr "Subir o crear archivo..." #: sagenb/data/sage/html/notebook/base.html:135 #, python-format msgid "Evaluate all input cells using %(i)s" msgstr "Evaluar todas las celdas de entrada utilizando %(i)s" #: sagenb/data/sage/html/notebook/base.html:141 msgid "Enable/disable pretty_printing" msgstr "Activar/desactivar impresión avanzada" #: sagenb/data/sage/html/notebook/base.html:143 msgid "Typeset" msgstr "Tipografía avanzada" #: sagenb/data/sage/html/notebook/base.html:144 msgid "Load 3-D Live. Not recommended for worksheets with > 2 3-D Plots." msgstr "Cargar 3-D Live. No se recomienda para hojas con más de 2 gráficas 3-D." #: sagenb/data/sage/html/notebook/base.html:146 msgid "Load 3-D Live" msgstr "Cargar 3-D Live" #: sagenb/data/sage/html/notebook/base.html:147 msgid "Use java for 3-D. Only applies to this running of worksheet." msgstr "Usar java para 3-D. Sólo para esta ejecución de la hoja." #: sagenb/data/sage/html/notebook/base.html:149 msgid "Use java for 3-D" msgstr "Usar java para 3-D" #: sagenb/data/sage/html/notebook/base.html:159 msgid "Interactively use this worksheet" msgstr "Utilizar esta hoja en modo interactivo" #: sagenb/data/sage/html/notebook/base.html:159 msgid "Worksheet" msgstr "Hoja" #: sagenb/data/sage/html/notebook/base.html:160 msgid "Edit text version of this worksheet" msgstr "Editar la versión de texto de esta hoja" #: sagenb/data/sage/html/notebook/base.html:160 msgid "Edit" msgstr "Editar" #: sagenb/data/sage/html/notebook/base.html:161 msgid "View plain text version of this worksheet" msgstr "Ver la versión en modo texto de esta hoja" #: sagenb/data/sage/html/notebook/base.html:161 msgid "Text" msgstr "Texto" #: sagenb/data/sage/html/notebook/base.html:162 msgid "View changes to this worksheet over time" msgstr "Ver historial de cambios de esta hoja" #: sagenb/data/sage/html/notebook/base.html:162 msgid "Revisions" msgstr "Revisiones" #: sagenb/data/sage/html/notebook/base.html:163 msgid "Let others edit this worksheet" msgstr "Permitir que otros editen esta hoja" #: sagenb/data/sage/html/notebook/base.html:163 msgid "Share" msgstr "Compartir" #: sagenb/data/sage/html/notebook/base.html:164 msgid "Make this worksheet publicly viewable" msgstr "Permitir que esta hoja se pueda ver públicamente" #: sagenb/data/sage/html/notebook/base.html:164 msgid "Publish" msgstr "Publicar" #: sagenb/data/sage/html/notebook/base.html:172 msgid "Exit" msgstr "Salir" #: sagenb/data/sage/html/notebook/beforepublish_window.html:5 msgid "" "You can publish your worksheet to the Internet, where anyone will be able" " to access and view it online." msgstr "" "Puede publicar su hoja en Internet de modo que cualquiera pueda acceder a" " ella y visualizarla remotamente." #: sagenb/data/sage/html/notebook/beforepublish_window.html:7 msgid "" "Your worksheet will be assigned a unique address (URL) that you can send " "to your friends and colleagues." msgstr "" "Se asignará una dirección única a su hoja (URL) que podrá enviar a sus " "amigos y colegas." #: sagenb/data/sage/html/notebook/beforepublish_window.html:9 msgid "Do you want to publish this worksheet?" msgstr "¿Quiere publicar esta hoja?" #: sagenb/data/sage/html/notebook/beforepublish_window.html:14 msgid "Yes" msgstr "Sí" #: sagenb/data/sage/html/notebook/beforepublish_window.html:15 msgid "No" msgstr "No" #: sagenb/data/sage/html/notebook/cell.html:35 #: sagenb/data/sage/html/notebook/text_cell.html:19 #: sagenb/data/sage/html/notebook/worksheet_page.html:21 msgid "Click to insert new compute cell." msgstr "Pulsar para insertar un nueva celda de cálculo." #: sagenb/data/sage/html/notebook/cell.html:39 #: sagenb/data/sage/html/notebook/text_cell.html:22 #: sagenb/data/sage/html/notebook/worksheet_page.html:25 msgid "Click to insert new rich-text cell." msgstr "Pulsar para insertar una nueva celda de texto." #: sagenb/data/sage/html/notebook/cell.html:90 msgid "Click here or press shift-return to evaluate" msgstr "Pulsar aquí o teclear mayúsculas-entrar para evaluar" #: sagenb/data/sage/html/notebook/cell.html:91 msgid "evaluate" msgstr "evaluar" #: sagenb/data/sage/html/notebook/download_or_delete_datafile.html:35 msgid "Data file" msgstr "Archivo de datos" #: sagenb/data/sage/html/notebook/download_or_delete_datafile.html:39 #, python-format msgid "" "You may download %(f)s or create a link to this " "file in worksheet " msgstr "" "Puede descargar %(f)s o crear un enlace a este " "archivo en la hoja " #: sagenb/data/sage/html/notebook/download_or_delete_datafile.html:40 msgid "select worksheet" msgstr "seleccionar hoja" #: sagenb/data/sage/html/notebook/download_or_delete_datafile.html:44 #, python-format msgid "" "or delete " "%(f)s." msgstr "" "o borrar " "%(f)s." #: sagenb/data/sage/html/notebook/download_or_delete_datafile.html:46 #, python-format msgid "" "Access %(f)s in this worksheet by typing DATA+'%(f)s'. Here DATA" " is a special variable that gives the exact path to all data files " "uploaded to this worksheet." msgstr "" "Acceda a %(f)s en esta hoja escribiendo DATA+'%(f)s'. Aquí DATA " "es una variable especial que proporciona la ruta exacta a todos los " "archivos de datos subidos a esta hoja." #: sagenb/data/sage/html/notebook/download_or_delete_datafile.html:54 #: sagenb/data/sage/html/notebook/edit_window.html:11 msgid "Save Changes" msgstr "Guardar Cambios" #: sagenb/data/sage/html/notebook/edit_window.html:10 msgid "Edit plain text" msgstr "Editar texto" #: sagenb/data/sage/html/notebook/guest_worksheet_page.html:20 msgid "Edit this." msgstr "Editar esto" #: sagenb/data/sage/html/notebook/guest_worksheet_page.html:23 msgid "Log in to edit a copy." msgstr "Entrar para editar una copia" #: sagenb/data/sage/html/notebook/guest_worksheet_page.html:26 msgid "Edit a copy." msgstr "Editar una copia" #: sagenb/data/sage/html/notebook/guest_worksheet_page.html:39 msgid "Download." msgstr "Descargar." #: sagenb/data/sage/html/notebook/guest_worksheet_page.html:45 #, python-format msgid "This page is rated %(wr).1f." msgstr "Esta página tiene la puntuación %(wr).1f." #: sagenb/data/sage/html/notebook/guest_worksheet_page.html:54 msgid "leave a comment" msgstr "dejar un comentario" #: sagenb/data/sage/html/notebook/guest_worksheet_page.html:55 msgid "Rerate" msgstr "Re-puntuar" #: sagenb/data/sage/html/notebook/guest_worksheet_page.html:55 msgid "Rate" msgstr "Puntuación" #: sagenb/data/sage/html/notebook/guest_worksheet_page.html:59 msgid "Other published documents..." msgstr "Otros documentos publicados..." #: sagenb/data/sage/html/notebook/plain_text_window.html:4 msgid "View plain text" msgstr "Ver texto" #: sagenb/data/sage/html/notebook/specific_revision.html:5 #, python-format msgid "Revision from %(ta)s ago" msgstr "Revisión desde hace %(ta)s" #: sagenb/data/sage/html/notebook/specific_revision.html:5 msgid "Revision List" msgstr "Lista de Revisiones" #: sagenb/data/sage/html/notebook/specific_revision.html:12 msgid "Older" msgstr "Anterior" #: sagenb/data/sage/html/notebook/specific_revision.html:14 msgid "Oldest" msgstr "La más antigua" #: sagenb/data/sage/html/notebook/specific_revision.html:18 msgid "Newer" msgstr "Posterior" #: sagenb/data/sage/html/notebook/specific_revision.html:20 msgid "Newest" msgstr "La más nueva" #: sagenb/data/sage/html/notebook/specific_revision.html:23 msgid "Revert to this one" msgstr "Revertir a esta" #: sagenb/data/sage/html/notebook/specific_revision.html:23 msgid "(note that images are not recorded)" msgstr "(observar que las imágenes no se han guardado)" #: sagenb/data/sage/html/notebook/specific_revision.html:24 msgid "Publish this one" msgstr "Publicar esta" #: sagenb/data/sage/html/notebook/text_cell.html:57 msgid "Cancel changes" msgstr "Cancelar cambios" #: sagenb/data/sage/html/notebook/upload_data_window.html:7 #, python-format msgid "Upload or Create Data File to attach to worksheet \"%(wn)s\"" msgstr "Subir o Crear Archivo de datos para adjuntar a la hoja \"%(wn)s\"" #: sagenb/data/sage/html/notebook/upload_data_window.html:19 msgid "Or enter the URL of a file on the web:" msgstr "O introducir el URL de un archivo en la web:" #: sagenb/data/sage/html/notebook/upload_data_window.html:23 msgid "Or enter the name of a new file, which will be created:" msgstr "O introducir el nombre de un archivo nuevo que será creado:" #: sagenb/data/sage/html/notebook/upload_data_window.html:30 msgid "Upload or Create Data File" msgstr "Subir o Crear Archivo de Datos" #: sagenb/data/sage/html/notebook/worksheet_page.html:40 #: sagenb/flask_version/worksheet.py:81 sagenb/flask_version/worksheet.py:1029 #: sagenb/notebook/misc.py:237 sagenb/notebook/worksheet.py:725 #: sagenb/notebook/worksheet.py:746 sagenb/notebook/worksheet.py:4345 msgid "Untitled" msgstr "Sin título" #: sagenb/data/sage/html/notebook/worksheet_revision_list.html:6 msgid "Revision History -- List of Snapshots" msgstr "Historial de revisiones -- Lista de sesiones guardadas" #: sagenb/data/sage/html/notebook/worksheet_revision_list.html:15 msgid "Revision" msgstr "Revisión" #: sagenb/data/sage/html/notebook/worksheet_revision_list.html:22 #, python-format msgid "Revision %(lr)s" msgstr "Revisión %(lr)s" #: sagenb/data/sage/html/notebook/worksheet_share.html:10 msgid "Share this document" msgstr "Compartir este documento" #: sagenb/data/sage/html/notebook/worksheet_share.html:17 msgid "" "Only the owner of a worksheet is allowed to share it. You can do whatever" " you want if you make your own copy." msgstr "" "Sólo se permite compartir una hoja a su propietario. Usted podrá hacer lo" " que desee si realiza su propia copia." #: sagenb/data/sage/html/notebook/worksheet_share.html:19 msgid "" "This Sage Worksheet is currently shared with the people listed in the box" " below." msgstr "" "Se ha compartido la hoja de Sage con los usuarios que figuran en el " "recuadro de abajo." #: sagenb/data/sage/html/notebook/worksheet_share.html:20 msgid "You may add or remove collaborators (separate user names by commas)." msgstr "Puede añadir o eliminar colaboradores (separe los usuarios con comas)" #: sagenb/data/sage/html/notebook/worksheet_share.html:24 msgid "Give access to your worksheet to the above collaborators" msgstr "Dar acceso a su hoja a los colaboradores anteriores" #: sagenb/data/sage/html/notebook/worksheet_share.html:24 msgid "Update Collaborators" msgstr "Actualizar colaboradores" #: sagenb/data/sage/html/settings/account_settings.html:3 #: sagenb/data/sage/html/settings/base.html:13 msgid "Account Settings" msgstr "Configurar Cuenta" #: sagenb/data/sage/html/settings/account_settings.html:13 msgid "Change Auto-Save Interval" msgstr "Cambiar el intervalo de auto-guardado" #: sagenb/data/sage/html/settings/account_settings.html:15 msgid "Minutes" msgstr "Minutos" #: sagenb/data/sage/html/settings/account_settings.html:25 msgid "Change Password" msgstr "Cambiar la Contraseña" #: sagenb/data/sage/html/settings/account_settings.html:31 msgid "Old password" msgstr "Contraseña anterior" #: sagenb/data/sage/html/settings/account_settings.html:35 msgid "New password" msgstr "Contraseña Nueva" #: sagenb/data/sage/html/settings/account_settings.html:39 msgid "Retype new password" msgstr "Volver a introducir la nueva contraseña" #: sagenb/data/sage/html/settings/account_settings.html:46 msgid "Change E-mail Address" msgstr "Cambiar la dirección de e-mail" #: sagenb/data/sage/html/settings/account_settings.html:50 msgid "Current e-mail" msgstr "E-mail actual" #: sagenb/data/sage/html/settings/account_settings.html:54 msgid "New e-mail" msgstr "Nuevo e-mail" #: sagenb/data/sage/html/settings/admin_add_user.html:2 #: sagenb/data/sage/html/settings/admin_add_user.html:6 msgid "Add New User" msgstr "Añadir Usuario Nuevo" #: sagenb/data/sage/html/settings/admin_add_user.html:9 msgid "Pick a username" msgstr "Elija un usuario" #: sagenb/data/sage/html/settings/admin_add_user.html:10 msgid "" "The username must start with a letter and be between 4 and 32 characters " "long. It can only consist of letters, numbers, underscores, and one dot " "(.)." msgstr "" "El usuario debe comenzar por una letra y tener entre 4 y 32 caracteres. " "Sólo puede contener letras, números, guiones bajos y un punto." #: sagenb/data/sage/html/settings/admin_add_user.html:14 msgid "Invalid username" msgstr "Usuario no válido" #: sagenb/data/sage/html/settings/admin_add_user.html:16 msgid "Username taken" msgstr "Usuario en uso" #: sagenb/data/sage/html/settings/admin_add_user.html:18 msgid "Username Error" msgstr "Error de Usuario" #: sagenb/data/sage/html/settings/admin_add_user.html:24 msgid "Create Account" msgstr "Crear Cuenta" #: sagenb/data/sage/html/settings/base.html:10 msgid "Manage Users" msgstr "Administrar Usuarios" #: sagenb/data/sage/html/settings/base.html:11 #: sagenb/data/sage/html/settings/notebook_settings.html:2 msgid "Notebook Settings" msgstr "Configuración del Notebook" #: sagenb/data/sage/html/settings/user_management.html:3 msgid "Users" msgstr "Usuarios" #: sagenb/data/sage/html/settings/user_management.html:7 msgid "User Management" msgstr "Administración de Usuarios" #: sagenb/data/sage/html/settings/user_management.html:8 msgid "Add User" msgstr "Añadir Usuario" #: sagenb/data/sage/html/settings/user_management.html:10 #, python-format msgid "The password for the user %(u)s has been reset to %(p)s" msgstr "" "La contraseña para el usuario %(u)s se ha reiniciado a " "%(p)s" #: sagenb/data/sage/html/settings/user_management.html:14 #: sagenb/data/sage/html/worksheet/ratings_info.html:9 msgid "User" msgstr "Usuario" #: sagenb/data/sage/html/settings/user_management.html:16 msgid "Suspension" msgstr "Suspensión" #: sagenb/data/sage/html/settings/user_management.html:17 msgid "Admin" msgstr "Admin" #: sagenb/data/sage/html/settings/user_management.html:26 msgid "Reset" msgstr "Reiniciar" #: sagenb/data/sage/html/settings/user_management.html:29 msgid "Unsuspend" msgstr "Restablecer" #: sagenb/data/sage/html/settings/user_management.html:29 msgid "Suspend" msgstr "Suspender" #: sagenb/data/sage/html/settings/user_management.html:30 msgid "Revoke" msgstr "Revocar" #: sagenb/data/sage/html/settings/user_management.html:30 msgid "Grant" msgstr "Permitir" #: sagenb/data/sage/html/source_code.html:3 sagenb/notebook/tutorial.py:358 msgid "Source Code" msgstr "Código Fuente" #: sagenb/data/sage/html/source_code.html:13 msgid "Sage Source Browser" msgstr "Visualizador de Fuentes de Sage" #: sagenb/data/sage/html/source_code.html:14 msgid "browse directory" msgstr "Ver directorio" #: sagenb/data/sage/html/test_report.html:79 msgid "Sage Notebook version" msgstr "Versión del Notebook Sage" #: sagenb/data/sage/html/test_report.html:85 msgid "Sage version" msgstr "Versión de Sage" #: sagenb/data/sage/html/test_report.html:91 msgid "Environment" msgstr "Entorno" #: sagenb/data/sage/html/test_report.html:96 msgid "Start" msgstr "Iniciar" #: sagenb/data/sage/html/test_report.html:100 #: sagenb/data/sage/html/worksheet_listing.html:77 msgid "Stop" msgstr "Parar" #: sagenb/data/sage/html/test_report.html:104 msgid "Elapsed" msgstr "Transcurrido" #: sagenb/data/sage/html/test_report.html:108 msgid "Status" msgstr "Estado" #: sagenb/data/sage/html/test_report.html:110 #: sagenb/data/sage/html/test_report.html:129 msgid "Pass" msgstr "Pasa" #: sagenb/data/sage/html/test_report.html:111 #: sagenb/data/sage/html/test_report.html:130 msgid "Fail" msgstr "Fallo" #: sagenb/data/sage/html/test_report.html:113 msgid "Total" msgstr "Total" #: sagenb/data/sage/html/test_report.html:121 msgid "Hide" msgstr "Ocultar" #: sagenb/data/sage/html/test_report.html:122 msgid "Show" msgstr "Mostrar" #: sagenb/data/sage/html/test_report.html:128 msgid "Cases / Tests" msgstr "Casos / Tests" #: sagenb/data/sage/html/test_report.html:132 msgid "Count" msgstr "Contador" #: sagenb/data/sage/html/test_report.html:141 msgid "Totals" msgstr "Total" #: sagenb/data/sage/html/upload.html:3 msgid "Upload File" msgstr "Subir fichero" #: sagenb/data/sage/html/upload.html:11 sagenb/data/sage/html/upload.html:27 msgid "Upload worksheet to the Sage Notebook" msgstr "Subir una hoja al Notebook Sage" #: sagenb/data/sage/html/upload.html:15 msgid "URL of file on web" msgstr "URL de un archivo de la web" #: sagenb/data/sage/html/upload.html:19 sagenb/data/sage/html/upload.html:48 #: sagenb/data/sage/html/notebook/upload_data_window.html:27 msgid "What do you want to call it? (if different than the original name)" msgstr "¿Cómo quiere llamarlo? (en caso de que sea diferente al nombre original)" #: sagenb/data/sage/html/upload.html:22 sagenb/data/sage/html/upload.html:51 msgid "Upload Worksheet" msgstr "Subir Hoja" #: sagenb/data/sage/html/upload.html:28 msgid "Supported file formats:" msgstr "Formatos de archivo soportados" #: sagenb/data/sage/html/upload.html:30 msgid "a Sage worksheet" msgstr "una hoja Sage" #: sagenb/data/sage/html/upload.html:31 msgid "" "or .txt - a worksheet text file with html code and cells " "surrounded by {{{ and }}}" " that defines a worksheet" msgstr "" "o .txt - una hoja en un archivo de texto con html y celdas entre" " {{{ y }}} que definan " "una hoja" #: sagenb/data/sage/html/upload.html:32 msgid "" "the URL of a page of the Sage Documentation, for example the URL of this" " page" msgstr "" "el URL de una página de Documentación de Sage, por ejemplo el URL de esta" " página" #: sagenb/data/sage/html/upload.html:33 msgid "an HTML page generated by docutils from a ReStructuredText file" msgstr "" "una página HTML generada por docutils a partir de un archivo en formato " "ReStructuredText" #: sagenb/data/sage/html/upload.html:34 msgid "" "a ReStructuredText file (Add \".. escape-backslashes\" as a line" " in the file if you want backslashes to be escaped. Put latex code inside" " backticks \"`\" or dollar signs \"$\" or " "\"$$\". Math role is not supported for now.)" msgstr "" "un archivo en formato ReStructuredText (Añadir \".. escape-" "backslashes\" al archivo para que \"\\\" sea un carácter de escape. " "Poner el código de latex entre acentos graves \"`\" o dólares " "\"$\" o \"$$\". El modo matemático no esta soportado " "por ahora.)" #: sagenb/data/sage/html/upload.html:35 msgid "a zip archive of any of the above" msgstr "un archivo zip de cualquiera de los anteriores" #: sagenb/data/sage/html/upload.html:40 #: sagenb/data/sage/html/notebook/upload_data_window.html:15 msgid "Browse your computer to select a file to upload:" msgstr "Seleccionar un archivo para subir en su ordenador:" #: sagenb/data/sage/html/upload.html:44 msgid "" "Or enter the URL of a file on the web. This can be a direct link to any " "of the above kinds of files, or the URL of any HTML page that supports " "\"linked worksheet autodiscovery\"." msgstr "" "O introducir el URL de un archivo de la web. Puede ser un enlace directo " "a cualquiera de las clases anteriores de archivos, o el URL de cualquier " "página HTML que soporte la característica \"linked worksheet " "autodiscovery\"." #: sagenb/data/sage/html/worksheet/ratings_info.html:3 #: sagenb/data/sage/html/worksheet/ratings_info.html:6 #, python-format msgid "Ratings for %(wn)s" msgstr "Puntuación para %(wn)s" #: sagenb/data/sage/html/worksheet/ratings_info.html:7 msgid "Go to the worksheet." msgstr "Ir a la hoja" #: sagenb/data/sage/html/worksheet/ratings_info.html:9 msgid "Comment" msgstr "Comentario" #: sagenb/data/sage/html/worksheet/time_last_edited.html:6 #, python-format msgid "%(t)s by %(le)s" msgstr "%(t)s por %(le)s" #: sagenb/data/sage/html/worksheet/time_since_last_edited.html:6 #: sagenb/notebook/worksheet.py:2125 #, python-format msgid "%(t)s ago by %(le)s" msgstr "hace %(t)s por %(le)s" #: sagenb/data/sage/html/worksheet_listing.html:10 msgid "Published Worksheets" msgstr "Hojas Publicadas" #: sagenb/data/sage/html/worksheet_listing.html:12 msgid "Deleted Worksheets" msgstr "Hojas Eliminadas" #: sagenb/data/sage/html/worksheet_listing.html:14 msgid "Active Worksheets" msgstr "Hojas activas" #: sagenb/data/sage/html/worksheet_listing.html:16 msgid "Archived Worksheets" msgstr "Hojas Archivadas" #: sagenb/data/sage/html/worksheet_listing.html:45 #: sagenb/data/sage/html/notebook/base.html:75 msgid "Account is read only. You may download or delete worksheets or data." msgstr "La cuenta es de sólo lectura. Se pueden descargar o borrar hojas o datos." #: sagenb/data/sage/html/worksheet_listing.html:49 msgid "New Worksheet" msgstr "Hoja Nueva" #: sagenb/data/sage/html/worksheet_listing.html:50 msgid "Upload" msgstr "Subir" #: sagenb/data/sage/html/worksheet_listing.html:51 msgid "Download All Active" msgstr "Descargar activas" #: sagenb/data/sage/html/worksheet_listing.html:58 msgid "Search Worksheets" msgstr "Buscar hojas" #: sagenb/data/sage/html/worksheet_listing.html:66 msgid "Unarchive selected worksheets so it appears in the default worksheet list" msgstr "" "Des-archivar las hojas seleccionadas para que aparezcan en la lista " "normal de hojas" #: sagenb/data/sage/html/worksheet_listing.html:66 msgid "Unarchive" msgstr "Des-archivar" #: sagenb/data/sage/html/worksheet_listing.html:68 msgid "" "Archive selected worksheets so they do not appear in the default " "worksheet list" msgstr "" "Archivar hojas seleccionadas para que no aparezcan en la lista normal de " "hojas" #: sagenb/data/sage/html/worksheet_listing.html:68 msgid "Archive" msgstr "Archivar" #: sagenb/data/sage/html/worksheet_listing.html:72 msgid "Move the selected worksheets to the trash" msgstr "Enviar las hojas seleccionadas a la papelera" #: sagenb/data/sage/html/worksheet_listing.html:72 #: sagenb/data/sage/html/settings/user_management.html:18 #: sagenb/data/sage/html/settings/user_management.html:31 msgid "Delete" msgstr "Borrar" #: sagenb/data/sage/html/worksheet_listing.html:74 msgid "Move the selected worksheets out of the trash" msgstr "Sacar las hojas seleccionadas de la papelera" #: sagenb/data/sage/html/worksheet_listing.html:74 msgid "Undelete" msgstr "Recuperar" #: sagenb/data/sage/html/worksheet_listing.html:77 msgid "Stop selected worksheets" msgstr "Parar las hojas seleccionadas" #: sagenb/data/sage/html/worksheet_listing.html:78 msgid "Download selected worksheets" msgstr "Descargar las hojas seleccionadas" #: sagenb/data/sage/html/worksheet_listing.html:78 msgid "Download" msgstr "Descargar" #: sagenb/data/sage/html/worksheet_listing.html:81 msgid "Current Folder" msgstr "Carpeta actual" #: sagenb/data/sage/html/worksheet_listing.html:82 msgid "Active" msgstr "Activas" #: sagenb/data/sage/html/worksheet_listing.html:83 msgid "Archived" msgstr "Archivadas" #: sagenb/data/sage/html/worksheet_listing.html:84 msgid "Trash" msgstr "Papelera" #: sagenb/data/sage/html/worksheet_listing.html:88 msgid "Empty Trash" msgstr "Vaciar Papelera" #: sagenb/data/sage/html/worksheet_listing.html:103 #: sagenb/data/sage/html/worksheet/ratings_info.html:9 msgid "Rating" msgstr "Puntuación" #: sagenb/data/sage/html/worksheet_listing.html:114 msgid "Owner" msgstr "Propietario" #: sagenb/data/sage/html/worksheet_listing.html:114 msgid "Collaborators" msgstr "Colaboradores" #: sagenb/data/sage/html/worksheet_listing.html:120 #: sagenb/data/sage/html/notebook/worksheet_revision_list.html:16 msgid "Last Edited" msgstr "Editada" #: sagenb/data/sage/html/worksheet_listing.html:130 msgid "There are no published worksheets." msgstr "No hay hojas publicadas" #: sagenb/data/sage/html/worksheet_listing.html:136 msgid "" "Welcome to Sage! You can create a new " "worksheet, view published worksheets, or read " "the documentation." msgstr "" "¡Bienvenido a Sage! Puede crear una hoja " "nueva, ver las hojas publicadas, o leer la documentación." #: sagenb/data/sage/html/worksheet_listing.html:178 msgid "running" msgstr "ejecutando" #: sagenb/data/sage/html/worksheet_listing.html:211 msgid "Add or Delete" msgstr "Añadir o Borrar" #: sagenb/data/sage/html/worksheet_listing.html:213 msgid "Share now" msgstr "Compartir" #: sagenb/data/sage/html/worksheet_listing.html:218 msgid "published" msgstr "publicadas" #: sagenb/data/sage/js/localization.js:9 msgid "" "Your browser / OS combination is not supported.\\nPlease use Firefox or " "Opera under Linux, Windows, or Mac OS X, or Safari." msgstr "" "Su combinación navegador / OS no está soportada.\\nPor favor, utilice " "Firefox u Opera bajo Linux, Windows o Mac OS X, o Safari." #: sagenb/data/sage/js/localization.js:10 msgid "Java Applet Hidden" msgstr "Applet Java Oculta" #: sagenb/data/sage/js/localization.js:11 msgid "Click here to pop out" msgstr "Pulsar aquí para activar" #: sagenb/data/sage/js/localization.js:12 msgid "Error applying function to worksheet(s)." msgstr "Error al aplicar función a la hoja(s)" #: sagenb/data/sage/js/localization.js:13 msgid "Title of saved worksheet" msgstr "Título de la hojas guardadas" #: sagenb/data/sage/js/localization.js:14 msgid "Failed to save worksheet." msgstr "Fallo al guardar la hoja." #: sagenb/data/sage/js/localization.js:16 msgid "Please enter a name for this worksheet." msgstr "Por favor, introduzca un nombre para esta hoja." #: sagenb/data/sage/js/localization.js:17 msgid "Rename" msgstr "Renombrar" #: sagenb/data/sage/js/localization.js:18 msgid "Possible failure deleting worksheet." msgstr "Posible fallo al borrar la hoja." #: sagenb/data/sage/js/localization.js:19 msgid "unprinted" msgstr "no impresa" #: sagenb/data/sage/js/localization.js:20 msgid "" "You requested to evaluate a cell that, for some reason, the server is " "unaware of." msgstr "El servidor no puede evaluar la celda solicitada por alguna razón" #: sagenb/data/sage/js/localization.js:22 msgid "" "This worksheet is read only. Please make a copy or contact the owner to " "change it." msgstr "" "Esta hoja es de sólo lectura. Por favor haga una copia o contacte con el " "propietario para cambiarlo." #: sagenb/data/sage/js/localization.js:23 msgid "loading..." msgstr "cargando..." #: sagenb/data/sage/js/localization.js:24 msgid "Error updating cell output after " msgstr "Error al actualizar el resultado de la celda después de " #: sagenb/data/sage/js/localization.js:25 msgid "s (canceling further update checks)." msgstr "s (cancelando comprobaciones de actualización posteriores)." #: sagenb/data/sage/js/localization.js:26 msgid "Problem inserting new input cell after current input cell.\\n" msgstr "" "Problema al insertar una celda de entrada nueva después de la celda de " "entrada actual.\\n" #: sagenb/data/sage/js/localization.js:27 msgid "Problem inserting new input cell before current input cell.\\n" msgstr "" "Problema al insertar una celda de entrada nueva antes de la celda de " "entrada actual.\\n" #: sagenb/data/sage/js/localization.js:28 msgid "Problem inserting new text cell before current input cell." msgstr "" "Problema al insertar una celda de texto nueva antes de la celda de " "entrada actual." #: sagenb/data/sage/js/localization.js:29 msgid "Problem inserting new text cell before current input cell.\\n" msgstr "" "Problema al insertar una celda de texto nueva antes de la celda de " "entrada actual.\\n" #: sagenb/data/sage/js/localization.js:30 msgid "Worksheet is locked. Cannot insert cells." msgstr "La hoja está bloqueada. No se pueden insertar celdas" #: sagenb/data/sage/js/localization.js:31 msgid "Unable to interrupt calculation." msgstr "Imposible interrumpir cálculo." #: sagenb/data/sage/js/localization.js:32 msgid "Close this box to stop trying." msgstr "Cerrar este cuadro para dejar de intentarlo." #: sagenb/data/sage/js/localization.js:33 msgid "Interrupt attempt" msgstr "Intento de interrupción" #: sagenb/data/sage/js/localization.js:34 msgid "Restart, instead?" msgstr "¿Reiniciar, si no?" #: sagenb/data/sage/js/localization.js:35 msgid "" "Emptying the trash will permanently delete all items in the trash. " "Continue?" msgstr "Vaciar la papelera borrará permanente sus elementos. ¿Continuar?" #: sagenb/data/sage/js/localization.js:36 msgid "Get Image" msgstr "Obtener Imagen" #: sagenb/data/sage/js/localization.js:37 msgid "Jmol Image" msgstr "Imagen Jmol" #: sagenb/data/sage/js/localization.js:38 msgid "" "To save this image, you can try right-clicking on the image to copy it or" " save it to a file, or you may be able to just drag the image to your " "desktop." msgstr "" "Para guardar esta imagen, puede intentar pulsar el botón derecho sobre " "ella y copiarla o guardarla en un archivo, o puede intentar arrastrar la " "imagen a su escritorio." #: sagenb/data/sage/js/localization.js:39 msgid "Sorry, but you need a browser that supports the <canvas> tag." msgstr "Lo siento, pero necesita un navegador que soporte <canvas>" #: sagenb/data/sage/js/localization.js:43 #, python-format msgid "Trying again in %(num)d second..." msgid_plural "Trying again in %(num)d seconds..." msgstr[0] "Se intentará de nuevo en %(num)d segundo..." msgstr[1] "Se intentará de nuevo en %(num)d segundos..." #: sagenb/flask_version/admin.py:98 #, python-format msgid "" "The temporary password for the new user %(username)s is " "%(password)s" msgstr "" "La contraseña provisional para el nuevo usuario %(username)s es " "%(password)s" #: sagenb/flask_version/admin.py:100 msgid "New User" msgstr "Nuevo usuario" #: sagenb/flask_version/authentication.py:36 msgid "" "Please enable cookies or delete all Sage cookies and localhost cookies in" " your browser and try again." msgstr "" "Por favor, active las cookies o borre todas las cookies de Sage y de " "localhost de su navegador e inténtelo de nuevo" #: sagenb/flask_version/authentication.py:63 msgid "Your account is currently suspended" msgstr "Su cuenta se encuentra suspendida actualmente" #: sagenb/flask_version/authentication.py:239 msgid "Sage Notebook Registration" msgstr "Registro en el Notebook de Sage" #: sagenb/flask_version/authentication.py:258 msgid "The confirmation system is not active." msgstr "El sistema de confirmación está desactivado" #: sagenb/flask_version/authentication.py:261 msgid "" "

    Invalid confirmation key

    \n" "

    You are reporting a confirmation key that has not been assigned by" " this\n" " server. Please register with the " "server.

    \n" " " msgstr "" "

    Contraseña de confirmación inválida

    \n" "

    Usted ha proporcionado una contraseña de confirmación no asignada " "por este\n" " servidor. Por favor regístrese en el " "servidor.

    \n" " " #: sagenb/flask_version/authentication.py:272 #, python-format msgid "

    Email address confirmed for user %(username)s

    " msgstr "

    Dirección de e-mail confirmada para el usuario %(username)s

    " #: sagenb/flask_version/authentication.py:274 msgid "Email Confirmed" msgstr "E-mail confirmado" #: sagenb/flask_version/authentication.py:280 msgid "The account recovery system is not active." msgstr "El sistema de recuperación de cuentas no está activo." #: sagenb/flask_version/authentication.py:292 msgid "Username is invalid." msgstr "El nombre de usuario no es válido." #: sagenb/flask_version/authentication.py:295 msgid "The e-mail address hasn't been confirmed." msgstr "No se ha confirmado la dirección de e-mail." #: sagenb/flask_version/authentication.py:315 msgid "Sage Notebook Account Recovery" msgstr "Recuperación de cuentas del Notebook de Sage" #: sagenb/flask_version/authentication.py:318 #, python-format msgid "The new password couldn't be sent to %(dest)s." msgstr "No se ha podido enviar la nueva contraseña a %(dest)s." #: sagenb/flask_version/authentication.py:322 msgid "A new password has been sent to your e-mail address." msgstr "Se ha enviado una nueva contraseña a su dirección de e-mail." #: sagenb/flask_version/base.py:471 msgid "" "500: Internal server error.\n" " An e-mail has been sent to the administrator(s)." msgstr "" "500: Error interno del servidor.\n" " Se ha enviado un e-mail al administrador." #: sagenb/flask_version/decorators.py:30 msgid "You do not have permission to access this location" msgstr "Usted no está autorizado para acceder a esta página" #: sagenb/flask_version/doc.py:41 msgid "nothing to see." msgstr "nada que mostrar" #: sagenb/flask_version/settings.py:33 msgid "Old password not given" msgstr "No se ha introducido la contraseña antigua" #: sagenb/flask_version/settings.py:35 msgid "Incorrect password given" msgstr "Se ha introducido una contraseña incorrecta" #: sagenb/flask_version/settings.py:37 msgid "New password not given" msgstr "No se ha introducido la nueva contraseña" #: sagenb/flask_version/settings.py:39 msgid "" "Password not acceptable. Must be 4 to 32 characters and not contain " "spaces or username." msgstr "" "Su contraseña no es aceptable. Debe tener al menos 4 caracteres y no debe " "contener espacios ni su nombre de usuario." #: sagenb/flask_version/settings.py:41 msgid "Please type in new password again." msgstr "Vuelva a introducir la nueva contraseña, por favor" #: sagenb/flask_version/settings.py:43 msgid "The passwords you entered do not match." msgstr "Las contraseñas introducidas no coinciden" #: sagenb/flask_version/settings.py:59 msgid "Invalid e-mail address." msgstr "La dirección de e-mail no es válida." #: sagenb/flask_version/settings.py:80 msgid "Confirmed" msgstr "Confirmado" #: sagenb/flask_version/settings.py:82 msgid "Not confirmed" msgstr "No confirmado" #: sagenb/flask_version/worksheet.py:30 sagenb/flask_version/worksheet.py:39 #: sagenb/flask_version/worksheet_listing.py:174 #: sagenb/flask_version/worksheet_listing.py:183 msgid "You do not have permission to access this worksheet" msgstr "Usted no está autorizado para acceder a esta hoja" #: sagenb/flask_version/worksheet.py:79 sagenb/flask_version/worksheet.py:129 #: sagenb/flask_version/worksheet_listing.py:240 #: sagenb/flask_version/worksheet_listing.py:340 msgid "Account is in read-only mode" msgstr "La cuenta está en modo de sólo lectura" #: sagenb/flask_version/worksheet.py:587 msgid "Error: can't add more than 500 collaborators at a time" msgstr "Error: No se pueden añadir más de 500 colaboradores a la vez" #: sagenb/flask_version/worksheet.py:685 msgid "Invalid JSmol encoding: " msgstr "Codificación JSmol inválida: " #: sagenb/flask_version/worksheet.py:695 msgid "Invalid JSmol query: " msgstr "Petición JSmol inválida: " #: sagenb/flask_version/worksheet.py:706 msgid "Invalid JSmol request: " msgstr "Petición JSmol inválida: " #: sagenb/flask_version/worksheet.py:734 msgid "No data files" msgstr "No hay archivos de datos" #: sagenb/flask_version/worksheet.py:748 #, python-format msgid "Successfully deleted '%(filename)s'" msgstr "'%(filename)s' Se ha borrado con éxito" #: sagenb/flask_version/worksheet.py:775 msgid "illegal link attempt!" msgstr "Intento no permitido de enlace" #: sagenb/flask_version/worksheet.py:777 msgid "" "The data filename already exists in other worksheet\n" "Delete the file in the other worksheet before creating a link." msgstr "" "El nombre del archivo de datos ya existe en otra hoja\n" "Borre el archivo en la otra hoja antes de crear el enlace." #: sagenb/flask_version/worksheet.py:791 #, python-format msgid "" " Return to Upload or Create Data " "File or %(worksheet_name)s." msgstr "" " Vuelva a Subir o Crear Archivo " "de Datos o %(worksheet_name)s." #: sagenb/flask_version/worksheet.py:795 #, python-format msgid "Error uploading file (missing field \"file\"). %(backlinks)s" msgstr "Error subiendo archivo (falta el campo \"archivo\"). %(backlinks)s" #: sagenb/flask_version/worksheet.py:802 #, python-format msgid "Error uploading file (missing %(field)s arg).%(backlinks)s" msgstr "Error subiendo archivo (falta el argumento de %(field)s).%(backlinks)s" #: sagenb/flask_version/worksheet.py:815 #, python-format msgid "Error uploading file (missing filename).%(backlinks)s" msgstr "Error subiendo archivo (falta el nombre del archivo).%(backlinks)s" #: sagenb/flask_version/worksheet.py:823 #, python-format msgid "URL must start with http, https, or ftp.%(backlinks)s" msgstr "El URL debe comenzar con http, https, o ftp.%(backlinks)s" #: sagenb/flask_version/worksheet.py:830 #, python-format msgid "" "Suspicious filename \"%(filename)s\" encountered uploading " "file.%(backlinks)s" msgstr "" "Se ha encontrado un nombre de archivo \"%(filename)s\" sospechoso " "subiendo archivo.%(backlinks)s" #: sagenb/flask_version/worksheet.py:920 msgid "Gees -- You can't fool the rating system that easily!" msgstr "¡No se puede engañar tan fácilmente al sistema de puntuación!" #: sagenb/flask_version/worksheet.py:928 #, python-format msgid "" "\n" " Thank you for rating the worksheet %(worksheet_name)s!\n" " You can see all ratings of this " "worksheet.\n" " " msgstr "" "\n" " Gracias por puntuar la hoja %(worksheet_name)s!\n" " Puede ver todas las puntuaciones de esta " "hoja.\n" " " #: sagenb/flask_version/worksheet.py:930 msgid "Rating Accepted" msgstr "Puntuación aceptada" #: sagenb/flask_version/worksheet.py:952 msgid "No such worksheet." msgstr "No existe la hoja." #: sagenb/flask_version/worksheet.py:1037 msgid "Document does not exist." msgstr "No existe el documento." #: sagenb/flask_version/worksheet_listing.py:50 msgid "Error displaying worksheet listing." msgstr "Error al mostrar la lista de hojas" #: sagenb/flask_version/worksheet_listing.py:65 #, python-format msgid "" "User '%(user)s' does not have permission to view the home page of " "'%(name)s'." msgstr "" "El usuario '%(user)s' no tiene permiso para ver la página personal de " "'%(name)s'." #: sagenb/flask_version/worksheet_listing.py:155 msgid "Requested public worksheet does not exist" msgstr "La hoja pública requerida no existe" #: sagenb/flask_version/worksheet_listing.py:277 #, python-format msgid "" "This Sage notebook is not configured to load worksheets from 'https' " "URLs. Try a different URL or download the worksheet and upload it " "directly from your computer.\n" "%(backlinks)s" msgstr "" "Este notebook Sage no está configurado para recuperar hojas desde URLs " "'https'. Pruebe con un URL diferente, o descargue la hoja y súbala " "directamente desde su ordenador.\n" "%(backlinks)s" #: sagenb/flask_version/worksheet_listing.py:342 msgid "" "Return to Upload" " File." msgstr "" "Vuelva a Subir " "Archivo." #: sagenb/flask_version/worksheet_listing.py:354 #, python-format msgid "Unknown worksheet extension: %(ext)s. %(links)s" msgstr "Extensión de hoja desconocida: %(ext)s. %(links)s" #: sagenb/flask_version/worksheet_listing.py:361 #, python-format msgid "" "Unable to load file URL's when not running on localhost.\n" "%(backlinks)s" msgstr "" "No se pueden cargar URL de archivos cuando no está ejecutando la " "aplicación en la máquina local.\n" "%(backlinks)s" #: sagenb/flask_version/worksheet_listing.py:376 #, python-format msgid "" "Please specify a worksheet to load.\n" "%(backlinks)s" msgstr "" "Por favor, especifique una hoja para recuperar.\n" "%(backlinks)s" #: sagenb/flask_version/worksheet_listing.py:380 #, python-format msgid "" "Invalid filename.\n" "%(backlinks)s" msgstr "" "Nombre de archivo no válido.\n" "%(backlinks)s" #: sagenb/flask_version/worksheet_listing.py:424 #, python-format msgid "" "There was an error uploading the worksheet. It could be an old " "unsupported format or worse. If you desperately need its contents " "contact the sage-" "support group and post a link to your worksheet. Alternatively, an " "sws file is just a bzip2 tarball; take a look inside!\n" "%(backlinks)s" msgstr "" "Ocurrió un error al subir la hoja. Pudiera estar en un formato antiguo no" " soportado o peor aún. Si necesita sus contenidos desesperadamente " "contacte con el grupo sage-support y envíe un enlace a su hoja. Alternativamente," " un archivo sws simplemente es un tarball comprimido con bzip2; ¡Eche un " "vistazo dentro de él!\n" "%(backlinks)s" #: sagenb/flask_version/worksheet_listing.py:435 #, python-format msgid "Error uploading worksheet '%(msg)s'.%(backlinks)s" msgstr "Error subiendo la hoja '%(msg)s'.%(backlinks)s" #: sagenb/notebook/challenge.py:180 msgid "Please ask the server administrator to configure a challenge!" msgstr "¡Por favor consulte al administrador para que configure un reto!" #: sagenb/notebook/challenge.py:221 msgid "Is pi > e?" msgstr "¿pi > e?" #: sagenb/notebook/challenge.py:221 msgid "y|yes" msgstr "s|si" #: sagenb/notebook/challenge.py:222 msgid "What is 3 times 8?" msgstr "¿Cuánto es 3 por 8?" #: sagenb/notebook/challenge.py:222 msgid "24|twenty-four" msgstr "24|veinticuatro" #: sagenb/notebook/challenge.py:223 msgid "What is 2 plus 3?" msgstr "¿Cuánto es 2 más 3?" #: sagenb/notebook/challenge.py:223 sagenb/notebook/challenge.py:225 msgid "5|five" msgstr "5|cinco" #: sagenb/notebook/challenge.py:224 msgid "How many bits are in one byte?" msgstr "¿Cuántos bits hay en un byte?" #: sagenb/notebook/challenge.py:224 msgid "8|eight" msgstr "8|ocho" #: sagenb/notebook/challenge.py:225 msgid "What is the largest prime factor of 15?" msgstr "¿Cuál es el mayor factor primo de 15?" #: sagenb/notebook/conf.py:130 msgid "Updated" msgstr "Actualizado" #: sagenb/notebook/notebook.py:211 msgid "optional" msgstr "opcional" #: sagenb/notebook/notebook.py:1727 msgid "The worksheet does not exist" msgstr "La hoja no existe" #: sagenb/notebook/register.py:19 sagenb/notebook/register.py:29 #, python-format msgid "" "Hi %(username)s!\n" "\n" msgstr "" "¡Hola %(username)s!\n" "\n" #: sagenb/notebook/register.py:20 #, python-format msgid "" "Thank you for registering for the Sage notebook. To complete your " "registration, copy and paste the following link into your browser:\n" "\n" "%(url_prefix)s://%(addr)s:%(port)s/confirm?key=%(key)s\n" "\n" "You will be taken to a page which will confirm that you have indeed " "registered." msgstr "" "Gracias por registrarse en el Notebook Sage. Para completar su registro " "copie y pegue el siguiente enlace en su navegador:\n" "\n" "%(url_prefix)s://%(addr)s:%(port)s/confirm?key=%(key)s\n" "\n" "Será conducido a una página que le confirmará que se ha registrado." #: sagenb/notebook/register.py:30 #, python-format msgid "" "Your new password is %(key)s\n" "\n" "Sign in at %(url_prefix)s://%(addr)s:%(port)s/\n" "\n" "Make sure to reset your password by going to Settings in the upper right " "bar." msgstr "" "Su nueva contraseña es %(key)s\n" "\n" "Entre en %(url_prefix)s://%(addr)s:%(port)s/\n" "\n" "Asegúrese de reiniciar su contraseña entrando en Configuración." #: sagenb/notebook/server_conf.py:60 sagenb/notebook/user_conf.py:23 msgid "Appearance" msgstr "Apariencia" #: sagenb/notebook/server_conf.py:61 msgid "Authentication" msgstr "Autentificación" #: sagenb/notebook/server_conf.py:62 msgid "Server" msgstr "Servidor" #: sagenb/notebook/server_conf.py:63 msgid "LDAP" msgstr "LDAP" #: sagenb/notebook/server_conf.py:68 msgid "Maximum history length" msgstr "Longitud máxima del historial" #: sagenb/notebook/server_conf.py:75 msgid "Idle timeout for normal worksheets (seconds)" msgstr "Tiempo de espera inactivo para las hojas normales (segundos)" #: sagenb/notebook/server_conf.py:82 msgid "Idle timeout for live documentation (seconds)" msgstr "Tiempo de espera inactivo para la documentación dinámica (segundos)" #: sagenb/notebook/server_conf.py:88 msgid "Idle check interval (seconds)" msgstr "Comprobación del intervalo de inactividad (segundos)" #: sagenb/notebook/server_conf.py:94 msgid "Save interval (seconds)" msgstr "Intervalo de guardado (segundos)" #: sagenb/notebook/server_conf.py:100 msgid "Doc worksheet pool size" msgstr "Espacio para hojas de documentación " #: sagenb/notebook/server_conf.py:106 msgid "Enable published interacts (EXPERIMENTAL; USE AT YOUR OWN RISK)" msgstr "" "Activar interacciones en hojas publicadas (EXPERIMENTAL; UTILÃZELO A SU " "CRITERIO)" #: sagenb/notebook/server_conf.py:112 msgid "Worksheet process users (comma-separated list)" msgstr "" "Usuarios del sistema para el procesado de hojas (lista separada por" " coma)" #: sagenb/notebook/server_conf.py:118 msgid "Default system" msgstr "Sistema por defecto" #: sagenb/notebook/server_conf.py:124 msgid "Worksheet process limits" msgstr "Límites para el procesado de hojas" #: sagenb/notebook/server_conf.py:130 msgid "Model Version" msgstr "Versión del Modelo" #: sagenb/notebook/server_conf.py:136 msgid "Send notification e-mails to (comma-separated list)" msgstr "Enviar e-mails de notificación a (lista separada por comas)" #: sagenb/notebook/server_conf.py:142 msgid "Number of word-wrap columns" msgstr "Número de columnas para el ajuste de línea" #: sagenb/notebook/server_conf.py:148 msgid "Pretty print (typeset) output" msgstr "Typografía avanzada" #: sagenb/notebook/server_conf.py:154 msgid "Default Language" msgstr "Idioma por defecto" #: sagenb/notebook/server_conf.py:163 msgid "Allow OpenID authentication (requires python ssl module)" msgstr "Permitir autentificación OpenID (se requiere el módulo ssl de python)" #: sagenb/notebook/server_conf.py:170 msgid "Enable user registration" msgstr "Permitir el registro de usuarios" #: sagenb/notebook/server_conf.py:177 msgid "Require e-mail for account registration" msgstr "Requerir e-mail para el registro de cuentas" #: sagenb/notebook/server_conf.py:184 msgid "Use a challenge for account registration" msgstr "Utilizar un reto para el registro de cuentas" #: sagenb/notebook/server_conf.py:191 msgid "Type of challenge" msgstr "Tipo de reto" #: sagenb/notebook/server_conf.py:194 msgid "simple" msgstr "simple" #: sagenb/notebook/server_conf.py:194 msgid "recaptcha" msgstr "recaptcha" #: sagenb/notebook/server_conf.py:198 msgid "reCAPTCHA public key" msgstr "reCAPTCHA public key" #: sagenb/notebook/server_conf.py:204 msgid "reCAPTCHA private key" msgstr "reCAPTCHA private key" #: sagenb/notebook/server_conf.py:212 msgid "Enable LDAP Authentication" msgstr "Activar Autentificación LDAP" #: sagenb/notebook/server_conf.py:219 msgid "LDAP URI" msgstr "LDAP URI" #: sagenb/notebook/server_conf.py:226 msgid "Bind DN" msgstr "Bind DN" #: sagenb/notebook/server_conf.py:233 msgid "Bind Password" msgstr "Contraseña Bind" #: sagenb/notebook/server_conf.py:240 msgid "Use GSSAPI instead of Bind DN/Password" msgstr "Utilizar GSSAPI en vez de Bind DN/clave" #: sagenb/notebook/server_conf.py:247 msgid "Base DN" msgstr "Base DN" #: sagenb/notebook/server_conf.py:254 msgid "Username Attribute (i.e. cn, uid or userPrincipalName)" msgstr "Atributo de usuario (i.e. cn, uid o userPrincipalName)" #: sagenb/notebook/server_conf.py:261 msgid "Query timeout (seconds)" msgstr "Tiempo de espera para peticiones (segundos)" #: sagenb/notebook/template.py:73 #, python-format msgid "%(num)d second" msgid_plural "%(num)d seconds" msgstr[0] "%(num)d segundo" msgstr[1] "%(num)d segundos" #: sagenb/notebook/template.py:76 #, python-format msgid "%(num)d minute" msgid_plural "%(num)d minutes" msgstr[0] "%(num)d minuto" msgstr[1] "%(num)d minutos" #: sagenb/notebook/template.py:79 #, python-format msgid "%(num)d hour" msgid_plural "%(num)d hours" msgstr[0] "%(num)d hora" msgstr[1] "%(num)d horas" #: sagenb/notebook/template.py:81 #, python-format msgid "%(num)d day" msgid_plural "%(num)d days" msgstr[0] "%(num)d día" msgstr[1] "%(num)d días" #: sagenb/notebook/template.py:139 msgid "Sage Notebook" msgstr "Notebook Sage" #: sagenb/notebook/tutorial.py:354 msgid "Find Help and Documentation" msgstr "Encontrar Ayuda y Documentación" #: sagenb/notebook/tutorial.py:355 msgid "Get Started with Sage" msgstr "Empezando con Sage" #: sagenb/notebook/tutorial.py:355 msgid "" "Work through the tutorial " "(if you have trouble with it, view the static version)." msgstr "" "Tutorial interactivo (si " "tiene problemas con él, utilice la versión estática)." #: sagenb/notebook/tutorial.py:356 msgid "Help About" msgstr "Ayuda sobre..." #: sagenb/notebook/tutorial.py:357 msgid "" "Type ? immediately after the object or function and press tab or shift-" "enter (shift-enter overwrites output and saves to worksheet). Doing this" " twice or more toggles with formatted source code." msgstr "" "Teclee ? inmediatamente después del objeto o función y presione tab o " "mayúsculas-entrar (mayúsculas-entrar sobrescribe la salida de la celda" " con la ayuda en la propia hoja). Realizar esta acción dos o más veces cambia" " entre la documentación y el código fuente formateado." #: sagenb/notebook/tutorial.py:359 msgid "" "Put ?? after the object and press tab or shift-enter (shift-enter " "overwrites output and saves to worksheet). Doing this twice or more " "toggles with just the documentation." msgstr "" "Teclee ?? después del objeto y pulse tab o mayúsculas-entrar" " (mayúsculas-entrar sobrescribe la salida de la hoja con el código fuente en" " la propia hoja). Realizar esta acción dos o más veces cambia entre el código" " fuente y la documentación." #: sagenb/notebook/tutorial.py:360 msgid "Full Text Search of Docs and Source" msgstr "Búsqueda a Texto Completo en Documentación y Fuentes" #: sagenb/notebook/tutorial.py:361 msgid "" "Search the SAGE documentation by typing
    search_doc(\"my "
    "query\")
    in an input cell and press shift-enter. Search the source" " code of SAGE by typing
    search_src(\"my query\")
    and pressing " "shift-enter. Arbitrary regular expressions are allowed as queries." msgstr "" "Busque en la documentación de SAGE escribiendo
    search_doc(\"mi "
    "búsqueda\")
    en una celda de entrada y pulse mayúsculas-entrar. Busque" " en el código fuente de SAGE tecleando
    search_src(\"mi búsqueda\")
    " " y pulsando mayúsculas-entrar. Se admiten expresiones regulares arbitrarias" " en las búsquedas." #: sagenb/notebook/tutorial.py:362 msgid "Live Documentation" msgstr "Documentación activa" #: sagenb/notebook/tutorial.py:363 msgid "" "Use live documentation to try out " "the full Sage documentation \"live\". (Only new compute cells allowed, " "click the icon.)" msgstr "" "Utilice la documentación activa para " "obtener toda la documentación de Sage en forma \"activa\". (Sólo se " "permiten celdas de cálculo nuevas, pulsar el icono.)" #: sagenb/notebook/tutorial.py:367 msgid "Key and Mouse Bindings" msgstr "Teclas Rápidas" #: sagenb/notebook/tutorial.py:368 msgid "Evaluate Input" msgstr "Evaluar una celda de entrada" #: sagenb/notebook/tutorial.py:369 msgid "" "Press shift-enter or click the \"evaluate\" button. You" " can start several calculations at once. If you press alt-" "enter instead, then a new cell is created after the current one." " If you press ctrl-enter then the cell is split and " "both pieces are evaluated separately." msgstr "" "Pulse mayúsculas-entrar o pinche en el botón \"evaluar\". Se " "pueden iniciar varios cálculos a la vez. Si en lugar de ello, pulsa " "alt-entrar, se crea una celda nueva después de la actual." " Si pulsa ctrl-entrar, la celda se divide en dos y se evalúan " "ambas partes por separado." #: sagenb/notebook/tutorial.py:370 msgid "Tab Completion" msgstr "Completar con Tab" #: sagenb/notebook/tutorial.py:371 msgid "" "Press tab while the cursor is on an identifier. On some " "web browsers (e.g., Opera) you must use control-space instead of tab." msgstr "" "Pulse tab cuando el cursor está sobre un identificador. " "En algunos navegadores (e.g., Opera) se debe usar control-space en vez de" " tab." #: sagenb/notebook/tutorial.py:372 msgid "Insert New Cell" msgstr "Insertar Celda Nueva" #: sagenb/notebook/tutorial.py:373 msgid "" "Put the mouse between an output and input until the blue horizontal line " "appears and click, or click the \"plus\" icon. If you press Alt-Enter in" " a cell, the cell is evaluated and a new cell is inserted after it." msgstr "" "Sitúe el ratón entre un cuadro de salida y uno de entrada hasta que " "aparezca una línea horizontal y pinche, o bien pinche en el icono \"más\". " "Si pulsa Alt-Enter en una celda, ésta se evalúa y se inserta una nueva " "a continuación." #: sagenb/notebook/tutorial.py:374 msgid "Delete Cell" msgstr "Borrar Celda" #: sagenb/notebook/tutorial.py:375 msgid "Delete all cell contents, then press backspace." msgstr "" "Borrar todo el contenido de una celda y después pulsar " "retroceso." #: sagenb/notebook/tutorial.py:376 msgid "Split and Join Cells" msgstr "Dividir y Unir Celdas" #: sagenb/notebook/tutorial.py:377 msgid "" "Press ctrl-; in a cell to split it into two cells, and " "ctrl-backspace to join them. Press ctrl-" "enter to split a cell and evaluate both pieces." msgstr "" "Pulse ctrl-; en una celda para dividirla en dos, y " "ctrl-retroceso para unirlas. Pulse ctrl-" "entrar para dividir una celda y evaluar ambas." #: sagenb/notebook/tutorial.py:378 msgid "Insert New Text Cell" msgstr "Insertar una celda de texto nueva" #: sagenb/notebook/tutorial.py:379 msgid "" "Move the mouse between cells until a blue bar appears. Shift-" "click on the blue bar, or click on the text bubble icon, to " "create a new text cell. Use $...$ and $$...$$ to include typeset math in" " the text block. Click the button to save changes, or press shift-enter." msgstr "" "Mueva el ratón entre celdas hasta que aparezca una barra horizontal. Pinche " "mientras mantiene pulsada la tecla Mayúsculas en la barra " "horizontal, o bien pinche en el icono de texto" " para crear una celda de texto nueva. Utilice $...$ y $$...$$ para " "incluir tipografía matemática en el bloque de texto. Pinche el botón " "para guardar los cambios o pulse Mayúsculas-Entrar." #: sagenb/notebook/tutorial.py:380 msgid "Edit Text Cell" msgstr "Editar una celda de texto" #: sagenb/notebook/tutorial.py:381 msgid "Double click on existing text to edit it." msgstr "Haga doble click sobre el texto preexistente para editarlo." #: sagenb/notebook/tutorial.py:382 msgid "Hide/Show Output" msgstr "Ocultar/Mostrar Resultados" #: sagenb/notebook/tutorial.py:383 msgid "" "Click on the left side of output to toggle between hidden, shown with " "word wrap, and shown without word wrap." msgstr "" "Pulse en el lado izquierdo para cambiar entre ocultar, mostrar con ajuste" " de línea, y mostrar sin ajuste de línea." #: sagenb/notebook/tutorial.py:384 msgid "Indenting Blocks" msgstr "Sangrar bloques" #: sagenb/notebook/tutorial.py:385 msgid "" "Highlight text and press > to indent it all and < to unindent it all " "(works in Safari and Firefox). In Firefox you can also press tab and " "shift-tab." msgstr "" "Seleccione un texto y pulse > para sangrarlo < para reducir la sangría " "(funciona en Safari y Firefox). En Firefox también se puede pulsar " "tab y mayúsculas-tab." #: sagenb/notebook/tutorial.py:386 msgid "Comment/Uncomment Blocks" msgstr "Comentar/Des-comentar bloques" #: sagenb/notebook/tutorial.py:387 msgid "" "Highlight text and press ctrl-. to comment it and " "ctrl-, to uncomment it. As an alternative (necessary in " "some browsers), use ctrl-3 and ctrl-4." msgstr "" "Seleccione un texto y pulse ctrl-. para comentarlo y " "ctrl-, para quitar los comentarios. También se puede " "usar ctrl-3 y ctrl-4 (esto es necesario" " en algunos navegadores)." #: sagenb/notebook/tutorial.py:388 msgid "Paren matching" msgstr "Emparejado de Paréntesis" #: sagenb/notebook/tutorial.py:388 msgid "" "To fix unmatched or mis-matched parentheses, braces or brackets, press " "ctrl-0. Parentheses before the cursor will be matched, " "minding strings and (Python) comments." msgstr "" "Para emparejar paréntesis, llaves o corchetes, pulse " "ctrl-0. Se emparejarán los paréntesis que estén antes " "del cursor, teniendo en cuenta strings y comentarios de Python." #: sagenb/notebook/tutorial.py:392 msgid "Interrupt and Restart Sessions" msgstr "Interrumpir y Reiniciar Sesiones" #: sagenb/notebook/tutorial.py:393 msgid "Interrupt Running Calculations" msgstr "Interrumpir Cálculos" #: sagenb/notebook/tutorial.py:394 msgid "" "Click Interrupt or press escape in any input cell. This will " "(attempt) to interrupt SAGE by sending many interrupt signals." msgstr "" "Pulse Interrupt o pulse escape en cualquier celda de entrada. Esto" " interrumpirá (o al menos intentará interrumpir) a SAGE enviando múltiples " "señales de interrupción." #: sagenb/notebook/tutorial.py:395 msgid "Restart" msgstr "Reiniciar" #: sagenb/notebook/tutorial.py:396 msgid "" "Type \"restart\" to restart the SAGE interpreter for a given worksheet. " "(You have to interrupt first.)" msgstr "" "Teclee \"restart\" para reiniciar el intérprete de SAGE para una " "determinada hoja. (Primero hay que interrumpir los cálculos en curso)." #: sagenb/notebook/tutorial.py:398 msgid "Special Cell Blocks" msgstr "Bloques de Celdas Especiales" #: sagenb/notebook/tutorial.py:399 msgid "Evaluate Cell using GAP, Singular, etc." msgstr "Evaluar celdas usando GAP, Singular, etc." #: sagenb/notebook/tutorial.py:400 #, python-format msgid "" "Put \"%%gap\", \"%%singular\", etc. as the first input line of a cell; " "the rest of the cell is evaluated in that system." msgstr "" "Escriba \"%%gap\", \"%%singular\", etc. como primera línea de la celda; " "el resto de la celda se evaluará en ese sistema." #: sagenb/notebook/tutorial.py:401 msgid "Shell Scripts" msgstr "Scripts de Shell" #: sagenb/notebook/tutorial.py:402 #, python-format msgid "" "Begin a block with %%sh to have the rest of the block evaluated as a " "shell script. The current working directory is maintained." msgstr "" "Comience un bloque con %%sh para que el resto se evalúe como un script de" " shell. Se mantiene el directorio por defecto actual." #: sagenb/notebook/tutorial.py:403 msgid "Interactive Dynamic Widgets" msgstr "Widgets Dinámicas Interactivas" #: sagenb/notebook/tutorial.py:404 msgid "" "Put @interact on the line before a function definition. Type interact? " "for more details." msgstr "" "Escriba @interact en una línea antes de una función. Teclee interact? " "para más detalles." #: sagenb/notebook/tutorial.py:405 msgid "Autoevaluate Cells on Load" msgstr "Auto-evaluar Celdas al Cargar" #: sagenb/notebook/tutorial.py:406 msgid "" "Any cells with \"#auto\" in the input is automatically evaluated when the" " worksheet is first opened." msgstr "" "Todas las celdas que contengan \"#auto\" se evaluarán automáticamente al " "abrir la hoja." #: sagenb/notebook/tutorial.py:407 msgid "Time" msgstr "Tiempo" #: sagenb/notebook/tutorial.py:408 #, python-format msgid "Type \"%%time\" at the beginning of the cell." msgstr "Escriba \"%%time\" al inicio de la celda." #: sagenb/notebook/tutorial.py:410 msgid "Useful Tips" msgstr "Indicaciones Útiles" #: sagenb/notebook/tutorial.py:411 msgid "Input Rules" msgstr "Reglas de Entrada" #: sagenb/notebook/tutorial.py:412 msgid "" "Code is evaluated by exec'ing (after preparsing). Only the output of the" " last line of the cell is implicitly printed. If any line starts with " "\"sage:\" or \">>>\" the entire block is assumed to contain text and " "examples, so only lines that begin with a prompt are executed. Thus you" " can paste in complete examples from the docs without any editing, and " "you can write input cells that contains non-evaluated plain text mixed " "with examples by starting the block with \">>>\" or including an example." msgstr "" "El código se evalúa mediante ejecución (después de un preprocesado). Sólo se " "muestra la salida de la última línea. Si alguna línea comienza por " "\"sage:\" o \">>>\" se asume que todo el bloque contiene texto y " "ejemplos, por lo que solo se ejecutan las líneas que comiencen por un " "inductor. Así, se pueden pegar ejemplos completos de la documentación sin" " necesidad de editarlos y se puede escribir texto sin evaluar en las " "celdas mezclado con ejemplos, comenzando el bloque con \">>>\" o " "incluyendo un ejemplo." #: sagenb/notebook/tutorial.py:413 msgid "History" msgstr "Historial" #: sagenb/notebook/tutorial.py:414 msgid "" "Click log commands you have entered in any " "worksheet of this notebook." msgstr "" "Pulse historial para ver los comandos que ha " "tecleado en cualquier hoja de este notebook." #: sagenb/notebook/tutorial.py:415 msgid "Typesetting All Output" msgstr "Utilizar siempre tipografía avanzada" #: sagenb/notebook/tutorial.py:416 msgid "" "Type pretty_print_default() in an input cell and press shift-enter. All " "future output will be typeset automatically." msgstr "" "Teclee pretty_print_default() en una celda de entrada y pulse mayúsculas-" "entrar. Toda la salida a partir de ahora se mostrará con tipografía avanzada." #: sagenb/notebook/tutorial.py:418 msgid "Files and Scripts" msgstr "Archivos y Scripts" #: sagenb/notebook/tutorial.py:419 msgid "Loading SAGE/Python Scripts" msgstr "Cargando Scripts de SAGE/Python" #: sagenb/notebook/tutorial.py:420 msgid "" "Use \"load filename.sage\" and \"load filename.py\". Load is relative to" " the path you started the notebook in. The .sage files are preparsed and" " .py files are not. You may omit the .sage or .py extension. Files may" " load other files." msgstr "" "Utilice \"load filename.sage\" y \"load filename.py\". La ruta será " "relativa a la del directorio donde inició el notebook. Los archivos .sage" " son preprocesados y los .py no. Se puede omitir la extensión .sage o " ".py. Los archivos pueden cargar otros archivos." #: sagenb/notebook/tutorial.py:421 msgid "Attaching Scripts" msgstr "Adjuntar Scripts" #: sagenb/notebook/tutorial.py:422 msgid "" "(Currently no different from \"load\", see bug report) Use \"attach filename.sage\" or " "\"attach filename.py\". Attached files are automatically reloaded when " "the file changes. The file $HOME/.sage/init.sage is attached on startup " "if it exists." msgstr "" "(Actualmente \"attach\" funciona como \"load\", ver informe de errores) Utilice \"attach " "filename.sage\" o \"attach filename.py\". Los archivos adjuntos se " "recargarán automáticamente cuando se produzcan cambios en ellos. El archivo " "$HOME/.sage/init.sage, si existe, se adjunta automáticamente al inicio." #: sagenb/notebook/tutorial.py:423 msgid "Working Directory" msgstr "Directorio de Trabajo" #: sagenb/notebook/tutorial.py:424 msgid "" "Each block of code is run from its own directory. If any images are " "created as a side effect, they will automatically be displayed." msgstr "" "Cada bloque de código se ejecuta en su propio directorio. Si se crea " "alguna imagen como efecto colateral, se mostrará automáticamente." #: sagenb/notebook/tutorial.py:425 msgid "DIR Variable" msgstr "Variable DIR" #: sagenb/notebook/tutorial.py:426 msgid "" "The variable DIR contains the directory from which you started the SAGE " "notebook. For example, to open a file in that directory, do " "\"open(DIR+'filename')\"." msgstr "" "La variable DIR contiene el directorio desde el que se inicio el notebook" " de SAGE. Por ejemplo, para abrir un archivo en ese directorio, teclee " "\"open(DIR+'filename')\"." #: sagenb/notebook/tutorial.py:427 msgid "DATA Variable" msgstr "Variable DATA" #: sagenb/notebook/tutorial.py:428 msgid "" "Use the Data menu to upload images and other files, and create new files " "that can be shared between worksheets. The DATA variable contains the " "path to the data files. For example, to open a file in that directory, " "do \"open(DATA+'filename')\". If foo.sage is a Sage file that you " "uploaded, type \"load foo.sage\"; if foo.py is a Python file, you can " "import it by typing \"import foo\"." msgstr "" "Utilice el menú Datos para subir imágenes y otros archivos, y crear " "nuevos archivos que se puedan compartir entre hojas. La variable DATA " "contiene la ruta a los archivos de datos. Por ejemplo, para abrir un " "archivo de ese directorio, escribir \"open(DATA+'filename')\". Si usted " "ha subido el archivo foo.sage, podrá cargarlo con \"load foo.sage\"; Si " "foo.py es un archivo Python, podrá importarlo con \"import foo\"." #: sagenb/notebook/tutorial.py:429 msgid "Loading and Saving Objects" msgstr "Cargando y Guardando Objetos" #: sagenb/notebook/tutorial.py:430 msgid "" "Use \"save(obj1,DATA+'foo')\" to save an object to the data directory of " "a worksheet, and \"obj1 = load(DATA+'foo')\" to load it again. To use " "such objects between worksheets, you may save to any filename (given as a" " string) Sage can write to on your system." msgstr "" "Utilice \"save(obj1, DATA + 'foo') para guardar un objeto en el directorio " "de datos de una hoja, y \"obj1 = load(DATA + 'foo')\" para cargarlo de " "nuevo. Para utilizar tales objetos entre distintas hojas, se pueden " "guardar en cualquier archivo (cuyo nombre se da en forma de cadena de " "caracteres) en el que Sage pueda escribir." #: sagenb/notebook/tutorial.py:431 msgid "Loading and Saving Sessions" msgstr "Cargando y Salvando sesiones" #: sagenb/notebook/tutorial.py:432 msgid "" "Use \"save_session('name')\" to save all variables to an object. Use " "\"load_session('name')\" to merge in all variables from a saved " "session." msgstr "" "Utilice \"save_session('name')\" para guardar todas las variables en un " "objeto. Utilice \"load_session('name')\" para mezclar todas las " "variables de una sesión guardada." #: sagenb/notebook/tutorial.py:433 msgid "Customizing the Notebook CSS" msgstr "Personalizando el Notebook" #: sagenb/notebook/tutorial.py:434 msgid "" "If you create a file $HOME/.sage/notebook.css then it will get " "applied when rendering the notebook. See " msgstr "" "Si crea un archivo $HOME/.sage/notebook.css, se aplicará " "cuando se muestre el notebook. Ver" #: sagenb/notebook/user_conf.py:22 msgid "Language" msgstr "Idioma" #: sagenb/notebook/wiki2html.py:647 #, python-format msgid "Expected \"%(wanted)s\" after \"%(key)s\", got \"%(token)s\"" msgstr "" "Se esperaba \"%(wanted)s\" después de \"%(key)s\" y se obtuvo " "\"%(token)s\"" #: sagenb/notebook/wiki2html.py:653 #, python-format msgid "Expected an integer \"%(key)s\" before \"%(token)s\"" msgstr "Se esperaba un entero \"%(key)s\" antes de \"%(token)s\"" #: sagenb/notebook/wiki2html.py:663 sagenb/notebook/wiki2html.py:673 #, python-format msgid "Expected an integer \"%(arg)s\" after \"%(key)s\"" msgstr "Se esperaba un entero\"%(arg)s\" después de \"%(key)s\"" #: sagenb/notebook/wiki2html.py:699 #, python-format msgid "Expected a color value \"%(arg)s\" after \"%(key)s\"" msgstr "Se esperaba un valor de color \"%(arg)s\" después de \"%(key)s\"" #: sagenb/notebook/worksheet.py:2130 #, python-format msgid "%(seconds)s ago" msgstr "hace %(seconds)s" #: sagenb/notebook/worksheet.py:4421 msgid "January" msgstr "Enero" #: sagenb/notebook/worksheet.py:4422 msgid "February" msgstr "Febrero" #: sagenb/notebook/worksheet.py:4423 msgid "March" msgstr "Marzo" #: sagenb/notebook/worksheet.py:4424 msgid "April" msgstr "Abril" #: sagenb/notebook/worksheet.py:4425 msgid "May" msgstr "Mayo" #: sagenb/notebook/worksheet.py:4426 msgid "June" msgstr "Junio" #: sagenb/notebook/worksheet.py:4427 msgid "July" msgstr "Julio" #: sagenb/notebook/worksheet.py:4428 msgid "August" msgstr "Agosto" #: sagenb/notebook/worksheet.py:4429 msgid "September" msgstr "Septiembre" #: sagenb/notebook/worksheet.py:4430 msgid "October" msgstr "Octubre" #: sagenb/notebook/worksheet.py:4431 msgid "November" msgstr "Noviembre" #: sagenb/notebook/worksheet.py:4432 msgid "December" msgstr "Diciembre" sagenb-1.0.1/sagenb/translations/fr_FR/000077500000000000000000000000001311436262400177305ustar00rootroot00000000000000sagenb-1.0.1/sagenb/translations/fr_FR/LC_MESSAGES/000077500000000000000000000000001311436262400215155ustar00rootroot00000000000000sagenb-1.0.1/sagenb/translations/fr_FR/LC_MESSAGES/messages.mo000066400000000000000000001521261311436262400236700ustar00rootroot00000000000000Þ•úì¼½Öñ / ? #S w †  «• :A!,|!°©!FZ"G¡"Ié"«3#§ß#‡$˜$ ©$³$º$ Ì$Ù$ â$8ð$)%b<% Ÿ%ª%°%O¸%&&%&7&>&M&.h&$—& ¼& É&Ö&7V'Ž'0®':ß'§(Â(É( Ø(æ())*&)]Q)‚¯),2*_*2u*m¨*(+?+^+ï}+ m-{-ƒ- œ-?¦- æ-ô-ý-. .&.5.NL.›.².Ä.4Ó.//&/ C/ Q/ ^/h/p/y/Š/™/ / ²/@¾/ÿ/0"050E0!T0&v0 0 «0¹0Â0Ö0 ó0„ý0‚1 ‡1”1#¤1 È1Ó1Û1 ë1L÷1?D2„22¼2 Õ2á2(ç2 3*3!G3(i30’3*Ã3 î3 û3'404)?4$i4Ž46“40Ê4-û40)5Z5_5)y5£5¬5´5Æ5â5#ò5561L6 ~6ˆ68ž6×6ì6 ñ6ü67"7'777G7³X7• 8¢8ª8¯8Ï8î8 9)9s@9´9Í9 Þ9ê9ú9: +: L:V:u:”:5¦:Ü:÷: ;; 3;>;F;=Y; —;¢;§;¬;Ã; Ì;Ø;õ;%<:<X<t<<«<¯<¶<Í<%ê< ==#=:=>=ìG=-4>)b> Œ>­> ½> Ë> Ö>ã> ú>???? 4?B?Y?k?~? ?ž?°?¹?Õ? Ý?ê?@@ @€@&@0Ä@7õ@&-ATAZAiAnAwAŽA=žA'ÜA"B#'B%KB"qB$”B¹B|CŽœD+EIEOE<dE¡E©E ºEÄEÙErìEl_FYÌF´&GÛGöGÿGHH)H>HTH eHqHxHŽHŸH0°H'áH III"I@I×RI*J>JQJZJjJ {J‰J¢J µJÃJÙJ íJšùJ ”K¡K¹K ¾K ÊK×K ïKüKL"2LULqLƒL’M¯MÎMêMNN !N+N2N;N ANKN _NmNrN‚N’NšN£N#«N'ÏN&÷NCO bOnO‚O—OO¯O¶O»OËOäOëOP P6POPiP„P“Py˜PðQ^RbRÂtR&7SH^S'§S$ÏS•ôSœŠT,'U"TUzwU=òUI0VPzWËW5èWRXqXvX¶X"FY—iYZZZ!Z(ZD.ZsZ*|Ze§Z„ [’[u¤[\ 1\ R\I\\¦\¯\ ´\¾\Ç\Ï\Ö\ç\:]7=]u]:Ž]ºÉ]é„^žn_‘ `.Ÿ`·Î`%†a(¬aÕa~ôa sccA„cÆcÖcßcîcd$d3d9d-Ad!od(‘dºd)Êd¹ôd®eB·eúe f'f¹Gfg g)gZGg¢g.»gêgùg#ýgB!hgdhDÌhSiEeiE«iQñi“Cjz×j“Rk~ækoelŒÕlhbmËmÜmûmnn nnn"n AnLnMUn£n ©n³nÉnÞnän$ìno"o (o2o;o‘AoÓpîp q *qKq^q-vq¤q´q»q©Âq@lr:­r¯èrP˜saés`KtŸ¬tÌLuv2v HvRvXvtv‹v¢vI·v!wl#w wšw w`©w xx$2xWx]x-nx0œx.ÍxüxyŠ/yNºy+ z5z.Uzµ„z:{B{ \{)h{’{­{7Å{…ý{’ƒ|?})V}G€}‰È}6R~.‰~*¸~ñã~Õ€ ä€!ð€ F c q{›»ÂÓ^î%M‚s‚‰‚9š‚Ô‚ã‚,ý‚ *ƒ 8ƒEƒ Yƒ eƒoƒ‚ƒ —ƒ¡ƒ¿ƒIÕƒ„"=„`„€„–„2ª„.Ý„ … -…;…/D…)t… ž…¨…*†2†E†1[†!†¯†¾†Ú†Fí†d4‡ ™‡*º‡å‡ ˆˆDˆ]ˆ:mˆ9¨ˆ9âˆ7‰<T‰‘‰ £‰,±‰Þ‰5ò‰'(ŠPŠGXŠ+ Š)ÌŠ*öŠ!‹-(‹+V‹‚‹ ‹‹–‹ª‹È‹1Ý‹NŒ=^ŒœŒ¬ŒFÁŒ',> Xfmˆ£ÃÁ…Ž #.">(a"Š7­5åt§ºÌê‘4'‘ \‘ h‘$‰‘®‘-È‘ö‘ ’$’?’Z’n’v’>Š’ É’Ô’Ü’á’ÿ’“(“DF“0‹“¼“#Û“ÿ“” ;” F”"P”s”1’”Ä”ä”!é” • •)•C–7c–/›–Ë–Þ–ú–—")—L— h—u—…—‰—¡—½—Ü—$÷—˜ <˜J˜h˜q˜˜•˜©˜ ȘÔ˜㘔õ˜8Š™DÙ8š'Aš išwš“š šš&§šΚJëš+6›)b›4Œ›5Á›2÷›8*œécœ1M‘ž"Ÿ4Ÿ!=ŸI_Ÿ©Ÿ ±ŸÒŸÚŸøŸ  –‹ t"¡Ç—¡-_¢¢ –¢¢¢¸¢ Ñ¢$ò¢£-£@£!I£!k££4££1Ø£ ¤¤-¤.6¤e¤„¤)†¥°¥ È¥Ò¥ã¥û¥¦+¦A¦P¦g¦ƒ¦¹š¦ T§a§~§…§–§'¯§×§.ð§2¨4R¨/‡¨"·¨.Ú¨ ª+&ªRªgª…ª¡ª ©ª³ª »ªǪЪ!äª «««8« T« ^« k«'w«0Ÿ«2ЫI¬ M¬Y¬#v¬ 𬤬¸¬¿¬Ȭ(Ú¬ ­ ­ +­ 5­:?­z­—­³­Ç­ŸÍ­ m®|w¯ô¯È°-̰Wú°'R±>z±ž¹±¤X²$ý²,"³•O³?å³Å%´jëµ"V¶5y¶q¯¶!·&'·ÙN· (¸¬I¸ ö¸$¹(¹.¹ 5¹V?¹–¹&Ÿ¹{ƹšBºݺ›ôº$»#µ»Ù»lï»\¼s¼ |¼ †¼ ‘¼œ¼¥¼)żUï¼HE½޽E¬½Éò½A¼¾¹þ¿³¸À9lÁ¦Á+­Â6ÙÂÃä/ÃÅ %ÅJ1Å|ŕŧÅÃÅáÅûÅ Æ'Æ</Æ,lÆ>™ÆØÆ3ëÆâÇÈKÈ_ÈwÈ.Èä¾È£ÉºÉIÍÉqÊ-‰ÊV·ÊË#Ë-'ËNUËa¤ËeÌ_lÌXÌÌZ%ÍE€ÍªÆÍ‘qΪÏŸ®ÏzNЪÉÐitÑÞÑ;÷Ñ3ÒQÒgÒÒ’Ò›Ò*®ÒÙÒ ðÒPúÒKÓ_ÓgÓ~Ó–Ó´Ó#ÈÓìÓ% Ô 1Ô>ÔPÔ%(num)d day%(num)d days%(num)d hour%(num)d hours%(num)d minute%(num)d minutes%(num)d second%(num)d seconds%(seconds)s ago%(t)s ago by %(le)s(note that images are not recorded)24|twenty-four5|five8|eightWork through the tutorial (if you have trouble with it, view the static version).Restart, instead?

    Email address confirmed for user %s

    Invalid confirmation key

    You are reporting a confirmation key that has not been assigned by this server. Please register with the server.

    Sage is a different approach to mathematics software.A session is a worksheet and a set of variables in some state.A worksheet is an ordered list of Sage calculations with output.A new password will be emailed to the email address connected to your account. However if you didn't confirm your email address you will be unable to recover your account.Access %(f)s in this worksheet by typing DATA+'%(f)s'. Here DATA is a special variable that gives the exact path to all data files uploaded to this worksheet.Account RecoveryAccount SettingsAction...ActiveActive WorksheetsAdd New UserAdd UserAdd or DeleteAllow OpenID authentication (requires python ssl module)Answer a challengeAny cells with "#auto" in the input is automatically evaluated when the worksheet is first opened.AppearanceAprilArchiveArchive selected worksheets so they do not appear in the default worksheet listArchivedArchived WorksheetsAttaching ScriptsAugustAuthenticationAutoevaluate Cells on LoadAutomatically re-publish when changes are madeBack to your personal worksheet listBad passwordBad usernameBegin a block with %sh to have the rest of the block evaluated as a shell script. The current working directory is maintained.Browse published Sage worksheets
    (no login required)Browse the published worksheetsBrowse your computer to select a file to upload:Browse your computer to select a worksheet file to upload:By using Sage you help to support a viable open source alternative to Magma, Maple, Mathematica, and MATLAB. Sage includes many high-quality open source math packages.CancelCancel changesCases / TestsChange Auto-Save IntervalChange E-mail AddressChange PasswordChange account settings including passwordClick log commands you have entered in any worksheet of this notebook.Click Interrupt or press escape in any input cell. This will (attempt) to interrupt SAGE by sending many interrupt signals.Click here or press shift-return to evaluateClick here to pop outClick here to turn the above into a Sage worksheetClick on the left side of output to toggle between hidden, shown with word wrap, and shown without word wrap.Click to download and install tex fonts.Click to rename this worksheetClose this box to stop trying.Code is evaluated by exec'ing (after preparsing). Only the output of the last line of the cell is implicitly printed. If any line starts with "sage:" or ">>>" the entire block is assumed to contain text and examples, so only lines that begin with a prompt are executed. Thus you can paste in complete examples from the docs without any editing, and you can write input cells that contains non-evaluated plain text mixed with examples by starting the block with ">>>" or including an example.CollaboratorsCommentComment/Uncomment BlocksConfirmedCongratulations %(u)s! You can now sign into the Sage Notebook.ConstructionsContinueCopy this worksheetCopy worksheetCountCreate AccountCreate a good passwordCreate a new Sage worksheet version of the last 100 commands in the above log.Create a new worksheetCreate a usernameCreate accountCreating new users is disabled by the administrator.Current FolderCurrent e-mailCustomizing the Notebook CSSDATA VariableDIR VariableData fileData...DecemberDefault LanguageDefault systemDeleteDelete All OutputDelete CellDelete all cell contents, then press backspace.Delete all outputDelete worksheetDeleted WorksheetsDeveloper GuideDiscard & quitDiscard changes to this worksheetDo you want to publish this worksheet?Doc pool sizeDocumentationDownloadDownload All ActiveDownload selected worksheetsDownload.Each block of code is run from its own directory. If any images are created as a side effect, they will automatically be displayed.EditEdit a copy.Edit plain textEdit text version of this worksheetEdit this.ElapsedEmail ConfirmedEmpty TrashEmptying the trash will permanently delete all items in the trash. Continue?Enable published interacts (EXPERIMENTAL; USE AT YOUR OWN RISK)Enable user registrationEnable/disable pretty_printingEnter your email addressEnvironmentErrorError applying function to worksheet(s).Error foundError in introspection -- invalid cell id.Error updating cell output after Error uploading file (missing %s arg).%sError uploading file (missing fileField file).%sError uploading file (missing filename).%sErrors foundEvaluate AllEvaluate Cell using GAP, Singular, etc.Evaluate InputEvaluate all input cells in the worksheetEvaluate all input cells using %(i)sExitExpected "%(wanted)s" after "%(key)s", got "%(token)s"Expected a color value "%(arg)s" after "%(key)s"Expected an integer "%(arg)s" after "%(key)s"Expected an integer "%(key)s" before "%(token)s"FailFailed to save worksheet.Fast Static Versions of the DocumentationFebruaryFile...Files and ScriptsFind Help and DocumentationForgot passwordFull Text Search of Docs and SourceGees -- You can't fool the rating system that easily!General and Advanced Pure and Applied MathematicsGet ImageGet Started with SageGive access to your worksheet to the above collaboratorsGo to the worksheet.HelpHelp AboutHelp via Internet Chat (IRC)Hi %s! HideHide All OutputHide all outputHide/Show OutputHighlight text and press ctrl-. to comment it and ctrl-, to uncomment it. Alternatively, use ctrl-3 and ctrl-4.Highlight text and press > to indent it all and < to unindent it all (works in Safari and Firefox). In Firefox you can also press tab and shift-tab.HistoryHomeHow do I construct ... in Sage?How many bits are in one byte?How to use the Sage NotebookIdle check interval (seconds)Idle timeout (seconds)If you create a file $HOME/.sage/notebook.css then it will get applied when rendering the notebook. See Incorrect password givenIndenting BlocksInput RulesInsert New CellInsert New Text CellInteractive Dynamic WidgetsInteractively use this worksheetInterruptInterrupt Running CalculationsInterrupt and Restart SessionsInterrupt attemptInterrupt currently running calculations, if possibleInvalid challenge responseInvalid email addressInvalid usernameInvite CollaboratorsIs pi > e?JanuaryJava Applet HiddenJavascript must be enabled in order to use the Sage Notebook.Jmol ImageJulyJuneKey and Mouse BindingsLanguageLast EditedLearn to write Sage programsLet others edit this worksheetLoad a new worksheet stored in a fileLoad worksheet from a file...Loading SAGE/Python ScriptsLoading and Saving ObjectsLoading and Saving SessionsLogLog inLog in to edit a copy.Log out of the Sage notebookMake this worksheet publicly viewableManage UsersMarchMaximum history lengthMayMinutes:Move the mouse between cells until a blue bar appears. Shift-click on the blue bar to create a new text cell. Double click on existing text to edit it. Use $...$ and $$...$$ to include typeset math in the text block.Move the selected worksheets out of the trashMove the selected worksheets to the trashMove this worksheet to the trashMulti Cell ModeNew WorksheetNew e-mailNew passwordNew password not givenNew worksheetNewerNewestNoNo challenge response givenNo data filesNo email address givenNo password givenNo such worksheet.No username givenNot confirmedNotebook SettingsNovemberNumber of word-wrap columnsOctoberOld passwordOld password not givenOlderOldestOne Cell ModeOnly the owner of a worksheet is allowed to share it. You can do whatever you want if you make your own copy.Or enter the URL of a file on the web:Or enter the URL of a worksheet file on the web:Or enter the name of a new file, which will be created:Other published feuilles de travail...OwnerParen matchingPassPasswordPasswords didn't matchPick a usernamePlease ask the server administrator to configure a challenge!Please enter a name for this worksheet.Please log in to the Sage notebookPlease request a specific worksheetPlease specify a worksheet to load.%sPlease type in new password again.Possible failure deleting worksheet.Press ctrl-; in a cell to split it into two cells, and ctrl-backspace to join them. Press ctrl-enter to split a cell and evaluate both pieces.Press shift-enter. You can start several calculations at once. If you press alt-enter instead, then a new cell is created after the current one. If you press ctrl-enter then the cell is split and both pieces are evaluated separately.Press tab while the cursor is on an identifier. On some web browsers (e.g., Opera) you must use control-space instead of tab.Pretty print (typeset) outputPrintPrint this worksheetProblem inserting new input cell after current input cell.\nPublishPublish this onePublishedPublished WorksheetsPublished on %(t)sPut "%gap", "%singular", etc. as the first input line of a cell; the rest of the cell is evaluated in that system.Put ?? after the object and press tab or shift-enter (shift-enter overwrites output and saves to worksheet).Put @interact on the line before a function definition. Type interact? for more details.Put the mouse between an output and input until the horizontal line appears and click. If you press Alt-Enter in a cell, the cell is evaluated and a new cell is inserted after it.Quit the worksheet processRate it:RatingRating AcceptedRatings for %(wn)sRe-publish worksheetRe-type your passwordReference ManualRemember meRenameRename this worksheetRename worksheetReport a ProblemReport a problem or submit a bug to improve SageRequire e-mail for account registrationRerate it:ResetRestartRestart the worksheet processRestart worksheetReturn to Upload or Create Data File or %s.Retype new passwordRevert to this oneRevisionRevision %(lr)sRevision HistoryRevision ListRevision from %(ta)s agoSage DocumentationSage NotebookSage Notebook versionSage Source BrowserSage Users:Sage makes it easy for you to use most mathematics software together. Sage includes GAP, GP/PARI, Maxima, and Singular, and dozens of other open packages.Sage versionSage: History for %(u)sSaveSave & quitSave ChangesSave and quit worksheetSave changesSave changes and close windowSave interval (seconds)Save this worksheet to an sws fileSave worksheet to a file...Search WorksheetsSearch the SAGE documentation by typing
    search_doc("my query")
    in an input cell and press shift-enter. Search the source code of SAGE by typing
    search_src("my query")
    and pressing shift-enter. Arbitrary regular expressions are allowed as queries.Searching for Sage server...Select a file related functionSelect a worksheet functionSelect an OpenID providerSelect an attached fileSendSeptemberServerSettingsShareShare nowShare this documentShell ScriptsShowShow All OutputShow all outputSign inSign outSign upSign up for a Sage Notebook accountSign up for a new Sage Notebook accountSomeone else is viewing this worksheetSorry, but you need a browser that supports the <canvas> tag.Source CodeSpecial Cell BlocksSplit and Join CellsStartStatic version...StatusStopStop publishingStop selected worksheetsSubmitSuccessfully deleted "%s"SuspendSuspensionSuspicious filename "%s" encountered uploading file.%sSwitch to multi-cell modeSwitch to single-cell modeTab CompletionTextThank you for rating the worksheet %s! You can see all ratings of this worksheet.Thank you for registering for the Sage notebook. To complete your registration, copy and paste the following link into your browser: %s://%s:%s/confirm?key=%s You will be taken to a page which will confirm that you have indeed registered.The Sage notebook is a collection of worksheets, saved objects, and user information.The Sage NotebookThe Sage Notebook was primarily written by William Stein with substantial contributions from Tom Boothby, Timothy Clemans, Alex Clemesha, Mike Hansen, Bobby Moretti, Yi Qiang, and Dorian Raymer.The confirmation system is not active.The password for the user %(u)s has been reset to %(p)sThe passwords you entered do not match.The user "%s" has no worksheet "%s".The username must start with a letter and be between 4 and 32 characters long. It can only consist of letters, numbers, underscores, and one dot (.).The variable DIR contains the directory from which you started the SAGE notebook. For example, to open a file in that directory, do "open(DIR+'filename')".The worksheet operation "%s" is not defined.There are no published worksheets.There is no published worksheet with name "%s". Redirecting to the index of published worksheets in 10 seconds...

    There was an error uploading "%s" (please recheck the URL).%sThere was an error uploading the worksheet. It could be an old unsupported format or worse. If you desperately need its contents contact the sage-support group and post a link to your worksheet. Alternatively, an sws file is just a bzip2 tarball; take a look inside!%sThis Sage Worksheet is currently shared with the people listed in the box below.This page is rated %(wr).1f.This url can only be accessed through a POST request.This worksheet is read only. Please make a copy or contact the owner to change it.TimeTitle of saved worksheetTo fix unmatched or mis-matched parentheses, braces or brackets, press ctrl-0. Parentheses before the cursor will be matched, minding strings and (Python) comments.To quickly try out Sage start hereTo save this image, you can try right-clicking on the image to copy it or save it to a file, or you may be able to just drag the image to your desktop.ToggleToggle the top barTotalTotalsTrashTrying again in %(num)d second...Trying again in %(num)d seconds...TutorialType "%time" at the beginning of the cell.Type "restart" to restart the SAGE interpreter for a given worksheet. (You have to interrupt first.)Type ? immediately after the object or function and press tab or shift-enter (shift-enter overwrites output and saves to worksheet).Type of challengeType pretty_print_default() in an input cell and press shift-enter. All future output will be typeset automatically.Typesetting All OutputUnable to interrupt calculation.UnarchiveUnarchive selected worksheets so it appears in the default worksheet listUndeleteUndoUnsuspendUntitledUpdatedUploadUpload WorksheetUpload or Create Data FileUpload or Create Data File to attach to worksheet "%(wn)s"Upload or create a data file in a wide range of formatsUpload or create file...Upload worksheet (an sws or txt file) to the Sage NotebookUse "attach filename.sage" or "attach filename.py". Attached files are automatically reloaded when the file changes. The file $HOME/.sage/init.sage is attached on startup if it exists.Use "load filename.sage" and "load filename.py". Load is relative to the path you started the notebook in. The .sage files are preparsed and .py files are not. You may omit the .sage or .py extension. Files may load other files.Use "save obj1 obj2 ..." and "load obj1 obj2 ...". This allows for easy moving of objects from one worksheet to another, and saving of objects for later use.Use "save_session('name')" to save all variables to an object. Use "load_session('name')" to merge in all variables from a saved session.Use Most Mathematics Software from Within SageUse Sage for studying calculus, elementary to very advanced number theory, cryptography, commutative algebra, group theory, graph theory, numerical and exact linear algebra, and more.Use a Mainstream Programming LanguageUse a challenge for account registrationUse an Open Source AlternativeUse the Data menu to upload images and other files, and create new files that can be shared between worksheets. The DATA variable contains the path to the data files. For example, to open a file in that directory, do "open(DATA+'filename')". If foo.sage is a Sage file that you uploaded, type "load foo.sage"; if foo.py is a Python file, you can import it by typing "import foo".Useful TipsUserUser "%s" does not have permission to view the home page of "%s".User ManagementUsernameUsername ErrorUsername already in useUsername is not in the systemUsername takenUsersVersionView a 4000+ page reference manual about SageView a log of recent computationsView changes to this worksheet over timeView plain textView plain text version of this worksheetWelcome to Sage! You can create a new worksheet, view published worksheets, or read the documentation.Welcome!What do you want to call it? (if different than the original name)What is 2 plus 3?What is 3 times 8?What is the largest prime factor of 15?With the Sage Notebook anyone can create, collaborate on, and publish interactive worksheets. In a worksheet, one can write code using Sage, Python, and other software included in Sage.Working DirectoryWorksheetWorksheet is locked. Cannot insert cells.Worksheet is publicly viewable at %(u)sWorksheet process limitsWorksheet process users (comma-separated list)Wrong passwordYesYou are not authorized to move "%s"You are not logged in or do not have access to the worksheet "%s".You can publish your worksheet to the Internet, where anyone will be able to access and view it online.You may add or remove collaborators (separate user names by commas).You may download %(f)s or create a linked copy to the worksheetYou must login first in order to edit this worksheet.You must login first in order to rate this worksheet.You requested to evaluate a cell that, for some reason, the server is unaware of.You work with Sage using the highly regarded scripting language Python. You can write programs that combine serious mathematics with anything else.Your browser / OS combination is not supported.\nPlease use Firefox or Opera under Linux, Windows, or Mac OS X, or Safari.Your email address is required for account confirmation and recovery. You will be emailed a confirmation link right after you successfully sign up.Your new password is %s Sign in at %s://%s:%s/ Make sure to reset your password by going to Settings in the upper right bar.Your password must be between 4 and 32 characters long. Your password can not contain your username nor spaces.Your username must start with a letter and be between 3 and 64 characters long. You may only use letters, numbers, underscores, @, and dots.Your worksheet will be assigned a unique address (URL) that you can send to your friends and colleagues.browse directorycan't evaluate worksheet cellscs_CZde_ATen_USes_ESevaluatefr_FRlast edited on %(t)s by %(le)sloading...optionalor delete %(f)s.pt_BRpublishedreCAPTCHA private keyreCAPTCHA public keyru_RUrunnings (canceling further update checks).select worksheetuk_UAunprintedusernamey|yesProject-Id-Version: Sage Notebook 0.8 Report-Msgid-Bugs-To: EMAIL@ADDRESS POT-Creation-Date: 2011-06-18 15:38-0300 PO-Revision-Date: 2014-03-08 21:21+0100 Last-Translator: Frédéric Chapoton Language-Team: Frédéric Chapoton MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit Generated-By: Babel 1.3 %(num)d jour%(num)d jours%(num)d heure%(num)d heures%(num)d minute%(num)d minutes%(num)d seconde%(num)d secondesdepuis %(seconds)sdepuis %(t)s par %(le)s(note : les images ne sont pas enregistrées)24|vingt-quatre5|cinq8|huitUtiliser le tutoriel (si vous avez des difficultés, voir la version statique).Plutôt relancer Sage ?

    Adresse courriel confirmée pour l'utilisateur %s

    Clé de confirmation invalide

    Vous proposez une clé qui n'a pas été donnée par ce serveur. Merci de vous enregistrer sur le serveur.

    Sage est une approche différente des logiciels mathématiques.Une session est une feuille de travail et un ensemble de variables dans un état donné.Une feuille de travail est une liste ordonnée de commandes Sage avec leurs résultats.Un nouveau mot de passe sera envoyé à l'adresse courriel du compte. Si vous n'avez pas confirmé cette adresse, vous ne pourrez pas récupérer votre compte.Utiliser DATA+'%(f)s' pour accéder à %(f)s dans cette feuille de travail. DATA est ici une variable spéciale, qui contient le chemin exact vers les fichiers attachés à la feuille de travail.Récupération de compteParamètres du compteAction...ActifFeuilles de travail activesAjouter un utilisateurAjouter un utilisateurAjouter ou supprimerAutoriser l'authentification par OpenID (nécessite le module python ssl)Veuillez répondre à la questionLes cellules contenant "#auto" sont évaluées automatiquement lors de l'ouverture de la feuille de travail.ApparenceAvrilArchiverArchiver les feuilles de travail choisies, pour les faire disparaître dans la liste par défautArchivéFeuilles de travail archivéesAttacher des fichiers Sage ou PythonAoûtAuthentificationAuto-évaluer les cellules lors du chargementRe-publier automatiquement lors de modificationsRevenir à la liste de vos feuilles de travailMot de passe incorrectNom d'utilisateur incorrectCommencer un bloc par %sh pour que le reste du bloc soit évalué comme un script shell. Le répertoire de travail actuel est préservé.Consulter les feuilles de travail publiées
    (pas de connexion nécessaire)Parcourir les feuilles de travail publiéesChoisir un fichier à charger :Choisir un fichier .sws sur votre ordinateur :En utilisant Sage, vous soutenez une alternative libre à Magma®, Maple®, Mathematica® et MATLAB®. Sage incorpore de nombreux logiciels mathématiques libres de grande qualité.AnnulerAnnuler les modificationsCas / TestsIntervalle pour la sauvegarde automatiqueChanger l'adresse courrielChanger le mot de passeChanger les paramètres du compte, dont le mot de passeCliquer sur Historique pour voir toutes les commandes entrées dans tous les feuilles de travail de ce carnet.Cliquer sur Interrompre ou taper Escape dans une cellule. Ceci va tenter d'interrompre Sage en envoyant de nombreux signaux d'interruption.Cliquer ici ou taper Maj-Entrée pour évaluerCliquer ici pour ouvrir une mini-fenêtreCliquer ici pour transformer ce qui précède en une feuille de travailCliquer à gauche du résultat pour basculer entre trois modes : caché, montré avec retour à la ligne, montré sans retour à la ligneCliquer pour télécharger et installer les fontes TeXCliquer pour renommer cette feuille de travailFermer cette boîte pour cesser d'essayer.Le code est évalué par exec (après un filtre). Seul le résultat de la dernière ligne de la cellule est affiché. Si une ligne commence par "sage:" ou ">>>" le bloc entier est supposé contenir du texte et des exemples, et seules les lignes commençant par "sage:" sont exécutées. Vous pouvez ainsi copier-coller des exemples complets depuis la documentation. Vous pouvez écrire des cellules qui mélangent texte non-évalué et exemples, en commençant par ">>>" ou en incluant un exemple.CollaborateursCommentaireCommenter/dé-commenter les blocsConfirméBravo %(u)s ! Vous pouvez maintenant vous connecter au Bloc-note Sage.ConstructionsContinuerCopier cette feuille de travailCopier cette feuille de travailCompteCréer un compteCréer un bon mot de passeCréer une nouvelle feuille de travail avec les 100 dernières commandes de la liste ci-dessusCréer un nouvelle feuille de travailCréer un utilisateurCréer un compteL'ouverture de compte est interdite par l'administrateur.Dossier actuelAdresse courriel actuellePersonnaliser le style CSS du Bloc-note SageVariable DATAVariable DIRFichier de donnéesDonnées...DécembreLangue par défautSystème par défautSupprimerSupprimer tous les résultatsSupprimer une celluleSupprimer le contenu de la cellule puis taper Backspace.Supprimer tous les résultatsSupprimer cette feuille de travailFeuilles de travail suppriméesGuide du développeurQuitter sans sauverOublier les modifications de la feuille de travailVoulez-vous publier cette feuille de travail ?Volume de stockage des documentsDocumentationExporterExporter toutes les feuilles de travail activesExporter les feuilles de travail choisiesExporter.Chaque bloc de code est executé depuis son propre répertoire. Si des images sont crées, elles sont automatiquement affichées.ÉditerÉditer une copie.Éditer en mode texteÉditer cette feuille de travail en version texteÉditer cette feuille de travail.Temps écouléAdresse courriel confirméeVider la corbeilleVider la corbeille supprimera définitivement son contenu. Continuer ?Autoriser les feuilles de travail interactives publiées (EXPÉRIMENTAL : À VOS RISQUES ET PÉRILS)Autoriser l'ouverture de comptesActiver/désactiver l'affichage amélioréEntrez votre adresse courrielEnvironnementErreurErreur lors de l'application de la fonction à la feuille de travailErreur trouvéeErreur d'introspection -- identifiant de cellule invalide.Erreur d'actualisation du résultat de la cellule après Erreur de chargement du fichier (argument %s manquant).%sErreur de chargement du fichier (fichier manquant ?).%sErreur de chargement du fichier (nom de fichier manquant).%sErreurs trouvéesTout évaluerÉvaluer la cellule avec GAP, Singular, etc.Évaluer la celluleÉvaluer toutes les cellules de la feuille de travailÉvaluer toutes les cellules avec %(i)sQuitter "%(wanted)s" attendu après "%(key)s", trouvé "%(token)s" à la placeCouleur "%(arg)s" attendue après "%(key)s"Entier "%(arg)s" attendu après "%(key)s"Entier "%(key)s" attendu avant "%(token)s"ÉchecÉchec de sauvegarde de la feuille de travailVersion statique rapide de la documentationFévrierFichier...Fichiers et ScriptsTrouver Aide et DocumentationMot de passe oubliéRecherche dans la documentation et le code sourcePouah, vous ne pouvez pas tromper le système d'évaluation aussi facilement !Mathématiques pures et appliquées, générales et avancéesObtenir l'imagePremiers pas en SageDonner accès à votre feuille de travail aux collaborateurs ci-dessusAller à la feuille de travailAideAide contextuelleAide par clavardage (IRC)Bonjour %s! CacherCacher tous les résultatsCacher tous les résultatsCacher/montrer les résultatsSélectionner du texte et faire Ctrl+. pour le commenter et Ctrl+, pour le dé-commenter. Aussi possible avec Ctrl+3 et Ctrl+4.Sélectionner du texte et taper > pour l'indenter et < pour le désindenter (marche avec Safari et Firefox). Dans Firefox, marche aussi avec Tab et Maj+Tab.HistoriquePage principaleComment construire ... dans Sage ?Combien de bits y a-t-il dans un octet ?Comment utiliser le Bloc-note SageIntervalle de vérification d'inactivité (en secondes)Terminaison après durée d'inactivité (en secondes)Si vous créez un fichier $HOME/.sage/notebook.css, il sera utilisé pour le rendu du Bloc-note Sage. Voir Mot de passe incorrectIndenter les blocsRègles d'entréeInsérer une nouvelle celluleInsérer une cellule de texteGadgets dynamiques interactifsUtiliser cette feuille de travail en mode interactifInterrompreInterrompre les calculs en coursInterrompre et relancer les sessionsTentative d'interruption.Interrompre les calculs en cours, si possibleRéponse incorrecteAdresse courriel invalideNom d'utilisateur invalideInviter des collaborateursEst-ce que pi > e ?JanvierApplet Java cachéePour utiliser le Bloc-note Sage, il faut autoriser Javascript.Image JmolJuilletJuinRaccourcis claviers et sourisLangueDernière modificationApprendre à écrire des programmes SageAutoriser d'autres utilisateurs à modifier cette feuille de travailCharger une feuille de travail depuis un fichierCharger une feuille de travailCharger des fichiers Sage ou PythonCharger et sauver des objetsCharger et sauver des sessionsHistoriqueConnexionSe connecter pour éditer un copieDéconnexion du Bloc-note SageRendre cette feuille de travail visible au publicGérer les comptes utilisateursMarsLongueur maximale de l'historiqueMaiMinutes :Déplacer la souris jusqu'à faire apparaître une barre bleue. Utiliser Maj+Clic sur la barre bleue pour créer une nouvelle cellule texte. Double-cliquer sur le texte pour l'éditer. Utiliser $...$ et $$...$$, pour insérer des formules mathématiques dans une cellule texte.Récupérer depuis la corbeilleMettre à la corbeille les feuilles de travail choisiesMettre cette feuille de travail à la corbeilleMode multi-celluleNouvelle feuille de travailNouvelle adresse courrielNouveau mot de passePas de nouveau mot de passe fourniNouvelle feuille de travailPlus nouveauLe plus nouveauNonPas de réponse fourniePas de fichiers de donnéesPas d'adresse courriel fourniePas de mot de passe fourniPas de feuille de travail de ce nom.Pas de nom d'utilisateur fourniNon confirméParamètres du Bloc-note SageNovembreChoix du nombre de colonnesOctobreAncien mot de passeAncien mot de passe non fourniPlus ancienLe plus ancienMode mono-celluleSeul le possesseur d'une feuille de travail peut la partager. Vous pouvez faire ce que vous voulez en faisant votre propre copie.Ou bien entrer l'adresse URL d'un fichier sur internet :Ou bien entrer l'adresse URL d'une feuille de travail sur internet :Ou donner le nom d'un nouveau fichier, qui sera créé :Autres feuilles de travail publiées...PropriétaireCorrection des parenthèsesPasserMot de passeLes mots de passe ne correspondent pasChoisir un nom d'utilisateurMerci de demander à l'administrateur du serveur de choisir une question !Entrer un nom pour cette feuille de travailVeuillez vous connecter au Bloc-note SageMerci de demander une feuille de travail spécifiqueMerci de choisir une feuille de travail à charger.%sMerci de taper à nouveau le nouveau mot de passe.Échec possible de suppression de la feuille de travail.Taper Ctrl+; dans une cellule pour la couper en deux et Ctrl+Backspace pour fusionner deux cellules. Taper Ctrl+Entrée pour couper une cellule en deux et évaluer les deux parties.Taper Maj+Entrée. On peut lancer plusieurs calculs à la fois. En tapant plutôt Alt+Entrée, une nouvelle cellule est crée après la cellule courante. En tapant Ctrl+Entrée, la cellule est coupée en deux et les deux parties évaluées séparément.Taper Tab avec le curseur sur une commande. Dans certains navigateurs (par ex. Opera) il faut taper Ctrl-Espace plutôt que Tab.Affichage amélioré (typographie)ImprimerImprimer cette feuille de travailProblème lors de l'insertion d'une cellule après la cellule courante.\nPublierPublier cette feuille de travailPubliéFeuilles de travail publiéesPublié le %(t)sÉcrire "%gap", "%singular" etc. comme première ligne d'une cellule, le reste de la cellule est alors évalué avec ce système.Taper ?? après un objet ou une fonction et appuyer sur Tab ou Maj+Entrée (la combinaison Maj+Entrée écrit les sources dans la feuille de travail).Écrire @interact dans la ligne précédant la définition d'une fonction. Voir interact? pour plus d'informations.Placer la souris entre une sortie et une entrée, pour faire apparaître la ligne horizontale, puis cliquer. En tapant Alt+Entrée dans une cellule, une nouvelle cellule est créée juste en dessous.Quitter le processus de la feuille de travailÉvaluerÉvaluationÉvaluation acceptéeÉvaluations pour %(wn)sRe-publier la feuille de travailVeuillez re-taper votre mot de passeManuel de référenceSe rappeler de moiRenommerRenommer cette feuille de travailRenommer cette feuille de travailSignaler un problèmeSignaler un problème ou un bug pour améliorer SageExiger une adresse courriel pour ouvrir un compteÉvaluer à nouveauRéinitialiserRelancerRelancer le processus de la feuille de travailRelancer la feuille de travailRevenir à Importer ou créer un fichier de données ou %s.Saisir à nouveau le nouveau mot de passeRétablir cette versionRévisionRévision %(lr)sHistorique des versionsListe des révisionsRévision datant de %(ta)sDocumentation de SageBloc-note SageBloc-note Sage versionNavigateur des sources SageUtilisateurs de Sage :Sage permet d'utiliser facilement dans un cadre unique la plupart des logiciels mathématiques. Sage incorpore GAP, GP/PARI, Maxima, Singular et des douzaines d'autres logiciels libres.Sage versionSage : historique pour %(u)sSauverSauver & quitterSauver les modificationsSauver et quitter la feuille de travailSauver les modificationsSauver les modifications et fermer la fenêtreIntervalle de sauvegarde automatique (en secondes)Sauver cette feuille de travail dans un fichier .swsSauver cette feuille de travail dans un fichierRechercher des feuilles de travailChercher dans la documentation en tapant
    search_doc("ma requête")
    dans une cellule puis taper Maj+Entrée. Chercher dans le code source de Sage en tapant
    search_src("ma requête")
    dans une cellule puis taper Maj+Entrée. Les requêtes peuvent être des expressions régulières.Recherche du serveur Sage...Choisir un fonction agissant sur un fichierChoisir une fonctionChoisir un fournisseur OpenIDChoisir un fichier attachéEnvoyerSeptembreServeurParamètresPartagerPartager maintenantPartager cette feuille de travailScripts ShellMontrerMontrer tous les résultatsMontrer tous les résultatsConnexionDéconnexionInscriptionOuvrir un compte dans le Bloc-note SageConnexion à un nouveau compte de Bloc-note SageQuelqu'un d'autre regarde cette feuille de travailDésolé, il vous faut un navigateur supportant la balise <canvas>.Code sourceBlocs de cellules spécialesDécouper ou fusionner des cellulesCommencerVersion statique...StatutTerminerCesser de publierStopper les feuilles de travail choisiesSoumettreSuppression réussie de "%s" SuspendreSuspendreNom de fichier suspect "%s" trouvé lors du chargement .%sPasser au mode multi-cellulePasser au mode mono-celluleComplétion par TabTexteMerci d'avoir évalué la feuille de travail %s ! Vous pouvez voir toutes les évaluations de cette feuille de travail.Merci de votre enregistrement dans le Bloc-note Sage. Pour compléter l'enregistrement, veuillez copier-coller le lien suivant dans votre navigateur : %s://%s:%s/confirm?key=%s Ce lien vous mènera à une page qui confirmera que vous avez bien été enregistrés.Le Bloc-note Sage est une collection de feuilles de travail, d'objets sauvés et d'information sur les utilisateursBloc-note SageLe Bloc-note Sage a été écrit principalement par William Stein avec des contributions notables de Tom Boothby, Timothy Clemans, Alex Clemesha, Mike Hansen, Bobby Moretti, Yi Qiang et Dorian Raymer.Le système de configuration n'est pas actif.Le mot de passe de l'utilisateur %(u)s a été réinitialisé en %(p)sLes mots de passe ne correspondent pas.L'utilisateur "%s" ne possède pas de feuille de travail "%s".Le nom d'utilisateur doit commencer par un lettre, comporter entre 4 et 32 signes. Il peut contenir seulement des lettres, des nombres, des _ et un point (.).La variable DIR contient le répertoire dans lequel le Bloc-note Sage a été lancé. Pour ouvrir un fichier dans ce répertoire, taper "open(DIR+'nomdefichier')".La fonction "%s" n'est pas définie.Il n'y a aucune feuille de travail publiée.Il n'y a pas de feuille de travail publié sous le nom "%s". Redirection vers la liste des feuilles de travail publiées dans 10 secondes...

    Erreur lors du chargement de "%s" (merci de vérifier l'URL).%sIl s'est produit une erreur lors du chargement de la feuille de travail. Peut-être est-elle dans un format obsolète, ou pire encore. Si vous avez désespérement besoin de son contenu, vous pouvez contacter le groupe sage-support et y poster un lien vers votre feuille de travail. Autre solution : un fichier .sws est juste un fichier compressé au format tar+bzip ; regardez son contenu ! %sCette feuille de travail est actuellement partagée avec les personnes listées dans la boîte ci-dessous.Cette page est évaluée %(wr).1f.Cette URL n'est accessible que via une requête POST.Cette feuille de travail est en mode lecture seule. Faire une copie ou contacter son possesseur pour la modifier.TempsTitre de la feuille de travail sauvéePour corriger des parenthèses manquantes ou incorrectes, taper Ctrl+0. Les parenthèses avant le curseur seront complétées, en tenant compte des chaînes de caractères et des commentaires Python.Pour essayer Sage, commencer iciPour sauver cette image, essayer un clic droit sur l'image pour la copier ou la sauver dans un fichier. Il est peut-être aussi possible de glisser-déposer vers le bureau.â– â– â– â– Afficher/cacher la barre horizontaleTotalTotauxCorbeilleEssayer à nouveau dans %(num)d seconde...Essayer à nouveau dans %(num)d secondes...TutorielTaper "%time" au début de la cellule.Taper "restart", pour relancer l’interpréteur Sage pour une feuille de travail donné. (Il faut d'abord l'interrompre.)Taper ? après un objet ou une fonction et appuyer sur Tab ou Maj+Entrée (la combinaison Maj+Entrée écrit la documentation dans la feuille de travail).Type de question/défiTaper pretty_print_default() dans une cellule puis taper Maj+Entrée. Les sorties suivantes seront alors typographiées.Mise en forme de tous les résultatsimpossible d'interrompre le calcul.Extraire des archivesExtraire des archives les feuilles de travail choisies, pour les faire apparaître dans la liste par défautAnnuler la suppressionDéfaireReprendreSans titreActualiséImporterImporter une feuille de travailImporter ou créer un fichier de donnéesImporter ou créer un fichier de données attaché à la feuille de travail "%(wn)s" Importer ou créer un fichier de données dans un large choix de formatsImporter ou créer un fichierImporter une feuille de travail (fichier .sws) vers le Bloc-note SageUtiliser "load nomdefichier.sage" et "load nomdefichier.py". Les fichiers attachés modifiés sont rechargés automatiquement. Le fichier $HOME/.sage/init.sage est attaché au démarrage s'il existe.Utiliser "load nomdefichier.sage" et "load nomdefichier.py". L'adresse est relative au répertoire dans lequel le Bloc-note Sage a été lancé. Les fichiers .sage sont d'abord passés par un filtre, mais pas les fichiers .py. On peut omettre l'extension (.py ou .sage). Des fichiers peuvent charger d'autres fichiers.Utiliser "save obj1 obj2 ..." und "load obj1 obj2 ...". Ceci permer de transférer facilement des objets d'une feuille de travail à un autre, ou de les conserver pour usage ultérieur.Utiliser "save_session('Nom')" pour sauver toutes les variables dans un objet. Utiliser "load_session('Nom')" pour restaurer toutes les variables d'une session sauvgardée.Utiliser la plupart des logiciels mathématiques via SageUtilisez Sage pour étudier le calcul différentiel, la théorie des nombres élémentaire ou avancée, la cryptographie, l'algèbre commutative, la théorie des groupes, la théorie des graphes, l'algèbre linéaire numérique et exacte et bien d'autres choses.Utiliser un langage de programmation majeurutiliser une question/défi pour l'ouverture de compteUtiliser une alternative libreUtiliser le menu Données pour charger des images et autres fichiers, et créer de nouveaux fichiers qui peuvent être partagés entre les feuilles de travail. La variable DATA contient le chemin vers les fichiers de données. Par exemple, pour ouvrir un fichier dans ce répertoire, écrire "open(DATA+'nomdefichier')". Si truc.sage est un fichier Sage que vous avez chargé, taper "load truc.sage" ; si truc.py est un fichier Python, vous pouvez l'importer en tapant "import truc".Trucs et AstucesUtilisateurL'utilisateur "%s" n'est pas autorisé à voir la page principale de "%s".Gestion des utilisateursNom d'utilisateurErreur de nom d'utilisateurNom d'utilisateur déjà prisNom d'utilisateur inconnuNom d'utilisateur indisponibleutilisateursVersionConsulter le manuel de référence de Sage (+ de 4000 pages)Consulter un historique des calculs récentsVoir les modifications successives de cette feuille de travailVoir en mode texteVoir cette feuille de travail en version texte brutBienvenue dans Sage ! Vous pouvez créer une nouvelle feuille de travail, consulter les feuilles de travail publiées ou lire la Documentation.Bienvenue !Comment nommer cette feuille de travail ? (si un nouveau nom est souhaité)Combien font 2 plus 3 ?Combien font 3 fois 8 ?Quel est le plus grand facteur premier de 15 ?Avec le Bloc-note Sage, chacun peut créer et publier des feuilles de travail interactives, et aussi collaborer. Dans une feuille de travail, on peut écrire du code en Sage, en Python ou dans d'autres langages inclus dans Sage.Répertoire de travailFeuille de travailLa feuille de travail est verrouillée. Insertion de cellules impossible.La feuille de travail est visible au public à l'adresse %(u)sLimites des processus des feuilles de travailUtilisateurs des processus de la feuille de travail (liste séparée par des virgules)Mot de passe erronéOuiVous n'êtes pas autorisé à déplacer "%s"Vous n'êtes pas connecté ou n'avez pas accès à la feuille de travail "%s".Vous pouvez publier votre feuille de travail sur internet, tout le monde pourra alors y accéder.Vous pouvez ajouter ou enlever des collaborateurs (séparer les noms d'utilisateurs par des virgules)Vous pouvez sauver %(f)s ou créer un copie liée à la feuille de travail.Vous devez vous connecter pour pouvoir éditer cette feuille de travail.Vous devez vous connecter, pour pouvoir évaluer cette feuille de travail.Vous demandez à évaluer une cellule que le serveur ne connaît pas.Votre travail dans Sage utilise Python, un langage de programmation très renommé. Vous pouvez combiner dans un programme des mathématiques et beaucoup d'autres choses.Votre combinaison Système/navigateur n'est pas supportée.\nMerci d'utiliser Firefox ou Opera sous Linux, Mac OS X ou Windows, ou encore Safari.Votre adresse courriel est requise pour confirmation du compte et récupération éventuelle. Vous allez recevoir par mail un lien de confirmation après votre connexion.Votre nouveau mot de passe est : %s Connectez-vous : %s://%s:%s/ Assurez-vous de modifier votre mot de passe via le menu Paramètres de la barre horizontale.Votre mot de passe doit comporter entre 4 et 32 caractères. Il ne doit pas contenir votre nom d'utilisateur, ni d'espace.Votre nom d'utilisateur doit commencer par une lettre et comporter entre 3 et 64 signes. Vous pouvez utiliser des lettres, des nombres, les caractères _ @ et des points.Votre feuille de travail aura une adresse unique (URL) que vous pourrez donner à vos amis et collègues.Parcourir le répertoireImpossible d'évaluer les cellules de la feuille de travailÄeÅ¡tina (ÄŒeská republika)Deutsch (Österreich)English (United States)español (España)Évaluerfrançais (France)Dernière modification le %(t)s par %(le)schargement en cours...optionnelou supprimer %(f)s.português (Brasil)publiéreCAPTCHA clé privéereCAPTCHA clé publiqueруÑÑкий (РоÑÑиÑ)exécution en courss (fin des essais d'actualisation).Choisir une feuille de travailукраїнÑька (Україна)pas impriméNom d'utilisateuro|ouisagenb-1.0.1/sagenb/translations/fr_FR/LC_MESSAGES/messages.po000066400000000000000000002365451311436262400237030ustar00rootroot00000000000000# Translations template for SAGE Notebook. # Copyright (C) 2013 SAGE # This file is distributed under the same license as the SAGE project. # FIRST AUTHOR chapoton@math.univ-lyon1.fr, 2013. # msgid "" msgstr "" "Project-Id-Version: Sage Notebook 0.8\n" "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" "POT-Creation-Date: 2011-06-18 15:38-0300\n" "PO-Revision-Date: 2014-03-08 21:21+0100\n" "Last-Translator: Frédéric Chapoton \n" "Language-Team: Frédéric Chapoton \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Generated-By: Babel 0.9.5\n" "Plural-Forms: nplurals=2; plural=n>1;\n" "X-Poedit-Language: French\n" "X-Poedit-Country: FRANCE\n" "X-Poedit-SourceCharset: utf-8\n" msgid "cs_CZ" msgstr "ÄeÅ¡tina (ÄŒeská republika)" msgid "de_AT" msgstr "Deutsch (Österreich)" msgid "en_US" msgstr "English (United States)" msgid "es_ES" msgstr "español (España)" msgid "pt_BR" msgstr "português (Brasil)" msgid "ru_RU" msgstr "руÑÑкий (РоÑÑиÑ)" msgid "fr_FR" msgstr "français (France)" msgid "uk_UA" msgstr "українÑька (Україна)" #: data/sage/html/base.html:31 #: data/sage/html/login.html:35 msgid "The Sage Notebook" msgstr "Bloc-note Sage" #: data/sage/html/base.html:33 msgid "Searching for Sage server..." msgstr "Recherche du serveur Sage..." #: data/sage/html/base.html:35 msgid "Version" msgstr "Version" #: data/sage/html/base_authenticated.html:7 msgid "Please log in to the Sage notebook" msgstr "Veuillez vous connecter au Bloc-note Sage" #: data/sage/html/base_authenticated.html:7 msgid "Log in" msgstr "Connexion" #: data/sage/html/base_authenticated.html:9 msgid "Toggle the top bar" msgstr "Afficher/cacher la barre horizontale" #: data/sage/html/base_authenticated.html:9 #: data/sage/html/test_report.html:123 msgid "Toggle" msgstr "â– â– â– â– " #: data/sage/html/base_authenticated.html:10 msgid "Back to your personal worksheet list" msgstr "Revenir à la liste de vos feuilles de travail" #: data/sage/html/base_authenticated.html:10 msgid "Home" msgstr "Page principale" #: data/sage/html/base_authenticated.html:12 #: data/sage/html/base_authenticated.html:14 msgid "Published" msgstr "Publié" #: data/sage/html/base_authenticated.html:14 msgid "Browse the published worksheets" msgstr "Parcourir les feuilles de travail publiées" #: data/sage/html/base_authenticated.html:15 msgid "View a log of recent computations" msgstr "Consulter un historique des calculs récents" #: data/sage/html/base_authenticated.html:15 msgid "Log" msgstr "Historique" #: data/sage/html/base_authenticated.html:17 msgid "Change account settings including password" msgstr "Changer les paramètres du compte, dont le mot de passe" #: data/sage/html/base_authenticated.html:17 msgid "Settings" msgstr "Paramètres" #: data/sage/html/base_authenticated.html:18 msgid "Documentation" msgstr "Documentation" #: data/sage/html/base_authenticated.html:18 msgid "Help" msgstr "Aide" #: data/sage/html/base_authenticated.html:19 msgid "Report a problem or submit a bug to improve Sage" msgstr "Signaler un problème ou un bug pour améliorer Sage" #: data/sage/html/base_authenticated.html:19 msgid "Report a Problem" msgstr "Signaler un problème" #: data/sage/html/base_authenticated.html:20 msgid "Log out of the Sage notebook" msgstr "Déconnexion du Bloc-note Sage" #: data/sage/html/base_authenticated.html:20 msgid "Sign out" msgstr "Déconnexion" #: data/sage/html/docs.html:3 msgid "Sage Documentation" msgstr "Documentation de Sage" #: data/sage/html/docs.html:15 msgid "To quickly try out Sage start here" msgstr "Pour essayer Sage, commencer ici" #: data/sage/html/docs.html:15 msgid "Tutorial" msgstr "Tutoriel" #: data/sage/html/docs.html:16 msgid "View a 4000+ page reference manual about Sage" msgstr "Consulter le manuel de référence de Sage (+ de 4000 pages)" #: data/sage/html/docs.html:16 msgid "Reference Manual" msgstr "Manuel de référence" #: data/sage/html/docs.html:17 msgid "Learn to write Sage programs" msgstr "Apprendre à écrire des programmes Sage" #: data/sage/html/docs.html:17 msgid "Developer Guide" msgstr "Guide du développeur" #: data/sage/html/docs.html:18 msgid "How do I construct ... in Sage?" msgstr "Comment construire ... dans Sage ?" #: data/sage/html/docs.html:18 msgid "Constructions" msgstr "Constructions" #: data/sage/html/docs.html:21 msgid "Static version..." msgstr "Version statique..." #: data/sage/html/docs.html:21 msgid "Fast Static Versions of the Documentation" msgstr "Version statique rapide de la documentation" #: data/sage/html/docs.html:22 msgid "Help via Internet Chat (IRC)" msgstr "Aide par clavardage (IRC)" #: data/sage/html/docs.html:28 msgid "How to use the Sage Notebook" msgstr "Comment utiliser le Bloc-note Sage" #: data/sage/html/docs.html:30 msgid "A worksheet is an ordered list of Sage calculations with output." msgstr "Une feuille de travail est une liste ordonnée de commandes Sage avec leurs résultats." #: data/sage/html/docs.html:31 msgid "A session is a worksheet and a set of variables in some state." msgstr "Une session est une feuille de travail et un ensemble de variables dans un état donné." #: data/sage/html/docs.html:32 msgid "The Sage notebook is a collection of worksheets, saved objects, and user information." msgstr "Le Bloc-note Sage est une collection de feuilles de travail, d'objets sauvés et d'information sur les utilisateurs" #: data/sage/html/docs.html:45 msgid "The Sage Notebook was primarily written by William Stein with substantial contributions from Tom Boothby, Timothy Clemans, Alex Clemesha, Mike Hansen, Bobby Moretti, Yi Qiang, and Dorian Raymer." msgstr "Le Bloc-note Sage a été écrit principalement par William Stein avec des contributions notables de Tom Boothby, Timothy Clemans, Alex Clemesha, Mike Hansen, Bobby Moretti, Yi Qiang et Dorian Raymer." #: data/sage/html/error_message.html:4 #: data/sage/html/login.html:63 #: data/sage/html/login.html:70 #: data/sage/html/login.html:98 #: data/sage/html/login.html:100 #: data/sage/html/recaptcha.html:27 #: data/sage/html/test_report.html:112 #: data/sage/html/test_report.html:131 #: data/sage/html/accounts/registration.html:20 #: data/sage/html/accounts/registration.html:23 #: data/sage/html/accounts/registration.html:26 #: data/sage/html/accounts/registration.html:36 #: data/sage/html/accounts/registration.html:39 #: data/sage/html/accounts/registration.html:46 #: data/sage/html/accounts/registration.html:57 #: data/sage/html/accounts/registration.html:60 #: data/sage/html/accounts/registration.html:69 #: data/sage/html/accounts/registration.html:72 #: data/sage/html/settings/admin_add_user.html:17 #: data/sage/html/settings/admin_add_user.html:19 #: data/sage/js/translated-messages.js:17 msgid "Error" msgstr "Erreur" #: data/sage/html/error_message.html:19 msgid "Continue" msgstr "Continuer" #: data/sage/html/history.html:3 #, python-format msgid "Sage: History for %(u)s" msgstr "Sage : historique pour %(u)s" #: data/sage/html/history.html:13 msgid "Click here to turn the above into a Sage worksheet" msgstr "Cliquer ici pour transformer ce qui précède en une feuille de travail" #: data/sage/html/history.html:13 msgid "Create a new Sage worksheet version of the last 100 commands in the above log." msgstr "Créer une nouvelle feuille de travail avec les 100 dernières commandes de la liste ci-dessus" #: data/sage/html/login.html:12 msgid "username" msgstr "Nom d'utilisateur" #: data/sage/html/login.html:13 msgid "Select an OpenID provider" msgstr "Choisir un fournisseur OpenID" #: data/sage/html/login.html:14 msgid "Send" msgstr "Envoyer" #: data/sage/html/login.html:22 #: data/sage/html/login.html:78 msgid "Sign in" msgstr "Connexion" #: data/sage/html/login.html:28 #, python-format msgid "Congratulations %(u)s! You can now sign into the Sage Notebook." msgstr "Bravo %(u)s ! Vous pouvez maintenant vous connecter au Bloc-note Sage." #: data/sage/html/login.html:32 msgid "Welcome!" msgstr "Bienvenue !" #: data/sage/html/login.html:33 msgid "Sage is a different approach to mathematics software." msgstr "Sage est une approche différente des logiciels mathématiques." #: data/sage/html/login.html:36 msgid "With the Sage Notebook anyone can create, collaborate on, and publish interactive worksheets. In a worksheet, one can write code using Sage, Python, and other software included in Sage." msgstr "Avec le Bloc-note Sage, chacun peut créer et publier des feuilles de travail interactives, et aussi collaborer. Dans une feuille de travail, on peut écrire du code en Sage, en Python ou dans d'autres langages inclus dans Sage." #: data/sage/html/login.html:39 msgid "General and Advanced Pure and Applied Mathematics" msgstr "Mathématiques pures et appliquées, générales et avancées" #: data/sage/html/login.html:40 msgid "Use Sage for studying calculus, elementary to very advanced number theory, cryptography, commutative algebra, group theory, graph theory, numerical and exact linear algebra, and more." msgstr "Utilisez Sage pour étudier le calcul différentiel, la théorie des nombres élémentaire ou avancée, la cryptographie, l'algèbre commutative, la théorie des groupes, la théorie des graphes, l'algèbre linéaire numérique et exacte et bien d'autres choses." #: data/sage/html/login.html:43 msgid "Use an Open Source Alternative" msgstr "Utiliser une alternative libre" #: data/sage/html/login.html:44 msgid "By using Sage you help to support a viable open source alternative to Magma, Maple, Mathematica, and MATLAB. Sage includes many high-quality open source math packages." msgstr "En utilisant Sage, vous soutenez une alternative libre à Magma®, Maple®, Mathematica® et MATLAB®. Sage incorpore de nombreux logiciels mathématiques libres de grande qualité." #: data/sage/html/login.html:47 msgid "Use Most Mathematics Software from Within Sage" msgstr "Utiliser la plupart des logiciels mathématiques via Sage" #: data/sage/html/login.html:48 msgid "Sage makes it easy for you to use most mathematics software together. Sage includes GAP, GP/PARI, Maxima, and Singular, and dozens of other open packages." msgstr "Sage permet d'utiliser facilement dans un cadre unique la plupart des logiciels mathématiques. Sage incorpore GAP, GP/PARI, Maxima, Singular et des douzaines d'autres logiciels libres." #: data/sage/html/login.html:51 msgid "Use a Mainstream Programming Language" msgstr "Utiliser un langage de programmation majeur" #: data/sage/html/login.html:52 msgid "You work with Sage using the highly regarded scripting language Python. You can write programs that combine serious mathematics with anything else." msgstr "Votre travail dans Sage utilise Python, un langage de programmation très renommé. Vous pouvez combiner dans un programme des mathématiques et beaucoup d'autres choses." #: data/sage/html/login.html:60 #: data/sage/html/accounts/account_recovery.html:13 msgid "Username" msgstr "Nom d'utilisateur" #: data/sage/html/login.html:63 msgid "Username is not in the system" msgstr "Nom d'utilisateur inconnu" #: data/sage/html/login.html:67 #: data/sage/html/settings/user_management.html:13 msgid "Password" msgstr "Mot de passe" #: data/sage/html/login.html:70 msgid "Wrong password" msgstr "Mot de passe erroné" #: data/sage/html/login.html:74 msgid "Remember me" msgstr "Se rappeler de moi" #: data/sage/html/login.html:83 msgid "Sign up for a new Sage Notebook account" msgstr "Connexion à un nouveau compte de Bloc-note Sage" #: data/sage/html/login.html:87 msgid "Browse published Sage worksheets
    (no login required)" msgstr "Consulter les feuilles de travail publiées
    (pas de connexion nécessaire)" #: data/sage/html/login.html:91 msgid "Forgot password" msgstr "Mot de passe oublié" #: data/sage/html/login.html:98 msgid "Creating new users is disabled by the administrator." msgstr "L'ouverture de compte est interdite par l'administrateur." #: data/sage/html/login.html:100 msgid "Javascript must be enabled in order to use the Sage Notebook." msgstr "Pour utiliser le Bloc-note Sage, il faut autoriser Javascript." #: data/sage/html/source_code.html:3 #: notebook/tutorial.py:358 msgid "Source Code" msgstr "Code source" #: data/sage/html/source_code.html:13 msgid "Sage Source Browser" msgstr "Navigateur des sources Sage" #: data/sage/html/source_code.html:14 msgid "browse directory" msgstr "Parcourir le répertoire" #: data/sage/html/test_report.html:79 msgid "Sage Notebook version" msgstr "Bloc-note Sage version" #: data/sage/html/test_report.html:85 msgid "Sage version" msgstr "Sage version" #: data/sage/html/test_report.html:91 msgid "Environment" msgstr "Environnement" #: data/sage/html/test_report.html:96 msgid "Start" msgstr "Commencer" #: data/sage/html/test_report.html:100 #: data/sage/html/worksheet_listing.html:73 msgid "Stop" msgstr "Terminer" #: data/sage/html/test_report.html:104 msgid "Elapsed" msgstr "Temps écoulé" #: data/sage/html/test_report.html:108 msgid "Status" msgstr "Statut" #: data/sage/html/test_report.html:110 #: data/sage/html/test_report.html:129 msgid "Pass" msgstr "Passer" #: data/sage/html/test_report.html:111 #: data/sage/html/test_report.html:130 msgid "Fail" msgstr "Échec" #: data/sage/html/test_report.html:113 msgid "Total" msgstr "Total" #: data/sage/html/test_report.html:121 msgid "Hide" msgstr "Cacher" #: data/sage/html/test_report.html:122 msgid "Show" msgstr "Montrer" #: data/sage/html/test_report.html:128 msgid "Cases / Tests" msgstr "Cas / Tests" #: data/sage/html/test_report.html:132 msgid "Count" msgstr "Compte" #: data/sage/html/test_report.html:141 msgid "Totals" msgstr "Totaux" #: data/sage/html/upload.html:10 msgid "Upload worksheet (an sws or txt file) to the Sage Notebook" msgstr "Importer une feuille de travail (fichier .sws) vers le Bloc-note Sage" #: data/sage/html/upload.html:14 msgid "Browse your computer to select a worksheet file to upload:" msgstr "Choisir un fichier .sws sur votre ordinateur :" #: data/sage/html/upload.html:18 msgid "Or enter the URL of a worksheet file on the web:" msgstr "Ou bien entrer l'adresse URL d'une feuille de travail sur internet :" #: data/sage/html/upload.html:22 #: data/sage/html/notebook/upload_data_window.html:27 msgid "What do you want to call it? (if different than the original name)" msgstr "Comment nommer cette feuille de travail ? (si un nouveau nom est souhaité)" #: data/sage/html/upload.html:25 msgid "Upload Worksheet" msgstr "Importer une feuille de travail" #: data/sage/html/worksheet_listing.html:9 msgid "Published Worksheets" msgstr "Feuilles de travail publiées" #: data/sage/html/worksheet_listing.html:11 msgid "Deleted Worksheets" msgstr "Feuilles de travail supprimées" #: data/sage/html/worksheet_listing.html:13 msgid "Active Worksheets" msgstr "Feuilles de travail actives" #: data/sage/html/worksheet_listing.html:15 msgid "Archived Worksheets" msgstr "Feuilles de travail archivées" #: data/sage/html/worksheet_listing.html:45 msgid "New Worksheet" msgstr "Nouvelle feuille de travail" #: data/sage/html/worksheet_listing.html:46 msgid "Upload" msgstr "Importer" #: data/sage/html/worksheet_listing.html:47 msgid "Download All Active" msgstr "Exporter toutes les feuilles de travail actives" #: data/sage/html/worksheet_listing.html:54 msgid "Search Worksheets" msgstr "Rechercher des feuilles de travail" #: data/sage/html/worksheet_listing.html:62 msgid "Unarchive selected worksheets so it appears in the default worksheet list" msgstr "Extraire des archives les feuilles de travail choisies, pour les faire apparaître dans la liste par défaut" #: data/sage/html/worksheet_listing.html:62 msgid "Unarchive" msgstr "Extraire des archives" #: data/sage/html/worksheet_listing.html:64 msgid "Archive selected worksheets so they do not appear in the default worksheet list" msgstr "Archiver les feuilles de travail choisies, pour les faire disparaître dans la liste par défaut" #: data/sage/html/worksheet_listing.html:64 msgid "Archive" msgstr "Archiver" #: data/sage/html/worksheet_listing.html:68 msgid "Move the selected worksheets to the trash" msgstr "Mettre à la corbeille les feuilles de travail choisies" #: data/sage/html/worksheet_listing.html:68 msgid "Delete" msgstr "Supprimer" #: data/sage/html/worksheet_listing.html:70 msgid "Move the selected worksheets out of the trash" msgstr "Récupérer depuis la corbeille" #: data/sage/html/worksheet_listing.html:70 msgid "Undelete" msgstr "Annuler la suppression" #: data/sage/html/worksheet_listing.html:73 msgid "Stop selected worksheets" msgstr "Stopper les feuilles de travail choisies" #: data/sage/html/worksheet_listing.html:75 msgid "Download selected worksheets" msgstr "Exporter les feuilles de travail choisies" #: data/sage/html/worksheet_listing.html:75 msgid "Download" msgstr "Exporter" #: data/sage/html/worksheet_listing.html:79 msgid "Current Folder" msgstr "Dossier actuel" #: data/sage/html/worksheet_listing.html:80 msgid "Active" msgstr "Actif" #: data/sage/html/worksheet_listing.html:81 msgid "Archived" msgstr "Archivé" #: data/sage/html/worksheet_listing.html:82 msgid "Trash" msgstr "Corbeille" #: data/sage/html/worksheet_listing.html:86 msgid "Empty Trash" msgstr "Vider la corbeille" #: data/sage/html/worksheet_listing.html:101 #: data/sage/html/worksheet/ratings_info.html:9 msgid "Rating" msgstr "Évaluation" #: data/sage/html/worksheet_listing.html:112 msgid "Owner" msgstr "Propriétaire" #: data/sage/html/worksheet_listing.html:112 msgid "Collaborators" msgstr "Collaborateurs" #: data/sage/html/worksheet_listing.html:118 #: data/sage/html/notebook/worksheet_revision_list.html:16 msgid "Last Edited" msgstr "Dernière modification" #: data/sage/html/worksheet_listing.html:128 msgid "There are no published worksheets." msgstr "Il n'y a aucune feuille de travail publiée." #: data/sage/html/worksheet_listing.html:134 msgid "Welcome to Sage! You can create a new worksheet, view published worksheets, or read the documentation." msgstr "Bienvenue dans Sage ! Vous pouvez créer une nouvelle feuille de travail, consulter les feuilles de travail publiées ou lire la Documentation." #: data/sage/html/worksheet_listing.html:176 msgid "running" msgstr "exécution en cours" #: data/sage/html/worksheet_listing.html:209 msgid "Add or Delete" msgstr "Ajouter ou supprimer" #: data/sage/html/worksheet_listing.html:211 msgid "Share now" msgstr "Partager maintenant" #: data/sage/html/worksheet_listing.html:216 msgid "published" msgstr "publié" #: data/sage/html/accounts/account_recovery.html:3 #: data/sage/html/accounts/account_recovery.html:8 msgid "Account Recovery" msgstr "Récupération de compte" #: data/sage/html/accounts/account_recovery.html:9 msgid "A new password will be emailed to the email address connected to your account. However if you didn't confirm your email address you will be unable to recover your account." msgstr "Un nouveau mot de passe sera envoyé à l'adresse courriel du compte. Si vous n'avez pas confirmé cette adresse, vous ne pourrez pas récupérer votre compte." #: data/sage/html/accounts/account_recovery.html:17 msgid "Submit" msgstr "Soumettre" #: data/sage/html/accounts/account_recovery.html:17 #: data/sage/html/accounts/registration.html:78 #: data/sage/html/notebook/download_or_delete_datafile.html:54 #: data/sage/html/notebook/edit_window.html:12 #: data/sage/html/settings/account_settings.html:10 #: data/sage/html/settings/account_settings.html:67 #: data/sage/html/settings/admin_add_user.html:26 #: data/sage/html/settings/notebook_settings.html:20 #: data/sage/html/settings/notebook_settings.html:27 msgid "Cancel" msgstr "Annuler" #: data/sage/html/accounts/registration.html:3 msgid "Sign up" msgstr "Inscription" #: data/sage/html/accounts/registration.html:9 msgid "Sign up for a Sage Notebook account" msgstr "Ouvrir un compte dans le Bloc-note Sage" #: data/sage/html/accounts/registration.html:11 msgid "Errors found" msgstr "Erreurs trouvées" #: data/sage/html/accounts/registration.html:11 msgid "Error found" msgstr "Erreur trouvée" #: data/sage/html/accounts/registration.html:16 msgid "Create a username" msgstr "Créer un utilisateur" #: data/sage/html/accounts/registration.html:17 msgid "Your username must start with a letter and be between 3 and 64 characters long. You may only use letters, numbers, underscores, @, and dots." msgstr "Votre nom d'utilisateur doit commencer par une lettre et comporter entre 3 et 64 signes. Vous pouvez utiliser des lettres, des nombres, les caractères _ @ et des points." #: data/sage/html/accounts/registration.html:20 msgid "No username given" msgstr "Pas de nom d'utilisateur fourni" #: data/sage/html/accounts/registration.html:23 msgid "Username already in use" msgstr "Nom d'utilisateur déjà pris" #: data/sage/html/accounts/registration.html:26 msgid "Bad username" msgstr "Nom d'utilisateur incorrect" #: data/sage/html/accounts/registration.html:30 msgid "Create a good password" msgstr "Créer un bon mot de passe" #: data/sage/html/accounts/registration.html:32 msgid "Your password must be between 4 and 32 characters long. Your password can not contain your username nor spaces." msgstr "Votre mot de passe doit comporter entre 4 et 32 caractères. Il ne doit pas contenir votre nom d'utilisateur, ni d'espace." #: data/sage/html/accounts/registration.html:36 msgid "No password given" msgstr "Pas de mot de passe fourni" #: data/sage/html/accounts/registration.html:39 msgid "Bad password" msgstr "Mot de passe incorrect" #: data/sage/html/accounts/registration.html:43 msgid "Re-type your password" msgstr "Veuillez re-taper votre mot de passe" #: data/sage/html/accounts/registration.html:46 msgid "Passwords didn't match" msgstr "Les mots de passe ne correspondent pas" #: data/sage/html/accounts/registration.html:51 msgid "Enter your email address" msgstr "Entrez votre adresse courriel" #: data/sage/html/accounts/registration.html:53 msgid "Your email address is required for account confirmation and recovery. You will be emailed a confirmation link right after you successfully sign up." msgstr "Votre adresse courriel est requise pour confirmation du compte et récupération éventuelle. Vous allez recevoir par mail un lien de confirmation après votre connexion." #: data/sage/html/accounts/registration.html:57 msgid "No email address given" msgstr "Pas d'adresse courriel fournie" #: data/sage/html/accounts/registration.html:60 msgid "Invalid email address" msgstr "Adresse courriel invalide" #: data/sage/html/accounts/registration.html:66 msgid "Answer a challenge" msgstr "Veuillez répondre à la question" #: data/sage/html/accounts/registration.html:69 msgid "No challenge response given" msgstr "Pas de réponse fournie" #: data/sage/html/accounts/registration.html:72 msgid "Invalid challenge response" msgstr "Réponse incorrecte" #: data/sage/html/accounts/registration.html:77 msgid "Create account" msgstr "Créer un compte" #: data/sage/html/notebook/afterpublish_window.html:8 #, python-format msgid "Worksheet is publicly viewable at %(u)s" msgstr "La feuille de travail est visible au public à l'adresse %(u)s" #: data/sage/html/notebook/afterpublish_window.html:9 #, python-format msgid "Published on %(t)s" msgstr "Publié le %(t)s" #: data/sage/html/notebook/afterpublish_window.html:11 msgid "Re-publish worksheet" msgstr "Re-publier la feuille de travail" #: data/sage/html/notebook/afterpublish_window.html:12 msgid "Stop publishing" msgstr "Cesser de publier" #: data/sage/html/notebook/afterpublish_window.html:14 #: data/sage/html/notebook/beforepublish_window.html:18 msgid "Automatically re-publish when changes are made" msgstr "Re-publier automatiquement lors de modifications" #: data/sage/html/notebook/base.html:74 msgid "Click to rename this worksheet" msgstr "Cliquer pour renommer cette feuille de travail" #: data/sage/html/notebook/base.html:79 msgid "Someone else is viewing this worksheet" msgstr "Quelqu'un d'autre regarde cette feuille de travail" #: data/sage/html/notebook/base.html:84 #: data/sage/html/notebook/text_cell.html:46 msgid "Save changes" msgstr "Sauver les modifications" #: data/sage/html/notebook/base.html:84 #: data/sage/html/settings/account_settings.html:9 #: data/sage/html/settings/account_settings.html:66 #: data/sage/html/settings/notebook_settings.html:19 #: data/sage/html/settings/notebook_settings.html:26 msgid "Save" msgstr "Sauver" #: data/sage/html/notebook/base.html:84 msgid "Save changes and close window" msgstr "Sauver les modifications et fermer la fenêtre" #: data/sage/html/notebook/base.html:84 msgid "Save & quit" msgstr "Sauver & quitter" #: data/sage/html/notebook/base.html:84 msgid "Discard changes to this worksheet" msgstr "Oublier les modifications de la feuille de travail" #: data/sage/html/notebook/base.html:84 msgid "Discard & quit" msgstr "Quitter sans sauver" #: data/sage/html/notebook/base.html:90 msgid "Select a file related function" msgstr "Choisir un fonction agissant sur un fichier" #: data/sage/html/notebook/base.html:90 msgid "File..." msgstr "Fichier..." #: data/sage/html/notebook/base.html:91 msgid "Load a new worksheet stored in a file" msgstr "Charger une feuille de travail depuis un fichier" #: data/sage/html/notebook/base.html:91 msgid "Load worksheet from a file..." msgstr "Charger une feuille de travail" #: data/sage/html/notebook/base.html:92 msgid "Create a new worksheet" msgstr "Créer un nouvelle feuille de travail" #: data/sage/html/notebook/base.html:92 msgid "New worksheet" msgstr "Nouvelle feuille de travail" #: data/sage/html/notebook/base.html:93 msgid "Save this worksheet to an sws file" msgstr "Sauver cette feuille de travail dans un fichier .sws" #: data/sage/html/notebook/base.html:93 msgid "Save worksheet to a file..." msgstr "Sauver cette feuille de travail dans un fichier" #: data/sage/html/notebook/base.html:94 #: data/sage/html/notebook/base.html:143 msgid "Print this worksheet" msgstr "Imprimer cette feuille de travail" #: data/sage/html/notebook/base.html:94 #: data/sage/html/notebook/base.html:143 msgid "Print" msgstr "Imprimer" #: data/sage/html/notebook/base.html:95 msgid "Rename this worksheet" msgstr "Renommer cette feuille de travail" #: data/sage/html/notebook/base.html:95 #: data/sage/js/translated-messages.js:11 msgid "Rename worksheet" msgstr "Renommer cette feuille de travail" #: data/sage/html/notebook/base.html:96 msgid "Copy this worksheet" msgstr "Copier cette feuille de travail" #: data/sage/html/notebook/base.html:96 msgid "Copy worksheet" msgstr "Copier cette feuille de travail" #: data/sage/html/notebook/base.html:97 msgid "Move this worksheet to the trash" msgstr "Mettre cette feuille de travail à la corbeille" #: data/sage/html/notebook/base.html:97 msgid "Delete worksheet" msgstr "Supprimer cette feuille de travail" #: data/sage/html/notebook/base.html:101 msgid "Select a worksheet function" msgstr "Choisir une fonction" #: data/sage/html/notebook/base.html:101 msgid "Action..." msgstr "Action..." #: data/sage/html/notebook/base.html:102 msgid "Interrupt currently running calculations, if possible" msgstr "Interrompre les calculs en cours, si possible" #: data/sage/html/notebook/base.html:102 msgid "Interrupt" msgstr "Interrompre" #: data/sage/html/notebook/base.html:103 msgid "Restart the worksheet process" msgstr "Relancer le processus de la feuille de travail" #: data/sage/html/notebook/base.html:103 msgid "Restart worksheet" msgstr "Relancer la feuille de travail" #: data/sage/html/notebook/base.html:104 msgid "Quit the worksheet process" msgstr "Quitter le processus de la feuille de travail" #: data/sage/html/notebook/base.html:104 msgid "Save and quit worksheet" msgstr "Sauver et quitter la feuille de travail" #: data/sage/html/notebook/base.html:106 msgid "Evaluate all input cells in the worksheet" msgstr "Évaluer toutes les cellules de la feuille de travail" #: data/sage/html/notebook/base.html:106 msgid "Evaluate All" msgstr "Tout évaluer" #: data/sage/html/notebook/base.html:107 msgid "Hide all output" msgstr "Cacher tous les résultats" #: data/sage/html/notebook/base.html:107 msgid "Hide All Output" msgstr "Cacher tous les résultats" #: data/sage/html/notebook/base.html:108 msgid "Show all output" msgstr "Montrer tous les résultats" #: data/sage/html/notebook/base.html:108 msgid "Show All Output" msgstr "Montrer tous les résultats" #: data/sage/html/notebook/base.html:109 msgid "Delete all output" msgstr "Supprimer tous les résultats" #: data/sage/html/notebook/base.html:109 msgid "Delete All Output" msgstr "Supprimer tous les résultats" #: data/sage/html/notebook/base.html:111 msgid "Switch to single-cell mode" msgstr "Passer au mode mono-cellule" #: data/sage/html/notebook/base.html:111 msgid "One Cell Mode" msgstr "Mode mono-cellule" #: data/sage/html/notebook/base.html:112 msgid "Switch to multi-cell mode" msgstr "Passer au mode multi-cellule" #: data/sage/html/notebook/base.html:112 msgid "Multi Cell Mode" msgstr "Mode multi-cellule" #: data/sage/html/notebook/base.html:115 msgid "Select an attached file" msgstr "Choisir un fichier attaché" #: data/sage/html/notebook/base.html:115 msgid "Data..." msgstr "Données..." #: data/sage/html/notebook/base.html:116 msgid "Upload or create a data file in a wide range of formats" msgstr "Importer ou créer un fichier de données dans un large choix de formats" #: data/sage/html/notebook/base.html:116 msgid "Upload or create file..." msgstr "Importer ou créer un fichier" #: data/sage/html/notebook/base.html:126 #, python-format msgid "Evaluate all input cells using %(i)s" msgstr "Évaluer toutes les cellules avec %(i)s" #: data/sage/html/notebook/base.html:132 msgid "Enable/disable pretty_printing" msgstr "Activer/désactiver l'affichage amélioré" #: data/sage/html/notebook/base.html:144 msgid "Interactively use this worksheet" msgstr "Utiliser cette feuille de travail en mode interactif" #: data/sage/html/notebook/base.html:144 msgid "Worksheet" msgstr "Feuille de travail" #: data/sage/html/notebook/base.html:145 msgid "Edit text version of this worksheet" msgstr "Éditer cette feuille de travail en version texte" #: data/sage/html/notebook/base.html:145 msgid "Edit" msgstr "Éditer" #: data/sage/html/notebook/base.html:146 msgid "View plain text version of this worksheet" msgstr "Voir cette feuille de travail en version texte brut" #: data/sage/html/notebook/base.html:146 msgid "Text" msgstr "Texte" #: data/sage/html/notebook/base.html:147 msgid "View changes to this worksheet over time" msgstr "Voir les modifications successives de cette feuille de travail" #: data/sage/html/notebook/base.html:147 msgid "Undo" msgstr "Défaire" #: data/sage/html/notebook/base.html:148 msgid "Let others edit this worksheet" msgstr "Autoriser d'autres utilisateurs à modifier cette feuille de travail" #: data/sage/html/notebook/base.html:148 msgid "Share" msgstr "Partager" #: data/sage/html/notebook/base.html:149 msgid "Make this worksheet publicly viewable" msgstr "Rendre cette feuille de travail visible au public" #: data/sage/html/notebook/base.html:149 msgid "Publish" msgstr "Publier" #: data/sage/html/notebook/base.html:157 msgid "Exit" msgstr "Quitter" #: data/sage/html/notebook/beforepublish_window.html:5 msgid "You can publish your worksheet to the Internet, where anyone will be able to access and view it online." msgstr "Vous pouvez publier votre feuille de travail sur internet, tout le monde pourra alors y accéder." #: data/sage/html/notebook/beforepublish_window.html:7 msgid "Your worksheet will be assigned a unique address (URL) that you can send to your friends and colleagues." msgstr "Votre feuille de travail aura une adresse unique (URL) que vous pourrez donner à vos amis et collègues." #: data/sage/html/notebook/beforepublish_window.html:9 msgid "Do you want to publish this worksheet?" msgstr "Voulez-vous publier cette feuille de travail ?" #: data/sage/html/notebook/beforepublish_window.html:14 msgid "Yes" msgstr "Oui" #: data/sage/html/notebook/beforepublish_window.html:15 msgid "No" msgstr "Non" #: data/sage/html/notebook/cell.html:63 msgid "Click here or press shift-return to evaluate" msgstr "Cliquer ici ou taper Maj-Entrée pour évaluer" #: data/sage/html/notebook/cell.html:64 msgid "evaluate" msgstr "Évaluer" #: data/sage/html/notebook/download_or_delete_datafile.html:35 msgid "Data file" msgstr "Fichier de données" #: data/sage/html/notebook/download_or_delete_datafile.html:39 #, python-format msgid "You may download %(f)s or create a linked copy to the worksheet" msgstr "Vous pouvez sauver %(f)s ou créer un copie liée à la feuille de travail." #: data/sage/html/notebook/download_or_delete_datafile.html:40 msgid "select worksheet" msgstr "Choisir une feuille de travail" #: data/sage/html/notebook/download_or_delete_datafile.html:44 #, python-format msgid "or delete %(f)s." msgstr "ou supprimer %(f)s." #: data/sage/html/notebook/download_or_delete_datafile.html:46 #, python-format msgid "Access %(f)s in this worksheet by typing DATA+'%(f)s'. Here DATA is a special variable that gives the exact path to all data files uploaded to this worksheet." msgstr "Utiliser DATA+'%(f)s' pour accéder à %(f)s dans cette feuille de travail. DATA est ici une variable spéciale, qui contient le chemin exact vers les fichiers attachés à la feuille de travail." #: data/sage/html/notebook/download_or_delete_datafile.html:54 #: data/sage/html/notebook/edit_window.html:11 msgid "Save Changes" msgstr "Sauver les modifications" #: data/sage/html/notebook/edit_window.html:10 msgid "Edit plain text" msgstr "Éditer en mode texte" #: data/sage/html/notebook/guest_worksheet_page.html:14 msgid "Edit this." msgstr "Éditer cette feuille de travail." #: data/sage/html/notebook/guest_worksheet_page.html:16 msgid "Log in to edit a copy." msgstr "Se connecter pour éditer un copie" #: data/sage/html/notebook/guest_worksheet_page.html:19 msgid "Edit a copy." msgstr "Éditer une copie." #: data/sage/html/notebook/guest_worksheet_page.html:28 msgid "Download." msgstr "Exporter." #: data/sage/html/notebook/guest_worksheet_page.html:34 #, python-format msgid "This page is rated %(wr).1f." msgstr "Cette page est évaluée %(wr).1f." #: data/sage/html/notebook/guest_worksheet_page.html:39 msgid "Rerate it:" msgstr "Évaluer à nouveau" #: data/sage/html/notebook/guest_worksheet_page.html:39 msgid "Rate it:" msgstr "Évaluer" #: data/sage/html/notebook/guest_worksheet_page.html:49 msgid "Other published feuilles de travail..." msgstr "Autres feuilles de travail publiées..." #: data/sage/html/notebook/plain_text_window.html:4 msgid "View plain text" msgstr "Voir en mode texte" #: data/sage/html/notebook/specific_revision.html:5 #, python-format msgid "Revision from %(ta)s ago" msgstr "Révision datant de %(ta)s" #: data/sage/html/notebook/specific_revision.html:5 msgid "Revision List" msgstr "Liste des révisions" #: data/sage/html/notebook/specific_revision.html:12 msgid "Older" msgstr "Plus ancien" #: data/sage/html/notebook/specific_revision.html:14 msgid "Oldest" msgstr "Le plus ancien" #: data/sage/html/notebook/specific_revision.html:18 msgid "Newer" msgstr "Plus nouveau" #: data/sage/html/notebook/specific_revision.html:20 msgid "Newest" msgstr "Le plus nouveau" #: data/sage/html/notebook/specific_revision.html:23 msgid "Revert to this one" msgstr "Rétablir cette version" #: data/sage/html/notebook/specific_revision.html:23 msgid "(note that images are not recorded)" msgstr "(note : les images ne sont pas enregistrées)" #: data/sage/html/notebook/specific_revision.html:24 msgid "Publish this one" msgstr "Publier cette feuille de travail" #: data/sage/html/notebook/text_cell.html:47 msgid "Cancel changes" msgstr "Annuler les modifications" #: data/sage/html/notebook/upload_data_window.html:7 #, python-format msgid "Upload or Create Data File to attach to worksheet \"%(wn)s\"" msgstr "Importer ou créer un fichier de données attaché à la feuille de travail \"%(wn)s\" " #: data/sage/html/notebook/upload_data_window.html:15 msgid "Browse your computer to select a file to upload:" msgstr "Choisir un fichier à charger :" #: data/sage/html/notebook/upload_data_window.html:19 msgid "Or enter the URL of a file on the web:" msgstr "Ou bien entrer l'adresse URL d'un fichier sur internet :" #: data/sage/html/notebook/upload_data_window.html:23 msgid "Or enter the name of a new file, which will be created:" msgstr "Ou donner le nom d'un nouveau fichier, qui sera créé :" #: data/sage/html/notebook/upload_data_window.html:30 msgid "Upload or Create Data File" msgstr "Importer ou créer un fichier de données" #: data/sage/html/notebook/worksheet_page.html:27 #: notebook/twist.py:413 #: notebook/twist.py:2217 #: notebook/worksheet.py:703 #: notebook/worksheet.py:723 #: notebook/worksheet.py:4079 msgid "Untitled" msgstr "Sans titre" #: data/sage/html/notebook/worksheet_revision_list.html:6 msgid "Revision History" msgstr "Historique des versions" #: data/sage/html/notebook/worksheet_revision_list.html:15 msgid "Revision" msgstr "Révision" #: data/sage/html/notebook/worksheet_revision_list.html:22 #, python-format msgid "Revision %(lr)s" msgstr "Révision %(lr)s" #: data/sage/html/notebook/worksheet_share.html:10 msgid "Share this document" msgstr "Partager cette feuille de travail" #: data/sage/html/notebook/worksheet_share.html:17 msgid "Only the owner of a worksheet is allowed to share it. You can do whatever you want if you make your own copy." msgstr "Seul le possesseur d'une feuille de travail peut la partager. Vous pouvez faire ce que vous voulez en faisant votre propre copie." #: data/sage/html/notebook/worksheet_share.html:19 msgid "This Sage Worksheet is currently shared with the people listed in the box below." msgstr "Cette feuille de travail est actuellement partagée avec les personnes listées dans la boîte ci-dessous." #: data/sage/html/notebook/worksheet_share.html:20 msgid "You may add or remove collaborators (separate user names by commas)." msgstr "Vous pouvez ajouter ou enlever des collaborateurs (séparer les noms d'utilisateurs par des virgules)" #: data/sage/html/notebook/worksheet_share.html:24 msgid "Give access to your worksheet to the above collaborators" msgstr "Donner accès à votre feuille de travail aux collaborateurs ci-dessus" #: data/sage/html/notebook/worksheet_share.html:24 msgid "Invite Collaborators" msgstr "Inviter des collaborateurs" #: data/sage/html/notebook/worksheet_share.html:28 msgid "Sage Users:" msgstr "Utilisateurs de Sage :" #: data/sage/html/settings/account_settings.html:3 #: data/sage/html/settings/base.html:13 msgid "Account Settings" msgstr "Paramètres du compte" #: data/sage/html/settings/account_settings.html:13 msgid "Change Auto-Save Interval" msgstr "Intervalle pour la sauvegarde automatique" #: data/sage/html/settings/account_settings.html:15 msgid "Minutes:" msgstr "Minutes :" #: data/sage/html/settings/account_settings.html:24 msgid "Change Password" msgstr "Changer le mot de passe" #: data/sage/html/settings/account_settings.html:30 msgid "Old password" msgstr "Ancien mot de passe" #: data/sage/html/settings/account_settings.html:34 msgid "New password" msgstr "Nouveau mot de passe" #: data/sage/html/settings/account_settings.html:38 msgid "Retype new password" msgstr "Saisir à nouveau le nouveau mot de passe" #: data/sage/html/settings/account_settings.html:46 msgid "Change E-mail Address" msgstr "Changer l'adresse courriel" #: data/sage/html/settings/account_settings.html:50 msgid "Current e-mail" msgstr "Adresse courriel actuelle" #: data/sage/html/settings/account_settings.html:54 msgid "New e-mail" msgstr "Nouvelle adresse courriel" #: data/sage/html/settings/admin_add_user.html:2 #: data/sage/html/settings/admin_add_user.html:6 msgid "Add New User" msgstr "Ajouter un utilisateur" #: data/sage/html/settings/admin_add_user.html:8 msgid "Username Error" msgstr "Erreur de nom d'utilisateur" #: data/sage/html/settings/admin_add_user.html:12 msgid "Pick a username" msgstr "Choisir un nom d'utilisateur" #: data/sage/html/settings/admin_add_user.html:13 msgid "The username must start with a letter and be between 4 and 32 characters long. It can only consist of letters, numbers, underscores, and one dot (.)." msgstr "Le nom d'utilisateur doit commencer par un lettre, comporter entre 4 et 32 signes. Il peut contenir seulement des lettres, des nombres, des _ et un point (.)." #: data/sage/html/settings/admin_add_user.html:17 msgid "Invalid username" msgstr "Nom d'utilisateur invalide" #: data/sage/html/settings/admin_add_user.html:19 msgid "Username taken" msgstr "Nom d'utilisateur indisponible" #: data/sage/html/settings/admin_add_user.html:25 msgid "Create Account" msgstr "Créer un compte" #: data/sage/html/settings/base.html:10 msgid "Manage Users" msgstr "Gérer les comptes utilisateurs" #: data/sage/html/settings/base.html:11 #: data/sage/html/settings/notebook_settings.html:2 msgid "Notebook Settings" msgstr "Paramètres du Bloc-note Sage" #: data/sage/html/settings/user_management.html:3 #: data/sage/html/settings/user_management.html:13 msgid "Users" msgstr "utilisateurs" #: data/sage/html/settings/user_management.html:7 msgid "User Management" msgstr "Gestion des utilisateurs" #: data/sage/html/settings/user_management.html:8 msgid "Add User" msgstr "Ajouter un utilisateur" #: data/sage/html/settings/user_management.html:10 #, python-format msgid "The password for the user %(u)s has been reset to %(p)s" msgstr "Le mot de passe de l'utilisateur %(u)s a été réinitialisé en %(p)s" #: data/sage/html/settings/user_management.html:13 msgid "Suspension" msgstr "Suspendre" #: data/sage/html/settings/user_management.html:16 msgid "Reset" msgstr "Réinitialiser" #: data/sage/html/settings/user_management.html:16 msgid "Unsuspend" msgstr "Reprendre" #: data/sage/html/settings/user_management.html:16 msgid "Suspend" msgstr "Suspendre" #: data/sage/html/worksheet/ratings_info.html:3 #: data/sage/html/worksheet/ratings_info.html:6 #, python-format msgid "Ratings for %(wn)s" msgstr "Évaluations pour %(wn)s" #: data/sage/html/worksheet/ratings_info.html:7 msgid "Go to the worksheet." msgstr "Aller à la feuille de travail" #: data/sage/html/worksheet/ratings_info.html:9 msgid "User" msgstr "Utilisateur" #: data/sage/html/worksheet/ratings_info.html:9 msgid "Comment" msgstr "Commentaire" #: data/sage/html/worksheet/time_last_edited.html:6 #, python-format msgid "last edited on %(t)s by %(le)s" msgstr "Dernière modification le %(t)s par %(le)s" #: data/sage/html/worksheet/time_since_last_edited.html:6 #: notebook/worksheet.py:2009 #, python-format msgid "%(t)s ago by %(le)s" msgstr "depuis %(t)s par %(le)s" #: data/sage/js/translated-messages.js:4 msgid "Click to download and install tex fonts." msgstr "Cliquer pour télécharger et installer les fontes TeX" #: data/sage/js/translated-messages.js:5 msgid "" "Your browser / OS combination is not supported.\\n" "Please use Firefox or Opera under Linux, Windows, or Mac OS X, or Safari." msgstr "" "Votre combinaison Système/navigateur n'est pas supportée.\\n" "Merci d'utiliser Firefox ou Opera sous Linux, Mac OS X ou Windows, ou encore Safari." #: data/sage/js/translated-messages.js:6 msgid "Java Applet Hidden" msgstr "Applet Java cachée" #: data/sage/js/translated-messages.js:7 msgid "Click here to pop out" msgstr "Cliquer ici pour ouvrir une mini-fenêtre" #: data/sage/js/translated-messages.js:8 msgid "Error applying function to worksheet(s)." msgstr "Erreur lors de l'application de la fonction à la feuille de travail" #: data/sage/js/translated-messages.js:9 msgid "Title of saved worksheet" msgstr "Titre de la feuille de travail sauvée" #: data/sage/js/translated-messages.js:10 msgid "Failed to save worksheet." msgstr "Échec de sauvegarde de la feuille de travail" #: data/sage/js/translated-messages.js:12 msgid "Please enter a name for this worksheet." msgstr "Entrer un nom pour cette feuille de travail" #: data/sage/js/translated-messages.js:13 msgid "Rename" msgstr "Renommer" #: data/sage/js/translated-messages.js:14 msgid "Possible failure deleting worksheet." msgstr "Échec possible de suppression de la feuille de travail." #: data/sage/js/translated-messages.js:15 msgid "unprinted" msgstr "pas imprimé" #: data/sage/js/translated-messages.js:16 msgid "You requested to evaluate a cell that, for some reason, the server is unaware of." msgstr "Vous demandez à évaluer une cellule que le serveur ne connaît pas." #: data/sage/js/translated-messages.js:18 msgid "This worksheet is read only. Please make a copy or contact the owner to change it." msgstr "Cette feuille de travail est en mode lecture seule. Faire une copie ou contacter son possesseur pour la modifier." #: data/sage/js/translated-messages.js:19 msgid "loading..." msgstr "chargement en cours..." #: data/sage/js/translated-messages.js:20 msgid "Error updating cell output after " msgstr "Erreur d'actualisation du résultat de la cellule après " #: data/sage/js/translated-messages.js:21 msgid "s (canceling further update checks)." msgstr "s (fin des essais d'actualisation)." #: data/sage/js/translated-messages.js:22 msgid "Problem inserting new input cell after current input cell.\\n" msgstr "Problème lors de l'insertion d'une cellule après la cellule courante.\\n" #: data/sage/js/translated-messages.js:23 msgid "Worksheet is locked. Cannot insert cells." msgstr "La feuille de travail est verrouillée. Insertion de cellules impossible." #: data/sage/js/translated-messages.js:24 msgid "Unable to interrupt calculation." msgstr "impossible d'interrompre le calcul." #: data/sage/js/translated-messages.js:25 msgid "Close this box to stop trying." msgstr "Fermer cette boîte pour cesser d'essayer." #: data/sage/js/translated-messages.js:26 msgid "Interrupt attempt" msgstr "Tentative d'interruption." #: data/sage/js/translated-messages.js:27 msgid "Restart, instead?" msgstr "Plutôt relancer Sage ?" #: data/sage/js/translated-messages.js:28 msgid "Emptying the trash will permanently delete all items in the trash. Continue?" msgstr "Vider la corbeille supprimera définitivement son contenu. Continuer ?" #: data/sage/js/translated-messages.js:29 msgid "Get Image" msgstr "Obtenir l'image" #: data/sage/js/translated-messages.js:30 msgid "Jmol Image" msgstr "Image Jmol" #: data/sage/js/translated-messages.js:31 msgid "To save this image, you can try right-clicking on the image to copy it or save it to a file, or you may be able to just drag the image to your desktop." msgstr "Pour sauver cette image, essayer un clic droit sur l'image pour la copier ou la sauver dans un fichier. Il est peut-être aussi possible de glisser-déposer vers le bureau." #: data/sage/js/translated-messages.js:32 msgid "Sorry, but you need a browser that supports the <canvas> tag." msgstr "Désolé, il vous faut un navigateur supportant la balise <canvas>." #: data/sage/js/translated-messages.js:33 #, python-format msgid "Trying again in %(num)d second..." msgid_plural "Trying again in %(num)d seconds..." msgstr[0] "Essayer à nouveau dans %(num)d seconde..." msgstr[1] "Essayer à nouveau dans %(num)d secondes..." #: notebook/challenge.py:179 msgid "Please ask the server administrator to configure a challenge!" msgstr "Merci de demander à l'administrateur du serveur de choisir une question !" #: notebook/challenge.py:217 msgid "Is pi > e?" msgstr "Est-ce que pi > e ?" #: notebook/challenge.py:217 msgid "y|yes" msgstr "o|oui" #: notebook/challenge.py:218 msgid "What is 3 times 8?" msgstr "Combien font 3 fois 8 ?" #: notebook/challenge.py:218 msgid "24|twenty-four" msgstr "24|vingt-quatre" #: notebook/challenge.py:219 msgid "What is 2 plus 3?" msgstr "Combien font 2 plus 3 ?" #: notebook/challenge.py:219 #: notebook/challenge.py:221 msgid "5|five" msgstr "5|cinq" #: notebook/challenge.py:220 msgid "How many bits are in one byte?" msgstr "Combien de bits y a-t-il dans un octet ?" #: notebook/challenge.py:220 msgid "8|eight" msgstr "8|huit" #: notebook/challenge.py:221 msgid "What is the largest prime factor of 15?" msgstr "Quel est le plus grand facteur premier de 15 ?" #: notebook/conf.py:120 msgid "Updated" msgstr "Actualisé" #: notebook/notebook.py:169 msgid "optional" msgstr "optionnel" #: notebook/register.py:19 #: notebook/register.py:26 #, python-format msgid "" "Hi %s!\n" "\n" msgstr "" "Bonjour %s!\n" "\n" #: notebook/register.py:20 #, python-format msgid "" "Thank you for registering for the Sage notebook. To complete your registration, copy and paste the following link into your browser:\n" "\n" "%s://%s:%s/confirm?key=%s\n" "\n" "You will be taken to a page which will confirm that you have indeed registered." msgstr "" "Merci de votre enregistrement dans le Bloc-note Sage. Pour compléter l'enregistrement, veuillez copier-coller le lien suivant dans votre navigateur :\n" "\n" "%s://%s:%s/confirm?key=%s\n" "\n" "Ce lien vous mènera à une page qui confirmera que vous avez bien été enregistrés." #: notebook/register.py:27 #, python-format msgid "" "Your new password is %s\n" "\n" "Sign in at %s://%s:%s/\n" "\n" "Make sure to reset your password by going to Settings in the upper right bar." msgstr "" "Votre nouveau mot de passe est : %s\n" "\n" "Connectez-vous : %s://%s:%s/\n" "\n" "Assurez-vous de modifier votre mot de passe via le menu Paramètres de la barre horizontale." #: notebook/server_conf.py:42 #: notebook/user_conf.py:24 msgid "Appearance" msgstr "Apparence" #: notebook/server_conf.py:43 msgid "Authentication" msgstr "Authentification" #: notebook/server_conf.py:44 msgid "Server" msgstr "Serveur" #: notebook/server_conf.py:49 msgid "Number of word-wrap columns" msgstr "Choix du nombre de colonnes" #: notebook/server_conf.py:55 msgid "Maximum history length" msgstr "Longueur maximale de l'historique" #: notebook/server_conf.py:61 msgid "Idle timeout (seconds)" msgstr "Terminaison après durée d'inactivité (en secondes)" #: notebook/server_conf.py:67 msgid "Idle check interval (seconds)" msgstr "Intervalle de vérification d'inactivité (en secondes)" #: notebook/server_conf.py:73 msgid "Save interval (seconds)" msgstr "Intervalle de sauvegarde automatique (en secondes)" #: notebook/server_conf.py:79 msgid "Doc pool size" msgstr "Volume de stockage des documents" #: notebook/server_conf.py:85 msgid "Worksheet process users (comma-separated list)" msgstr "Utilisateurs des processus de la feuille de travail (liste séparée par des virgules)" #: notebook/server_conf.py:91 msgid "Default system" msgstr "Système par défaut" #: notebook/server_conf.py:97 msgid "Pretty print (typeset) output" msgstr "Affichage amélioré (typographie)" #: notebook/server_conf.py:103 msgid "Worksheet process limits" msgstr "Limites des processus des feuilles de travail" #: notebook/server_conf.py:107 msgid "Enable published interacts (EXPERIMENTAL; USE AT YOUR OWN RISK)" msgstr "Autoriser les feuilles de travail interactives publiées (EXPÉRIMENTAL : À VOS RISQUES ET PÉRILS)" #: notebook/server_conf.py:109 msgid "Require e-mail for account registration" msgstr "Exiger une adresse courriel pour ouvrir un compte" #: notebook/server_conf.py:115 msgid "Enable user registration" msgstr "Autoriser l'ouverture de comptes" #: notebook/server_conf.py:121 msgid "Use a challenge for account registration" msgstr "utiliser une question/défi pour l'ouverture de compte" #: notebook/server_conf.py:127 msgid "Type of challenge" msgstr "Type de question/défi" #: notebook/server_conf.py:134 msgid "reCAPTCHA public key" msgstr "reCAPTCHA clé publique" #: notebook/server_conf.py:140 msgid "reCAPTCHA private key" msgstr "reCAPTCHA clé privée" #: notebook/server_conf.py:146 msgid "Default Language" msgstr "Langue par défaut" #: notebook/server_conf.py:156 msgid "Allow OpenID authentication (requires python ssl module)" msgstr "Autoriser l'authentification par OpenID (nécessite le module python ssl)" #: notebook/template.py:68 #, python-format msgid "%(num)d second" msgid_plural "%(num)d seconds" msgstr[0] "%(num)d seconde" msgstr[1] "%(num)d secondes" #: notebook/template.py:71 #, python-format msgid "%(num)d minute" msgid_plural "%(num)d minutes" msgstr[0] "%(num)d minute" msgstr[1] "%(num)d minutes" #: notebook/template.py:74 #, python-format msgid "%(num)d hour" msgid_plural "%(num)d hours" msgstr[0] "%(num)d heure" msgstr[1] "%(num)d heures" #: notebook/template.py:76 #, python-format msgid "%(num)d day" msgid_plural "%(num)d days" msgstr[0] "%(num)d jour" msgstr[1] "%(num)d jours" #: notebook/template.py:135 msgid "Sage Notebook" msgstr "Bloc-note Sage" #: notebook/tutorial.py:354 msgid "Find Help and Documentation" msgstr "Trouver Aide et Documentation" #: notebook/tutorial.py:355 msgid "Get Started with Sage" msgstr "Premiers pas en Sage" #: notebook/tutorial.py:355 msgid "Work through the tutorial (if you have trouble with it, view the static version)." msgstr "Utiliser le tutoriel (si vous avez des difficultés, voir la version statique)." #: notebook/tutorial.py:356 msgid "Help About" msgstr "Aide contextuelle" #: notebook/tutorial.py:357 msgid "Type ? immediately after the object or function and press tab or shift-enter (shift-enter overwrites output and saves to worksheet)." msgstr "Taper ? après un objet ou une fonction et appuyer sur Tab ou Maj+Entrée (la combinaison Maj+Entrée écrit la documentation dans la feuille de travail)." #: notebook/tutorial.py:359 msgid "Put ?? after the object and press tab or shift-enter (shift-enter overwrites output and saves to worksheet)." msgstr "Taper ?? après un objet ou une fonction et appuyer sur Tab ou Maj+Entrée (la combinaison Maj+Entrée écrit les sources dans la feuille de travail)." #: notebook/tutorial.py:360 msgid "Full Text Search of Docs and Source" msgstr "Recherche dans la documentation et le code source" #: notebook/tutorial.py:361 msgid "Search the SAGE documentation by typing
    search_doc(\"my query\")
    in an input cell and press shift-enter. Search the source code of SAGE by typing
    search_src(\"my query\")
    and pressing shift-enter. Arbitrary regular expressions are allowed as queries." msgstr "Chercher dans la documentation en tapant
    search_doc(\"ma requête\")
    dans une cellule puis taper Maj+Entrée. Chercher dans le code source de Sage en tapant
    search_src(\"ma requête\")
    dans une cellule puis taper Maj+Entrée. Les requêtes peuvent être des expressions régulières." #: notebook/tutorial.py:365 msgid "Key and Mouse Bindings" msgstr "Raccourcis claviers et souris" #: notebook/tutorial.py:366 msgid "Evaluate Input" msgstr "Évaluer la cellule" #: notebook/tutorial.py:367 msgid "Press shift-enter. You can start several calculations at once. If you press alt-enter instead, then a new cell is created after the current one. If you press ctrl-enter then the cell is split and both pieces are evaluated separately." msgstr "Taper Maj+Entrée. On peut lancer plusieurs calculs à la fois. En tapant plutôt Alt+Entrée, une nouvelle cellule est crée après la cellule courante. En tapant Ctrl+Entrée, la cellule est coupée en deux et les deux parties évaluées séparément." #: notebook/tutorial.py:368 msgid "Tab Completion" msgstr "Complétion par Tab" #: notebook/tutorial.py:369 msgid "Press tab while the cursor is on an identifier. On some web browsers (e.g., Opera) you must use control-space instead of tab." msgstr "Taper Tab avec le curseur sur une commande. Dans certains navigateurs (par ex. Opera) il faut taper Ctrl-Espace plutôt que Tab." #: notebook/tutorial.py:370 msgid "Insert New Cell" msgstr "Insérer une nouvelle cellule" #: notebook/tutorial.py:371 msgid "Put the mouse between an output and input until the horizontal line appears and click. If you press Alt-Enter in a cell, the cell is evaluated and a new cell is inserted after it." msgstr "Placer la souris entre une sortie et une entrée, pour faire apparaître la ligne horizontale, puis cliquer. En tapant Alt+Entrée dans une cellule, une nouvelle cellule est créée juste en dessous." #: notebook/tutorial.py:372 msgid "Delete Cell" msgstr "Supprimer une cellule" #: notebook/tutorial.py:373 msgid "Delete all cell contents, then press backspace." msgstr "Supprimer le contenu de la cellule puis taper Backspace." #: notebook/tutorial.py:374 msgid "Split and Join Cells" msgstr "Découper ou fusionner des cellules" #: notebook/tutorial.py:375 msgid "Press ctrl-; in a cell to split it into two cells, and ctrl-backspace to join them. Press ctrl-enter to split a cell and evaluate both pieces." msgstr "Taper Ctrl+; dans une cellule pour la couper en deux et Ctrl+Backspace pour fusionner deux cellules. Taper Ctrl+Entrée pour couper une cellule en deux et évaluer les deux parties." #: notebook/tutorial.py:376 msgid "Insert New Text Cell" msgstr "Insérer une cellule de texte" #: notebook/tutorial.py:377 msgid "Move the mouse between cells until a blue bar appears. Shift-click on the blue bar to create a new text cell. Double click on existing text to edit it. Use $...$ and $$...$$ to include typeset math in the text block." msgstr "Déplacer la souris jusqu'à faire apparaître une barre bleue. Utiliser Maj+Clic sur la barre bleue pour créer une nouvelle cellule texte. Double-cliquer sur le texte pour l'éditer. Utiliser $...$ et $$...$$, pour insérer des formules mathématiques dans une cellule texte." #: notebook/tutorial.py:378 msgid "Hide/Show Output" msgstr "Cacher/montrer les résultats" #: notebook/tutorial.py:379 msgid "Click on the left side of output to toggle between hidden, shown with word wrap, and shown without word wrap." msgstr "Cliquer à gauche du résultat pour basculer entre trois modes : caché, montré avec retour à la ligne, montré sans retour à la ligne" #: notebook/tutorial.py:380 msgid "Indenting Blocks" msgstr "Indenter les blocs" #: notebook/tutorial.py:381 msgid "Highlight text and press > to indent it all and < to unindent it all (works in Safari and Firefox). In Firefox you can also press tab and shift-tab." msgstr "Sélectionner du texte et taper > pour l'indenter et < pour le désindenter (marche avec Safari et Firefox). Dans Firefox, marche aussi avec Tab et Maj+Tab." #: notebook/tutorial.py:382 msgid "Comment/Uncomment Blocks" msgstr "Commenter/dé-commenter les blocs" #: notebook/tutorial.py:383 msgid "Highlight text and press ctrl-. to comment it and ctrl-, to uncomment it. Alternatively, use ctrl-3 and ctrl-4." msgstr "Sélectionner du texte et faire Ctrl+. pour le commenter et Ctrl+, pour le dé-commenter. Aussi possible avec Ctrl+3 et Ctrl+4." #: notebook/tutorial.py:384 msgid "Paren matching" msgstr "Correction des parenthèses" #: notebook/tutorial.py:384 msgid "To fix unmatched or mis-matched parentheses, braces or brackets, press ctrl-0. Parentheses before the cursor will be matched, minding strings and (Python) comments." msgstr "Pour corriger des parenthèses manquantes ou incorrectes, taper Ctrl+0. Les parenthèses avant le curseur seront complétées, en tenant compte des chaînes de caractères et des commentaires Python." #: notebook/tutorial.py:388 msgid "Interrupt and Restart Sessions" msgstr "Interrompre et relancer les sessions" #: notebook/tutorial.py:389 msgid "Interrupt Running Calculations" msgstr "Interrompre les calculs en cours" #: notebook/tutorial.py:390 msgid "Click Interrupt or press escape in any input cell. This will (attempt) to interrupt SAGE by sending many interrupt signals." msgstr "Cliquer sur Interrompre ou taper Escape dans une cellule. Ceci va tenter d'interrompre Sage en envoyant de nombreux signaux d'interruption." #: notebook/tutorial.py:391 msgid "Restart" msgstr "Relancer" #: notebook/tutorial.py:392 msgid "Type \"restart\" to restart the SAGE interpreter for a given worksheet. (You have to interrupt first.)" msgstr "Taper \"restart\", pour relancer l’interpréteur Sage pour une feuille de travail donné. (Il faut d'abord l'interrompre.)" #: notebook/tutorial.py:394 msgid "Special Cell Blocks" msgstr "Blocs de cellules spéciales" #: notebook/tutorial.py:395 msgid "Evaluate Cell using GAP, Singular, etc." msgstr "Évaluer la cellule avec GAP, Singular, etc." #: notebook/tutorial.py:396 #, python-format msgid "Put \"%gap\", \"%singular\", etc. as the first input line of a cell; the rest of the cell is evaluated in that system." msgstr "Écrire \"%gap\", \"%singular\" etc. comme première ligne d'une cellule, le reste de la cellule est alors évalué avec ce système." #: notebook/tutorial.py:397 msgid "Shell Scripts" msgstr "Scripts Shell" #: notebook/tutorial.py:398 #, python-format msgid "Begin a block with %sh to have the rest of the block evaluated as a shell script. The current working directory is maintained." msgstr "Commencer un bloc par %sh pour que le reste du bloc soit évalué comme un script shell. Le répertoire de travail actuel est préservé." #: notebook/tutorial.py:399 msgid "Interactive Dynamic Widgets" msgstr "Gadgets dynamiques interactifs" #: notebook/tutorial.py:400 msgid "Put @interact on the line before a function definition. Type interact? for more details." msgstr "Écrire @interact dans la ligne précédant la définition d'une fonction. Voir interact? pour plus d'informations." #: notebook/tutorial.py:401 msgid "Autoevaluate Cells on Load" msgstr "Auto-évaluer les cellules lors du chargement" #: notebook/tutorial.py:402 msgid "Any cells with \"#auto\" in the input is automatically evaluated when the worksheet is first opened." msgstr "Les cellules contenant \"#auto\" sont évaluées automatiquement lors de l'ouverture de la feuille de travail." #: notebook/tutorial.py:403 msgid "Time" msgstr "Temps" #: notebook/tutorial.py:404 msgid "Type \"%time\" at the beginning of the cell." msgstr "Taper \"%time\" au début de la cellule." #: notebook/tutorial.py:406 msgid "Useful Tips" msgstr "Trucs et Astuces" #: notebook/tutorial.py:407 msgid "Input Rules" msgstr "Règles d'entrée" #: notebook/tutorial.py:408 msgid "Code is evaluated by exec'ing (after preparsing). Only the output of the last line of the cell is implicitly printed. If any line starts with \"sage:\" or \">>>\" the entire block is assumed to contain text and examples, so only lines that begin with a prompt are executed. Thus you can paste in complete examples from the docs without any editing, and you can write input cells that contains non-evaluated plain text mixed with examples by starting the block with \">>>\" or including an example." msgstr "Le code est évalué par exec (après un filtre). Seul le résultat de la dernière ligne de la cellule est affiché. Si une ligne commence par \"sage:\" ou \">>>\" le bloc entier est supposé contenir du texte et des exemples, et seules les lignes commençant par \"sage:\" sont exécutées. Vous pouvez ainsi copier-coller des exemples complets depuis la documentation. Vous pouvez écrire des cellules qui mélangent texte non-évalué et exemples, en commençant par \">>>\" ou en incluant un exemple." #: notebook/tutorial.py:409 msgid "History" msgstr "Historique" #: notebook/tutorial.py:410 msgid "Click log commands you have entered in any worksheet of this notebook." msgstr "Cliquer sur Historique pour voir toutes les commandes entrées dans tous les feuilles de travail de ce carnet." #: notebook/tutorial.py:411 msgid "Typesetting All Output" msgstr "Mise en forme de tous les résultats" #: notebook/tutorial.py:412 msgid "Type pretty_print_default() in an input cell and press shift-enter. All future output will be typeset automatically." msgstr "Taper pretty_print_default() dans une cellule puis taper Maj+Entrée. Les sorties suivantes seront alors typographiées." #: notebook/tutorial.py:416 msgid "Files and Scripts" msgstr "Fichiers et Scripts" #: notebook/tutorial.py:417 msgid "Loading SAGE/Python Scripts" msgstr "Charger des fichiers Sage ou Python" #: notebook/tutorial.py:418 msgid "Use \"load filename.sage\" and \"load filename.py\". Load is relative to the path you started the notebook in. The .sage files are preparsed and .py files are not. You may omit the .sage or .py extension. Files may load other files." msgstr "Utiliser \"load nomdefichier.sage\" et \"load nomdefichier.py\". L'adresse est relative au répertoire dans lequel le Bloc-note Sage a été lancé. Les fichiers .sage sont d'abord passés par un filtre, mais pas les fichiers .py. On peut omettre l'extension (.py ou .sage). Des fichiers peuvent charger d'autres fichiers." #: notebook/tutorial.py:419 msgid "Attaching Scripts" msgstr "Attacher des fichiers Sage ou Python" #: notebook/tutorial.py:420 msgid "Use \"attach filename.sage\" or \"attach filename.py\". Attached files are automatically reloaded when the file changes. The file $HOME/.sage/init.sage is attached on startup if it exists." msgstr "Utiliser \"load nomdefichier.sage\" et \"load nomdefichier.py\". Les fichiers attachés modifiés sont rechargés automatiquement. Le fichier $HOME/.sage/init.sage est attaché au démarrage s'il existe." #: notebook/tutorial.py:421 msgid "Working Directory" msgstr "Répertoire de travail" #: notebook/tutorial.py:422 msgid "Each block of code is run from its own directory. If any images are created as a side effect, they will automatically be displayed." msgstr "Chaque bloc de code est executé depuis son propre répertoire. Si des images sont crées, elles sont automatiquement affichées." #: notebook/tutorial.py:423 msgid "DIR Variable" msgstr "Variable DIR" #: notebook/tutorial.py:424 msgid "The variable DIR contains the directory from which you started the SAGE notebook. For example, to open a file in that directory, do \"open(DIR+'filename')\"." msgstr "La variable DIR contient le répertoire dans lequel le Bloc-note Sage a été lancé. Pour ouvrir un fichier dans ce répertoire, taper \"open(DIR+'nomdefichier')\"." #: notebook/tutorial.py:425 msgid "DATA Variable" msgstr "Variable DATA" #: notebook/tutorial.py:426 msgid "Use the Data menu to upload images and other files, and create new files that can be shared between worksheets. The DATA variable contains the path to the data files. For example, to open a file in that directory, do \"open(DATA+'filename')\". If foo.sage is a Sage file that you uploaded, type \"load foo.sage\"; if foo.py is a Python file, you can import it by typing \"import foo\"." msgstr "Utiliser le menu Données pour charger des images et autres fichiers, et créer de nouveaux fichiers qui peuvent être partagés entre les feuilles de travail. La variable DATA contient le chemin vers les fichiers de données. Par exemple, pour ouvrir un fichier dans ce répertoire, écrire \"open(DATA+'nomdefichier')\". Si truc.sage est un fichier Sage que vous avez chargé, taper \"load truc.sage\" ; si truc.py est un fichier Python, vous pouvez l'importer en tapant \"import truc\"." #: notebook/tutorial.py:427 msgid "Loading and Saving Objects" msgstr "Charger et sauver des objets" #: notebook/tutorial.py:428 msgid "Use \"save obj1 obj2 ...\" and \"load obj1 obj2 ...\". This allows for easy moving of objects from one worksheet to another, and saving of objects for later use." msgstr "Utiliser \"save obj1 obj2 ...\" und \"load obj1 obj2 ...\". Ceci permer de transférer facilement des objets d'une feuille de travail à un autre, ou de les conserver pour usage ultérieur." #: notebook/tutorial.py:429 msgid "Loading and Saving Sessions" msgstr "Charger et sauver des sessions" #: notebook/tutorial.py:430 msgid "Use \"save_session('name')\" to save all variables to an object. Use \"load_session('name')\" to merge in all variables from a saved session." msgstr "Utiliser \"save_session('Nom')\" pour sauver toutes les variables dans un objet. Utiliser \"load_session('Nom')\" pour restaurer toutes les variables d'une session sauvgardée." #: notebook/tutorial.py:431 msgid "Customizing the Notebook CSS" msgstr "Personnaliser le style CSS du Bloc-note Sage" #: notebook/tutorial.py:432 msgid "If you create a file $HOME/.sage/notebook.css then it will get applied when rendering the notebook. See " msgstr "Si vous créez un fichier $HOME/.sage/notebook.css, il sera utilisé pour le rendu du Bloc-note Sage. Voir " #: notebook/twist.py:448 #, python-format msgid "Please specify a worksheet to load.%s" msgstr "Merci de choisir une feuille de travail à charger.%s" #: notebook/twist.py:486 #, python-format msgid "There was an error uploading the worksheet. It could be an old unsupported format or worse. If you desperately need its contents contact the sage-support group and post a link to your worksheet. Alternatively, an sws file is just a bzip2 tarball; take a look inside!%s" msgstr "Il s'est produit une erreur lors du chargement de la feuille de travail. Peut-être est-elle dans un format obsolète, ou pire encore. Si vous avez désespérement besoin de son contenu, vous pouvez contacter le groupe sage-support et y poster un lien vers votre feuille de travail. Autre solution : un fichier .sws est juste un fichier compressé au format tar+bzip ; regardez son contenu ! %s" #: notebook/twist.py:515 #: notebook/twist.py:645 #, python-format msgid "There was an error uploading \"%s\" (please recheck the URL).%s" msgstr "Erreur lors du chargement de \"%s\" (merci de vérifier l'URL).%s" #: notebook/twist.py:597 #, python-format msgid "Return to Upload or Create Data File or %s." msgstr "Revenir à Importer ou créer un fichier de données ou %s." #: notebook/twist.py:601 #, python-format msgid "Error uploading file (missing fileField file).%s" msgstr "Erreur de chargement du fichier (fichier manquant ?).%s" #: notebook/twist.py:606 #, python-format msgid "Error uploading file (missing %s arg).%s" msgstr "Erreur de chargement du fichier (argument %s manquant).%s" #: notebook/twist.py:623 #, python-format msgid "Error uploading file (missing filename).%s" msgstr "Erreur de chargement du fichier (nom de fichier manquant).%s" #: notebook/twist.py:627 #, python-format msgid "Suspicious filename \"%s\" encountered uploading file.%s" msgstr "Nom de fichier suspect \"%s\" trouvé lors du chargement .%s" #: notebook/twist.py:674 #, python-format msgid "Successfully deleted \"%s\"" msgstr "Suppression réussie de \"%s\" " #: notebook/twist.py:691 msgid "No data files" msgstr "Pas de fichiers de données" #: notebook/twist.py:770 msgid "Error in introspection -- invalid cell id." msgstr "Erreur d'introspection -- identifiant de cellule invalide." #: notebook/twist.py:824 msgid "You must login first in order to edit this worksheet." msgstr "Vous devez vous connecter pour pouvoir éditer cette feuille de travail." #: notebook/twist.py:998 msgid "Old password not given" msgstr "Ancien mot de passe non fourni" #: notebook/twist.py:1000 msgid "Incorrect password given" msgstr "Mot de passe incorrect" #: notebook/twist.py:1002 msgid "New password not given" msgstr "Pas de nouveau mot de passe fourni" #: notebook/twist.py:1004 msgid "Please type in new password again." msgstr "Merci de taper à nouveau le nouveau mot de passe." #: notebook/twist.py:1006 msgid "The passwords you entered do not match." msgstr "Les mots de passe ne correspondent pas." #: notebook/twist.py:1039 msgid "Confirmed" msgstr "Confirmé" #: notebook/twist.py:1041 msgid "Not confirmed" msgstr "Non confirmé" #: notebook/twist.py:1294 msgid "can't evaluate worksheet cells" msgstr "Impossible d'évaluer les cellules de la feuille de travail" #: notebook/twist.py:1391 msgid "You must login first in order to rate this worksheet." msgstr "Vous devez vous connecter, pour pouvoir évaluer cette feuille de travail." #: notebook/twist.py:1395 msgid "Gees -- You can't fool the rating system that easily!" msgstr "Pouah, vous ne pouvez pas tromper le système d'évaluation aussi facilement !" #: notebook/twist.py:1398 #, python-format msgid "Thank you for rating the worksheet %s! You can see all ratings of this worksheet." msgstr "Merci d'avoir évalué la feuille de travail %s ! Vous pouvez voir toutes les évaluations de cette feuille de travail." #: notebook/twist.py:1398 msgid "Rating Accepted" msgstr "Évaluation acceptée" #: notebook/twist.py:1415 msgid "No such worksheet." msgstr "Pas de feuille de travail de ce nom." #: notebook/twist.py:1521 #, python-format msgid "The worksheet operation \"%s\" is not defined." msgstr "La fonction \"%s\" n'est pas définie." #: notebook/twist.py:1618 #, python-format msgid "User \"%s\" does not have permission to view the home page of \"%s\"." msgstr "L'utilisateur \"%s\" n'est pas autorisé à voir la page principale de \"%s\"." #: notebook/twist.py:1629 #, python-format msgid "The user \"%s\" has no worksheet \"%s\"." msgstr "L'utilisateur \"%s\" ne possède pas de feuille de travail \"%s\"." #: notebook/twist.py:1632 #, python-format msgid "There is no published worksheet with name \"%s\". Redirecting to the index of published worksheets in 10 seconds...

    " msgstr "Il n'y a pas de feuille de travail publié sous le nom \"%s\". Redirection vers la liste des feuilles de travail publiées dans 10 secondes...

    " #: notebook/twist.py:1637 #, python-format msgid "You are not logged in or do not have access to the worksheet \"%s\"." msgstr "Vous n'êtes pas connecté ou n'avez pas accès à la feuille de travail \"%s\"." #: notebook/twist.py:1662 msgid "This url can only be accessed through a POST request." msgstr "Cette URL n'est accessible que via une requête POST." #: notebook/twist.py:1712 #, python-format msgid "You are not authorized to move \"%s\"" msgstr "Vous n'êtes pas autorisé à déplacer \"%s\"" #: notebook/twist.py:1781 msgid "Please request a specific worksheet" msgstr "Merci de demander une feuille de travail spécifique" #: notebook/twist.py:2022 msgid "The confirmation system is not active." msgstr "Le système de configuration n'est pas actif." #: notebook/twist.py:2024 msgid "

    Invalid confirmation key

    You are reporting a confirmation key that has not been assigned by this server. Please register with the server.

    " msgstr "

    Clé de confirmation invalide

    Vous proposez une clé qui n'a pas été donnée par ce serveur. Merci de vous enregistrer sur le serveur.

    " #: notebook/twist.py:2033 #, python-format msgid "

    Email address confirmed for user %s

    " msgstr "

    Adresse courriel confirmée pour l'utilisateur %s

    " #: notebook/twist.py:2035 msgid "Email Confirmed" msgstr "Adresse courriel confirmée" #: notebook/user_conf.py:23 msgid "Language" msgstr "Langue" #: notebook/wiki2html.py:647 #, python-format msgid "Expected \"%(wanted)s\" after \"%(key)s\", got \"%(token)s\"" msgstr " \"%(wanted)s\" attendu après \"%(key)s\", trouvé \"%(token)s\" à la place" #: notebook/wiki2html.py:653 #, python-format msgid "Expected an integer \"%(key)s\" before \"%(token)s\"" msgstr "Entier \"%(key)s\" attendu avant \"%(token)s\"" #: notebook/wiki2html.py:663 #: notebook/wiki2html.py:673 #, python-format msgid "Expected an integer \"%(arg)s\" after \"%(key)s\"" msgstr "Entier \"%(arg)s\" attendu après \"%(key)s\"" #: notebook/wiki2html.py:699 #, python-format msgid "Expected a color value \"%(arg)s\" after \"%(key)s\"" msgstr "Couleur \"%(arg)s\" attendue après \"%(key)s\"" #: notebook/worksheet.py:2014 #, python-format msgid "%(seconds)s ago" msgstr "depuis %(seconds)s" #: notebook/worksheet.py:4155 msgid "January" msgstr "Janvier" #: notebook/worksheet.py:4156 msgid "February" msgstr "Février" #: notebook/worksheet.py:4157 msgid "March" msgstr "Mars" #: notebook/worksheet.py:4158 msgid "April" msgstr "Avril" #: notebook/worksheet.py:4159 msgid "May" msgstr "Mai" #: notebook/worksheet.py:4160 msgid "June" msgstr "Juin" #: notebook/worksheet.py:4161 msgid "July" msgstr "Juillet" #: notebook/worksheet.py:4162 msgid "August" msgstr "Août" #: notebook/worksheet.py:4163 msgid "September" msgstr "Septembre" #: notebook/worksheet.py:4164 msgid "October" msgstr "Octobre" #: notebook/worksheet.py:4165 msgid "November" msgstr "Novembre" #: notebook/worksheet.py:4166 msgid "December" msgstr "Décembre" #~ msgid "Sign into the Sage Notebook v%(v)s" #~ msgstr "Im Sage-Notebook anmelden v%(v)s" #~ msgid "Problem inserting new input cell before current input cell." #~ msgstr "Problem beim Einfügen einer neuen Eingabezelle vor der aktuellen Eingabezelle." #~ msgid "Problem inserting new text cell before current input cell." #~ msgstr "" #~ "Problem beim Einfügen einer neuen Text-Zelle vor der aktuellen Eingabezelle." #~ msgid "simple" #~ msgstr "einfach" #~ msgid "recaptcha" #~ msgstr "recaptcha" #~ msgid "Sage Notebook Registration" #~ msgstr "Sage-Notebook-Registrierung" #~ msgid "The account recovery system is not active." #~ msgstr "Das Kontowiederherstellungssystem ist nicht aktiv." #~ msgid "Username is invalid." #~ msgstr "Ungültiger Benutzername." #~ msgid "The e-mail address hasn't been confirmed." #~ msgstr "Die E-Mail-Adresse wurde nicht unbestätigt." #~ msgid "Sage Notebook Account Recovery" #~ msgstr "Sage-Notebook-Kontowiederherstellung" #~ msgid "The new password couldn't be sent to %s." #~ msgstr "Das neue Passwort konnte nicht an %s gesendet werden." #~ msgid "A new password has been sent to your e-mail address." #~ msgstr "Ein neues Passwort wurde an Ihre E-Mail-Adresse gesendet." #~ msgid "The temporary password for the new user %s is %s" #~ msgstr "Das vorläufige Passwort für den neuen Benutzer %s lautet %s" #~ msgid "This is an invalid page." #~ msgstr "Diese Seite ist ungültig." #~ msgid " You might have to login to view this page." #~ msgstr " Möglicherweise müssen Sie sich einloggen, um diese Seite anzeigen zu können." #~ msgid "unauthorized request" #~ msgstr "unberechtigte Anfrage" #~ msgid "Your account is currently suspended." #~ msgstr "Ihr Konto ist zur Zeit gesperrt." #~ msgid "" #~ "Please enable cookies or delete all Sage cookies and localhost cookies in " #~ "your browser and try again." #~ msgstr "" #~ "Bitte aktivieren Sie Cookies oder löschen Sie alle Cookies mit Bezug zu " #~ "Sage oder localhost in Ihrem Browser und versuchen es erneut." #~ msgid "%s ago" #~ msgstr "vor %s" #~ msgid "No data file (%s)" #~ msgstr "Keine Daten-Datei (%s)" #~ msgid "ago by %s" #~ msgstr "durch %s" sagenb-1.0.1/sagenb/translations/pt_BR/000077500000000000000000000000001311436262400177405ustar00rootroot00000000000000sagenb-1.0.1/sagenb/translations/pt_BR/LC_MESSAGES/000077500000000000000000000000001311436262400215255ustar00rootroot00000000000000sagenb-1.0.1/sagenb/translations/pt_BR/LC_MESSAGES/messages.mo000066400000000000000000001454001311436262400236750ustar00rootroot00000000000000Þ•öÌ|}–±Ðïÿ# 7 F M «U :!,:T:e: z:…::= : Þ:é:î:ó: ; ;;<;%[;;Ÿ;»;Ö;ò;ö;ý;<%1< W<d<j<<…<ì<-z=)¨= Ò=ó= > > >)> @>N>T>[>^> z>ˆ>Ÿ>±>Ä> Ö>ä>ö>ÿ>? #?0?G?M? T?€b?&ã?0 @7;@s@@–@¥@ª@³@Ê@=Ú@'A"@A#cA%‡A"­A$ÐAÂõA¸BŽØCgD…D‹D< DÝDåD öDEEr(El›EYF´bFG2G7G>GNGaGvGŒG G©G°GÆG×G0èG'HAHHHNHVHtH׆H^IrI…IŽIžI ¯I½IÖI éI÷I J !Jš-J ÈJÕJíJ òJ þJ K #K0KNK"fK‰K¥K·KÆLãLMM8M PMZMaMjM pMzM ŽMœM¡M±MÁMÉMÒM#ÚM'þM&&NCMN ‘NN±NÆNÌNÞNåNêNúNOO4O ƒXƒgƒnƒ‚ƒ ƒ­¨ƒV„]„ p„"}„  „­„½„Ï„Và„7…%V… |……¦…)«…Õ…2å…+†1D†5v†3¬†à† ò†*ÿ†*‡&:‡1a‡“‡A˜‡:Ú‡5ˆ6Kˆ‚ˆ‰ˆ+¥ˆ ш ۈ戉 ‰.0‰K_‰6«‰ â‰ï‰5 Š?ŠSŠYŠ jŠ ‹Š–ŠŸŠ¹ŠÓŠ½êŠ¡¨‹ JŒUŒ]Œ{Œ˜Œ%²ŒØŒvøŒo‰™«!À â!Ž %Ž1Ž NŽoŽ)ˆŽ²ŽÏŽíŽ6>=X–¥«±ËÒ!ã238+l%˜¾Ü û‘! ‘/‘*E‘p‘„‘‹‘©‘®‘¶‘(Ï’+ø’"$“G“ ]“ k“ w“‚“ œ“ª“ ¯“¹“¾“Ü“ñ“”(”@”]”m”‰”’”¯” ·”Ä”à” æ”ñ”Š•6“•8Ê•1–5– T–b–~–…–*‹–¶–JÒ–+—&I—-p—3ž—/Ò—#˜Ï&˜Pö˜¡Gš'éš››:1›l›u› ˆ›’›§›€º›‹;œjÇœÔ2ž'ž/ž7žJžbžvžž¥ž¶ž¿žÖžèžGüž'DŸ lŸ vŸ €ŸŠŸªŸã¼Ÿ  ¾ Ö ß ï ¡¡3¡ J¡X¡"q¡”¡ª¤¡O¢_¢y¢ €¢Ž¢¢¢»¢%Ï¢"õ¢'£ @£a£Ns£ ¤-ã¤(¥:¥T¥f¥o¥x¥ ˆ¥•¥¨¥ Ä¥Ò¥Ù¥ñ¥ ¦¦¦(¦(E¦/n¦Fž¦ å¦ó¦§&§.§C§J§P§c§€§‡§  § ª§Gµ§!ý§$¨D¨`¨€f¨óç¨bÛ© >ªÀLª, «D:«*«+ª«Ö«£d¬4­=­\­;Ü­u®Zޝ&é¯Q°zb°ݰã°Áý°"¿±ÈⱫ²´²̲Ò²Ù²Ná²0³$9³p^³–ϳf´˜v´%µ*5µ `µ[lµ ȵÒµÛµ ìµ øµ¶ ¶ ¶?;¶8{¶´¶?Ò¶Ê· Ý·›é¸¡…¹.'º¯Vº0»%7»!]»Í» M½Z½=c½¡½¹½½&Û½!¾$¾ ?¾I¾6Q¾+ˆ¾5´¾ê¾&û¾»"¿ Þ¿Ué¿?ÀSÀ"hÀ¹‹ÀEÁ\Á8eÁPžÁ$ïÁEÂZÂjÂ(nÂ>—ÂVÖÂP-ÃT~ÃNÓÃK"ÄUnĪÄćoŹ÷űÆq?ÇŽ±Çn@ȯÈ2ÇÈúÈÉ.ÉFÉYÉaÉ$tÉ ™É§ÉM°ÉþÉ ÊÊ7ÊSÊ qÊ2|ʯÊ%ÆÊ ìÊúÊ%(num)d day%(num)d days%(num)d hour%(num)d hours%(num)d minute%(num)d minutes%(num)d second%(num)d seconds%(seconds)s ago%(t)s ago by %(le)s(note that images are not recorded)24|twenty-four5|five8|eightWork through the tutorial (if you have trouble with it, view the static version).Restart, instead?

    Email address confirmed for user %s

    Invalid confirmation key

    You are reporting a confirmation key that has not been assigned by this server. Please register with the server.

    Sage is a different approach to mathematics software.A session is a worksheet and a set of variables in some state.A worksheet is an ordered list of Sage calculations with output.A new password will be emailed to the email address connected to your account. However if you didn't confirm your email address you will be unable to recover your account.Access %(f)s in this worksheet by typing DATA+'%(f)s'. Here DATA is a special variable that gives the exact path to all data files uploaded to this worksheet.Account RecoveryAccount SettingsAction...ActiveActive WorksheetsAdd New UserAdd UserAdd or DeleteAnswer a challengeAny cells with "#auto" in the input is automatically evaluated when the worksheet is first opened.AppearanceAprilArchiveArchive selected worksheets so they do not appear in the default worksheet listArchivedArchived WorksheetsAttaching ScriptsAugustAuthenticationAutoevaluate Cells on LoadAutomatically re-publish when changes are madeBack to your personal worksheet listBad passwordBad usernameBegin a block with %sh to have the rest of the block evaluated as a shell script. The current working directory is maintained.Browse published Sage worksheets
    (no login required)Browse the published worksheetsBrowse your computer to select a file to upload:Browse your computer to select a worksheet file to upload:By using Sage you help to support a viable open source alternative to Magma, Maple, Mathematica, and MATLAB. Sage includes many high-quality open source math packages.CancelCancel changesCases / TestsChange Auto-Save IntervalChange E-mail AddressChange PasswordChange account settings including passwordClick log commands you have entered in any worksheet of this notebook.Click Interrupt or press escape in any input cell. This will (attempt) to interrupt SAGE by sending many interrupt signals.Click here or press shift-return to evaluateClick here to pop outClick here to turn the above into a Sage worksheetClick on the left side of output to toggle between hidden, shown with word wrap, and shown without word wrap.Click to download and install tex fonts.Click to rename this worksheetClose this box to stop trying.Code is evaluated by exec'ing (after preparsing). Only the output of the last line of the cell is implicitly printed. If any line starts with "sage:" or ">>>" the entire block is assumed to contain text and examples, so only lines that begin with a prompt are executed. Thus you can paste in complete examples from the docs without any editing, and you can write input cells that contains non-evaluated plain text mixed with examples by starting the block with ">>>" or including an example.CollaboratorsCommentComment/Uncomment BlocksConfirmedCongratulations %(u)s! You can now sign into the Sage Notebook.ConstructionsContinueCopy this worksheetCopy worksheetCountCreate AccountCreate a good passwordCreate a new Sage worksheet version of the last 100 commands in the above log.Create a new worksheetCreate a usernameCreate accountCreating new users is disabled by the administrator.Current FolderCurrent e-mailCustomizing the Notebook CSSDATA VariableDIR VariableData fileData...DecemberDefault LanguageDefault systemDeleteDelete All OutputDelete CellDelete all cell contents, then press backspace.Delete all outputDelete worksheetDeleted WorksheetsDeveloper GuideDiscard & quitDiscard changes to this worksheetDo you want to publish this worksheet?Doc pool sizeDocumentationDownloadDownload All ActiveDownload selected worksheetsDownload.Each block of code is run from its own directory. If any images are created as a side effect, they will automatically be displayed.EditEdit a copy.Edit plain textEdit text version of this worksheetEdit this.ElapsedEmail ConfirmedEmpty TrashEmptying the trash will permanently delete all items in the trash. Continue?Enable user registrationEnable/disable pretty_printingEnter your email addressEnvironmentErrorError applying function to worksheet(s).Error foundError in introspection -- invalid cell id.Error updating cell output after Error uploading file (missing %s arg).%sError uploading file (missing fileField file).%sError uploading file (missing filename).%sErrors foundEvaluate AllEvaluate Cell using GAP, Singular, etc.Evaluate InputEvaluate all input cells in the worksheetEvaluate all input cells using %(i)sExitExpected "%(wanted)s" after "%(key)s", got "%(token)s"Expected a color value "%(arg)s" after "%(key)s"Expected an integer "%(arg)s" after "%(key)s"Expected an integer "%(key)s" before "%(token)s"FailFailed to save worksheet.Fast Static Versions of the DocumentationFebruaryFile...Files and ScriptsFind Help and DocumentationForgot passwordFull Text Search of Docs and SourceGees -- You can't fool the rating system that easily!General and Advanced Pure and Applied MathematicsGet ImageGet Started with SageGive access to your worksheet to the above collaboratorsGo to the worksheet.HelpHelp AboutHelp via Internet Chat (IRC)Hi %s! HideHide All OutputHide all outputHide/Show OutputHighlight text and press ctrl-. to comment it and ctrl-, to uncomment it. Alternatively, use ctrl-3 and ctrl-4.Highlight text and press > to indent it all and < to unindent it all (works in Safari and Firefox). In Firefox you can also press tab and shift-tab.HistoryHomeHow do I construct ... in Sage?How many bits are in one byte?How to use the Sage NotebookIdle check interval (seconds)Idle timeout (seconds)If you create a file $HOME/.sage/notebook.css then it will get applied when rendering the notebook. See Incorrect password givenIndenting BlocksInput RulesInsert New CellInsert New Text CellInteractive Dynamic WidgetsInteractively use this worksheetInterruptInterrupt Running CalculationsInterrupt and Restart SessionsInterrupt attemptInterrupt currently running calculations, if possibleInvalid challenge responseInvalid email addressInvalid usernameInvite CollaboratorsIs pi > e?JanuaryJava Applet HiddenJavascript must be enabled in order to use the Sage Notebook.Jmol ImageJulyJuneKey and Mouse BindingsLanguageLast EditedLearn to write Sage programsLet others edit this worksheetLoad a new worksheet stored in a fileLoad worksheet from a file...Loading SAGE/Python ScriptsLoading and Saving ObjectsLoading and Saving SessionsLogLog inLog in to edit a copy.Log out of the Sage notebookMake this worksheet publicly viewableManage UsersMarchMaximum history lengthMayMinutesMove the mouse between cells until a blue bar appears. Shift-click on the blue bar to create a new text cell. Double click on existing text to edit it. Use $...$ and $$...$$ to include typeset math in the text block.Move the selected worksheets out of the trashMove the selected worksheets to the trashMove this worksheet to the trashMulti Cell ModeNew WorksheetNew e-mailNew passwordNew password not givenNew worksheetNewerNewestNoNo challenge response givenNo data filesNo email address givenNo password givenNo such worksheet.No username givenNot confirmedNotebook SettingsNovemberNumber of word-wrap columnsOctoberOld passwordOld password not givenOlderOldestOne Cell ModeOnly the owner of a worksheet is allowed to share it. You can do whatever you want if you make your own copy.Or enter the URL of a file on the web:Or enter the URL of a worksheet file on the web:Or enter the name of a new file, which will be created:Other published documents...OwnerParen matchingPassPasswordPasswords didn't matchPick a usernamePlease ask the server administrator to configure a challenge!Please enter a name for this worksheet.Please log in to the Sage notebookPlease request a specific worksheetPlease specify a worksheet to load.%sPlease type in new password again.Possible failure deleting worksheet.Press ctrl-; in a cell to split it into two cells, and ctrl-backspace to join them. Press ctrl-enter to split a cell and evaluate both pieces.Press shift-enter. You can start several calculations at once. If you press alt-enter instead, then a new cell is created after the current one. If you press ctrl-enter then the cell is split and both pieces are evaluated separately.Press tab while the cursor is on an identifier. On some web browsers (e.g., Opera) you must use control-space instead of tab.Pretty print (typeset) outputPrintPrint this worksheetProblem inserting new input cell after current input cell.\nPublishPublish this onePublishedPublished WorksheetsPublished on %(t)sPut "%gap", "%singular", etc. as the first input line of a cell; the rest of the cell is evaluated in that system.Put ?? after the object and press tab or shift-enter (shift-enter overwrites output and saves to worksheet).Put @interact on the line before a function definition. Type interact? for more details.Put the mouse between an output and input until the horizontal line appears and click. If you press Alt-Enter in a cell, the cell is evaluated and a new cell is inserted after it.Quit the worksheet processRateRatingRating AcceptedRatings for %(wn)sRe-publish worksheetRe-type your passwordReference ManualRemember meRenameRename this worksheetRename worksheetReport a ProblemReport a problem or submit a bug to improve SageRequire e-mail for account registrationRerateResetRestartRestart the worksheet processRestart worksheetReturn to Upload or Create Data File or %s.Retype new passwordRevert to this oneRevisionRevision %(lr)sRevision HistoryRevision ListRevision from %(ta)s agoSage DocumentationSage NotebookSage Notebook versionSage Source BrowserSage Users:Sage makes it easy for you to use most mathematics software together. Sage includes GAP, GP/PARI, Maxima, and Singular, and dozens of other open packages.Sage versionSage: History for %(u)sSaveSave & quitSave ChangesSave and quit worksheetSave changesSave changes and close windowSave interval (seconds)Save this worksheet to an sws fileSave worksheet to a file...Search WorksheetsSearch the SAGE documentation by typing
    search_doc("my query")
    in an input cell and press shift-enter. Search the source code of SAGE by typing
    search_src("my query")
    and pressing shift-enter. Arbitrary regular expressions are allowed as queries.Searching for Sage server...Select a file related functionSelect a worksheet functionSelect an OpenID providerSelect an attached fileSeptemberServerSettingsShareShare nowShare this documentShell ScriptsShowShow All OutputShow all outputSign inSign outSign upSign up for a Sage Notebook accountSign up for a new Sage Notebook accountSomeone else is viewing this worksheetSorry, but you need a browser that supports the <canvas> tag.Source CodeSpecial Cell BlocksSplit and Join CellsStartStatic version...StatusStopStop publishingStop selected worksheetsSubmitSuccessfully deleted "%s"SuspendSuspensionSuspicious filename "%s" encountered uploading file.%sSwitch to multi-cell modeSwitch to single-cell modeTab CompletionTextThank you for rating the worksheet %s! You can see all ratings of this worksheet.Thank you for registering for the Sage notebook. To complete your registration, copy and paste the following link into your browser: %s://%s:%s/confirm?key=%s You will be taken to a page which will confirm that you have indeed registered.The Sage notebook is a collection of worksheets, saved objects, and user information.The Sage NotebookThe Sage Notebook was primarily written by William Stein with substantial contributions from Tom Boothby, Timothy Clemans, Alex Clemesha, Mike Hansen, Bobby Moretti, Yi Qiang, and Dorian Raymer.The confirmation system is not active.The password for the user %(u)s has been reset to %(p)sThe passwords you entered do not match.The user "%s" has no worksheet "%s".The username must start with a letter and be between 4 and 32 characters long. It can only consist of letters, numbers, underscores, and one dot (.).The variable DIR contains the directory from which you started the SAGE notebook. For example, to open a file in that directory, do "open(DIR+'filename')".The worksheet operation "%s" is not defined.There are no published worksheets.There is no published worksheet with name "%s". Redirecting to the index of published worksheets in 10 seconds...

    There was an error uploading "%s" (please recheck the URL).%sThere was an error uploading the worksheet. It could be an old unsupported format or worse. If you desperately need its contents contact the sage-support group and post a link to your worksheet. Alternatively, an sws file is just a bzip2 tarball; take a look inside!%sThis Sage Worksheet is currently shared with the people listed in the box below.This page is rated %(wr).1f.This url can only be accessed through a POST request.This worksheet is read only. Please make a copy or contact the owner to change it.TimeTitle of saved worksheetTo fix unmatched or mis-matched parentheses, braces or brackets, press ctrl-0. Parentheses before the cursor will be matched, minding strings and (Python) comments.To quickly try out Sage start hereTo save this image, you can try right-clicking on the image to copy it or save it to a file, or you may be able to just drag the image to your desktop.ToggleToggle the top barTotalTotalsTrashTrying again in %(num)d second...Trying again in %(num)d seconds...TutorialType "%time" at the beginning of the cell.Type "restart" to restart the SAGE interpreter for a given worksheet. (You have to interrupt first.)Type ? immediately after the object or function and press tab or shift-enter (shift-enter overwrites output and saves to worksheet).Type of challengeType pretty_print_default() in an input cell and press shift-enter. All future output will be typeset automatically.Typesetting All OutputUnable to interrupt calculation.UnarchiveUnarchive selected worksheets so it appears in the default worksheet listUndeleteUndoUnsuspendUntitledUpdatedUploadUpload WorksheetUpload or Create Data FileUpload or Create Data File to attach to worksheet "%(wn)s"Upload or create a data file in a wide range of formatsUpload or create file...Upload worksheet (an sws or txt file) to the Sage NotebookUse "attach filename.sage" or "attach filename.py". Attached files are automatically reloaded when the file changes. The file $HOME/.sage/init.sage is attached on startup if it exists.Use "load filename.sage" and "load filename.py". Load is relative to the path you started the notebook in. The .sage files are preparsed and .py files are not. You may omit the .sage or .py extension. Files may load other files.Use "save obj1 obj2 ..." and "load obj1 obj2 ...". This allows for easy moving of objects from one worksheet to another, and saving of objects for later use.Use "save_session('name')" to save all variables to an object. Use "load_session('name')" to merge in all variables from a saved session.Use Most Mathematics Software from Within SageUse Sage for studying calculus, elementary to very advanced number theory, cryptography, commutative algebra, group theory, graph theory, numerical and exact linear algebra, and more.Use a Mainstream Programming LanguageUse a challenge for account registrationUse an Open Source AlternativeUse the Data menu to upload images and other files, and create new files that can be shared between worksheets. The DATA variable contains the path to the data files. For example, to open a file in that directory, do "open(DATA+'filename')". If foo.sage is a Sage file that you uploaded, type "load foo.sage"; if foo.py is a Python file, you can import it by typing "import foo".Useful TipsUserUser "%s" does not have permission to view the home page of "%s".User ManagementUsernameUsername ErrorUsername already in useUsername is not in the systemUsername takenUsersVersionView a 4000+ page reference manual about SageView a log of recent computationsView changes to this worksheet over timeView plain textView plain text version of this worksheetWelcome to Sage! You can create a new worksheet, view published worksheets, or read the documentation.Welcome!What do you want to call it? (if different than the original name)What is 2 plus 3?What is 3 times 8?What is the largest prime factor of 15?With the Sage Notebook anyone can create, collaborate on, and publish interactive worksheets. In a worksheet, one can write code using Sage, Python, and other software included in Sage.Working DirectoryWorksheetWorksheet is locked. Cannot insert cells.Worksheet is publicly viewable at %(u)sWorksheet process limitsWorksheet process users (comma-separated list)Wrong passwordYesYou are not authorized to move "%s"You are not logged in or do not have access to the worksheet "%s".You can publish your worksheet to the Internet, where anyone will be able to access and view it online.You may add or remove collaborators (separate user names by commas).You may download %(f)s or create a linked copy to the worksheetYou must login first in order to edit this worksheet.You must login first in order to rate this worksheet.You requested to evaluate a cell that, for some reason, the server is unaware of.You work with Sage using the highly regarded scripting language Python. You can write programs that combine serious mathematics with anything else.Your browser / OS combination is not supported.\nPlease use Firefox or Opera under Linux, Windows, or Mac OS X, or Safari.Your email address is required for account confirmation and recovery. You will be emailed a confirmation link right after you successfully sign up.Your new password is %s Sign in at %s://%s:%s/ Make sure to reset your password by going to Settings in the upper right bar.Your password must be between 4 and 32 characters long. Your password can not contain your username nor spaces.Your username must start with a letter and be between 3 and 64 characters long. You may only use letters, numbers, underscores, @, and dots.Your worksheet will be assigned a unique address (URL) that you can send to your friends and colleagues.browse directorycan't evaluate worksheet cellscs_CZde_ATen_USes_ESevaluatefr_FRlast edited on %(t)s by %(le)sloading...optionalor delete %(f)s.pt_BRpublishedreCAPTCHA private keyreCAPTCHA public keyru_RUrunnings (canceling further update checks).select worksheetuk_UAunprintedy|yesProject-Id-Version: Sage Notebook 0.8 Report-Msgid-Bugs-To: EMAIL@ADDRESS POT-Creation-Date: 2011-06-13 12:49-0700 PO-Revision-Date: 2011-06-13 12:57-0800 Last-Translator: Mike Hansen Language-Team: Luiz C. M. de Aquino MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit Generated-By: Babel 1.3 %(num)d dia%(num)d dias%(num)d hora%(num)d horas%(num)d minuto%(num)d minutos%(num)d segundo%(num)d segundos%(seconds)s ago%(t)s atrás por %(le)s(note que imagens não são gravadas)24|vinte e quatro5|cinco8|oitoNavegue através do tutorial (se você tiver problema com essa opção, veja a versão estática).Reiniciar, ao invés disso?

    Endereço de e-mail confirmado para o usuário %s

    Chave de confirmação inválida

    Você está reportando uma chave de confirmação que não foi atribuída por esse servidor. Por favor, registre-se no servidor.

    Sage é uma alternativa diferente para programas matemáticosUma seção é uma planilha com um conjunto de variáveis em algum estado.Uma planilha é uma lista ordenada de cálculos efetuados com o Sage.Uma nova senha será enviada para o endereço de e-mail cadastrado na sua conta. Porém, se você não tiver confirmado seu e-mail então não será possível recuperar sua conta.Acesse %(f)s nesta planilha através de DATA+'%(f)s'. Sendo DATA uma variável especial que fornece o diretório onde está todos os arquivos de dados enviados para esta planilha.Recuperação de ContaConfigurações de ContaAção...AtivasPlanilhas AtivasAdicionar Novo UsuárioAdicionar UsuárioAdicionar ou RemoverResponda um desafioQualquer célula com "#auto" na entrada é automaticamente avaliada quando a planilha é aberta pela primeira vez.AparênciaabrilArquivarArquivar planilhas selecionadas. Desse modo, elas não aparecem na lista de planilhas padrãoArquivadasPlanilhas ArquivadasScripts AnexosagostoAutenticaçãoAvaliar Células Automaticamente ao CarregarRepublicar automaticamente quando alterações forem feitasRetornar para a sua lista pessoal de planilhasSenha ruimNome de usuário inválidoInicio um bloco com %sh para que o resto do mesmo seja avaliado como um script shell. O diretório de trabalho atual é mantido.Navegue entre planilhas Sage publicadas
    (não é necessário cadastrar-se)Navegar entre as planilhas publicadasNavegue pelo seu computador para selecionar um arquivo:Navegue por seu computador para selecionar uma planilha para enviar:Usando o Sage você ajuda a suportar uma alternativa viável de código aberto ao Magma, Maple, Mathematica e MATLAB. O Sage inclue muitos pacotes matemáticos abertos de alta qualidade.CancelarCancelar alteraçõesCasos / TestesAlterar intervalo de salvamento automáticoAlterar endereço de e-mailAlterar SenhaAlterar as configurações da conta, incluindo senhaClique no menu Histórico para ver os comandos que você digitou em qualquer planilha desse notebook.Clique em Interromper ou pressione Espaço em qualquer célula de entrada. Isso irá (tentar) interromper o SAGE enviando muitos sinais de interrupção.Clique aqui ou pressione shift+enter para avaliarClique aqui para aparecerClique aqui para transformar o que está acima em uma planilha do Sage.Clique sobre o lado esquerdo da saída para alternar entre linhas com número de colunas limitado ou não limitado.Clique para baixar e instalar as fontes tex.Clique para renomear a planilhaFeche essa caixa para parar de tentar.Os códigos são avaliados por execução (depois de uma pré-análise). Somente a saída da última linha da célula é impressa implicitamente. Se qualquer linha começa com "sage:" ou ">>>" será considerado que o bloco inteiro contém textos e exemplos, então somente as linhas iniciadas com um prompt serão executadas. Sendo assim, você pode copiar inteiramente os exemplos da documentação sem editar nada. Além disso, você pode escrever células de entrada que contém textos que não precisam ser avaliados juntamente com exemplos, bastando para isso iniciar o bloco com ">>>" ou incluindo um exemplo.ColaboradoresComentárioComentar / Remover Comentário de BlocosConfirmadoParabéns %(u)s! Você agora pode conectar-se no Notebook Sage.ConstruçõesContinuarCopiar essa planilhaCopiar planilhaContagemCriar ContaCrie uma boa senhaCrie uma nova planilha do Sage com os últimos 100 comandos do histórico acima.Criar uma nova planilhaEscolha um nome de usuárioCriar ContaCreating new users is disabled by the administrator.Pasta AtualE-mail atualPersonalizando o CSS do NotebookVariável DATAVariável DIRArquivo de DadosDados...dezembroIdioma padrãoSistema padrãoApagarApagar todas as saídasApagar CélulaApague todo o conteúdo da célula e pressione Backspace.Apagar todas as saídasApagar planilhaPlanilhas ApagadasGuia do DesenvolvedorDescartar & SairDescartar alterações feitas nessa planilhaVocê deseja publicar essa planilha?Tamanho da documentaçãoDocumentaçãoBaixarBaixar todas AtivasBaixar planilhas selecionadasBaixar.Cada bloco de código é rodado a partir de seu próprio diretório. Se quaisquer imagens são criadas como um efeito colateral, então elas serão automaticamente exibidas.EditarEditar uma cópia.Editar textoEditar essa planilha como um textoEditar isto.Tempo decorridoE-mail confirmadoEsvaziar LixeiraEsvaziando a lixeira todos os itens serão apagados permanentemente. Deseja continuar?Habilitar registro de usuárioHabilitar/Desabilitar saída eleganteDigite o seu endereço de e-mailAmbienteErroErro aplicando a função na planilha(s).Erro encontradoErro na introspecção -- id inválido de célula.Erro atualizando a saída da célula após Erro enviando arquivo (argumentos %s faltando).%sErro enviando arquivo (arquivo fileField faltando).%sErro enviando arquivo (nome do arquivo faltando).%sErros encontradosAvaliar TudoAvalie células usando GAP, Singular, etc.Avaliar EntradaAvalizar todas as células da planilhaAvaliar todas as células de entrada usando %(i)sSairEra esperado "%(wanted)s" depois de "%(key)s", obtido "%(token)s"Era esperado um valor de cor "%(arg)s" depois de "%(key)s"Era esperado um inteiro "%(arg)s" depois de "%(key)s"Era esperado um inteiro "%(key)s" antes de "%(token)s"FalhouFalha ao salvar a planilha.Versão estática rápida da DocumentaçãofevereiroArquivo...Arquivos e ScriptsEncontre Ajuda e DocumentaçãoRecuperar senhaBusca de Texto Completa em Documentos e FontesEpa! -- Você não pode enganar o sistema de pontuação assim tão fácil!Matemática Pura e Aplicada de forma geral e avançadaObter ImagemComeçe a conhecer o SageDar acesso a sua planilha para os colaboradores acimaIr para a planilha.AjudaAjuda Sobre AlgoAjuda via Chat na Internet (IRC)Olá %s! EsconderEsconder todas as saídasEsconder todas as saídasExibir/Esconder SaídaSelecione o texto e pressione Ctrl+. para comentá-lo e Ctrl+, para remover o comentário. Ou ainda, use Ctrl+3 e Ctrl+4.Selecione o texto e pressione > para avançar tudo e < para recuar tudo (funciona no Safari e Firefox). No Firefox você também pode pressionar Tab e Shift+Tab.HistóricoInícioComo eu construo ... no Sage?Quantos bits há em um byte?Como usar o Notebook SageIntervalo de checagem Idle (segundos)Tempo de saída Idle (segundos)Se você criar um arquivo $HOME/.sage/notebook.css, então ele será aplicado quando o notebook for iniciado.Senha incorreta fornecidaRecuo de BlocosRegras de EntradaInserir Nova CélulaInserir próxima célula de textoObjetos Interativos e DinâmicosUse essa planilha interativamenteInterromperInterromper cálculos atuaisInterromper e Reiniciar SessõesTentativa de interromperInterromper cálculos atuais se possívelReposta ao desafio inválidaEndereço de e-mail inválidoNome de usário inválidoConvidar ColaboradoresÉ verdade que pi > e ?janeiroAplicativo Java EscondidoJavascript must be enabled in order to use the Sage Notebook.Imagem do JmoljulhojunhoUso do Teclado e do MouseIdiomaÚltima EdiçãoAprenda a escrever programas SagePermitir que outros usuários editem essa planilhaCarregar uma nova planilha armazenada em um arquivoCarregar planilha a partir de um arquivo...Carregando Scripts SAGE/PythonCarregando e Salvando ObjetosCarregando e Salvando SessõesHistóricoEntrarConecte-se para editar uma cópiaSair do notebook SageTornar essa planilha visível publicamenteGerenciar UsuáriosmarçoTamanho máximo do históricomaioMinutosMova o mouse entre duas células até que uma barra azul apareça. Shift+click sobre a barra azul para criar uma nova célula de texto. Clique duas vezes sobre uma já existente para editá-la. Use $...$ e $$...$$ para incluir textos matemáticos dentro do bloco.Remover panilhas selecionadas da LixeiraMover planilhas selecionadas para a LixeiraMover essa planilha para a lixeiraModo de multi CélulaNova PlanilhaNovo e-mailSenha novaNova senha não fornecidaNova planilhaNovaMais novaNãoO desafio não foi respondidoSem arquivos de dadoNenhum endereço de e-mail dadoNenhuma senha foi dadaNenhuma planilha dessa.Nenhum nome de usuário dadoNão confirmadoConfigurações do NotebooknovembroNúmero de colunas por linhaoutubroSenha antigaSenha antiga não fornecidaVelhaMais velhaModo de Célula ÚnicaApenas o proprietário dessa planilha pode compartilhá-la. Você pode fazer o que quiser se fizer sua própria cópia.Ou digite o endereço (URL) de um arquivo na Internet:Ou digite o endereço (URL) de uma planilha na Internet:Ou entre o nome do novo arquivo que será criado:Outras planilhas publicadas...ProprietárioCombinação de ParêntesesPassouSenhaAs senhas que você forneceu não combinamEscolha um nome de usuárioPor favor, solicite ao administrador do servidor que configure um desafio!Por favor digite um nome para essa planilhaPor favor, conecte-se no notebook SagePor favor, requisite uma planilha específicaPor favor especifique uma planilha para carregar.%sPor favor digite no campo nova senha novamente.Possível falha apagando a planilhaPressione Ctrl+; em uma célula para separá-la em duas e Ctrl+Backspace para uni-las. Pressione Ctrl+Enter para separa uma célula e avaliar cada pedaço.Pressionando Shift+Enter você pode realizar vários cálculos de uma só vez. Se você pressionar Alt+Enter ao invés disso, então uma nova célula é criada depois da atual. Se você pressionar Ctrl+Enter, então a célula será dividida e cada pedaço será avaliado separadamente.Pressione Tab enquanto o cursor está sobre um identificador. Em alguns navegadores (e.g., Opera) você pode usar Ctrl+Espaço ao invés de Tab.Saída de impressão elegante (typeset)ImprimirImprimir essa planilhaProblema ao inserir nova célula de entrada após a atual.PublicarPublicar essa aquiPublicadaPlanilhas PublicadasPublicada em %(t)sColocando "%gap" ou "%singular" como a primeira linha de entrada da célula, o resto da célula será avaliada por esse sistema.Digite ?? imediatamente após o objeto e pressione Tab ou Shift+Enter (a combinação Shift+Enter sobrescreve a saída e salva na planilha)Coloque @interact sobre a linha antes da definição de uma função. Digite interact? para mais detalhes.Coloque o mouse entre uma saída e uma entrada até que uma linha horizontal apareça e clique nela. Se você pressionar Alt+Enter em uma célula, ela será avaliada e uma nova célula será inserida depois dela.Encerrar o processo da planilhaPontuarPontuarPontuação AceitaPontuação para %(wn)sRepublicar planilhaDigite a senha novamenteManual de ReferênciaLembre-se de mimRenomearRenomear essa planilhaRenomear planilhaRelatar um ProblemaRelatar um problema ou um bug. Isso é importante para melhorar o Sage!Requisitar e-mail para registrar contasRepontuarReiniciarReiniciarReinicar o processo da planilhaReinicar planilhaRetornar para Enviar ou Criar Arquivo de Dados ou %s.Digite a nova senha novamenteReverter para esta aquiRevisãoRevisão %(lr)sHistórico de RevisãoLista de RevisõesRevisão de %(ta)s atrásDocumentação do SageNotebook SageVersão do Notebook SageNavegador do Código Fonte do SageUsuários Sage:O Sage torna fácil para você a utilização de muitos programas matemáticos juntos. Ele inclue o GAP, GP/PARI, Maxima, Singular e uma dúzia de outros pacotes abertos.Versão do SageSage: Histórico de %(u)sSalvarSalvar & SairSalvar AlteraçõesSalvar e fechar planilhaSalvar alteraçõesSalvar alterações e fechar a janelaIntervalo de salvamento (segundos)Salvar essa planilha em um arquivo .swsSalvar planilha em um arquivo...Procurar PlanilhaFaça buscas dentro da documentação do SAGE digitando
    search_doc("minha pesquisa")
    em uma célula de entrada e pressionando Shift+Enter. Faça buscas dentro do código fonte do SAGE digitando
    search_src("minha pesquisa")
    e pressionando Shift+Enter. Você pode procurar por expressões regulares arbitrárias.Procurando pelo servidor Sage...Selecione uma função relacionada ao arquivoSelecionar uma função sobre a planilhaSelect an OpenID providerAnexar um arquivosetembroServidorConfiguraçõesCompartilharCompartilhar agoraCompartilhar este documentoScripts ShellExibirExibir todas as saídasExibir todas as saídasEntrarSairEntrarCadastre uma nova conta no Notebook SageCadastre uma nova conta no Notebook SageOutro usuário está visualizando essa planilhaDesculpe-me, mas o seu navegador precisa suportar o tag <canvas>Código FonteBloco Especial de CélulasSeparar e Unir CélulasIniciarVersão estática...StatusPararParar publicaçãoParar planilhas selecionadasEnviarApagado com sucesso "%s"SuspenderSuspensãoNome de arquivo "%s" suspeito encontrado enquanto enviando o arquivo.%sAlternar para modo multi célula Alternar para modo de célula únicaComplemento com a tecla TabTextoObrigado por pontuar a planilha %s! Você pode ver todas as pontuações desta planilha.Obrigado por registrar-se no Notebook Sage. Para completar seu registro, copie e cole o endereço a seguir no seu navegador: %s://%s:%s/confirm?key=%s Você será levado para uma página que irá confirmar que você está de fato registrado.O Notebook Sage é uma coleção de planilhas, objetos salvos e informações do usuárioNotebook SageO Notebook Sage foi primeiramente escrito por William Stein com contribuição substancial de Tom Boothby, Timothy Clemans, Alex Clemesha, Mike Hansen, Bobby Moretti, Yi Qiang e Dorian Raymer.O sistema de confirmação não está ativo.A senha do usuário %(u)s foi reiniciada para %(p)sAs senhas que você forneceu não combinamO usuário "%s" não tem uma planilha "%s".O nome de usuário deve iniciar com uma letra e ter entre 4 e 32 caracteres. Ele só pode conter letras, números, sublinhado (_) e um ponto.A variável DIR contém o diretório a partir do qual você iniciou o notebook SAGE. Por exemplo, para abrir um arquivo nesse diretório use "open(DIR+'arquivo')".A operação "%s" sobre a planilha não é definida.Não há planilhas publicadas.Não existe planilha publicada com o nome "%s". Redirecionando para o índice de planilhas publicadas em 10 segundos...

    Ocorreu um erro enviando "%s" (por favor, confira a URL).%sOcorreu um erro enviando a planilha. Pode ter sido devido a um velho formato não suportado ou pior. Se você precisa desesperadamente desse conteúdo, contate o grupo sage-support e poste o endereço (URL) de sua planilha. Ou ainda, uma arquivo .sws é apenas uma compactação bzip2. Dê uma olhada dentro dele!%sEssa planilha Sage está compartilhada atualmente com as pessoas listadas na caixa abaixo.Essa página foi pontuada em %(wr).1f.Esse endereço (url) somente pode ser acessado através de uma requisição POST.Essa planilha é somente para leitura. Por favor faça uma cópia ou entre em contato com o proprietário para alterá-la.TempoTítulo da planilha salvaPara concertar combinações de parênteses, colchetes ou chaves pressione Ctrl+0. Os parênteses antes do cursor serão combinados, pensando em textos e comentários (Python).Começe aqui a experimentar o SagePara salvar essa imagem você pode tentar clicar com o botão direito do mouse sobre ela e usar as opções de seu navegador. Talvez você também possa arrastar a imagem para a sua Ãrea de Trabalho.EsconderEsconder barra superiorTotalTotaisLixeiraTentar novamente em %(num)d segundo...Tentar novamente em %(num)d segundos...TutorialDigite "%time" no início da célulaDigite "restart" para reiniciar o interpretador SAGE de uma dada planilha. (Você deve interrompê-la primeiro.)Digite ? imediatamente após o objeto ou função e pressione Tab ou Shift+Enter (a combinação Shift+Enter sobrescreve a saída e salva na planilha)Tipo do desafioDigite pretty_print_default() em uma célula de entrada e pressione Shift+Enter. Todas as saídas futuras terão uma melhor impressão automaticamente. Melhor impressão de todas as saídasNão foi possível interromper o cálculo.DesarquivarDesarquivar planilhas selecionadas. Desse modo, elas aparecem na lista de planilhas padrãoRecuperarDesfazerTirar suspensãoSem títuloAtualizadoEnviarEnviar PlanilhaEnviar ou Criar Arquivo de DadosEnviar ou Criar um Arquivo de Dados anexado a planilha "%(wn)s"Enviar ou criar um arquivo de dados em vários formatos.Enviar ou criar um arquivo...Enviar uma planilha (arquivo .sws ou .txt) para o Notebook SageUse "attach arquivo.sage" ou "attach arquivo.py". Arquivos anexos são automaticamente recarregados quando são alterados. O arquivo $HOME/.sage/init.sage é anexado na inicialização, caso ele exista.Use "load arquivo.sage" e "load arquivo.py". O carregamento será relativo ao diretório onde você iniciou o notebook. Os arquivos .sage são pré-analisados, mas .py não são. Você pode omitir as extensões .sage e .py. Os arquivos podem carregar outros arquivos.Use "save obj1 obj2 ..." e "load obj1 obj2 ...". Isso permite o fácil deslocamento de objetos entre planilhas, além de salvar os objetos para uso futuro.Use "save_session('nome')" para salvar todas as variáveis em um objeto. Use "load_session('nome')" para mesclar todas as variáveis de uma sessão salva.Use mais programas Matemáticos dentro do SageUse o Sage para estudar Cálculo, Teoria dos Números, Criptografia, Ãlgebra Comutativa, Teoria de Grupos, Teoria de Grafos, Ãlgebra Linear (numérica e exata) e muito mais.Use uma Linguagem de Programação bem difundidaUsar um desafio para registrar contasUma alternativa de Código AbertoUse o menu Dados para enviar imagens e outros arquivos, ou ainda para criar novos, que podem ser compartilhados entre as planilhas. A variável DATA contém o diretório onde está esses arquivos de dados. Por exemplo, para abrir um arquivo desse diretório use "open(DATA+'arquivo')". Se exemplo.sage é um arquivo Sage que você enviou, então use "load exemplo.sage"; se exemplo.py é um arquivo Python, então você pode importá-lo usando "import exemplo".Dicas ÚteisUsuárioO usuário "%s" não tem permissão de ver a página de "%s".Gerenciador de UsuárioUsuárioErro no nome do usuárioEsse nome de usuário já está em usoUsuário não definido no sistemaNome de usuário escolhidoUsuáriosVersãoVeja mais de 4000 páginas de referência sobre o SageVer o histórico das computações recentesVeja as alterações dessa planilha ao longo do tempoVisualizar textoVisualizar essa planilha como um textoBem-vindo ao Sage! Você pode criar uma nova planilha, ver planilhas publicadas ou ler a documentação.Bem-vindo!Como você deseja chamar essa planilha? (deixe em branco para manter o nome original)Quanto é 2 mais 3?Quanto é 3 vezes 8?Qual é o maior fator primo de 15?Com o Notebook Sage você pode criar, colaborar e publicar planilhas interativas. Em uma planilha você pode escrever códigos usando Sage, Python e outros programas incluídos no Sage.Diretório de TrabalhoPlanilhaA planilha está travada. Não se pode inserir células.Planilha disponível em %(u)sLimites de processamento de planilhaUsuários de processamento de planilha (lista separada por vírgulas)Senha incorretaSimVocê não está autorizado a mover "%s"Você não está conectado ou não tem acesso a planilha "%s".Você pode publicar sua planilha na Internet, onde qualquer um pode acessá-la online.Você pode adicionar ou remover colaboradores (separando os nomes com vírgulas)Você pode baixar %(f)s ou criar uma cópia vinculada a planilhaVocê deve conectar-se primeiro antes de editar esta planilha.Você deve conectar-se primeiro para pontuar essa planilha.Você requisitou avaliar uma célula que, por alguma razão, o servidor não conhece.Você trabalha no Sage usando a bem recomendada linguagem de programação Python. Você pode escrever programas que combinam matemática séria com qualquer outra coisa.A combinação entre seu navegador e S.O. não é suportada.\nPor favor, use Firefox ou Opera com o Linux, Mac OS X, Safari ou Windows.O seu endereço de e-mail é necessário para a confirmação e a recuperação de sua conta. Será enviado para seu e-mail um endereço de confirmação após a criação de sua conta.A sua nova senha é: %s Conecte-se aqui: %s://%s:%s/ Certifique-se de alterar sua senha através do menu Configurações na barra superior.A sua senha deve ter entre 4 e 32 caracteres. A sua senha não pode conter o seu nome de usuário e nem espaços.O nome de usuário deve iniciar com uma letra e ter entre 4 e 32 caracteres. Ele só pode conter letras, números, sublinhado (_), @ e pontos.A sua planilha será associada a um endereço (URL) único que você poderá enviar aos seus amigos e colegas.navegar nos diretóriosnão foi possível avaliar as células da planilhaÄeÅ¡tina (ÄŒeská republika)Deutsch (Österreich)English (United States)español (España)avaliarfrançais (France)última edição em %(t)s por %(le)scarregando...opcionalou apagar %(f)s.português (Brasil)publicadaChave privada do reCAPTCHAChave pública do reCAPTCHAруÑÑкий (РоÑÑиÑ)executandos (cancelando futuras checagens de atualização).selecione uma planilhaукраїнÑька (Україна)não impressos|simsagenb-1.0.1/sagenb/translations/pt_BR/LC_MESSAGES/messages.po000066400000000000000000002314611311436262400237030ustar00rootroot00000000000000# Translations template for SAGE Notebook. # Copyright (C) 2007 SAGE # This file is distributed under the same license as the SAGE project. # FIRST AUTHOR aquino.luizclaudio@gmail.com, 2010. # msgid "" msgstr "" "Project-Id-Version: Sage Notebook 0.8\n" "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" "POT-Creation-Date: 2011-06-13 12:49-0700\n" "PO-Revision-Date: 2011-06-13 12:57-0800\n" "Last-Translator: Mike Hansen \n" "Language-Team: Luiz C. M. de Aquino \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Generated-By: Babel 0.9.5\n" "Plural-Forms: nplurals=2; plural=n>1;\n" "X-Poedit-Language: Portuguese\n" "X-Poedit-Country: BRAZIL\n" "X-Poedit-SourceCharset: utf-8\n" msgid "cs_CZ" msgstr "ÄeÅ¡tina (ÄŒeská republika)" msgid "de_AT" msgstr "Deutsch (Österreich)" msgid "en_US" msgstr "English (United States)" msgid "es_ES" msgstr "español (España)" msgid "pt_BR" msgstr "português (Brasil)" msgid "ru_RU" msgstr "руÑÑкий (РоÑÑиÑ)" msgid "fr_FR" msgstr "français (France)" msgid "uk_UA" msgstr "українÑька (Україна)" #: data/sage/html/base.html:31 #: data/sage/html/login.html:35 msgid "The Sage Notebook" msgstr "Notebook Sage" #: data/sage/html/base.html:33 msgid "Searching for Sage server..." msgstr "Procurando pelo servidor Sage..." #: data/sage/html/base.html:35 msgid "Version" msgstr "Versão" #: data/sage/html/base_authenticated.html:7 msgid "Please log in to the Sage notebook" msgstr "Por favor, conecte-se no notebook Sage" #: data/sage/html/base_authenticated.html:7 msgid "Log in" msgstr "Entrar" #: data/sage/html/base_authenticated.html:9 msgid "Toggle the top bar" msgstr "Esconder barra superior" #: data/sage/html/base_authenticated.html:9 #: data/sage/html/test_report.html:123 msgid "Toggle" msgstr "Esconder" #: data/sage/html/base_authenticated.html:10 msgid "Back to your personal worksheet list" msgstr "Retornar para a sua lista pessoal de planilhas" #: data/sage/html/base_authenticated.html:10 msgid "Home" msgstr "Início" #: data/sage/html/base_authenticated.html:12 #: data/sage/html/base_authenticated.html:14 msgid "Published" msgstr "Publicada" #: data/sage/html/base_authenticated.html:14 msgid "Browse the published worksheets" msgstr "Navegar entre as planilhas publicadas" #: data/sage/html/base_authenticated.html:15 msgid "View a log of recent computations" msgstr "Ver o histórico das computações recentes" #: data/sage/html/base_authenticated.html:15 msgid "Log" msgstr "Histórico" #: data/sage/html/base_authenticated.html:17 msgid "Change account settings including password" msgstr "Alterar as configurações da conta, incluindo senha" #: data/sage/html/base_authenticated.html:17 msgid "Settings" msgstr "Configurações" #: data/sage/html/base_authenticated.html:18 msgid "Documentation" msgstr "Documentação" #: data/sage/html/base_authenticated.html:18 msgid "Help" msgstr "Ajuda" #: data/sage/html/base_authenticated.html:19 msgid "Report a problem or submit a bug to improve Sage" msgstr "Relatar um problema ou um bug. Isso é importante para melhorar o Sage!" #: data/sage/html/base_authenticated.html:19 msgid "Report a Problem" msgstr "Relatar um Problema" #: data/sage/html/base_authenticated.html:20 msgid "Log out of the Sage notebook" msgstr "Sair do notebook Sage" #: data/sage/html/base_authenticated.html:20 msgid "Sign out" msgstr "Sair" #: data/sage/html/docs.html:3 msgid "Sage Documentation" msgstr "Documentação do Sage" #: data/sage/html/docs.html:15 msgid "To quickly try out Sage start here" msgstr "Começe aqui a experimentar o Sage" #: data/sage/html/docs.html:15 msgid "Tutorial" msgstr "Tutorial" #: data/sage/html/docs.html:16 msgid "View a 4000+ page reference manual about Sage" msgstr "Veja mais de 4000 páginas de referência sobre o Sage" #: data/sage/html/docs.html:16 msgid "Reference Manual" msgstr "Manual de Referência" #: data/sage/html/docs.html:17 msgid "Learn to write Sage programs" msgstr "Aprenda a escrever programas Sage" #: data/sage/html/docs.html:17 msgid "Developer Guide" msgstr "Guia do Desenvolvedor" #: data/sage/html/docs.html:18 msgid "How do I construct ... in Sage?" msgstr "Como eu construo ... no Sage?" #: data/sage/html/docs.html:18 msgid "Constructions" msgstr "Construções" #: data/sage/html/docs.html:21 msgid "Static version..." msgstr "Versão estática..." #: data/sage/html/docs.html:21 msgid "Fast Static Versions of the Documentation" msgstr "Versão estática rápida da Documentação" #: data/sage/html/docs.html:22 msgid "Help via Internet Chat (IRC)" msgstr "Ajuda via Chat na Internet (IRC)" #: data/sage/html/docs.html:28 msgid "How to use the Sage Notebook" msgstr "Como usar o Notebook Sage" #: data/sage/html/docs.html:30 msgid "A worksheet is an ordered list of Sage calculations with output." msgstr "Uma planilha é uma lista ordenada de cálculos efetuados com o Sage." #: data/sage/html/docs.html:31 msgid "A session is a worksheet and a set of variables in some state." msgstr "Uma seção é uma planilha com um conjunto de variáveis em algum estado." #: data/sage/html/docs.html:32 msgid "The Sage notebook is a collection of worksheets, saved objects, and user information." msgstr "O Notebook Sage é uma coleção de planilhas, objetos salvos e informações do usuário" #: data/sage/html/docs.html:45 msgid "The Sage Notebook was primarily written by William Stein with substantial contributions from Tom Boothby, Timothy Clemans, Alex Clemesha, Mike Hansen, Bobby Moretti, Yi Qiang, and Dorian Raymer." msgstr "O Notebook Sage foi primeiramente escrito por William Stein com contribuição substancial de Tom Boothby, Timothy Clemans, Alex Clemesha, Mike Hansen, Bobby Moretti, Yi Qiang e Dorian Raymer." #: data/sage/html/error_message.html:4 #: data/sage/html/login.html:63 #: data/sage/html/login.html:70 #: data/sage/html/login.html:98 #: data/sage/html/login.html:100 #: data/sage/html/recaptcha.html:27 #: data/sage/html/test_report.html:112 #: data/sage/html/test_report.html:131 #: data/sage/html/accounts/registration.html:20 #: data/sage/html/accounts/registration.html:23 #: data/sage/html/accounts/registration.html:26 #: data/sage/html/accounts/registration.html:36 #: data/sage/html/accounts/registration.html:39 #: data/sage/html/accounts/registration.html:46 #: data/sage/html/accounts/registration.html:57 #: data/sage/html/accounts/registration.html:60 #: data/sage/html/accounts/registration.html:69 #: data/sage/html/accounts/registration.html:72 #: data/sage/html/settings/admin_add_user.html:17 #: data/sage/html/settings/admin_add_user.html:19 #: data/sage/js/translated-messages.js:17 msgid "Error" msgstr "Erro" #: data/sage/html/error_message.html:19 msgid "Continue" msgstr "Continuar" #: data/sage/html/history.html:3 #, python-format msgid "Sage: History for %(u)s" msgstr "Sage: Histórico de %(u)s" #: data/sage/html/history.html:13 msgid "Click here to turn the above into a Sage worksheet" msgstr "Clique aqui para transformar o que está acima em uma planilha do Sage." #: data/sage/html/history.html:13 msgid "Create a new Sage worksheet version of the last 100 commands in the above log." msgstr "Crie uma nova planilha do Sage com os últimos 100 comandos do histórico acima." #: data/sage/html/login.html:12 #, fuzzy msgid "username" msgstr "Usuário" #: data/sage/html/login.html:13 msgid "Select an OpenID provider" msgstr "" #: data/sage/html/login.html:14 #, fuzzy msgid "Send" msgstr "Suspender" #: data/sage/html/login.html:22 #: data/sage/html/login.html:78 msgid "Sign in" msgstr "Entrar" #: data/sage/html/login.html:28 #, python-format msgid "Congratulations %(u)s! You can now sign into the Sage Notebook." msgstr "Parabéns %(u)s! Você agora pode conectar-se no Notebook Sage." #: data/sage/html/login.html:32 msgid "Welcome!" msgstr "Bem-vindo!" #: data/sage/html/login.html:33 msgid "Sage is a different approach to mathematics software." msgstr "Sage é uma alternativa diferente para programas matemáticos" #: data/sage/html/login.html:36 msgid "With the Sage Notebook anyone can create, collaborate on, and publish interactive worksheets. In a worksheet, one can write code using Sage, Python, and other software included in Sage." msgstr "Com o Notebook Sage você pode criar, colaborar e publicar planilhas interativas. Em uma planilha você pode escrever códigos usando Sage, Python e outros programas incluídos no Sage." #: data/sage/html/login.html:39 msgid "General and Advanced Pure and Applied Mathematics" msgstr "Matemática Pura e Aplicada de forma geral e avançada" #: data/sage/html/login.html:40 msgid "Use Sage for studying calculus, elementary to very advanced number theory, cryptography, commutative algebra, group theory, graph theory, numerical and exact linear algebra, and more." msgstr "Use o Sage para estudar Cálculo, Teoria dos Números, Criptografia, Ãlgebra Comutativa, Teoria de Grupos, Teoria de Grafos, Ãlgebra Linear (numérica e exata) e muito mais." #: data/sage/html/login.html:43 msgid "Use an Open Source Alternative" msgstr "Uma alternativa de Código Aberto" #: data/sage/html/login.html:44 msgid "By using Sage you help to support a viable open source alternative to Magma, Maple, Mathematica, and MATLAB. Sage includes many high-quality open source math packages." msgstr "Usando o Sage você ajuda a suportar uma alternativa viável de código aberto ao Magma, Maple, Mathematica e MATLAB. O Sage inclue muitos pacotes matemáticos abertos de alta qualidade." #: data/sage/html/login.html:47 msgid "Use Most Mathematics Software from Within Sage" msgstr "Use mais programas Matemáticos dentro do Sage" #: data/sage/html/login.html:48 msgid "Sage makes it easy for you to use most mathematics software together. Sage includes GAP, GP/PARI, Maxima, and Singular, and dozens of other open packages." msgstr "O Sage torna fácil para você a utilização de muitos programas matemáticos juntos. Ele inclue o GAP, GP/PARI, Maxima, Singular e uma dúzia de outros pacotes abertos." #: data/sage/html/login.html:51 msgid "Use a Mainstream Programming Language" msgstr "Use uma Linguagem de Programação bem difundida" #: data/sage/html/login.html:52 msgid "You work with Sage using the highly regarded scripting language Python. You can write programs that combine serious mathematics with anything else." msgstr "Você trabalha no Sage usando a bem recomendada linguagem de programação Python. Você pode escrever programas que combinam matemática séria com qualquer outra coisa." #: data/sage/html/login.html:60 #: data/sage/html/accounts/account_recovery.html:13 msgid "Username" msgstr "Usuário" #: data/sage/html/login.html:63 msgid "Username is not in the system" msgstr "Usuário não definido no sistema" #: data/sage/html/login.html:67 #: data/sage/html/settings/user_management.html:13 msgid "Password" msgstr "Senha" #: data/sage/html/login.html:70 msgid "Wrong password" msgstr "Senha incorreta" #: data/sage/html/login.html:74 msgid "Remember me" msgstr "Lembre-se de mim" #: data/sage/html/login.html:83 msgid "Sign up for a new Sage Notebook account" msgstr "Cadastre uma nova conta no Notebook Sage" #: data/sage/html/login.html:87 msgid "Browse published Sage worksheets
    (no login required)" msgstr "Navegue entre planilhas Sage publicadas
    (não é necessário cadastrar-se)" #: data/sage/html/login.html:91 msgid "Forgot password" msgstr "Recuperar senha" #: data/sage/html/login.html:98 msgid "Creating new users is disabled by the administrator." msgstr "" #: data/sage/html/login.html:100 msgid "Javascript must be enabled in order to use the Sage Notebook." msgstr "" #: data/sage/html/source_code.html:3 #: notebook/tutorial.py:358 msgid "Source Code" msgstr "Código Fonte" #: data/sage/html/source_code.html:13 msgid "Sage Source Browser" msgstr "Navegador do Código Fonte do Sage" #: data/sage/html/source_code.html:14 msgid "browse directory" msgstr "navegar nos diretórios" #: data/sage/html/test_report.html:79 msgid "Sage Notebook version" msgstr "Versão do Notebook Sage" #: data/sage/html/test_report.html:85 msgid "Sage version" msgstr "Versão do Sage" #: data/sage/html/test_report.html:91 msgid "Environment" msgstr "Ambiente" #: data/sage/html/test_report.html:96 msgid "Start" msgstr "Iniciar" #: data/sage/html/test_report.html:100 #: data/sage/html/worksheet_listing.html:73 msgid "Stop" msgstr "Parar" #: data/sage/html/test_report.html:104 msgid "Elapsed" msgstr "Tempo decorrido" #: data/sage/html/test_report.html:108 msgid "Status" msgstr "Status" #: data/sage/html/test_report.html:110 #: data/sage/html/test_report.html:129 msgid "Pass" msgstr "Passou" #: data/sage/html/test_report.html:111 #: data/sage/html/test_report.html:130 msgid "Fail" msgstr "Falhou" #: data/sage/html/test_report.html:113 msgid "Total" msgstr "Total" #: data/sage/html/test_report.html:121 msgid "Hide" msgstr "Esconder" #: data/sage/html/test_report.html:122 msgid "Show" msgstr "Exibir" #: data/sage/html/test_report.html:128 msgid "Cases / Tests" msgstr "Casos / Testes" #: data/sage/html/test_report.html:132 msgid "Count" msgstr "Contagem" #: data/sage/html/test_report.html:141 msgid "Totals" msgstr "Totais" #: data/sage/html/upload.html:10 msgid "Upload worksheet (an sws or txt file) to the Sage Notebook" msgstr "Enviar uma planilha (arquivo .sws ou .txt) para o Notebook Sage" #: data/sage/html/upload.html:14 msgid "Browse your computer to select a worksheet file to upload:" msgstr "Navegue por seu computador para selecionar uma planilha para enviar:" #: data/sage/html/upload.html:18 msgid "Or enter the URL of a worksheet file on the web:" msgstr "Ou digite o endereço (URL) de uma planilha na Internet:" #: data/sage/html/upload.html:22 #: data/sage/html/notebook/upload_data_window.html:27 msgid "What do you want to call it? (if different than the original name)" msgstr "Como você deseja chamar essa planilha? (deixe em branco para manter o nome original)" #: data/sage/html/upload.html:25 msgid "Upload Worksheet" msgstr "Enviar Planilha" #: data/sage/html/worksheet_listing.html:9 msgid "Published Worksheets" msgstr "Planilhas Publicadas" #: data/sage/html/worksheet_listing.html:11 msgid "Deleted Worksheets" msgstr "Planilhas Apagadas" #: data/sage/html/worksheet_listing.html:13 msgid "Active Worksheets" msgstr "Planilhas Ativas" #: data/sage/html/worksheet_listing.html:15 msgid "Archived Worksheets" msgstr "Planilhas Arquivadas" #: data/sage/html/worksheet_listing.html:45 msgid "New Worksheet" msgstr "Nova Planilha" #: data/sage/html/worksheet_listing.html:46 msgid "Upload" msgstr "Enviar" #: data/sage/html/worksheet_listing.html:47 msgid "Download All Active" msgstr "Baixar todas Ativas" #: data/sage/html/worksheet_listing.html:54 msgid "Search Worksheets" msgstr "Procurar Planilha" #: data/sage/html/worksheet_listing.html:62 msgid "Unarchive selected worksheets so it appears in the default worksheet list" msgstr "Desarquivar planilhas selecionadas. Desse modo, elas aparecem na lista de planilhas padrão" #: data/sage/html/worksheet_listing.html:62 msgid "Unarchive" msgstr "Desarquivar" #: data/sage/html/worksheet_listing.html:64 msgid "Archive selected worksheets so they do not appear in the default worksheet list" msgstr "Arquivar planilhas selecionadas. Desse modo, elas não aparecem na lista de planilhas padrão" #: data/sage/html/worksheet_listing.html:64 msgid "Archive" msgstr "Arquivar" #: data/sage/html/worksheet_listing.html:68 msgid "Move the selected worksheets to the trash" msgstr "Mover planilhas selecionadas para a Lixeira" #: data/sage/html/worksheet_listing.html:68 msgid "Delete" msgstr "Apagar" #: data/sage/html/worksheet_listing.html:70 msgid "Move the selected worksheets out of the trash" msgstr "Remover panilhas selecionadas da Lixeira" #: data/sage/html/worksheet_listing.html:70 msgid "Undelete" msgstr "Recuperar" #: data/sage/html/worksheet_listing.html:73 msgid "Stop selected worksheets" msgstr "Parar planilhas selecionadas" #: data/sage/html/worksheet_listing.html:75 msgid "Download selected worksheets" msgstr "Baixar planilhas selecionadas" #: data/sage/html/worksheet_listing.html:75 msgid "Download" msgstr "Baixar" #: data/sage/html/worksheet_listing.html:79 msgid "Current Folder" msgstr "Pasta Atual" #: data/sage/html/worksheet_listing.html:80 msgid "Active" msgstr "Ativas" #: data/sage/html/worksheet_listing.html:81 msgid "Archived" msgstr "Arquivadas" #: data/sage/html/worksheet_listing.html:82 msgid "Trash" msgstr "Lixeira" #: data/sage/html/worksheet_listing.html:86 msgid "Empty Trash" msgstr "Esvaziar Lixeira" #: data/sage/html/worksheet_listing.html:101 #: data/sage/html/worksheet/ratings_info.html:9 msgid "Rating" msgstr "Pontuar" #: data/sage/html/worksheet_listing.html:112 msgid "Owner" msgstr "Proprietário" #: data/sage/html/worksheet_listing.html:112 msgid "Collaborators" msgstr "Colaboradores" #: data/sage/html/worksheet_listing.html:118 #: data/sage/html/notebook/worksheet_revision_list.html:16 msgid "Last Edited" msgstr "Última Edição" #: data/sage/html/worksheet_listing.html:128 msgid "There are no published worksheets." msgstr "Não há planilhas publicadas." #: data/sage/html/worksheet_listing.html:134 msgid "Welcome to Sage! You can create a new worksheet, view published worksheets, or read the documentation." msgstr "Bem-vindo ao Sage! Você pode criar uma nova planilha, ver planilhas publicadas ou ler a documentação." #: data/sage/html/worksheet_listing.html:176 msgid "running" msgstr "executando" #: data/sage/html/worksheet_listing.html:209 msgid "Add or Delete" msgstr "Adicionar ou Remover" #: data/sage/html/worksheet_listing.html:211 msgid "Share now" msgstr "Compartilhar agora" #: data/sage/html/worksheet_listing.html:216 msgid "published" msgstr "publicada" #: data/sage/html/accounts/account_recovery.html:3 #: data/sage/html/accounts/account_recovery.html:8 msgid "Account Recovery" msgstr "Recuperação de Conta" #: data/sage/html/accounts/account_recovery.html:9 msgid "A new password will be emailed to the email address connected to your account. However if you didn't confirm your email address you will be unable to recover your account." msgstr "Uma nova senha será enviada para o endereço de e-mail cadastrado na sua conta. Porém, se você não tiver confirmado seu e-mail então não será possível recuperar sua conta." #: data/sage/html/accounts/account_recovery.html:17 msgid "Submit" msgstr "Enviar" #: data/sage/html/accounts/account_recovery.html:17 #: data/sage/html/accounts/registration.html:78 #: data/sage/html/notebook/download_or_delete_datafile.html:54 #: data/sage/html/notebook/edit_window.html:12 #: data/sage/html/settings/account_settings.html:10 #: data/sage/html/settings/account_settings.html:67 #: data/sage/html/settings/admin_add_user.html:26 #: data/sage/html/settings/notebook_settings.html:20 #: data/sage/html/settings/notebook_settings.html:27 msgid "Cancel" msgstr "Cancelar" #: data/sage/html/accounts/registration.html:3 msgid "Sign up" msgstr "Entrar" #: data/sage/html/accounts/registration.html:9 msgid "Sign up for a Sage Notebook account" msgstr "Cadastre uma nova conta no Notebook Sage" #: data/sage/html/accounts/registration.html:11 msgid "Errors found" msgstr "Erros encontrados" #: data/sage/html/accounts/registration.html:11 msgid "Error found" msgstr "Erro encontrado" #: data/sage/html/accounts/registration.html:16 msgid "Create a username" msgstr "Escolha um nome de usuário" #: data/sage/html/accounts/registration.html:17 msgid "Your username must start with a letter and be between 3 and 64 characters long. You may only use letters, numbers, underscores, @, and dots." msgstr "O nome de usuário deve iniciar com uma letra e ter entre 4 e 32 caracteres. Ele só pode conter letras, números, sublinhado (_), @ e pontos." #: data/sage/html/accounts/registration.html:20 msgid "No username given" msgstr "Nenhum nome de usuário dado" #: data/sage/html/accounts/registration.html:23 msgid "Username already in use" msgstr "Esse nome de usuário já está em uso" #: data/sage/html/accounts/registration.html:26 msgid "Bad username" msgstr "Nome de usuário inválido" #: data/sage/html/accounts/registration.html:30 msgid "Create a good password" msgstr "Crie uma boa senha" #: data/sage/html/accounts/registration.html:32 msgid "Your password must be between 4 and 32 characters long. Your password can not contain your username nor spaces." msgstr "A sua senha deve ter entre 4 e 32 caracteres. A sua senha não pode conter o seu nome de usuário e nem espaços." #: data/sage/html/accounts/registration.html:36 msgid "No password given" msgstr "Nenhuma senha foi dada" #: data/sage/html/accounts/registration.html:39 msgid "Bad password" msgstr "Senha ruim" #: data/sage/html/accounts/registration.html:43 msgid "Re-type your password" msgstr "Digite a senha novamente" #: data/sage/html/accounts/registration.html:46 msgid "Passwords didn't match" msgstr "As senhas que você forneceu não combinam" #: data/sage/html/accounts/registration.html:51 msgid "Enter your email address" msgstr "Digite o seu endereço de e-mail" #: data/sage/html/accounts/registration.html:53 msgid "Your email address is required for account confirmation and recovery. You will be emailed a confirmation link right after you successfully sign up." msgstr "O seu endereço de e-mail é necessário para a confirmação e a recuperação de sua conta. Será enviado para seu e-mail um endereço de confirmação após a criação de sua conta." #: data/sage/html/accounts/registration.html:57 msgid "No email address given" msgstr "Nenhum endereço de e-mail dado" #: data/sage/html/accounts/registration.html:60 msgid "Invalid email address" msgstr "Endereço de e-mail inválido" #: data/sage/html/accounts/registration.html:66 msgid "Answer a challenge" msgstr "Responda um desafio" #: data/sage/html/accounts/registration.html:69 msgid "No challenge response given" msgstr "O desafio não foi respondido" #: data/sage/html/accounts/registration.html:72 msgid "Invalid challenge response" msgstr "Reposta ao desafio inválida" #: data/sage/html/accounts/registration.html:77 msgid "Create account" msgstr "Criar Conta" #: data/sage/html/notebook/afterpublish_window.html:8 #, python-format msgid "Worksheet is publicly viewable at %(u)s" msgstr "Planilha disponível em %(u)s" #: data/sage/html/notebook/afterpublish_window.html:9 #, python-format msgid "Published on %(t)s" msgstr "Publicada em %(t)s" #: data/sage/html/notebook/afterpublish_window.html:11 msgid "Re-publish worksheet" msgstr "Republicar planilha" #: data/sage/html/notebook/afterpublish_window.html:12 msgid "Stop publishing" msgstr "Parar publicação" #: data/sage/html/notebook/afterpublish_window.html:14 #: data/sage/html/notebook/beforepublish_window.html:18 msgid "Automatically re-publish when changes are made" msgstr "Republicar automaticamente quando alterações forem feitas" #: data/sage/html/notebook/base.html:74 msgid "Click to rename this worksheet" msgstr "Clique para renomear a planilha" #: data/sage/html/notebook/base.html:79 msgid "Someone else is viewing this worksheet" msgstr "Outro usuário está visualizando essa planilha" #: data/sage/html/notebook/base.html:84 #: data/sage/html/notebook/text_cell.html:46 msgid "Save changes" msgstr "Salvar alterações" #: data/sage/html/notebook/base.html:84 #: data/sage/html/settings/account_settings.html:9 #: data/sage/html/settings/account_settings.html:66 #: data/sage/html/settings/notebook_settings.html:19 #: data/sage/html/settings/notebook_settings.html:26 msgid "Save" msgstr "Salvar" #: data/sage/html/notebook/base.html:84 msgid "Save changes and close window" msgstr "Salvar alterações e fechar a janela" #: data/sage/html/notebook/base.html:84 msgid "Save & quit" msgstr "Salvar & Sair" #: data/sage/html/notebook/base.html:84 msgid "Discard changes to this worksheet" msgstr "Descartar alterações feitas nessa planilha" #: data/sage/html/notebook/base.html:84 msgid "Discard & quit" msgstr "Descartar & Sair" #: data/sage/html/notebook/base.html:90 msgid "Select a file related function" msgstr "Selecione uma função relacionada ao arquivo" #: data/sage/html/notebook/base.html:90 msgid "File..." msgstr "Arquivo..." #: data/sage/html/notebook/base.html:91 msgid "Load a new worksheet stored in a file" msgstr "Carregar uma nova planilha armazenada em um arquivo" #: data/sage/html/notebook/base.html:91 msgid "Load worksheet from a file..." msgstr "Carregar planilha a partir de um arquivo..." #: data/sage/html/notebook/base.html:92 msgid "Create a new worksheet" msgstr "Criar uma nova planilha" #: data/sage/html/notebook/base.html:92 msgid "New worksheet" msgstr "Nova planilha" #: data/sage/html/notebook/base.html:93 msgid "Save this worksheet to an sws file" msgstr "Salvar essa planilha em um arquivo .sws" #: data/sage/html/notebook/base.html:93 msgid "Save worksheet to a file..." msgstr "Salvar planilha em um arquivo..." #: data/sage/html/notebook/base.html:94 #: data/sage/html/notebook/base.html:143 msgid "Print this worksheet" msgstr "Imprimir essa planilha" #: data/sage/html/notebook/base.html:94 #: data/sage/html/notebook/base.html:143 msgid "Print" msgstr "Imprimir" #: data/sage/html/notebook/base.html:95 msgid "Rename this worksheet" msgstr "Renomear essa planilha" #: data/sage/html/notebook/base.html:95 #: data/sage/js/translated-messages.js:11 msgid "Rename worksheet" msgstr "Renomear planilha" #: data/sage/html/notebook/base.html:96 msgid "Copy this worksheet" msgstr "Copiar essa planilha" #: data/sage/html/notebook/base.html:96 msgid "Copy worksheet" msgstr "Copiar planilha" #: data/sage/html/notebook/base.html:97 msgid "Move this worksheet to the trash" msgstr "Mover essa planilha para a lixeira" #: data/sage/html/notebook/base.html:97 msgid "Delete worksheet" msgstr "Apagar planilha" #: data/sage/html/notebook/base.html:101 msgid "Select a worksheet function" msgstr "Selecionar uma função sobre a planilha" #: data/sage/html/notebook/base.html:101 msgid "Action..." msgstr "Ação..." #: data/sage/html/notebook/base.html:102 msgid "Interrupt currently running calculations, if possible" msgstr "Interromper cálculos atuais se possível" #: data/sage/html/notebook/base.html:102 msgid "Interrupt" msgstr "Interromper" #: data/sage/html/notebook/base.html:103 msgid "Restart the worksheet process" msgstr "Reinicar o processo da planilha" #: data/sage/html/notebook/base.html:103 msgid "Restart worksheet" msgstr "Reinicar planilha" #: data/sage/html/notebook/base.html:104 msgid "Quit the worksheet process" msgstr "Encerrar o processo da planilha" #: data/sage/html/notebook/base.html:104 msgid "Save and quit worksheet" msgstr "Salvar e fechar planilha" #: data/sage/html/notebook/base.html:106 msgid "Evaluate all input cells in the worksheet" msgstr "Avalizar todas as células da planilha" #: data/sage/html/notebook/base.html:106 msgid "Evaluate All" msgstr "Avaliar Tudo" #: data/sage/html/notebook/base.html:107 msgid "Hide all output" msgstr "Esconder todas as saídas" #: data/sage/html/notebook/base.html:107 msgid "Hide All Output" msgstr "Esconder todas as saídas" #: data/sage/html/notebook/base.html:108 msgid "Show all output" msgstr "Exibir todas as saídas" #: data/sage/html/notebook/base.html:108 msgid "Show All Output" msgstr "Exibir todas as saídas" #: data/sage/html/notebook/base.html:109 msgid "Delete all output" msgstr "Apagar todas as saídas" #: data/sage/html/notebook/base.html:109 msgid "Delete All Output" msgstr "Apagar todas as saídas" #: data/sage/html/notebook/base.html:111 msgid "Switch to single-cell mode" msgstr "Alternar para modo de célula única" #: data/sage/html/notebook/base.html:111 msgid "One Cell Mode" msgstr "Modo de Célula Única" #: data/sage/html/notebook/base.html:112 msgid "Switch to multi-cell mode" msgstr "Alternar para modo multi célula " #: data/sage/html/notebook/base.html:112 msgid "Multi Cell Mode" msgstr "Modo de multi Célula" #: data/sage/html/notebook/base.html:115 msgid "Select an attached file" msgstr "Anexar um arquivo" #: data/sage/html/notebook/base.html:115 msgid "Data..." msgstr "Dados..." #: data/sage/html/notebook/base.html:116 msgid "Upload or create a data file in a wide range of formats" msgstr "Enviar ou criar um arquivo de dados em vários formatos." #: data/sage/html/notebook/base.html:116 msgid "Upload or create file..." msgstr "Enviar ou criar um arquivo..." #: data/sage/html/notebook/base.html:126 #, python-format msgid "Evaluate all input cells using %(i)s" msgstr "Avaliar todas as células de entrada usando %(i)s" #: data/sage/html/notebook/base.html:132 msgid "Enable/disable pretty_printing" msgstr "Habilitar/Desabilitar saída elegante" #: data/sage/html/notebook/base.html:144 msgid "Interactively use this worksheet" msgstr "Use essa planilha interativamente" #: data/sage/html/notebook/base.html:144 msgid "Worksheet" msgstr "Planilha" #: data/sage/html/notebook/base.html:145 msgid "Edit text version of this worksheet" msgstr "Editar essa planilha como um texto" #: data/sage/html/notebook/base.html:145 msgid "Edit" msgstr "Editar" #: data/sage/html/notebook/base.html:146 msgid "View plain text version of this worksheet" msgstr "Visualizar essa planilha como um texto" #: data/sage/html/notebook/base.html:146 msgid "Text" msgstr "Texto" #: data/sage/html/notebook/base.html:147 msgid "View changes to this worksheet over time" msgstr "Veja as alterações dessa planilha ao longo do tempo" #: data/sage/html/notebook/base.html:147 msgid "Undo" msgstr "Desfazer" #: data/sage/html/notebook/base.html:148 msgid "Let others edit this worksheet" msgstr "Permitir que outros usuários editem essa planilha" #: data/sage/html/notebook/base.html:148 msgid "Share" msgstr "Compartilhar" #: data/sage/html/notebook/base.html:149 msgid "Make this worksheet publicly viewable" msgstr "Tornar essa planilha visível publicamente" #: data/sage/html/notebook/base.html:149 msgid "Publish" msgstr "Publicar" #: data/sage/html/notebook/base.html:157 msgid "Exit" msgstr "Sair" #: data/sage/html/notebook/beforepublish_window.html:5 msgid "You can publish your worksheet to the Internet, where anyone will be able to access and view it online." msgstr "Você pode publicar sua planilha na Internet, onde qualquer um pode acessá-la online." #: data/sage/html/notebook/beforepublish_window.html:7 msgid "Your worksheet will be assigned a unique address (URL) that you can send to your friends and colleagues." msgstr "A sua planilha será associada a um endereço (URL) único que você poderá enviar aos seus amigos e colegas." #: data/sage/html/notebook/beforepublish_window.html:9 msgid "Do you want to publish this worksheet?" msgstr "Você deseja publicar essa planilha?" #: data/sage/html/notebook/beforepublish_window.html:14 msgid "Yes" msgstr "Sim" #: data/sage/html/notebook/beforepublish_window.html:15 msgid "No" msgstr "Não" #: data/sage/html/notebook/cell.html:63 msgid "Click here or press shift-return to evaluate" msgstr "Clique aqui ou pressione shift+enter para avaliar" #: data/sage/html/notebook/cell.html:64 msgid "evaluate" msgstr "avaliar" #: data/sage/html/notebook/download_or_delete_datafile.html:35 msgid "Data file" msgstr "Arquivo de Dados" #: data/sage/html/notebook/download_or_delete_datafile.html:39 #, python-format msgid "You may download %(f)s or create a linked copy to the worksheet" msgstr "Você pode baixar %(f)s ou criar uma cópia vinculada a planilha" #: data/sage/html/notebook/download_or_delete_datafile.html:40 msgid "select worksheet" msgstr "selecione uma planilha" #: data/sage/html/notebook/download_or_delete_datafile.html:44 #, python-format msgid "or delete %(f)s." msgstr "ou apagar %(f)s." #: data/sage/html/notebook/download_or_delete_datafile.html:46 #, python-format msgid "Access %(f)s in this worksheet by typing DATA+'%(f)s'. Here DATA is a special variable that gives the exact path to all data files uploaded to this worksheet." msgstr "Acesse %(f)s nesta planilha através de DATA+'%(f)s'. Sendo DATA uma variável especial que fornece o diretório onde está todos os arquivos de dados enviados para esta planilha." #: data/sage/html/notebook/download_or_delete_datafile.html:54 #: data/sage/html/notebook/edit_window.html:11 msgid "Save Changes" msgstr "Salvar Alterações" #: data/sage/html/notebook/edit_window.html:10 msgid "Edit plain text" msgstr "Editar texto" #: data/sage/html/notebook/guest_worksheet_page.html:14 msgid "Edit this." msgstr "Editar isto." #: data/sage/html/notebook/guest_worksheet_page.html:16 msgid "Log in to edit a copy." msgstr "Conecte-se para editar uma cópia" #: data/sage/html/notebook/guest_worksheet_page.html:19 msgid "Edit a copy." msgstr "Editar uma cópia." #: data/sage/html/notebook/guest_worksheet_page.html:28 msgid "Download." msgstr "Baixar." #: data/sage/html/notebook/guest_worksheet_page.html:34 #, python-format msgid "This page is rated %(wr).1f." msgstr "Essa página foi pontuada em %(wr).1f." #: data/sage/html/notebook/guest_worksheet_page.html:39 msgid "Rerate" msgstr "Repontuar" #: data/sage/html/notebook/guest_worksheet_page.html:39 msgid "Rate" msgstr "Pontuar" #: data/sage/html/notebook/guest_worksheet_page.html:49 msgid "Other published documents..." msgstr "Outras planilhas publicadas..." #: data/sage/html/notebook/plain_text_window.html:4 msgid "View plain text" msgstr "Visualizar texto" #: data/sage/html/notebook/specific_revision.html:5 #, python-format msgid "Revision from %(ta)s ago" msgstr "Revisão de %(ta)s atrás" #: data/sage/html/notebook/specific_revision.html:5 msgid "Revision List" msgstr "Lista de Revisões" #: data/sage/html/notebook/specific_revision.html:12 msgid "Older" msgstr "Velha" #: data/sage/html/notebook/specific_revision.html:14 msgid "Oldest" msgstr "Mais velha" #: data/sage/html/notebook/specific_revision.html:18 msgid "Newer" msgstr "Nova" #: data/sage/html/notebook/specific_revision.html:20 msgid "Newest" msgstr "Mais nova" #: data/sage/html/notebook/specific_revision.html:23 msgid "Revert to this one" msgstr "Reverter para esta aqui" #: data/sage/html/notebook/specific_revision.html:23 msgid "(note that images are not recorded)" msgstr "(note que imagens não são gravadas)" #: data/sage/html/notebook/specific_revision.html:24 msgid "Publish this one" msgstr "Publicar essa aqui" #: data/sage/html/notebook/text_cell.html:47 msgid "Cancel changes" msgstr "Cancelar alterações" #: data/sage/html/notebook/upload_data_window.html:7 #, python-format msgid "Upload or Create Data File to attach to worksheet \"%(wn)s\"" msgstr "Enviar ou Criar um Arquivo de Dados anexado a planilha \"%(wn)s\"" #: data/sage/html/notebook/upload_data_window.html:15 msgid "Browse your computer to select a file to upload:" msgstr "Navegue pelo seu computador para selecionar um arquivo:" #: data/sage/html/notebook/upload_data_window.html:19 msgid "Or enter the URL of a file on the web:" msgstr "Ou digite o endereço (URL) de um arquivo na Internet:" #: data/sage/html/notebook/upload_data_window.html:23 msgid "Or enter the name of a new file, which will be created:" msgstr "Ou entre o nome do novo arquivo que será criado:" #: data/sage/html/notebook/upload_data_window.html:30 msgid "Upload or Create Data File" msgstr "Enviar ou Criar Arquivo de Dados" #: data/sage/html/notebook/worksheet_page.html:27 #: notebook/twist.py:413 #: notebook/twist.py:2217 #: notebook/worksheet.py:703 #: notebook/worksheet.py:723 #: notebook/worksheet.py:4079 msgid "Untitled" msgstr "Sem título" #: data/sage/html/notebook/worksheet_revision_list.html:6 msgid "Revision History" msgstr "Histórico de Revisão" #: data/sage/html/notebook/worksheet_revision_list.html:15 msgid "Revision" msgstr "Revisão" #: data/sage/html/notebook/worksheet_revision_list.html:22 #, python-format msgid "Revision %(lr)s" msgstr "Revisão %(lr)s" #: data/sage/html/notebook/worksheet_share.html:10 msgid "Share this document" msgstr "Compartilhar este documento" #: data/sage/html/notebook/worksheet_share.html:17 msgid "Only the owner of a worksheet is allowed to share it. You can do whatever you want if you make your own copy." msgstr "Apenas o proprietário dessa planilha pode compartilhá-la. Você pode fazer o que quiser se fizer sua própria cópia." #: data/sage/html/notebook/worksheet_share.html:19 msgid "This Sage Worksheet is currently shared with the people listed in the box below." msgstr "Essa planilha Sage está compartilhada atualmente com as pessoas listadas na caixa abaixo." #: data/sage/html/notebook/worksheet_share.html:20 msgid "You may add or remove collaborators (separate user names by commas)." msgstr "Você pode adicionar ou remover colaboradores (separando os nomes com vírgulas)" #: data/sage/html/notebook/worksheet_share.html:24 msgid "Give access to your worksheet to the above collaborators" msgstr "Dar acesso a sua planilha para os colaboradores acima" #: data/sage/html/notebook/worksheet_share.html:24 msgid "Invite Collaborators" msgstr "Convidar Colaboradores" #: data/sage/html/notebook/worksheet_share.html:28 msgid "Sage Users:" msgstr "Usuários Sage:" #: data/sage/html/settings/account_settings.html:3 #: data/sage/html/settings/base.html:13 msgid "Account Settings" msgstr "Configurações de Conta" #: data/sage/html/settings/account_settings.html:13 msgid "Change Auto-Save Interval" msgstr "Alterar intervalo de salvamento automático" #: data/sage/html/settings/account_settings.html:15 msgid "Minutes" msgstr "Minutos" #: data/sage/html/settings/account_settings.html:24 msgid "Change Password" msgstr "Alterar Senha" #: data/sage/html/settings/account_settings.html:30 msgid "Old password" msgstr "Senha antiga" #: data/sage/html/settings/account_settings.html:34 msgid "New password" msgstr "Senha nova" #: data/sage/html/settings/account_settings.html:38 msgid "Retype new password" msgstr "Digite a nova senha novamente" #: data/sage/html/settings/account_settings.html:46 msgid "Change E-mail Address" msgstr "Alterar endereço de e-mail" #: data/sage/html/settings/account_settings.html:50 msgid "Current e-mail" msgstr "E-mail atual" #: data/sage/html/settings/account_settings.html:54 msgid "New e-mail" msgstr "Novo e-mail" #: data/sage/html/settings/admin_add_user.html:2 #: data/sage/html/settings/admin_add_user.html:6 msgid "Add New User" msgstr "Adicionar Novo Usuário" #: data/sage/html/settings/admin_add_user.html:8 msgid "Username Error" msgstr "Erro no nome do usuário" #: data/sage/html/settings/admin_add_user.html:12 msgid "Pick a username" msgstr "Escolha um nome de usuário" #: data/sage/html/settings/admin_add_user.html:13 msgid "The username must start with a letter and be between 4 and 32 characters long. It can only consist of letters, numbers, underscores, and one dot (.)." msgstr "O nome de usuário deve iniciar com uma letra e ter entre 4 e 32 caracteres. Ele só pode conter letras, números, sublinhado (_) e um ponto." #: data/sage/html/settings/admin_add_user.html:17 msgid "Invalid username" msgstr "Nome de usário inválido" #: data/sage/html/settings/admin_add_user.html:19 msgid "Username taken" msgstr "Nome de usuário escolhido" #: data/sage/html/settings/admin_add_user.html:25 msgid "Create Account" msgstr "Criar Conta" #: data/sage/html/settings/base.html:10 msgid "Manage Users" msgstr "Gerenciar Usuários" #: data/sage/html/settings/base.html:11 #: data/sage/html/settings/notebook_settings.html:2 msgid "Notebook Settings" msgstr "Configurações do Notebook" #: data/sage/html/settings/user_management.html:3 #: data/sage/html/settings/user_management.html:13 msgid "Users" msgstr "Usuários" #: data/sage/html/settings/user_management.html:7 msgid "User Management" msgstr "Gerenciador de Usuário" #: data/sage/html/settings/user_management.html:8 msgid "Add User" msgstr "Adicionar Usuário" #: data/sage/html/settings/user_management.html:10 #, python-format msgid "The password for the user %(u)s has been reset to %(p)s" msgstr "A senha do usuário %(u)s foi reiniciada para %(p)s" #: data/sage/html/settings/user_management.html:13 msgid "Suspension" msgstr "Suspensão" #: data/sage/html/settings/user_management.html:16 msgid "Reset" msgstr "Reiniciar" #: data/sage/html/settings/user_management.html:16 msgid "Unsuspend" msgstr "Tirar suspensão" #: data/sage/html/settings/user_management.html:16 msgid "Suspend" msgstr "Suspender" #: data/sage/html/worksheet/ratings_info.html:3 #: data/sage/html/worksheet/ratings_info.html:6 #, python-format msgid "Ratings for %(wn)s" msgstr "Pontuação para %(wn)s" #: data/sage/html/worksheet/ratings_info.html:7 msgid "Go to the worksheet." msgstr "Ir para a planilha." #: data/sage/html/worksheet/ratings_info.html:9 msgid "User" msgstr "Usuário" #: data/sage/html/worksheet/ratings_info.html:9 msgid "Comment" msgstr "Comentário" #: data/sage/html/worksheet/time_last_edited.html:6 #, python-format msgid "last edited on %(t)s by %(le)s" msgstr "última edição em %(t)s por %(le)s" #: data/sage/html/worksheet/time_since_last_edited.html:6 #: notebook/worksheet.py:2009 #, python-format msgid "%(t)s ago by %(le)s" msgstr "%(t)s atrás por %(le)s" #: data/sage/js/translated-messages.js:4 msgid "Click to download and install tex fonts." msgstr "Clique para baixar e instalar as fontes tex." #: data/sage/js/translated-messages.js:5 msgid "" "Your browser / OS combination is not supported.\\n" "Please use Firefox or Opera under Linux, Windows, or Mac OS X, or Safari." msgstr "" "A combinação entre seu navegador e S.O. não é suportada.\\n" "Por favor, use Firefox ou Opera com o Linux, Mac OS X, Safari ou Windows." #: data/sage/js/translated-messages.js:6 msgid "Java Applet Hidden" msgstr "Aplicativo Java Escondido" #: data/sage/js/translated-messages.js:7 msgid "Click here to pop out" msgstr "Clique aqui para aparecer" #: data/sage/js/translated-messages.js:8 msgid "Error applying function to worksheet(s)." msgstr "Erro aplicando a função na planilha(s)." #: data/sage/js/translated-messages.js:9 msgid "Title of saved worksheet" msgstr "Título da planilha salva" #: data/sage/js/translated-messages.js:10 msgid "Failed to save worksheet." msgstr "Falha ao salvar a planilha." #: data/sage/js/translated-messages.js:12 msgid "Please enter a name for this worksheet." msgstr "Por favor digite um nome para essa planilha" #: data/sage/js/translated-messages.js:13 msgid "Rename" msgstr "Renomear" #: data/sage/js/translated-messages.js:14 msgid "Possible failure deleting worksheet." msgstr "Possível falha apagando a planilha" #: data/sage/js/translated-messages.js:15 msgid "unprinted" msgstr "não impresso" #: data/sage/js/translated-messages.js:16 msgid "You requested to evaluate a cell that, for some reason, the server is unaware of." msgstr "Você requisitou avaliar uma célula que, por alguma razão, o servidor não conhece." #: data/sage/js/translated-messages.js:18 msgid "This worksheet is read only. Please make a copy or contact the owner to change it." msgstr "Essa planilha é somente para leitura. Por favor faça uma cópia ou entre em contato com o proprietário para alterá-la." #: data/sage/js/translated-messages.js:19 msgid "loading..." msgstr "carregando..." #: data/sage/js/translated-messages.js:20 msgid "Error updating cell output after " msgstr "Erro atualizando a saída da célula após " #: data/sage/js/translated-messages.js:21 msgid "s (canceling further update checks)." msgstr "s (cancelando futuras checagens de atualização)." #: data/sage/js/translated-messages.js:22 msgid "Problem inserting new input cell after current input cell.\\n" msgstr "Problema ao inserir nova célula de entrada após a atual." #: data/sage/js/translated-messages.js:23 msgid "Worksheet is locked. Cannot insert cells." msgstr "A planilha está travada. Não se pode inserir células." #: data/sage/js/translated-messages.js:24 msgid "Unable to interrupt calculation." msgstr "Não foi possível interromper o cálculo." #: data/sage/js/translated-messages.js:25 msgid "Close this box to stop trying." msgstr "Feche essa caixa para parar de tentar." #: data/sage/js/translated-messages.js:26 msgid "Interrupt attempt" msgstr "Tentativa de interromper" #: data/sage/js/translated-messages.js:27 msgid "Restart, instead?" msgstr "Reiniciar, ao invés disso?" #: data/sage/js/translated-messages.js:28 msgid "Emptying the trash will permanently delete all items in the trash. Continue?" msgstr "Esvaziando a lixeira todos os itens serão apagados permanentemente. Deseja continuar?" #: data/sage/js/translated-messages.js:29 msgid "Get Image" msgstr "Obter Imagem" #: data/sage/js/translated-messages.js:30 msgid "Jmol Image" msgstr "Imagem do Jmol" #: data/sage/js/translated-messages.js:31 msgid "To save this image, you can try right-clicking on the image to copy it or save it to a file, or you may be able to just drag the image to your desktop." msgstr "Para salvar essa imagem você pode tentar clicar com o botão direito do mouse sobre ela e usar as opções de seu navegador. Talvez você também possa arrastar a imagem para a sua Ãrea de Trabalho." #: data/sage/js/translated-messages.js:32 msgid "Sorry, but you need a browser that supports the <canvas> tag." msgstr "Desculpe-me, mas o seu navegador precisa suportar o tag <canvas>" #: data/sage/js/translated-messages.js:33 #, python-format msgid "Trying again in %(num)d second..." msgid_plural "Trying again in %(num)d seconds..." msgstr[0] "Tentar novamente em %(num)d segundo..." msgstr[1] "Tentar novamente em %(num)d segundos..." #: notebook/challenge.py:179 msgid "Please ask the server administrator to configure a challenge!" msgstr "Por favor, solicite ao administrador do servidor que configure um desafio!" #: notebook/challenge.py:217 msgid "Is pi > e?" msgstr "É verdade que pi > e ?" #: notebook/challenge.py:217 msgid "y|yes" msgstr "s|sim" #: notebook/challenge.py:218 msgid "What is 3 times 8?" msgstr "Quanto é 3 vezes 8?" #: notebook/challenge.py:218 msgid "24|twenty-four" msgstr "24|vinte e quatro" #: notebook/challenge.py:219 msgid "What is 2 plus 3?" msgstr "Quanto é 2 mais 3?" #: notebook/challenge.py:219 #: notebook/challenge.py:221 msgid "5|five" msgstr "5|cinco" #: notebook/challenge.py:220 msgid "How many bits are in one byte?" msgstr "Quantos bits há em um byte?" #: notebook/challenge.py:220 msgid "8|eight" msgstr "8|oito" #: notebook/challenge.py:221 msgid "What is the largest prime factor of 15?" msgstr "Qual é o maior fator primo de 15?" #: notebook/conf.py:120 msgid "Updated" msgstr "Atualizado" #: notebook/notebook.py:169 msgid "optional" msgstr "opcional" #: notebook/register.py:19 #: notebook/register.py:26 #, python-format msgid "" "Hi %s!\n" "\n" msgstr "" "Olá %s!\n" "\n" #: notebook/register.py:20 #, python-format msgid "" "Thank you for registering for the Sage notebook. To complete your registration, copy and paste the following link into your browser:\n" "\n" "%s://%s:%s/confirm?key=%s\n" "\n" "You will be taken to a page which will confirm that you have indeed registered." msgstr "" "Obrigado por registrar-se no Notebook Sage. Para completar seu registro, copie e cole o endereço a seguir no seu navegador:\n" "\n" "%s://%s:%s/confirm?key=%s\n" "\n" "Você será levado para uma página que irá confirmar que você está de fato registrado." #: notebook/register.py:27 #, python-format msgid "" "Your new password is %s\n" "\n" "Sign in at %s://%s:%s/\n" "\n" "Make sure to reset your password by going to Settings in the upper right bar." msgstr "" "A sua nova senha é: %s\n" "\n" "Conecte-se aqui: %s://%s:%s/\n" "\n" "Certifique-se de alterar sua senha através do menu Configurações na barra superior." #: notebook/server_conf.py:42 #: notebook/user_conf.py:24 msgid "Appearance" msgstr "Aparência" #: notebook/server_conf.py:43 msgid "Authentication" msgstr "Autenticação" #: notebook/server_conf.py:44 msgid "Server" msgstr "Servidor" #: notebook/server_conf.py:49 msgid "Number of word-wrap columns" msgstr "Número de colunas por linha" #: notebook/server_conf.py:55 msgid "Maximum history length" msgstr "Tamanho máximo do histórico" #: notebook/server_conf.py:61 msgid "Idle timeout (seconds)" msgstr "Tempo de saída Idle (segundos)" #: notebook/server_conf.py:67 msgid "Idle check interval (seconds)" msgstr "Intervalo de checagem Idle (segundos)" #: notebook/server_conf.py:73 msgid "Save interval (seconds)" msgstr "Intervalo de salvamento (segundos)" #: notebook/server_conf.py:79 msgid "Doc pool size" msgstr "Tamanho da documentação" #: notebook/server_conf.py:85 msgid "Worksheet process users (comma-separated list)" msgstr "Usuários de processamento de planilha (lista separada por vírgulas)" #: notebook/server_conf.py:91 msgid "Default system" msgstr "Sistema padrão" #: notebook/server_conf.py:97 msgid "Pretty print (typeset) output" msgstr "Saída de impressão elegante (typeset)" #: notebook/server_conf.py:103 msgid "Worksheet process limits" msgstr "Limites de processamento de planilha" #: notebook/server_conf.py:109 msgid "Require e-mail for account registration" msgstr "Requisitar e-mail para registrar contas" #: notebook/server_conf.py:115 msgid "Enable user registration" msgstr "Habilitar registro de usuário" #: notebook/server_conf.py:121 msgid "Use a challenge for account registration" msgstr "Usar um desafio para registrar contas" #: notebook/server_conf.py:127 msgid "Type of challenge" msgstr "Tipo do desafio" #: notebook/server_conf.py:134 msgid "reCAPTCHA public key" msgstr "Chave pública do reCAPTCHA" #: notebook/server_conf.py:140 msgid "reCAPTCHA private key" msgstr "Chave privada do reCAPTCHA" #: notebook/server_conf.py:146 msgid "Default Language" msgstr "Idioma padrão" #: notebook/template.py:68 #, python-format msgid "%(num)d second" msgid_plural "%(num)d seconds" msgstr[0] "%(num)d segundo" msgstr[1] "%(num)d segundos" #: notebook/template.py:71 #, python-format msgid "%(num)d minute" msgid_plural "%(num)d minutes" msgstr[0] "%(num)d minuto" msgstr[1] "%(num)d minutos" #: notebook/template.py:74 #, python-format msgid "%(num)d hour" msgid_plural "%(num)d hours" msgstr[0] "%(num)d hora" msgstr[1] "%(num)d horas" #: notebook/template.py:76 #, python-format msgid "%(num)d day" msgid_plural "%(num)d days" msgstr[0] "%(num)d dia" msgstr[1] "%(num)d dias" #: notebook/template.py:135 msgid "Sage Notebook" msgstr "Notebook Sage" #: notebook/tutorial.py:354 msgid "Find Help and Documentation" msgstr "Encontre Ajuda e Documentação" #: notebook/tutorial.py:355 msgid "Get Started with Sage" msgstr "Começe a conhecer o Sage" #: notebook/tutorial.py:355 msgid "Work through the tutorial (if you have trouble with it, view the static version)." msgstr "Navegue através do tutorial (se você tiver problema com essa opção, veja a versão estática)." #: notebook/tutorial.py:356 msgid "Help About" msgstr "Ajuda Sobre Algo" #: notebook/tutorial.py:357 msgid "Type ? immediately after the object or function and press tab or shift-enter (shift-enter overwrites output and saves to worksheet)." msgstr "Digite ? imediatamente após o objeto ou função e pressione Tab ou Shift+Enter (a combinação Shift+Enter sobrescreve a saída e salva na planilha)" #: notebook/tutorial.py:359 msgid "Put ?? after the object and press tab or shift-enter (shift-enter overwrites output and saves to worksheet)." msgstr "Digite ?? imediatamente após o objeto e pressione Tab ou Shift+Enter (a combinação Shift+Enter sobrescreve a saída e salva na planilha)" #: notebook/tutorial.py:360 msgid "Full Text Search of Docs and Source" msgstr "Busca de Texto Completa em Documentos e Fontes" #: notebook/tutorial.py:361 msgid "Search the SAGE documentation by typing
    search_doc(\"my query\")
    in an input cell and press shift-enter. Search the source code of SAGE by typing
    search_src(\"my query\")
    and pressing shift-enter. Arbitrary regular expressions are allowed as queries." msgstr "Faça buscas dentro da documentação do SAGE digitando
    search_doc(\"minha pesquisa\")
    em uma célula de entrada e pressionando Shift+Enter. Faça buscas dentro do código fonte do SAGE digitando
    search_src(\"minha pesquisa\")
    e pressionando Shift+Enter. Você pode procurar por expressões regulares arbitrárias." #: notebook/tutorial.py:365 msgid "Key and Mouse Bindings" msgstr "Uso do Teclado e do Mouse" #: notebook/tutorial.py:366 msgid "Evaluate Input" msgstr "Avaliar Entrada" #: notebook/tutorial.py:367 msgid "Press shift-enter. You can start several calculations at once. If you press alt-enter instead, then a new cell is created after the current one. If you press ctrl-enter then the cell is split and both pieces are evaluated separately." msgstr "Pressionando Shift+Enter você pode realizar vários cálculos de uma só vez. Se você pressionar Alt+Enter ao invés disso, então uma nova célula é criada depois da atual. Se você pressionar Ctrl+Enter, então a célula será dividida e cada pedaço será avaliado separadamente." #: notebook/tutorial.py:368 msgid "Tab Completion" msgstr "Complemento com a tecla Tab" #: notebook/tutorial.py:369 msgid "Press tab while the cursor is on an identifier. On some web browsers (e.g., Opera) you must use control-space instead of tab." msgstr "Pressione Tab enquanto o cursor está sobre um identificador. Em alguns navegadores (e.g., Opera) você pode usar Ctrl+Espaço ao invés de Tab." #: notebook/tutorial.py:370 msgid "Insert New Cell" msgstr "Inserir Nova Célula" #: notebook/tutorial.py:371 msgid "Put the mouse between an output and input until the horizontal line appears and click. If you press Alt-Enter in a cell, the cell is evaluated and a new cell is inserted after it." msgstr "Coloque o mouse entre uma saída e uma entrada até que uma linha horizontal apareça e clique nela. Se você pressionar Alt+Enter em uma célula, ela será avaliada e uma nova célula será inserida depois dela." #: notebook/tutorial.py:372 msgid "Delete Cell" msgstr "Apagar Célula" #: notebook/tutorial.py:373 msgid "Delete all cell contents, then press backspace." msgstr "Apague todo o conteúdo da célula e pressione Backspace." #: notebook/tutorial.py:374 msgid "Split and Join Cells" msgstr "Separar e Unir Células" #: notebook/tutorial.py:375 msgid "Press ctrl-; in a cell to split it into two cells, and ctrl-backspace to join them. Press ctrl-enter to split a cell and evaluate both pieces." msgstr "Pressione Ctrl+; em uma célula para separá-la em duas e Ctrl+Backspace para uni-las. Pressione Ctrl+Enter para separa uma célula e avaliar cada pedaço." #: notebook/tutorial.py:376 msgid "Insert New Text Cell" msgstr "Inserir próxima célula de texto" #: notebook/tutorial.py:377 msgid "Move the mouse between cells until a blue bar appears. Shift-click on the blue bar to create a new text cell. Double click on existing text to edit it. Use $...$ and $$...$$ to include typeset math in the text block." msgstr "Mova o mouse entre duas células até que uma barra azul apareça. Shift+click sobre a barra azul para criar uma nova célula de texto. Clique duas vezes sobre uma já existente para editá-la. Use $...$ e $$...$$ para incluir textos matemáticos dentro do bloco." #: notebook/tutorial.py:378 msgid "Hide/Show Output" msgstr "Exibir/Esconder Saída" #: notebook/tutorial.py:379 msgid "Click on the left side of output to toggle between hidden, shown with word wrap, and shown without word wrap." msgstr "Clique sobre o lado esquerdo da saída para alternar entre linhas com número de colunas limitado ou não limitado." #: notebook/tutorial.py:380 msgid "Indenting Blocks" msgstr "Recuo de Blocos" #: notebook/tutorial.py:381 msgid "Highlight text and press > to indent it all and < to unindent it all (works in Safari and Firefox). In Firefox you can also press tab and shift-tab." msgstr "Selecione o texto e pressione > para avançar tudo e < para recuar tudo (funciona no Safari e Firefox). No Firefox você também pode pressionar Tab e Shift+Tab." #: notebook/tutorial.py:382 msgid "Comment/Uncomment Blocks" msgstr "Comentar / Remover Comentário de Blocos" #: notebook/tutorial.py:383 msgid "Highlight text and press ctrl-. to comment it and ctrl-, to uncomment it. Alternatively, use ctrl-3 and ctrl-4." msgstr "Selecione o texto e pressione Ctrl+. para comentá-lo e Ctrl+, para remover o comentário. Ou ainda, use Ctrl+3 e Ctrl+4." #: notebook/tutorial.py:384 msgid "Paren matching" msgstr "Combinação de Parênteses" #: notebook/tutorial.py:384 msgid "To fix unmatched or mis-matched parentheses, braces or brackets, press ctrl-0. Parentheses before the cursor will be matched, minding strings and (Python) comments." msgstr "Para concertar combinações de parênteses, colchetes ou chaves pressione Ctrl+0. Os parênteses antes do cursor serão combinados, pensando em textos e comentários (Python)." #: notebook/tutorial.py:388 msgid "Interrupt and Restart Sessions" msgstr "Interromper e Reiniciar Sessões" #: notebook/tutorial.py:389 msgid "Interrupt Running Calculations" msgstr "Interromper cálculos atuais" #: notebook/tutorial.py:390 msgid "Click Interrupt or press escape in any input cell. This will (attempt) to interrupt SAGE by sending many interrupt signals." msgstr "Clique em Interromper ou pressione Espaço em qualquer célula de entrada. Isso irá (tentar) interromper o SAGE enviando muitos sinais de interrupção." #: notebook/tutorial.py:391 msgid "Restart" msgstr "Reiniciar" #: notebook/tutorial.py:392 msgid "Type \"restart\" to restart the SAGE interpreter for a given worksheet. (You have to interrupt first.)" msgstr "Digite \"restart\" para reiniciar o interpretador SAGE de uma dada planilha. (Você deve interrompê-la primeiro.)" #: notebook/tutorial.py:394 msgid "Special Cell Blocks" msgstr "Bloco Especial de Células" #: notebook/tutorial.py:395 msgid "Evaluate Cell using GAP, Singular, etc." msgstr "Avalie células usando GAP, Singular, etc." #: notebook/tutorial.py:396 #, python-format msgid "Put \"%gap\", \"%singular\", etc. as the first input line of a cell; the rest of the cell is evaluated in that system." msgstr "Colocando \"%gap\" ou \"%singular\" como a primeira linha de entrada da célula, o resto da célula será avaliada por esse sistema." #: notebook/tutorial.py:397 msgid "Shell Scripts" msgstr "Scripts Shell" #: notebook/tutorial.py:398 #, python-format msgid "Begin a block with %sh to have the rest of the block evaluated as a shell script. The current working directory is maintained." msgstr "Inicio um bloco com %sh para que o resto do mesmo seja avaliado como um script shell. O diretório de trabalho atual é mantido." #: notebook/tutorial.py:399 msgid "Interactive Dynamic Widgets" msgstr "Objetos Interativos e Dinâmicos" #: notebook/tutorial.py:400 msgid "Put @interact on the line before a function definition. Type interact? for more details." msgstr "Coloque @interact sobre a linha antes da definição de uma função. Digite interact? para mais detalhes." #: notebook/tutorial.py:401 msgid "Autoevaluate Cells on Load" msgstr "Avaliar Células Automaticamente ao Carregar" #: notebook/tutorial.py:402 msgid "Any cells with \"#auto\" in the input is automatically evaluated when the worksheet is first opened." msgstr "Qualquer célula com \"#auto\" na entrada é automaticamente avaliada quando a planilha é aberta pela primeira vez." #: notebook/tutorial.py:403 msgid "Time" msgstr "Tempo" #: notebook/tutorial.py:404 msgid "Type \"%time\" at the beginning of the cell." msgstr "Digite \"%time\" no início da célula" #: notebook/tutorial.py:406 msgid "Useful Tips" msgstr "Dicas Úteis" #: notebook/tutorial.py:407 msgid "Input Rules" msgstr "Regras de Entrada" #: notebook/tutorial.py:408 msgid "Code is evaluated by exec'ing (after preparsing). Only the output of the last line of the cell is implicitly printed. If any line starts with \"sage:\" or \">>>\" the entire block is assumed to contain text and examples, so only lines that begin with a prompt are executed. Thus you can paste in complete examples from the docs without any editing, and you can write input cells that contains non-evaluated plain text mixed with examples by starting the block with \">>>\" or including an example." msgstr "Os códigos são avaliados por execução (depois de uma pré-análise). Somente a saída da última linha da célula é impressa implicitamente. Se qualquer linha começa com \"sage:\" ou \">>>\" será considerado que o bloco inteiro contém textos e exemplos, então somente as linhas iniciadas com um prompt serão executadas. Sendo assim, você pode copiar inteiramente os exemplos da documentação sem editar nada. Além disso, você pode escrever células de entrada que contém textos que não precisam ser avaliados juntamente com exemplos, bastando para isso iniciar o bloco com \">>>\" ou incluindo um exemplo." #: notebook/tutorial.py:409 msgid "History" msgstr "Histórico" #: notebook/tutorial.py:410 msgid "Click log commands you have entered in any worksheet of this notebook." msgstr "Clique no menu Histórico para ver os comandos que você digitou em qualquer planilha desse notebook." #: notebook/tutorial.py:411 msgid "Typesetting All Output" msgstr "Melhor impressão de todas as saídas" #: notebook/tutorial.py:412 msgid "Type pretty_print_default() in an input cell and press shift-enter. All future output will be typeset automatically." msgstr "Digite pretty_print_default() em uma célula de entrada e pressione Shift+Enter. Todas as saídas futuras terão uma melhor impressão automaticamente. " #: notebook/tutorial.py:416 msgid "Files and Scripts" msgstr "Arquivos e Scripts" #: notebook/tutorial.py:417 msgid "Loading SAGE/Python Scripts" msgstr "Carregando Scripts SAGE/Python" #: notebook/tutorial.py:418 msgid "Use \"load filename.sage\" and \"load filename.py\". Load is relative to the path you started the notebook in. The .sage files are preparsed and .py files are not. You may omit the .sage or .py extension. Files may load other files." msgstr "Use \"load arquivo.sage\" e \"load arquivo.py\". O carregamento será relativo ao diretório onde você iniciou o notebook. Os arquivos .sage são pré-analisados, mas .py não são. Você pode omitir as extensões .sage e .py. Os arquivos podem carregar outros arquivos." #: notebook/tutorial.py:419 msgid "Attaching Scripts" msgstr "Scripts Anexos" #: notebook/tutorial.py:420 msgid "Use \"attach filename.sage\" or \"attach filename.py\". Attached files are automatically reloaded when the file changes. The file $HOME/.sage/init.sage is attached on startup if it exists." msgstr "Use \"attach arquivo.sage\" ou \"attach arquivo.py\". Arquivos anexos são automaticamente recarregados quando são alterados. O arquivo $HOME/.sage/init.sage é anexado na inicialização, caso ele exista." #: notebook/tutorial.py:421 msgid "Working Directory" msgstr "Diretório de Trabalho" #: notebook/tutorial.py:422 msgid "Each block of code is run from its own directory. If any images are created as a side effect, they will automatically be displayed." msgstr "Cada bloco de código é rodado a partir de seu próprio diretório. Se quaisquer imagens são criadas como um efeito colateral, então elas serão automaticamente exibidas." #: notebook/tutorial.py:423 msgid "DIR Variable" msgstr "Variável DIR" #: notebook/tutorial.py:424 msgid "The variable DIR contains the directory from which you started the SAGE notebook. For example, to open a file in that directory, do \"open(DIR+'filename')\"." msgstr "A variável DIR contém o diretório a partir do qual você iniciou o notebook SAGE. Por exemplo, para abrir um arquivo nesse diretório use \"open(DIR+'arquivo')\"." #: notebook/tutorial.py:425 msgid "DATA Variable" msgstr "Variável DATA" #: notebook/tutorial.py:426 msgid "Use the Data menu to upload images and other files, and create new files that can be shared between worksheets. The DATA variable contains the path to the data files. For example, to open a file in that directory, do \"open(DATA+'filename')\". If foo.sage is a Sage file that you uploaded, type \"load foo.sage\"; if foo.py is a Python file, you can import it by typing \"import foo\"." msgstr "Use o menu Dados para enviar imagens e outros arquivos, ou ainda para criar novos, que podem ser compartilhados entre as planilhas. A variável DATA contém o diretório onde está esses arquivos de dados. Por exemplo, para abrir um arquivo desse diretório use \"open(DATA+'arquivo')\". Se exemplo.sage é um arquivo Sage que você enviou, então use \"load exemplo.sage\"; se exemplo.py é um arquivo Python, então você pode importá-lo usando \"import exemplo\"." #: notebook/tutorial.py:427 msgid "Loading and Saving Objects" msgstr "Carregando e Salvando Objetos" #: notebook/tutorial.py:428 msgid "Use \"save obj1 obj2 ...\" and \"load obj1 obj2 ...\". This allows for easy moving of objects from one worksheet to another, and saving of objects for later use." msgstr "Use \"save obj1 obj2 ...\" e \"load obj1 obj2 ...\". Isso permite o fácil deslocamento de objetos entre planilhas, além de salvar os objetos para uso futuro." #: notebook/tutorial.py:429 msgid "Loading and Saving Sessions" msgstr "Carregando e Salvando Sessões" #: notebook/tutorial.py:430 msgid "Use \"save_session('name')\" to save all variables to an object. Use \"load_session('name')\" to merge in all variables from a saved session." msgstr "Use \"save_session('nome')\" para salvar todas as variáveis em um objeto. Use \"load_session('nome')\" para mesclar todas as variáveis de uma sessão salva." #: notebook/tutorial.py:431 msgid "Customizing the Notebook CSS" msgstr "Personalizando o CSS do Notebook" #: notebook/tutorial.py:432 msgid "If you create a file $HOME/.sage/notebook.css then it will get applied when rendering the notebook. See " msgstr "Se você criar um arquivo $HOME/.sage/notebook.css, então ele será aplicado quando o notebook for iniciado." #: notebook/twist.py:448 #, python-format msgid "Please specify a worksheet to load.%s" msgstr "Por favor especifique uma planilha para carregar.%s" #: notebook/twist.py:486 #, python-format msgid "There was an error uploading the worksheet. It could be an old unsupported format or worse. If you desperately need its contents contact the sage-support group and post a link to your worksheet. Alternatively, an sws file is just a bzip2 tarball; take a look inside!%s" msgstr "Ocorreu um erro enviando a planilha. Pode ter sido devido a um velho formato não suportado ou pior. Se você precisa desesperadamente desse conteúdo, contate o grupo sage-support e poste o endereço (URL) de sua planilha. Ou ainda, uma arquivo .sws é apenas uma compactação bzip2. Dê uma olhada dentro dele!%s" #: notebook/twist.py:515 #: notebook/twist.py:645 #, python-format msgid "There was an error uploading \"%s\" (please recheck the URL).%s" msgstr "Ocorreu um erro enviando \"%s\" (por favor, confira a URL).%s" #: notebook/twist.py:597 #, python-format msgid "Return to Upload or Create Data File or %s." msgstr "Retornar para Enviar ou Criar Arquivo de Dados ou %s." #: notebook/twist.py:601 #, python-format msgid "Error uploading file (missing fileField file).%s" msgstr "Erro enviando arquivo (arquivo fileField faltando).%s" #: notebook/twist.py:606 #, python-format msgid "Error uploading file (missing %s arg).%s" msgstr "Erro enviando arquivo (argumentos %s faltando).%s" #: notebook/twist.py:623 #, python-format msgid "Error uploading file (missing filename).%s" msgstr "Erro enviando arquivo (nome do arquivo faltando).%s" #: notebook/twist.py:627 #, python-format msgid "Suspicious filename \"%s\" encountered uploading file.%s" msgstr "Nome de arquivo \"%s\" suspeito encontrado enquanto enviando o arquivo.%s" #: notebook/twist.py:674 #, python-format msgid "Successfully deleted \"%s\"" msgstr "Apagado com sucesso \"%s\"" #: notebook/twist.py:691 msgid "No data files" msgstr "Sem arquivos de dado" #: notebook/twist.py:770 msgid "Error in introspection -- invalid cell id." msgstr "Erro na introspecção -- id inválido de célula." #: notebook/twist.py:824 msgid "You must login first in order to edit this worksheet." msgstr "Você deve conectar-se primeiro antes de editar esta planilha." #: notebook/twist.py:998 msgid "Old password not given" msgstr "Senha antiga não fornecida" #: notebook/twist.py:1000 msgid "Incorrect password given" msgstr "Senha incorreta fornecida" #: notebook/twist.py:1002 msgid "New password not given" msgstr "Nova senha não fornecida" #: notebook/twist.py:1004 msgid "Please type in new password again." msgstr "Por favor digite no campo nova senha novamente." #: notebook/twist.py:1006 msgid "The passwords you entered do not match." msgstr "As senhas que você forneceu não combinam" #: notebook/twist.py:1039 msgid "Confirmed" msgstr "Confirmado" #: notebook/twist.py:1041 msgid "Not confirmed" msgstr "Não confirmado" #: notebook/twist.py:1294 msgid "can't evaluate worksheet cells" msgstr "não foi possível avaliar as células da planilha" #: notebook/twist.py:1391 msgid "You must login first in order to rate this worksheet." msgstr "Você deve conectar-se primeiro para pontuar essa planilha." #: notebook/twist.py:1395 msgid "Gees -- You can't fool the rating system that easily!" msgstr "Epa! -- Você não pode enganar o sistema de pontuação assim tão fácil!" #: notebook/twist.py:1398 #, python-format msgid "Thank you for rating the worksheet %s! You can see all ratings of this worksheet." msgstr "Obrigado por pontuar a planilha %s! Você pode ver todas as pontuações desta planilha." #: notebook/twist.py:1398 msgid "Rating Accepted" msgstr "Pontuação Aceita" #: notebook/twist.py:1415 msgid "No such worksheet." msgstr "Nenhuma planilha dessa." #: notebook/twist.py:1521 #, python-format msgid "The worksheet operation \"%s\" is not defined." msgstr "A operação \"%s\" sobre a planilha não é definida." #: notebook/twist.py:1618 #, python-format msgid "User \"%s\" does not have permission to view the home page of \"%s\"." msgstr "O usuário \"%s\" não tem permissão de ver a página de \"%s\"." #: notebook/twist.py:1629 #, python-format msgid "The user \"%s\" has no worksheet \"%s\"." msgstr "O usuário \"%s\" não tem uma planilha \"%s\"." #: notebook/twist.py:1632 #, python-format msgid "There is no published worksheet with name \"%s\". Redirecting to the index of published worksheets in 10 seconds...

    " msgstr "Não existe planilha publicada com o nome \"%s\". Redirecionando para o índice de planilhas publicadas em 10 segundos...

    " #: notebook/twist.py:1637 #, python-format msgid "You are not logged in or do not have access to the worksheet \"%s\"." msgstr "Você não está conectado ou não tem acesso a planilha \"%s\"." #: notebook/twist.py:1662 msgid "This url can only be accessed through a POST request." msgstr "Esse endereço (url) somente pode ser acessado através de uma requisição POST." #: notebook/twist.py:1712 #, python-format msgid "You are not authorized to move \"%s\"" msgstr "Você não está autorizado a mover \"%s\"" #: notebook/twist.py:1781 msgid "Please request a specific worksheet" msgstr "Por favor, requisite uma planilha específica" #: notebook/twist.py:2022 msgid "The confirmation system is not active." msgstr "O sistema de confirmação não está ativo." #: notebook/twist.py:2024 msgid "

    Invalid confirmation key

    You are reporting a confirmation key that has not been assigned by this server. Please register with the server.

    " msgstr "

    Chave de confirmação inválida

    Você está reportando uma chave de confirmação que não foi atribuída por esse servidor. Por favor, registre-se no servidor.

    " #: notebook/twist.py:2033 #, python-format msgid "

    Email address confirmed for user %s

    " msgstr "

    Endereço de e-mail confirmado para o usuário %s

    " #: notebook/twist.py:2035 msgid "Email Confirmed" msgstr "E-mail confirmado" #: notebook/user_conf.py:23 msgid "Language" msgstr "Idioma" #: notebook/wiki2html.py:647 #, python-format msgid "Expected \"%(wanted)s\" after \"%(key)s\", got \"%(token)s\"" msgstr "Era esperado \"%(wanted)s\" depois de \"%(key)s\", obtido \"%(token)s\"" #: notebook/wiki2html.py:653 #, python-format msgid "Expected an integer \"%(key)s\" before \"%(token)s\"" msgstr "Era esperado um inteiro \"%(key)s\" antes de \"%(token)s\"" #: notebook/wiki2html.py:663 #: notebook/wiki2html.py:673 #, python-format msgid "Expected an integer \"%(arg)s\" after \"%(key)s\"" msgstr "Era esperado um inteiro \"%(arg)s\" depois de \"%(key)s\"" #: notebook/wiki2html.py:699 #, python-format msgid "Expected a color value \"%(arg)s\" after \"%(key)s\"" msgstr "Era esperado um valor de cor \"%(arg)s\" depois de \"%(key)s\"" #: notebook/worksheet.py:2014 #, python-format msgid "%(seconds)s ago" msgstr "" #: notebook/worksheet.py:4155 msgid "January" msgstr "janeiro" #: notebook/worksheet.py:4156 msgid "February" msgstr "fevereiro" #: notebook/worksheet.py:4157 msgid "March" msgstr "março" #: notebook/worksheet.py:4158 msgid "April" msgstr "abril" #: notebook/worksheet.py:4159 msgid "May" msgstr "maio" #: notebook/worksheet.py:4160 msgid "June" msgstr "junho" #: notebook/worksheet.py:4161 msgid "July" msgstr "julho" #: notebook/worksheet.py:4162 msgid "August" msgstr "agosto" #: notebook/worksheet.py:4163 msgid "September" msgstr "setembro" #: notebook/worksheet.py:4164 msgid "October" msgstr "outubro" #: notebook/worksheet.py:4165 msgid "November" msgstr "novembro" #: notebook/worksheet.py:4166 msgid "December" msgstr "dezembro" #~ msgid "Sign into the Sage Notebook v%(v)s" #~ msgstr "Acessar o Notebook Sage v%(v)s" #~ msgid "Problem inserting new input cell before current input cell." #~ msgstr "Problema ao inserir nova célula de entrada antes da atual." #~ msgid "Problem inserting new text cell before current input cell." #~ msgstr "" #~ "Problema ao inserir nova célula de texto antes da célula de entrada atual." #~ msgid "simple" #~ msgstr "simples" #~ msgid "recaptcha" #~ msgstr "recaptcha" #~ msgid "Sage Notebook Registration" #~ msgstr "Registro do Notebook Sage" #~ msgid "The account recovery system is not active." #~ msgstr "O sistema de recuperação de contas não está ativo." #~ msgid "Username is invalid." #~ msgstr "Nome de usuário inválido." #~ msgid "The e-mail address hasn't been confirmed." #~ msgstr "O endereço de e-mail não foi confirmado." #~ msgid "Sage Notebook Account Recovery" #~ msgstr "Recuperação de Conta do Notebook Sage" #~ msgid "The new password couldn't be sent to %s." #~ msgstr "A nova senha não pôde ser enviada para %s." #~ msgid "A new password has been sent to your e-mail address." #~ msgstr "Uma nova senha foi enviada para seu e-mail." #~ msgid "The temporary password for the new user %s is %s" #~ msgstr "A senha temporária para o novo usuário %s é %s" #~ msgid "This is an invalid page." #~ msgstr "Esta é uma página inválida." #~ msgid " You might have to login to view this page." #~ msgstr " Talvez você tenha que conectar-se para ver esta página." #~ msgid "unauthorized request" #~ msgstr "requisição não autorizada" #~ msgid "Your account is currently suspended." #~ msgstr "Sua conta está suspensa atualmente." #~ msgid "" #~ "Please enable cookies or delete all Sage cookies and localhost cookies in " #~ "your browser and try again." #~ msgstr "" #~ "Por favor, habilite os cookies ou apage todos os cookies do Sage e do " #~ "localhost em seu navagedor e tente novamente." #~ msgid "%s ago" #~ msgstr "%s atrás" #~ msgid "No data file (%s)" #~ msgstr "Sem arquivo de dado (%s)" #~ msgid "ago by %s" #~ msgstr "atrás por %s" sagenb-1.0.1/sagenb/translations/ru_RU/000077500000000000000000000000001311436262400177665ustar00rootroot00000000000000sagenb-1.0.1/sagenb/translations/ru_RU/LC_MESSAGES/000077500000000000000000000000001311436262400215535ustar00rootroot00000000000000sagenb-1.0.1/sagenb/translations/ru_RU/LC_MESSAGES/messages.mo000066400000000000000000002141721311436262400237260ustar00rootroot00000000000000Þ•ðœÂàä ý !7!V!f!z!#Š!®!½!Ä!«Ì!:x"6³"Fê"G1#Iy#«Ã#§o$%(%9% I%S%Z% l%y% ‚%8%É%bÜ% ?&J&OR&¢&«&¿&Ñ&ì&û&.'$E' j' w'„'€Œ' ( (7#([(0{(§¬(T)[) j)x)’)¨)*¸)]ã)‚A*,Ä*ñ*2+m:+(¨+Ñ+ð+ï, ÿ- ..?.. n.|.….™.¨.®.½.NÔ.#/:/L/4[//Ÿ/®/ Ë/ Ù/ æ/ð/ø/ 000 10@=0~00¡0´0Ä0!Ó0&õ0$1A1Y1 r1€1‰11 º1„Ä1I2 N2[2#k2 2š2¢2 ²2L¾2 3?&3f33ž3 ·3Ã3(É3#ò3!4:84:s45®41ä465 M5'Z5‚5)‘5$»5à56å506-M60{6=¬6ê6ï6) 737;7M7i7#y717 Ï7Ù78ï7(8=8 B8M8j8}8‚8’8¢8³³8•g9ý9: :*:I:f:„:s›:; ;,;<;Q; m; Ž;˜;·;Ö;5è;<9<O<o<€< •< <=³< ñ<ü<=%= *=6=S=%r=˜=¶=Ò=í= > >>+>%H> n>{>’> š>ì¨>-•?)Ã? í?@@ '@ 5@ @@ M@[@a@h@k@ ‡@•@¬@¾@Ñ@ã@õ@ AA$A +A€9A&ºA7áAB6Bh¹fh i 2i)h®=§®1å®0¯+H¯t¯’¯R¯¯°<°1[°°%’°<¸°fõ°Z\±=·±3õ±9)²5c²™² ¨²E³²ù²Y³/q³4¡³ Ö³á³ðû³[ìµWH¶I ¶"ê¶# ·"1·T·f·"~· ¡·¬·¿·<Æ· ¸E$¸%j¸A¸3Ò¸¹Q"¹t¹ ޹›¹"³¹òÖ¹2ɺ]üº?Z»š»«»É» Ú»$ç»0 ¼–=¼HÔ¼5½cS½e·½7¾ÍU¿#Á1$ VÂ5cÂk™ÂÃ,ÃKÃ6hßÃԾû“ÄOÅ‹íÅ=yÇ·Ç ÆÇÓÇ#îÇ+È/>ÈnȆÈA¡È2ãÈ"É{9ÉcµÉHÊbʀʑÊE¬Ê2òÊŒ%Ë+²Ë)ÞË ÌÌG)ÌqÌ-‘Ì ¿Ì"ÌÌ ïÌýÌ*ÍICÍÎ!ŸÎÁÎ ÔÎ%õÎ<Ï%XÏ@~ÏB¿ÏGÐ9JÐ%„Ð&ªÐ"ÑГôÐ!ˆÒIªÒPôÒ,EÓ0rÓ£Ó ¶ÓÃÓÖÓëÓ2Ô'3Ô[Ô,lÔ,™Ô ÆÔ ÑÔ ÜÔXçÔK@ÕNŒÕ}ÛÕYÖ3qÖ3¥Ö ÙÖ&äÖ ××0!×CRזש×ÄׄÙ×M^Ø@¬Ø4íØ "Ùµ-Ù³ãÚ —Û¤¥ÛÔJÞ>ßó^ßfRàx¹à2áÿPâHPã?™ãŸÙã”yæ|ç1‹èø½è¶éEÖéBêN_ëc®ëí2)í \í gíríÒí/Tî7„îÙ¼îÛ–ïrðІð<WñO”ñ:äñò˜>ò×òðò ó"ó5ó<Póóžô2®ôAáô’#ö¶÷.Ðøpÿù˜pú… üfüBöü9ý#Sw1Âiâ3LY€EÚ. O h`uKÖO"7r]ªA Jƒk1ï4!NV[¥_7«—CC }‡  # ²( LÛ Y( º‚ ‘= —Ï :g  ¢'°yØ R«_% À1%ò6LdwŠA%ß'-YA›¯#È%ì0S?(“U¼%8Rr

    Invalid confirmation key

    You are reporting a confirmation key that has not been assigned by this server. Please register with the server.

    Return to Upload or Create Data File or %(worksheet_name)s.%(num)d day%(num)d days%(num)d hour%(num)d hours%(num)d minute%(num)d minutes%(num)d second%(num)d seconds%(seconds)s ago%(t)s ago by %(le)s%(t)s by %(le)s(note that images are not recorded)24|twenty-four5|five8|eightWork through the tutorial (if you have trouble with it, view the static version).Restart, instead?

    Email address confirmed for user %(username)s

    Sage is a different approach to mathematics software.A session is a worksheet and a set of variables in some state.A worksheet is an ordered list of Sage calculations with output.A new password will be emailed to the email address connected to your account. However if you didn't confirm your email address you will be unable to recover your account.Access %(f)s in this worksheet by typing DATA+'%(f)s'. Here DATA is a special variable that gives the exact path to all data files uploaded to this worksheet.Account RecoveryAccount SettingsAcknowledgementAction...ActiveActive WorksheetsAdd New UserAdd UserAdd or DeleteAllow OpenID authentication (requires python ssl module)Answer a challengeAny cells with "#auto" in the input is automatically evaluated when the worksheet is first opened.AppearanceArchiveArchive selected worksheets so they do not appear in the default worksheet listArchivedArchived WorksheetsAttaching ScriptsAttributes for user lookupAuthenticationAutoevaluate Cells on LoadAutomatically re-publish when changes are madeBack to your personal worksheet listBad passwordBad usernameBase DNBegin a block with %%sh to have the rest of the block evaluated as a shell script. The current working directory is maintained.Bind DNBind PasswordBrowse published Sage worksheets
    (no login required)Browse the published worksheetsBrowse your computer to select a file to upload:By using Sage you help to support a viable open source alternative to Magma, Maple, Mathematica, and MATLAB. Sage includes many high-quality open source math packages.CancelCancel changesCases / TestsChange Auto-Save IntervalChange E-mail AddressChange PasswordChange account settings including passwordClick log commands you have entered in any worksheet of this notebook.Click Interrupt or press escape in any input cell. This will (attempt) to interrupt SAGE by sending many interrupt signals.Click here or press shift-return to evaluateClick here to pop outClick here to turn the above into a Sage worksheetClick on the left side of output to toggle between hidden, shown with word wrap, and shown without word wrap.Click to download and install tex fonts.Click to rename this worksheetClose this box to stop trying.Code is evaluated by exec'ing (after preparsing). Only the output of the last line of the cell is implicitly printed. If any line starts with "sage:" or ">>>" the entire block is assumed to contain text and examples, so only lines that begin with a prompt are executed. Thus you can paste in complete examples from the docs without any editing, and you can write input cells that contains non-evaluated plain text mixed with examples by starting the block with ">>>" or including an example.CollaboratorsCommentComment/Uncomment BlocksCongratulations %(u)s! You can now sign into the Sage Notebook.ConstructionsContinueCopy this worksheetCopy worksheetCountCreate AccountCreate a good passwordCreate a new Sage worksheet version of the last 100 commands in the above log.Create a new worksheetCreate a usernameCreate accountCreating new users is disabled by the administrator.Current FolderCurrent e-mailCustomizing the Notebook CSSDATA VariableDIR VariableData fileData...Default LanguageDefault systemDeleteDelete All OutputDelete CellDelete all cell contents, then press backspace.Delete all outputDelete worksheetDeleted WorksheetsDeveloper GuideDiscard & quitDiscard changes to this worksheetDo you want to publish this worksheet?Doc worksheet idle timeout (seconds)Doc worksheet pool sizeDocument does not exist.DocumentationDownloadDownload All ActiveDownload selected worksheetsDownload.Each block of code is run from its own directory. If any images are created as a side effect, they will automatically be displayed.EditEdit a copy.Edit plain textEdit text version of this worksheetEdit this.ElapsedEmail ConfirmedEmpty TrashEmptying the trash will permanently delete all items in the trash. Continue?Enable LDAP AuthenticationEnable published interacts (EXPERIMENTAL; USE AT YOUR OWN RISK)Enable user registrationEnable/disable pretty_printingEnter your email addressEnvironmentErrorError applying function to worksheet(s).Error displaying worksheet listing.Error updating cell output after Error uploading file (missing %(field)s arg).%(backlinks)sError uploading file (missing field "file"). %(backlinks)sError uploading file (missing filename).%(backlinks)sError uploading worksheet '%(msg)s'.%(backlinks)sError: can't add more than 500 collaborators at a timeEvaluate AllEvaluate Cell using GAP, Singular, etc.Evaluate InputEvaluate all input cells in the worksheetEvaluate all input cells using %(i)sExitExpected "%(wanted)s" after "%(key)s", got "%(token)s"Expected a color value "%(arg)s" after "%(key)s"Expected an integer "%(arg)s" after "%(key)s"Expected an integer "%(key)s" before "%(token)s"Explore a collection of in-depth tutorials on specific topicsFailFailed to save worksheet.Fast Static Versions of the DocumentationFile...Files and ScriptsFind Help and DocumentationForgot passwordFull Text Search of Docs and SourceGeneral and Advanced Pure and Applied MathematicsGet ImageGet Started with SageGive access to your worksheet to the above collaboratorsGo to the worksheet.HelpHelp AboutHelp via Internet Chat (IRC)Hi %(username)s! HideHide All OutputHide all outputHide/Show OutputHighlight text and press ctrl-. to comment it and ctrl-, to uncomment it. Alternatively, use ctrl-3 and ctrl-4.Highlight text and press > to indent it all and < to unindent it all (works in Safari and Firefox). In Firefox you can also press tab and shift-tab.HistoryHomeHow do I construct ... in Sage?How many bits are in one byte?How to use the Sage NotebookIdle check interval (seconds)Idle timeout (seconds)If you create a file $HOME/.sage/notebook.css then it will get applied when rendering the notebook. See Indenting BlocksInput RulesInsert New CellInsert New Text CellInteractive Dynamic WidgetsInteractively use this worksheetInterruptInterrupt Running CalculationsInterrupt and Restart SessionsInterrupt attemptInterrupt currently running calculations, if possibleInvalid challenge responseInvalid email addressInvalid filename. %(backlinks)sInvalid usernameInvite CollaboratorsIs pi > e?Java Applet HiddenJavascript must be enabled in order to use the Sage Notebook.Jmol ImageKey and Mouse BindingsKnown Sage Users:LDAPLast EditedLearn to write Sage programsLet others edit this worksheetLoad a new worksheet stored in a fileLoad worksheet from a file...Loading SAGE/Python ScriptsLoading and Saving ObjectsLoading and Saving SessionsLogLog inLog in to edit a copy.Log out of the Sage notebookMake this worksheet publicly viewableManage UsersMaximum history lengthMinutesModel VersionMove the mouse between cells until a blue bar appears. Shift-click on the blue bar to create a new text cell. Double click on existing text to edit it. Use $...$ and $$...$$ to include typeset math in the text block.Move the selected worksheets out of the trashMove the selected worksheets to the trashMove this worksheet to the trashMulti Cell ModeNew UserNew WorksheetNew e-mailNew passwordNew worksheetNewerNewestNoNo challenge response givenNo data filesNo email address givenNo password givenNo such worksheet.No username givenNotebook SettingsNumber of word-wrap columnsOld passwordOlderOldestOne Cell ModeOnly the owner of a worksheet is allowed to share it. You can do whatever you want if you make your own copy.Or enter the URL of a file on the web:Or enter the name of a new file, which will be created:Other published documents...OwnerParen matchingPassPasswordPasswords didn't matchPick a usernamePlease ask the server administrator to configure a challenge!Please enter a name for this worksheet.Please log in to the Sage notebookPlease specify a worksheet to load. %(backlinks)sPossible failure deleting worksheet.Press ctrl-; in a cell to split it into two cells, and ctrl-backspace to join them. Press ctrl-enter to split a cell and evaluate both pieces.Press shift-enter. You can start several calculations at once. If you press alt-enter instead, then a new cell is created after the current one. If you press ctrl-enter then the cell is split and both pieces are evaluated separately.Press tab while the cursor is on an identifier. On some web browsers (e.g., Opera) you must use control-space instead of tab.Pretty print (typeset) outputPrintPrint this worksheetProblem inserting new input cell after current input cell. PublishPublish this onePublishedPublished WorksheetsPublished on %(t)sPut "%%gap", "%%singular", etc. as the first input line of a cell; the rest of the cell is evaluated in that system.Put ?? after the object and press tab or shift-enter (shift-enter overwrites output and saves to worksheet).Put @interact on the line before a function definition. Type interact? for more details.Put the mouse between an output and input until the horizontal line appears and click. If you press Alt-Enter in a cell, the cell is evaluated and a new cell is inserted after it.Quit the worksheet processRateRatingRatings for %(wn)sRe-publish worksheetRe-type your passwordReference ManualRemember meRenameRename this worksheetRename worksheetReport a ProblemReport a problem or submit a bug to improve SageRequested public worksheet does not existRequire e-mail for account registrationRerateResetRestartRestart the worksheet processRestart worksheetReturn to Upload File.Retype new passwordRevert to this oneRevisionRevision %(lr)sRevision History -- Previous sessionsRevision ListRevision from %(ta)s agoRevisionsSage DocumentationSage NotebookSage Notebook versionSage Source BrowserSage makes it easy for you to use most mathematics software together. Sage includes GAP, GP/PARI, Maxima, and Singular, and dozens of other open packages.Sage versionSage: History for %(u)sSaveSave & quitSave ChangesSave and quit worksheetSave changesSave changes and close windowSave interval (seconds)Save this worksheet to an sws fileSave worksheet to a file...Search UsersSearch WorksheetsSearch results:Search the SAGE documentation by typing
    search_doc("my query")
    in an input cell and press shift-enter. Search the source code of SAGE by typing
    search_src("my query")
    and pressing shift-enter. Arbitrary regular expressions are allowed as queries.Searching for Sage server...Select a file related functionSelect a worksheet functionSelect an OpenID providerSelect an attached fileSendServerSettingsShareShare nowShare this documentShell ScriptsShowShow All OutputShow all outputSign inSign outSign upSign up for a Sage Notebook accountSign up for a new Sage Notebook accountSomeone else is viewing this worksheetSorry, but you need a browser that supports the <canvas> tag.Source CodeSpecial Cell BlocksSplit and Join CellsStartStatic version...StatusStopStop publishingStop selected worksheetsSubmitSuspendSuspensionSuspicious filename "%(filename)s" encountered uploading file.%(backlinks)sSwitch to multi-cell modeSwitch to single-cell modeTab CompletionTextThank you for registering for the Sage notebook. To complete your registration, copy and paste the following link into your browser: %(url_prefix)s://%(addr)s:%(port)s/confirm?key=%(key)s You will be taken to a page which will confirm that you have indeed registered.The Sage notebook is a collection of worksheets, saved objects, and user information.The Sage NotebookThe Sage Notebook is based upon work supported by the National Science Foundation under grants DMS-0821725, DMS-1020378, DMS-0713225, DMS-0555776, DMS-0545904, DMS-0838212, DMS-0757627, DUE-1020378, DUE-1022574, DMS-1015114, etc. Any opinions, findings, and conclusions or recommendations expressed in this material are those of the author(s) and do not necessarily reflect the views of the National Science Foundation. See also http://sagemath.org/development-ack.html.The Sage Notebook was primarily written by William Stein with substantial contributions from Tom Boothby, Timothy Clemans, Alex Clemesha, Mike Hansen, Bobby Moretti, Yi Qiang, and Dorian Raymer.The confirmation system is not active.The data filename already exists in other worksheet Delete the file in the other worksheet before creating a link.The password for the user %(u)s has been reset to %(p)sThe temporary password for the new user %(username)s is %(password)sThe username must start with a letter and be between 4 and 32 characters long. It can only consist of letters, numbers, underscores, and one dot (.).The variable DIR contains the directory from which you started the SAGE notebook. For example, to open a file in that directory, do "open(DIR+'filename')".Thematic TutorialsThere are no published worksheets.There was an error uploading the worksheet. It could be an old unsupported format or worse. If you desperately need its contents contact the sage-support group and post a link to your worksheet. Alternatively, an sws file is just a bzip2 tarball; take a look inside! %(backlinks)sThis Sage Worksheet is currently shared with the people listed in the box below.This Sage notebook is not configured to load worksheets from 'https' URLs. Try a different URL or download the worksheet and upload it directly from your computer. %(backlinks)sThis page is rated %(wr).1f.This worksheet is read only. Please make a copy or contact the owner to change it.TimeTitle of saved worksheetTo fix unmatched or mis-matched parentheses, braces or brackets, press ctrl-0. Parentheses before the cursor will be matched, minding strings and (Python) comments.To quickly try out Sage start hereTo save this image, you can try right-clicking on the image to copy it or save it to a file, or you may be able to just drag the image to your desktop.ToggleToggle the top barTotalTotalsTrashTrying again in %(num)d second...Trying again in %(num)d seconds...TutorialType "%%time" at the beginning of the cell.Type "restart" to restart the SAGE interpreter for a given worksheet. (You have to interrupt first.)Type ? immediately after the object or function and press tab or shift-enter (shift-enter overwrites output and saves to worksheet).Type of challengeType pretty_print_default() in an input cell and press shift-enter. All future output will be typeset automatically.Typesetting All OutputURL must start with http, https, or ftp.%(backlinks)sUnable to interrupt calculation.UnarchiveUnarchive selected worksheets so it appears in the default worksheet listUndeleteUnsuspendUntitledUpdatedUploadUpload or Create Data FileUpload or Create Data File to attach to worksheet "%(wn)s"Upload or create a data file in a wide range of formatsUpload or create file...Use "attach filename.sage" or "attach filename.py". Attached files are automatically reloaded when the file changes. The file $HOME/.sage/init.sage is attached on startup if it exists.Use "load filename.sage" and "load filename.py". Load is relative to the path you started the notebook in. The .sage files are preparsed and .py files are not. You may omit the .sage or .py extension. Files may load other files.Use "save obj1 obj2 ..." and "load obj1 obj2 ...". This allows for easy moving of objects from one worksheet to another, and saving of objects for later use.Use "save_session('name')" to save all variables to an object. Use "load_session('name')" to merge in all variables from a saved session.Use Most Mathematics Software from Within SageUse Sage for studying calculus, elementary to very advanced number theory, cryptography, commutative algebra, group theory, graph theory, numerical and exact linear algebra, and more.Use a Mainstream Programming LanguageUse a challenge for account registrationUse an Open Source AlternativeUse the Data menu to upload images and other files, and create new files that can be shared between worksheets. The DATA variable contains the path to the data files. For example, to open a file in that directory, do "open(DATA+'filename')". If foo.sage is a Sage file that you uploaded, type "load foo.sage"; if foo.py is a Python file, you can import it by typing "import foo".Useful TipsUserUser ManagementUsernameUsername Attribute (i.e. cn, uid or userPrincipalName)Username ErrorUsername already in useUsername is not in the systemUsername takenUsersVersionView a 4000+ page reference manual about SageView a log of recent computationsView changes to this worksheet over timeView plain textView plain text version of this worksheetWelcome to Sage! You can create a new worksheet, view published worksheets, or read the documentation.Welcome!What do you want to call it? (if different than the original name)What is 2 plus 3?What is 3 times 8?What is the largest prime factor of 15?With the Sage Notebook anyone can create, collaborate on, and publish interactive worksheets. In a worksheet, one can write code using Sage, Python, and other software included in Sage.Working DirectoryWorksheetWorksheet is locked. Cannot insert cells.Worksheet is publicly viewable at %(u)sWorksheet process limitsWorksheet process users (comma-separated list)Wrong passwordYesYou can publish your worksheet to the Internet, where anyone will be able to access and view it online.You do not have permission to access this locationYou do not have permission to access this worksheetYou may add or remove collaborators (separate user names by commas).You may download %(f)s or create a link to this file in worksheet You requested to evaluate a cell that, for some reason, the server is unaware of.You work with Sage using the highly regarded scripting language Python. You can write programs that combine serious mathematics with anything else.Your EmailYour browser / OS combination is not supported. Please use Firefox or Opera under Linux, Windows, or Mac OS X, or Safari.Your email address is required for account confirmation and recovery. You will be emailed a confirmation link right after you successfully sign up.Your new password is %(key)s Sign in at %(url_prefix)s://%(addr)s:%(port)s/ Make sure to reset your password by going to Settings in the upper right bar.Your password must have at least 4 characters. Your password can not contain your username or spaces.Your username must start with a letter and be between 3 and 64 characters long. You may only use letters, numbers, underscores, @, and dots.Your worksheet will be assigned a unique address (URL) that you can send to your friends and colleagues.browse directorycs_CZde_ATen_USes_ESevaluatefr_FRillegal link attempt!last editedleave a commentloading...or delete %(f)s.pt_BRpublishedreCAPTCHA private keyreCAPTCHA public keyru_RUrunnings (canceling further update checks).select worksheetsorry, no match founduk_UAunprintedusernamey|yesProject-Id-Version: sagenb Report-Msgid-Bugs-To: POT-Creation-Date: 2012-03-18 08:47+0400 PO-Revision-Date: 2011-06-13 12:55-0800 Last-Translator: Konstantin Podshumok Language-Team: ru_RU MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit Generated-By: Babel 1.3

    Ðеверный код подтверждениÑ

    Ð’Ñ‹ Ñообщили ключ подтверждениÑ, который не ÑвÑзан Ñ Ñтим Ñервером. ПожалуйÑта, зарегиÑтрируйтеÑÑŒ на Ñтом Ñервере.

    ВернутьÑÑ Ðº Загрузить или Ñоздать файл данных или %(worksheet_name)s.%(num)d день%(num)d днÑ%(num)d дней%(num)d чаÑ%(num)d чаÑа%(num)d чаÑов%(num)d минута%(num)d минуты%(num)d минут%(num)d Ñекунда%(num)d Ñекунды%(num)d Ñекунд%(seconds)s назад%(t)s назад пользователем %(le)s%(t)s назад пользователем %(le)s(обратите внимание, что Ð¸Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð¸Ñ Ð½Ðµ запиÑаны)24|двадцать четыре5|пÑть8|воÑемьИзучите практичеÑкое руководÑтво (еÑли у Ð²Ð°Ñ Ð²Ð¾Ð·Ð½Ð¸ÐºÐ°ÑŽÑ‚ проблемы Ñ ÐµÐ³Ð¾ проÑмотром, попробуйте ÑтатичеÑкую верÑию).Может быть, вмеÑто Ñтого вы хотите перезапуÑтить рабочий лиÑÑ‚?

    Электронный Ð°Ð´Ñ€ÐµÑ Ð¿Ð¾Ð´Ñ‚Ð²ÐµÑ€Ð¶Ð´Ñ‘Ð½ Ð´Ð»Ñ Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ %(username)s

    Sage — Ñто другой подход к математичеÑкому программному обеÑпечению.СеÑÑÐ¸Ñ â€” Ñто рабочий лиÑÑ‚ и набор переменных в некотором ÑоÑтоÑнии.Рабочий лиÑÑ‚ — Ñто упорÑдоченый ÑпиÑок вычиÑлений Sage Ñ Ñ€ÐµÐ·ÑƒÐ»ÑŒÑ‚Ð°Ñ‚Ð°Ð¼Ð¸.Ðовый пароль будет отправлен на email, указанный в вашем аккаунте. Однако, еÑли вы не подтвердили Ð°Ð´Ñ€ÐµÑ Ñлектронной почты, то вы не Ñможете воÑÑтановить Ñвой аккаунт.ИÑпользуйте %(f)s в Ñтом рабочем лиÑте, набрав DATA+'%(f)s'. ЗдеÑÑŒ DATA — Ñто ÑÐ¿ÐµÑ†Ð¸Ð°Ð»ÑŒÐ½Ð°Ñ Ð¿ÐµÑ€ÐµÐ¼ÐµÐ½Ð½Ð°Ñ, ÐºÐ¾Ñ‚Ð¾Ñ€Ð°Ñ Ñодержит полнуй путь ко вÑем файлам, приложенным к рабочему лиÑту.ВоÑÑтановление паролÑÐаÑтройки аккаунтаБлагодарноÑтиДейÑтвие...ÐктивныеÐктивные рабочие лиÑтыДобавить нового пользователÑДобавить пользователÑДобавить или удалитьРазрешить аутентификацию через OpenID (требуетÑÑ python модуль ssl)Пройдите проверкуВÑе Ñчейки Ñо введённым Ñловом "#auto" будут автоматичеÑки выполнены, когда рабочий лиÑÑ‚ будет открыт.Внешний видÐрхивироватьÐрхивировать выбранные рабочие лиÑты, чтобы они не поÑвлÑлиÑÑŒ на домашней ÑтраницеÐрхивированныеÐрхивированные рабочие лиÑтыПрикладывание Ñкриптов к рабочему лиÑтуÐттрибуты Ð´Ð»Ñ Ð¿Ð¾Ð¸Ñка пользователейÐутентификациÑÐвтоматичеÑки выполнÑть Ñчейки при загрузке рабочего лиÑтаÐвтоматичеÑки обновлÑть опубликованную верÑию, когда внеÑены изменениÑВернутьÑÑ Ðº ÑпиÑку ваших рабочих лиÑтовÐеподходÑщий парольÐеподходÑщее Ð¸Ð¼Ñ Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»ÑБаза поиÑкаÐаберите первой Ñтрочкой %%sh в Ñчейке ввода, чтобы оÑÑ‚Ð°Ð»ÑŒÐ½Ð°Ñ Ñ‡Ð°Ñть Ñчейки была интерпретирована как Ñкрипт оболочки. Изменение рабочей директории будет обработана правильно.ПодключатьÑÑ ÐºÐ°Ðº (Bind DN)Пароль подключениÑПроÑмотреть опубликованные рабочие лиÑты
    (региÑÑ‚Ñ€Ð°Ñ†Ð¸Ñ Ð½Ðµ требуетÑÑ)ПоÑмотреть опубликованные рабочие лиÑтыВыберите файл на вашем компьютере Ð´Ð»Ñ Ð·Ð°ÐºÐ°Ñ‡ÐºÐ¸:ИÑÐ¿Ð¾Ð»ÑŒÐ·ÑƒÑ Sage, вы помогаете поддерживать жизнеÑпоÑобную альтернативу Magma, Maple, Mathematica и MATLAB Ñ Ð¾Ñ‚ÐºÑ€Ñ‹Ñ‚Ñ‹Ð¼ иÑходным кодом. Sage включает множеÑтво выÑококачеÑтвенных пакетов математичеÑких программ Ñ Ð¾Ñ‚ÐºÑ€Ñ‹Ñ‚Ñ‹Ð¼ иÑходным кодом.ОтменитьОтменить изменениÑТеÑтыИзменить интервал авто-ÑохранениÑИзменить e-mailИзменить парольИзменить наÑтройки аккаунта, Ð²ÐºÐ»ÑŽÑ‡Ð°Ñ Ð¿Ð°Ñ€Ð¾Ð»ÑŒÐ©Ñ‘Ð»ÐºÐ½Ð¸Ñ‚Ðµ иÑториÑ, чтобы увидеть вÑе команды, которые вы ввели в любом рабочем лиÑте.Щёлкните Прервать или нажмите Escape в любой Ñчейке ввода. Это заÑтавит Sage (попытатьÑÑ) прервать текущую задачу, отправив много Ñигналов прерываниÑ.Щёлкните здеÑÑŒ или нажмите Shift+Enter, чтобы выполнитьОткрыть в отдельном окнеЩёлкните здеÑÑŒ, чтобы открыть Ñту программу как рабочий лиÑÑ‚ SageКликните Ñлева от вывода, чтобы переключить режим отображениÑ: Ñкрытый, Ñ Ð¿ÐµÑ€ÐµÐ½Ð¾Ñом Ñлов, без переноÑа Ñлов.Щёлкните, чтобы загрузить и уÑтановить шрифты TeX.Щёлкните, чтобы переименовать Ñтот рабочий лиÑтЗакройте Ñто Ñообщение, чтобы прекратить попытки.Код выполнÑетÑÑ Ð¿Ñ€Ð¸ помощи exec (поÑле препарÑинга). Только вывод поÑледней Ñтроки в Ñчейке будет отображён по умолчанию. ЕÑли какаÑ-либо Ñтрока начинаетÑÑ Ñ "sage:" или ">>>", то ÑчитаетÑÑ, что вÑÑ Ñчейка Ñодержит текÑÑ‚ и примеры, так что будут выполнены только Ñтроки, Ñодержащие приглашение. Таким образом, вы можете вÑтавлÑть примеры из документации целиком, без каких-либо иÑправлений, а также вы можете пиÑать в Ñчейках ввода проÑтой текÑÑ‚, который не будет выполнен, вмеÑте Ñ Ð¿Ñ€Ð¸Ð¼ÐµÑ€Ð°Ð¼Ð¸, еÑли начнёте Ñчейку Ñ ">>>" или вÑтавите пример из документации.СоавторыКомментарийКомментирование/раÑкомментирование блоковПоздравлÑем %(u)s! Теперь вы можете войти в Sage Notebook.Программные конÑтрукцииПродолжитьСкопировать текущий рабочий лиÑтСкопировать рабочий лиÑтПодÑчётСоздать аккаунтВыберите хороший парольСоздать новый рабочий лиÑÑ‚ из поÑледних 100 команд приведённой иÑторииСоздать новый рабочий лиÑтВыберите Ð¸Ð¼Ñ Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»ÑСоздать учётную запиÑÑŒÐ¡Ð¾Ð·Ð´Ð°Ð½Ð¸Ñ Ð½Ð¾Ð²Ñ‹Ñ… пользователей запрещено админиÑÑ‚Ñ€Ð°Ñ‚Ð¾Ñ€Ð¾Ð¼Ð¢ÐµÐºÑƒÑ‰Ð°Ñ Ð¿Ð°Ð¿ÐºÐ°Ð¢ÐµÐºÑƒÑ‰Ð¸Ð¹ e-mailКаÑÑ‚Ð¾Ð¼Ð¸Ð·Ð°Ñ†Ð¸Ñ CSS Sage NotebookÐŸÐµÑ€ÐµÐ¼ÐµÐ½Ð½Ð°Ñ DATAÐŸÐµÑ€ÐµÐ¼ÐµÐ½Ð½Ð°Ñ DIRФайл данныхДанные...Язык по умолчаниюСиÑтема по-умолчаниюУдалитьУдалить вÑе результатыУдалить ÑчейкуУдалите Ñодержимое Ñчейки и, затем, нажмите Backspace.Удалить вÑе результатыУдалить рабочий лиÑтУдалённые рабочие лиÑтыРуководÑтво разработчикаОтменить и выйтиОтменить Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ Ð² Ñтом рабочем лиÑтеХотите опубликовать Ñтот рабочий лиÑÑ‚?МакÑимальное Ð¾Ð¶Ð¸Ð´Ð°Ð½Ð¸Ñ (в Ñекундах) рабочего лиÑтаРазмер пула документации рабочего лиÑтаДокумент не ÑущеÑтвуетДокументациÑЭкÑпортироватьСохранить вÑе выделенныеЗагрузить выделенные рабочие лиÑтыСкачать.ÐšÐ°Ð¶Ð´Ð°Ñ Ñчейка запуÑкаетÑÑ Ð² ÑобÑтвенном каталоге. ЕÑли во Ð²Ñ€ÐµÐ¼Ñ Ñ€Ð°Ð±Ð¾Ñ‚Ñ‹ ÑоздаютÑÑ Ñ„Ð°Ð¹Ð»Ñ‹ изображений, то они будут автоматичеÑки отображены.ПравкаРедактировать копию.Редактировать как проÑтой текÑтРедактировать текÑтовую верÑию Ñтого рабочего лиÑтаРедактирвоать Ñто.ЗатраченоE-mail подтверждёнОчиÑтить корзинуОчиÑтка корзины окончательно удалит вÑе рабочие лиÑты в ней. Продолжить?Разрешить аутентификацию через LDAPРазрешить интерактивные опубликованные рабочие лиÑты (ЭКСПЕРИМЕÐТÐЛЬÐÐЯ ФУÐКЦИЯ; ИСПОЛЬЗУЙТЕ ÐРСВОЙ РИСК)Разрешить региÑтрацию пользователейРазрешить/запретить pretty_printing (автоматичеÑкое форматирование вывода)Введите ваш Ð°Ð´Ñ€ÐµÑ Ñлектронной почтыОкружениеОшибкаÐе удалоÑÑŒ применить функцию к рабочему(им) лиÑту(ам).Ошибка при отображении ÑпиÑка рабочих лиÑтовОшибка Ð¾Ð±Ð½Ð¾Ð²Ð»ÐµÐ½Ð¸Ñ Ð²Ñ‹Ð²Ð¾Ð´Ð° Ñчейки поÑле Ошибка при загрузке файла (отÑутÑтвует аргумент %(field)s). %(backlinks)sОшибка при загрузке файла (отÑутÑтвует файл fileField). %(backlinks)sОшибка при загрузке файла (отÑутÑтвует Ð¸Ð¼Ñ Ñ„Ð°Ð¹Ð»Ð°). %(backlinks)sОшибка при загрузке рабочего лиÑта '%(msg)s'. %(backlinks)sОшибка: Ð½ÐµÐ»ÑŒÐ·Ñ Ð´Ð¾Ð±Ð°Ð²Ð¸Ñ‚ÑŒ более 500 Ñоавторов за один разВыполнить вÑёВыполнить Ñчейку, иÑÐ¿Ð¾Ð»ÑŒÐ·ÑƒÑ GAP, Singular, и др.Выполнить вводВыполнить вÑе Ñчейки ввода рабочего лиÑтаВыполнÑть вÑе Ñчейки ввода, иÑÐ¿Ð¾Ð»ÑŒÐ·ÑƒÑ %(i)sВыходОжидалоÑÑŒ "%(wanted)s" поÑле "%(key)s", но получено "%(token)s"ОжидалоÑÑŒ определение цвета "%(arg)s" поÑле "%(key)s"ОжидалоÑÑŒ целое чиÑло "%(arg)s" поÑле "%(key)s"ОжидалоÑÑŒ целое чиÑло "%(key)s" перед "%(token)s"ПроÑмотреть коллекцию подробных практичеÑких руководÑтв по отдельным облаÑÑ‚ÑмСбойÐе удалоÑÑŒ Ñохранить рабочий лиÑÑ‚.БыÑÑ‚Ñ€Ð°Ñ ÑтатичеÑÐºÐ°Ñ Ð²ÐµÑ€ÑÐ¸Ñ Ð´Ð¾ÐºÑƒÐ¼ÐµÐ½Ñ‚Ð°Ñ†Ð¸Ð¸Ð¤Ð°Ð¹Ð»...Файлы и ÑкриптыÐайти помощь и документациюЗабыли парольПолнотекÑтовой поиÑк по документации и иÑходному кодуПроÑÑ‚Ð°Ñ Ð¸ выÑшаÑ, чиÑÑ‚Ð°Ñ Ð¸ Ð¿Ñ€Ð¸ÐºÐ»Ð°Ð´Ð½Ð°Ñ Ð¼Ð°Ñ‚ÐµÐ¼Ð°Ñ‚Ð¸ÐºÐ°ÐŸÐ¾Ð»ÑƒÑ‡Ð¸Ñ‚ÑŒ изображаниеÐачинаем работу Ñ SageПредоÑтавить доÑтуп к вашему рабочему лиÑту перечиÑленным выше ÑотрудникамПерейти к рабочему лиÑту.ПомощьКонтекÑÑ‚Ð½Ð°Ñ ÑправкаПомощь на канале IRC (интернет чат)Привет %(username)s! СкрытьСкрыть вÑе результатыСкрыть вÑе результатыСкрыть/показать вывод (результаты)Выделите текÑÑ‚ и нажмите Ctrl-., чтобы закомментировать его, и Ctrl-,, чтобы раÑкомментировать. Можно также иÑпользовать Ctrl-3 и Ctrl-4.Выделите текÑÑ‚ и нажмите > Ð´Ð»Ñ Ð¾Ñ‚Ñтупа, < Ð´Ð»Ñ ÑƒÐ´Ð°Ð»ÐµÐ½Ð¸Ñ Ð¾Ñ‚Ñтупа (Ñто работает в Safari и Firefox). Ð’ Firefox также можно иÑпользовать tab и shift-tab.ИÑториÑДомойКак мне Ñоздать ... в Sage?Сколько бит в одном байте?Как иÑпользовать Sage NotebookИнтервал между запроÑами (в Ñекундах)МакÑимальное Ð¾Ð¶Ð¸Ð´Ð°Ð½Ð¸Ñ (в Ñекундах)ЕÑли вы Ñоздадите файл $HOME/.sage/notebook.css, то он будет применён при отображении Sage Notebook. См. ОтÑтупы в блокахПравила вводаВÑтавить новую ÑчейкуВÑтавить новую текÑтовую ÑчейкуИнтерактивные динамичеÑкие виджетыИÑпользовать Ñтот рабочий лиÑÑ‚ интерактивноПрерватьПрерывание текущих вычиÑленийПрерывание и перезапуÑк ÑеÑÑийПопытка прерываниÑПрервать выполнÑемые ÑÐµÐ¹Ñ‡Ð°Ñ Ð²Ñ‹Ñ‡Ð¸ÑлениÑ, еÑли возможноÐеверный ответ в проверочном полеÐеверный Ð°Ð´Ñ€ÐµÑ Ñлектронной почтыÐеверное Ð¸Ð¼Ñ Ñ„Ð°Ð¹Ð»Ð°. %(backlinks)sÐеверное Ð¸Ð¼Ñ Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»ÑПриглаÑить ÑотрудниковВерно ли, что Ï€>e?Java апплет ÑÐºÑ€Ñ‹Ñ‚Ð”Ð»Ñ Ñ€Ð°Ð±Ð¾Ñ‚Ñ‹ Sage Notebook должне быть включён Javascript.Изображение JmolГорÑчие клавиши и дейÑÑ‚Ð²Ð¸Ñ Ð¼Ñ‹ÑˆÑŒÑŽÐ˜Ð·Ð²ÐµÑтные пользователи Sage:LDAPПоÑледнее изменениеÐаучитьÑÑ Ð¿Ð¸Ñать программы на SageРазрешить другим людÑм редактировать Ñтот рабочий лиÑтСоздать новый рабочий лиÑÑ‚, загрузив его из файлаЗагрузить рабочий лиÑÑ‚ из файла...Подключение Ñкриптов Sage/PythonЗагрузка и Ñохранение объектовЗагрузка и Ñохранение ÑеÑÑийИÑториÑВойтиВойдите, чтобы отредактировать копию.Выйти из Sage notebookРазрешить проÑматривать Ñтот лиÑÑ‚ вÑем желающимУправлÑть пользователÑмиМакÑимальный размер иÑторииМинутВерÑÐ¸Ñ Ð¼Ð¾Ð´ÐµÐ»Ð¸Ðаведите мышь между Ñчейками так, чтобы поÑвилаÑÑŒ ÑинÑÑ Ð¿Ð¾Ð»Ð¾Ñка. Shift-щелчок Ñоздат новую текÑтовую Ñчейку. Двойной щелчок по ÑущеÑтвующей текÑтовой Ñчейке позволит её отредактировать. Ð”Ð»Ñ Ð²Ð²Ð¾Ð´Ð° математичеÑких формул (в LaTeX) наберите $...$ и $$...$$ в текÑтовой Ñчейке.ВоÑÑтановить выделенные рабочие лиÑты из корзиныПеремеÑтить выделенные рабочие лиÑты в корзинуПеремеÑтить Ñтот рабочий лиÑÑ‚ в корзинуРежим многих ÑчеекÐовый пользовательÐовый рабочий лиÑÑ‚Ðовый e-mailÐовый парольÐовый рабочий лиÑÑ‚ÐовееПоÑледниеÐетВы не заполнили проверочное полеÐет файлов данныхÐÐ´Ñ€ÐµÑ Ñлектронной почты не был введёнПароль не был введёнЗапрошенный рабочий лиÑÑ‚ не найден.Ð˜Ð¼Ñ Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ Ð½Ðµ указаноÐаÑтройки NotebookМакÑÐ¸Ð¼Ð°Ð»ÑŒÐ½Ð°Ñ Ð´Ð»Ð¸Ð½Ð° Ñтроки при переноÑе ÑловСтарый парольРаньшеСамые ранниеРежим одной ÑчейкиТолько владелец рабочего лиÑта может поделитьÑÑ Ð¸Ð¼. Ð’Ñ‹ можете делать вÑÑ‘, что захотите, еÑли Ñоздадите ÑобÑтвенную копию.Или введите URL файла из Cети:Или введите Ð¸Ð¼Ñ Ð½Ð¾Ð²Ð¾Ð³Ð¾ файла, который будет Ñоздан:Другие опубликованные документы...ВладелецПарноÑть ÑкобокПройденоПарольПароли не ÑовпадаютВыберите Ð¸Ð¼Ñ Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»ÑПожалуйÑта, попроÑите админиÑтратора Ñервера наÑтроить ÑредÑтво защиты от ботов!ПожалуйÑта, назовите Ñтот рабочий лиÑÑ‚.ПожалуйÑта, войдите в Sage NotebookПожалуйÑта, укажите рабочий лиÑÑ‚ Ð´Ð»Ñ Ð·Ð°Ð³Ñ€ÑƒÐ·ÐºÐ¸. %(backlinks)sВозможнo, произошла ошибка при удалении рабочего лиÑта.Ðажмите Ctrl-; в Ñчейке, чтобы разбить её на две, и Ctrl-Backspace, чтобы объединить их. Ðажмите Ctrl-Enter, чтобы разбить Ñчейку на две и выполнить обе чаÑти. Ðажмите Shift-Enter. Ð’Ñ‹ можете начать неÑколько вычиÑлений за раз. ЕÑли же вы нажмёте Alt-Enter, то будет Ñоздана Ð½Ð¾Ð²Ð°Ñ Ñчейка Ñразу поÑле текущей. Рнажатие Ctrl-Enter разобьёт Ñчейку на две чаÑти, которые будут выполнÑтьÑÑ Ð¿Ð¾ отдельноÑти.Ðажмите Tab пока курÑор находитÑÑ Ð½Ð° идентификаторе. Ð’ некоторых браузерах (например, в Opera) вмеÑто Tab нужно иÑпользовать Control-Пробел.Ðвтоформатирование выводаПечатьÐапечатать Ñтот рабочий лиÑтВозникла проблема при вÑтавке новой Ñчейки поÑле текущей. ОпубликоватьОпубликовать Ñту верÑиюОпубликованныеОпубликованные рабочие лиÑтыОпубликовано %(t)sВведите "%%gap", "%%singular", и др. первой Ñтрочкой Ñчейки ввода; оÑÑ‚Ð°Ð»ÑŒÐ½Ð°Ñ Ñ‡Ð°Ñть Ñчейки будет выполнена в выбранной ÑиÑтеме.Ðаберите ?? поÑле объекта и нажмите Tab или Shift-Enter (Shift-Enter перезапиÑывает вывод и ÑохранÑет рабочий лиÑÑ‚).Ðаберите @interact на Ñтроке перед определением функции. Ðаберите interact? Ð´Ð»Ñ Ð¿Ð¾Ð´Ñ€Ð¾Ð±Ð½Ð¾Ñтей.Ðаведите указатель мыши на проÑтранÑтво над Ñчейкой ввода или под выводом, так, чтобы поÑвилаÑÑŒ Ð³Ð¾Ñ€Ð¸Ð·Ð¾Ð½Ñ‚Ð°Ð»ÑŒÐ½Ð°Ñ Ð»Ð¸Ð½Ð¸Ñ, и щёлкните. ЕÑли вы нажмёте Alt-Enter Ñчейка будет выполнена и Ð½Ð¾Ð²Ð°Ñ Ñчейка будет вÑтавлена поÑле неё.Завершить процеÑÑ Ñ€Ð°Ð±Ð¾Ñ‡ÐµÐ³Ð¾ лиÑтаОценитьОценкаОценки Ð´Ð»Ñ %(wn)sОпубликовать ÑноваÐаберите пароль ещё разРуководÑтво пользователÑПомнить менÑПереименоватьПереименовать текущий рабочий лиÑтПереименовать рабочий лиÑтСообщить об ошибкеСообщить о проблеме или отправить отчёт об ошибке, Ð´Ð»Ñ ÑƒÐ»ÑƒÑ‡ÑˆÐµÐ½Ð¸Ñ SageЗапрошеный опубликованный рабочий лиÑÑ‚ не ÑущеÑтвуетТребовать e-mail Ð´Ð»Ñ Ñ€ÐµÐ³Ð¸Ñтрации аккаунтаИзменить оценкуСброÑитьПерезапуÑтитьПерезапуÑтить процеÑÑ Ñ€Ð°Ð±Ð¾Ñ‡ÐµÐ³Ð¾ лиÑтаПерезапуÑтить рабочий лиÑтВернутьÑÑ Ðº Загрузить файл.Ðаберить пароль ещё разОткатить к Ñтой верÑииВерÑиÑВерÑÐ¸Ñ %(lr)sИÑÑ‚Ð¾Ñ€Ð¸Ñ Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ð¹ — Предыдущие ÑеÑÑииСпиÑок измененийОбновлено %(ta)s дней назадВерÑÐ¸Ð¸Ð”Ð¾ÐºÑƒÐ¼ÐµÐ½Ñ‚Ð°Ñ†Ð¸Ñ Ð¿Ð¾ SageSage NotebookВерÑÐ¸Ñ Sage NotebookБраузер иÑходного кодаС помощью Sage очень проÑто иÑпользовать большинÑтво математичеÑких программ вмеÑте. Sage включает в ÑÐµÐ±Ñ GAP, GP/PARI, Maxima, Singular и дюжины других открытых пакетов программного обеÑпечениÑ.ВерÑÐ¸Ñ SageSage: ИÑÑ‚Ð¾Ñ€Ð¸Ñ Ð´Ð»Ñ %(u)sСохранитьСохранить и выйтиСохранить изменениÑСохранить и закрыть рабочий лиÑтСохранить изменениÑСохранить Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ Ð¸ закрыть Ð¾ÐºÐ½Ð¾Ð’Ñ€ÐµÐ¼Ñ Ð´Ð¾ автоÑÐ¾Ñ…Ñ€Ð°Ð½ÐµÐ½Ð¸Ñ (в Ñекундах)Сохранить Ñтот рабочий лиÑÑ‚ как файл swsСохранить рабочий лиÑÑ‚ в файл...ПоиÑк пользователейПоиÑк рабочих лиÑтовРезультаты поиÑка:Ð”Ð»Ñ Ð¿Ð¾Ð¸Ñка в документации Sage введите
    search_doc("ваш запроÑ")
    в Ñчейку ввода и нажмите Shift-Enter. Ðайти иÑходный код Sage можно, набрав
    search_src("ваш запроÑ")
    . Ð’ запроÑах можно иÑпользовать произвольные регулÑрные выражениÑ.ПоиÑк Ñервера Sage...Выберите, что вы хотите Ñделать Ñ Ñ„Ð°Ð¹Ð»Ð¾Ð¼Ð’Ñ‹Ð±ÐµÑ€Ð¸Ñ‚Ðµ функцию ÑƒÐ¿Ñ€Ð°Ð²Ð»ÐµÐ½Ð¸Ñ Ñ€Ð°Ð±Ð¾Ñ‡Ð¸Ð¼ лиÑтомВыберите провайдера OpenIDВыберите приложенный файлОтправитьСерверÐаÑтройкиПоделитьÑÑПоделитьÑÑПоделитьÑÑ Ñтим документомСкрипты оболочки (shell)ПоказатьПоказать вÑе результатыПоказать вÑе результатыВойтиВыйтиВойтиЗарегиÑтрировать новую учётную запиÑÑŒ в Sage NotebookЗарегиÑтрировать новый аккаунт в Sage NotebookКто-то ещё проÑматривает Ñтот рабочий лиÑтПроÑтите, но требуетÑÑ Ð±Ñ€Ð°ÑƒÐ·ÐµÑ€, который поддерживает HTML Ñ‚Ñг <canvas>.ИÑходный кодСпециальные блоки в ÑчейкахРазбить и объединить ÑчейкиСтартСтатичеÑÐºÐ°Ñ Ð²ÐµÑ€ÑиÑ...СтатуÑСтопУдалить из опубликованныхОÑтановить выделенные рабочие лиÑтыОтправитьЗаблокироватьБлокировкаПодозрительное Ð¸Ð¼Ñ Ñ„Ð°Ð¹Ð»Ð° "%(filename)s" обнаружено при загрузке файла. %(backlinks)sПереключитьÑÑ Ð² режим Ñо многими ÑчейкамиПереключитьÑÑ Ð² режим одной ÑчейкиÐвтозавершение по нажатию TabТекÑтСпаÑибо за региÑтрацию в Sage Notebook. Чтобы завершить региÑтрацию, Ñкопируйте и вÑтавьте Ñледующую ÑÑылку в ваш браузер: %(url_prefix)s://%(addr)s:%(port)s/confirm?key=%(key)s ОткроетÑÑ Ñтраница, на которой будет Ñообщение, подтверждающее вашу уÑпешную региÑтрацию.Sage notebook — Ñто ÐºÐ¾Ð»Ð»ÐµÐºÑ†Ð¸Ñ Ñ€Ð°Ð±Ð¾Ñ‡Ð¸Ñ… лиÑтов, Ñохранённых объектов и пользовательÑкой информации.Sage NotebookSage Notebook оÑнован на работе, поддерживаемой National Science Foundation в рамках грантов DMS-0821725, DMS-1020378, DMS-0713225, DMS-0555776, DMS-0545904, DMS-0838212, DMS-0757627, DUE-1020378, DUE-1022574, DMS-1015114, и др. Любые мнениÑ, находки, оценки или рекомендации предÑтавленные здеÑÑŒ ÑвлÑÑŽÑ‚ÑÑ Ñ‡Ð°Ñтным мнением автора(ов) и могут не Ñовпадать Ñо взглÑдами National Science Foundation. См. также http://sagemath.org/development-ack.html.Sage Notebook был изначально Ñоздан William Stein, Ñ ÑущеÑтвенным вкладом Tom Boothby, Timothy Clemans, Alex Clemesha, Mike Hansen, Bobby Moretti, Yi Qiang и Dorian Raymer.СиÑтема Ð¿Ð¾Ð´Ñ‚Ð²ÐµÑ€Ð¶Ð´ÐµÐ½Ð¸Ñ Ð½Ðµ активна.Файл данных Ñ Ñ‚Ð°ÐºÐ¸Ð¼ именем уже ÑущеÑтвует в рабочем лиÑте Удалите файл в другом рабочем лиÑте, прежде чем Ñоздавать ÑвÑзанную копию.Пароль Ð´Ð»Ñ Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ %(u)s был Ñбарошен на %(p)sВременный пароль Ð´Ð»Ñ Ð½Ð¾Ð²Ð¾Ð³Ð¾ Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ %(username)s:%(password)sÐ˜Ð¼Ñ Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ Ð´Ð¾Ð»Ð¶Ð½Ð¾ начинатьÑÑ Ñ Ð±ÑƒÐºÐ²Ñ‹ и быть не короче 4 и не длиннее 32 Ñимволов. Можно иÑпользовать только буквы, цифры, знаки Ð¿Ð¾Ð´Ñ‡Ñ‘Ñ€ÐºÐ¸Ð²Ð°Ð½Ð¸Ñ Ð¸ точки (.).ÐŸÐµÑ€ÐµÐ¼ÐµÐ½Ð½Ð°Ñ DIR Ñодержит Ð°Ð´Ñ€ÐµÑ ÐºÐ°Ñ‚Ð°Ð»Ð¾Ð³Ð°, из которого запущен Sage Notebook. Ðапример, чтобы открыть файл в Ñтом каталоге, наберите "open(DIR+'имÑ_файла')".ТематичеÑкие практичеÑкое руководÑтваÐет опубликованных рабочих лиÑтовВозникла ошибка при загружке рабочего лиÑта. Возможно, Ñто Ñтарый неподдерживаемый формат или того хуже. ЕÑли вам вÑÑ‘ же очень нужно Ñодержание Ñтого файла, напишите в группу sage-support и дайте ÑÑылку на ваш рабочий лиÑÑ‚. Как вариант, попробуйте взглÑнуть внутрь файла Ñами: sws файл — Ñто проÑто текÑтовой файл в tar-архиве, Ñжатом bzip2! %(backlinks)sЭтот рабочий лиÑÑ‚ на данный момент разделен Ñ Ð»ÑŽÐ´ÑŒÐ¼Ð¸, перечиÑленными в поле ниже.Этот Sage Notebook-Ñервер не наÑтроен Ð´Ð»Ñ Ð·Ð°Ð³Ñ€ÑƒÐ·ÐºÐ¸ рабочих лиÑтов из URL, начинающихÑÑ Ñ 'https'.Попробуйте другой URL или Ñкачайте файл рабочего лиÑта, а потом загрузите его непоÑредÑтвенно Ñо Ñвоего компьютера. %(backlinks)sОценка Ñтой Ñтраницы: %(wr).1f.Этот рабочий лиÑÑ‚ доÑтупен только Ð´Ð»Ñ Ñ‡Ñ‚ÐµÐ½Ð¸Ñ. ПожалуйÑта, Ñделайте копию или ÑвÑзитеÑÑŒ Ñ Ð²Ð»Ð°Ð´ÐµÐ»ÑŒÑ†ÐµÐ¼, чтобы получить права на изменение.Ð’Ñ€ÐµÐ¼Ñ Ð²Ñ‹Ð¿Ð¾Ð»Ð½ÐµÐ½Ð¸ÑÐ—Ð°Ð³Ð»Ð°Ð²Ð¸Ñ Ñохранённого рабочего лиÑтаЧтобы иÑправить непарные круглые, квадратные, фигурные Ñкобки, нажмите Ctrl-0. Скобки перед курÑором Ñтанут парными, Ñ Ð¿Ñ€Ð°Ð²Ð¸Ð»ÑŒÐ½Ð¾Ð¹ обработкой Ñтрок и комментариев (в Python).Чтобы быÑтро попробовать Sage, начните здеÑьЧтобы Ñохранить Ñто изображение, вы можете попробовать щёлкнуть по нему правой кнопкой и выбрать Копировать или Сохранить. Также, возможно, вы можете проÑто перетащить картинку на рабочий Ñтол.ПереключитьПереключить верхнюю панельВÑÐµÐ³Ð¾Ð˜Ñ‚Ð¾Ð³Ð¸ÐšÐ¾Ñ€Ð·Ð¸Ð½Ð°ÐžÑ‡ÐµÑ€ÐµÐ´Ð½Ð°Ñ Ð¿Ð¾Ð¿Ñ‹Ñ‚ÐºÐ° через %(num)d Ñекунду...ÐžÑ‡ÐµÑ€ÐµÐ´Ð½Ð°Ñ Ð¿Ð¾Ð¿Ñ‹Ñ‚ÐºÐ° через %(num)d Ñекунды...ÐžÑ‡ÐµÑ€ÐµÐ´Ð½Ð°Ñ Ð¿Ð¾Ð¿Ñ‹Ñ‚ÐºÐ° через %(num)d Ñекунд...ПрактичеÑкое руководÑтвоДобавьте "%%time" в начало Ñчейки.Ðаберите "restart" Ð´Ð»Ñ Ð¿ÐµÑ€ÐµÐ·Ð°Ð¿ÑƒÑка интерпретатора Sage в текущем рабочем лиÑте. (Сначала нужно прервать текущие вычиÑлениÑ.)Ðаберите ? Ñразу поÑле объекта или функции и нажмите Tab или Shift-Enter (Shift-Enter перезапиÑывает вывод и ÑохранÑет рабочий лиÑÑ‚).Тип защитыВведите pretty_print_default() в Ñчейке ввода и нажмите Shift-Enter. ВеÑÑŒ поÑледующий ввывод будет автоматичеÑки отформатирован.Ðвтоформатирование вÑего выводаURL должен начинатьÑÑ Ñ http, https, или ftp. %(backlinks)sÐе удалоÑÑŒ прервать вычиÑлениÑ.РазархивироватьРазархивировать выбранные рабочие лиÑты, чтобы они поÑвилиÑÑŒ на домашней ÑтраницеВоÑÑтановитьРазблокироватьБезымÑнныйОбновленоИмпортироватьЗакачать или Ñоздать файл данныхЗакачать или Ñоздать файл данных и приложить его к рабочему лиÑту "%(wn)s"Закачайте или Ñоздайте файл данных в одном из многочиÑленных поддерживаемых форматовЗакачать или Ñоздать файл...ИÑпользуйте "attach filename.sage" или "attach filename.py". Приложенные файлы автоматичеÑки перезагружаютÑÑ Ð¿Ñ€Ð¸ их изменении. ЕÑли ÑущеÑтвует файл $HOME/.sage/init.sage, то он прикладываетÑÑ Ð¿Ñ€Ð¸ запуке.ИÑпользуйте "load filename.sage" и "load filename.py". Путь load отноÑителен директории, из которой запущен Sage Notebook. Файлы .sage будут обработаны препарÑером, а .py — нет. РаÑширение .sage или .py можно опуÑтить. Файлы могут загружать другие файлы.ИÑпользуйте "save obj1 obj2 ..." и "load obj1 obj2 ...". Так можно легко перемещать объекты из одного рабочего лиÑта в другой и ÑохранÑть их Ð´Ð»Ñ Ð´Ð°Ð»ÑŒÐ½ÐµÐ¹ÑˆÐµÐ³Ð¾ иÑпользованиÑ.ИÑпользуйте "save_session('name')", чтобы Ñохранить вÑе переменные в объект. Введите "load_session('name')", чтобы объединить текущее окружение Ñ Ð¿ÐµÑ€ÐµÐ¼ÐµÐ½Ð½Ñ‹Ð¼Ð¸ из Ñохранённой ÑеÑÑии.ИÑпользуйте большинÑтво математичеÑких программ прÑмо из SageИÑпользуйте Sage Ð´Ð»Ñ Ð¸Ð·ÑƒÑ‡ÐµÐ½Ð¸Ñ Ð¼Ð°Ñ‚ÐµÐ¼Ð°Ñ‚Ð¸Ñ‡ÐµÑкого анализа, Ñлементарной и продвинутой теории чиÑел, криптографии, коммутативной алгебры, теории групп, теории графов, клаÑÑичеÑкой и чиÑленной линейной алгебры и многого другого.ИÑпользуйте Ñовременный широко раÑпроÑтраненный Ñзык программированиÑИÑпользовать защиту от ботов при региÑтрации аккаунтовИÑпользуйте Ñвободную альтернативуИÑпользуйте меню Данные, чтобы загружать картинки и другие файлы, а также Ñоздавать новые файлы, которые могут быть иÑпользованы в разных рабочих лиÑтах одновременно. ÐŸÐµÑ€ÐµÐ¼ÐµÐ½Ð½Ð°Ñ DATA Ñодержит путь к Ñтим файлам данных. Ðапример, чтобы открыть файл в Ñтом каталоге, наберите "open(DATA+'файл')". ЕÑли вы загрузили Sage файл foo.sage, наберите "load foo.sage", чтобы выполнить его; еÑли вы загрузили Python файл foo.py, вы можете импортировать его Ñ Ð¿Ð¾Ð¼Ð¾Ñ‰ÑŒÑŽ "import foo".Полезные замечаниÑПользовательУправление пользователÑÐ¼Ð¸Ð˜Ð¼Ñ Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»ÑÐттрибут имени Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ (например, cn, uid или userPrincipalName)Ошибка в имени пользователÑПользователь Ñ Ñ‚Ð°ÐºÐ¸Ð¼ именем уже зарегиÑÑ‚Ñ€Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð˜Ð¼Ñ Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ Ð½Ðµ найдено в ÑиÑÑ‚ÐµÐ¼ÐµÐ˜Ð¼Ñ Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ Ð¿Ñ€Ð¸Ð½ÑтоПользователиВерÑиÑПроÑмотреть 4000+ Ñтраниц руководÑтва Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ SageПоÑмотреть иÑторию поÑледних вычиÑленийПроÑмотреть Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ Ð² Ñтом рабочем лиÑтеПроÑмотреть как проÑтой текÑтПроÑмотреть текÑтовую верÑию Ñтого рабочего лиÑтаДобро пожаловать в Sage! Ð’Ñ‹ можете Ñоздать новый рабочий лиÑÑ‚, проÑмотреть опубликованные рабочие лиÑты, или почитать документацию.Добро пожаловать!Как вы хотите назвать его? (еÑли хотите изменить имÑ, запиÑанное в файле)Сколько будет два Ð¿Ð»ÑŽÑ Ñ‚Ñ€Ð¸?Сколько будет трижды воÑемь?Какой наибольший проÑтой делитель чиÑла 15?При помощи Sage Notebook можно Ñоздавать интерактивные рабочие лиÑты, ÑовмеÑтно работать над ними и публиковать их. Ð’ рабочем лиÑте можно пиÑать код на Sage, Pyhton и других программах, включённых в Sage.Рабочий каталогРабочий лиÑтРабочий лиÑÑ‚ зафикÑирован. ÐÐµÐ»ÑŒÐ·Ñ Ð²ÑтавлÑть Ñчейки.Рабочий лиÑÑ‚ доÑтупен Ð´Ð»Ñ Ð¿Ñ€Ð¾Ñмотра вÑеми желающими по адреÑу %(u)sÐžÐ³Ñ€Ð°Ð½Ð¸Ñ‡ÐµÐ½Ð¸Ñ Ð¿Ñ€Ð¾Ñ†ÐµÑÑа рабочего лиÑтаПользователи процеÑÑа рабочего лиÑта (ÑпиÑок, разделённый запÑтыми)Ðеверный парольДаВы можете опубликовать ваш рабочий лиÑÑ‚ в Интернет, где любой желающий Ñможет увидеть его онлайн.У Ð²Ð°Ñ Ð½ÐµÑ‚ прав Ð´Ð»Ñ Ð´Ð¾Ñтупа к Ñтой ÑтраницеУ Ð²Ð°Ñ Ð½ÐµÑ‚ прав Ð´Ð»Ñ Ð´Ð¾Ñтупа к Ñтому рабочему лиÑтуВы можете добавить или удалить Ñотрудников (отделÑйте их имена пользователей друг от друга запÑтыми).Ð’Ñ‹ можете Ñкачать %(f)s или Ñоздать ÑÑылку на Ñтот файл в рабочем лиÑтеВы запроÑили выполнение Ñчейки, котораÑ, по каким-то причинам, не извеÑтна Ñерверу.Ð’ Sage вы работаете Ñ Ð¸Ñпользованием хорошо зарекомендовашего ÑÐµÐ±Ñ Ñкриптового Ñзыка Python. Ð’Ñ‹ можете пиÑать программы, в которых ÑÐµÑ€ÑŒÑ‘Ð·Ð½Ð°Ñ Ð¼Ð°Ñ‚ÐµÐ¼Ð°Ñ‚Ð¸ÐºÐ° Ñовмещена Ñ Ñ‡ÐµÐ¼ угодно.Ваш e-mailВаш браузер, Ð¾Ð¿ÐµÑ€Ð°Ñ†Ð¸Ð¾Ð½Ð½Ð°Ñ ÑиÑтема или их ÐºÐ¾Ð¼Ð±Ð¸Ð½Ð°Ñ†Ð¸Ñ Ð½Ðµ поддерживаетÑÑ. ПожалуйÑта, воÑпользуйтеÑÑŒ Firefox или Opera в операционных ÑиÑтемах Linux или Windows или Mac OS X и Safari.Ваш Ð°Ð´Ñ€ÐµÑ Ñлектронной почты иÑпользуетÑÑ Ð´Ð»Ñ Ð¿Ð¾Ð´Ñ‚Ð²ÐµÑ€Ð¶Ð´ÐµÐ½Ð¸Ñ Ð°ÐºÐºÐ°ÑƒÐ½Ñ‚Ð° и его воÑÑÑ‚Ð°Ð½Ð¾Ð²Ð»ÐµÐ½Ð¸Ñ Ð² Ñлучае, еÑли вы забыли пароль. ПоÑле региÑтрации на Ñтот Ð°Ð´Ñ€ÐµÑ Ð²Ð°Ð¼ будет отправлена ÑÑылка Ð´Ð»Ñ ÐµÐ³Ð¾ подтверждениÑ.Ваш новый пароль: %(key)s Войдите на Ñервер: %(url_prefix)s://%(addr)s:%(port)s/ ПожалуйÑта, ÑброÑьте ваш пароль, Ð¿ÐµÑ€ÐµÐ¹Ð´Ñ Ð¿Ð¾ ÑÑылке ÐаÑтройки в верхней правой панели.Пароль должен быть не короче 4 Ñимволов. Пароль не может Ñодержать Ð¸Ð¼Ñ Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ Ð¸ пробелы.Ваше Ð¸Ð¼Ñ Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ Ð´Ð¾Ð»Ð¶Ð½Ð¾ начинатьÑÑ Ñ Ð±ÑƒÐºÐ²Ñ‹ и быть не короче 3 и не длиннее 64 Ñимволов. Можно иÑпользовать только буквы, цифры, знаки подчёркиваниÑ, @ и точки.Вашему рабочему лиÑту будет приÑвоен уникальный Ð°Ð´Ñ€ÐµÑ (URL), который можно отправить друзьÑм или коллегам.проÑмотр директорииÄeÅ¡tina (ÄŒeská republika)Deutsch (Österreich)English (United States)español (España)выполнитьfrançais (France)попытка доÑтупа по неверной ÑÑылке!поÑледнее изменениеоÑтавить комментарийзагрузка...или удалить %(f)s.português (Brasil)опубликованоЗакрытый ключ reCAPTCHAПубличный ключ reCAPTCHAруÑÑкий (РоÑÑиÑ)запущенs (дальнейшие проверки Ð¾Ð±Ð½Ð¾Ð²Ð»ÐµÐ½Ð¸Ñ Ð¿Ñ€ÐµÐºÑ€Ð°Ñ‰ÐµÐ½Ñ‹)выберите рабочий лиÑтпроÑтите, по данному запроÑу ничего не найденоукраїнÑька (Україна)не Ð½Ð°Ð¿ÐµÑ‡Ð°Ñ‚Ð°Ð½Ð¾Ð¸Ð¼Ñ Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñд|даsagenb-1.0.1/sagenb/translations/ru_RU/LC_MESSAGES/messages.po000066400000000000000000003236571311436262400237420ustar00rootroot00000000000000# Konstantin Podshumok , 2012. # Russian translation for Sage (www.sagemath.org) msgid "" msgstr "" "Project-Id-Version: sagenb\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2012-03-18 08:47+0400\n" "PO-Revision-Date: 2011-06-13 12:55-0800\n" "Last-Translator: Konstantin Podshumok \n" "Language-Team: ru_RU \n" "Plural-Forms: nplurals=3; plural=n==1 ? 0 : n>=2 && n<=4 ? 1 : 2\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" "Generated-By: Babel 0.9.6\n" msgid "cs_CZ" msgstr "ÄeÅ¡tina (ÄŒeská republika)" msgid "de_AT" msgstr "Deutsch (Österreich)" msgid "en_US" msgstr "English (United States)" msgid "es_ES" msgstr "español (España)" msgid "pt_BR" msgstr "português (Brasil)" msgid "ru_RU" msgstr "руÑÑкий (РоÑÑиÑ)" msgid "fr_FR" msgstr "français (France)" msgid "uk_UA" msgstr "українÑька (Україна)" #: flask_version/admin.py:67 #, python-format msgid "" "The temporary password for the new user %(username)s is " "%(password)s" msgstr "" "Временный пароль Ð´Ð»Ñ Ð½Ð¾Ð²Ð¾Ð³Ð¾ Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ " "%(username)s:%(password)s" #: flask_version/admin.py:69 msgid "New User" msgstr "Ðовый пользователь" #: flask_version/authentication.py:258 msgid "The confirmation system is not active." msgstr "СиÑтема Ð¿Ð¾Ð´Ñ‚Ð²ÐµÑ€Ð¶Ð´ÐµÐ½Ð¸Ñ Ð½Ðµ активна." #: flask_version/authentication.py:261 msgid "" "

    Invalid confirmation key

    \n" "

    You are reporting a confirmation key that has not been assigned by" " this\n" " server. Please register with the " "server.

    \n" " " msgstr "" "

    Ðеверный код подтверждениÑ

    \n" "

    Ð’Ñ‹ Ñообщили ключ подтверждениÑ,\n" "который не ÑвÑзан Ñ Ñтим Ñервером.\n" "ПожалуйÑта, зарегиÑтрируйтеÑÑŒ на Ñтом " "Ñервере.

    " #: flask_version/authentication.py:272 #, python-format msgid "

    Email address confirmed for user %(username)s

    " msgstr "

    Электронный Ð°Ð´Ñ€ÐµÑ Ð¿Ð¾Ð´Ñ‚Ð²ÐµÑ€Ð¶Ð´Ñ‘Ð½ Ð´Ð»Ñ Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ %(username)s

    " #: flask_version/authentication.py:274 msgid "Email Confirmed" msgstr "E-mail подтверждён" #: flask_version/base.py:226 #: ../sagenb/data/sage/html/base_authenticated.html:15 msgid "Log" msgstr "ИÑториÑ" #: flask_version/decorators.py:35 msgid "You do not have permission to access this location" msgstr "У Ð²Ð°Ñ Ð½ÐµÑ‚ прав Ð´Ð»Ñ Ð´Ð¾Ñтупа к Ñтой Ñтранице" #: flask_version/worksheet.py:27 flask_version/worksheet.py:36 #: flask_version/worksheet_listing.py:195 msgid "You do not have permission to access this worksheet" msgstr "У Ð²Ð°Ñ Ð½ÐµÑ‚ прав Ð´Ð»Ñ Ð´Ð¾Ñтупа к Ñтому рабочему лиÑту" #: flask_version/worksheet.py:75 flask_version/worksheet.py:951 #: ../sagenb/data/sage/html/notebook/worksheet_page.html:28 #: ../sagenb/notebook/misc.py:237 ../sagenb/notebook/worksheet.py:703 #: ../sagenb/notebook/worksheet.py:723 ../sagenb/notebook/worksheet.py:4230 msgid "Untitled" msgstr "БезымÑнный" #: flask_version/worksheet.py:578 msgid "Error: can't add more than 500 collaborators at a time" msgstr "Ошибка: Ð½ÐµÐ»ÑŒÐ·Ñ Ð´Ð¾Ð±Ð°Ð²Ð¸Ñ‚ÑŒ более 500 Ñоавторов за один раз" #: flask_version/worksheet.py:631 #: ../sagenb/data/sage/html/error_message.html:4 #: ../sagenb/data/sage/html/login.html:69 #: ../sagenb/data/sage/html/login.html:76 #: ../sagenb/data/sage/html/login.html:104 #: ../sagenb/data/sage/html/login.html:106 #: ../sagenb/data/sage/html/recaptcha.html:27 #: ../sagenb/data/sage/html/test_report.html:112 #: ../sagenb/data/sage/html/test_report.html:131 #: ../sagenb/data/sage/html/accounts/registration.html:22 #: ../sagenb/data/sage/html/accounts/registration.html:25 #: ../sagenb/data/sage/html/accounts/registration.html:28 #: ../sagenb/data/sage/html/accounts/registration.html:39 #: ../sagenb/data/sage/html/accounts/registration.html:42 #: ../sagenb/data/sage/html/accounts/registration.html:49 #: ../sagenb/data/sage/html/accounts/registration.html:62 #: ../sagenb/data/sage/html/accounts/registration.html:65 #: ../sagenb/data/sage/html/accounts/registration.html:74 #: ../sagenb/data/sage/html/accounts/registration.html:77 #: ../sagenb/data/sage/html/settings/admin_add_user.html:17 #: ../sagenb/data/sage/html/settings/admin_add_user.html:19 #: ../sagenb/data/sage/js/translated-messages.js:17 msgid "Error" msgstr "Ошибка" #: flask_version/worksheet.py:661 msgid "No data files" msgstr "Ðет файлов данных" #: flask_version/worksheet.py:702 msgid "illegal link attempt!" msgstr "попытка доÑтупа по неверной ÑÑылке!" #: flask_version/worksheet.py:704 msgid "" "The data filename already exists in other worksheet\n" "Delete the file in the other worksheet before creating a link." msgstr "" "Файл данных Ñ Ñ‚Ð°ÐºÐ¸Ð¼ именем уже ÑущеÑтвует в рабочем лиÑте \n" "Удалите файл в другом рабочем лиÑте, прежде чем Ñоздавать ÑвÑзанную копию." #: flask_version/worksheet.py:720 #, python-format msgid "" " Return to Upload or Create Data " "File or %(worksheet_name)s." msgstr "" "ВернутьÑÑ Ðº Загрузить или Ñоздать файл данных или %(worksheet_name)s." #: flask_version/worksheet.py:724 #, python-format msgid "Error uploading file (missing field \"file\"). %(backlinks)s" msgstr "Ошибка при загрузке файла (отÑутÑтвует файл fileField). %(backlinks)s" #: flask_version/worksheet.py:731 #, python-format msgid "Error uploading file (missing %(field)s arg).%(backlinks)s" msgstr "Ошибка при загрузке файла (отÑутÑтвует аргумент %(field)s). %(backlinks)s" #: flask_version/worksheet.py:744 #, python-format msgid "Error uploading file (missing filename).%(backlinks)s" msgstr "Ошибка при загрузке файла (отÑутÑтвует Ð¸Ð¼Ñ Ñ„Ð°Ð¹Ð»Ð°). %(backlinks)s" #: flask_version/worksheet.py:752 #, python-format msgid "URL must start with http, https, or ftp.%(backlinks)s" msgstr "URL должен начинатьÑÑ Ñ http, https, или ftp. %(backlinks)s" #: flask_version/worksheet.py:759 #, python-format msgid "" "Suspicious filename \"%(filename)s\" encountered uploading " "file.%(backlinks)s" msgstr "" "Подозрительное Ð¸Ð¼Ñ Ñ„Ð°Ð¹Ð»Ð° \"%(filename)s\" обнаружено при загрузке файла. " "%(backlinks)s" #: flask_version/worksheet.py:874 msgid "No such worksheet." msgstr "Запрошенный рабочий лиÑÑ‚ не найден." #: flask_version/worksheet.py:959 msgid "Document does not exist." msgstr "Документ не ÑущеÑтвует" #: flask_version/worksheet_listing.py:57 msgid "Error displaying worksheet listing." msgstr "Ошибка при отображении ÑпиÑка рабочих лиÑтов" #: flask_version/worksheet_listing.py:176 msgid "Requested public worksheet does not exist" msgstr "Запрошеный опубликованный рабочий лиÑÑ‚ не ÑущеÑтвует" #: flask_version/worksheet_listing.py:295 #, python-format msgid "" "This Sage notebook is not configured to load worksheets from 'https' " "URLs. Try a different URL or download the worksheet and upload it " "directly from your computer.\n" "%(backlinks)s" msgstr "" "Этот Sage Notebook-Ñервер не наÑтроен Ð´Ð»Ñ Ð·Ð°Ð³Ñ€ÑƒÐ·ÐºÐ¸ рабочих лиÑтов из URL," " начинающихÑÑ Ñ 'https'.Попробуйте другой URL или Ñкачайте файл рабочего " "лиÑта, а потом загрузите его непоÑредÑтвенно Ñо Ñвоего компьютера.\n" "%(backlinks)s" #: flask_version/worksheet_listing.py:357 msgid "" "Return to Upload" " File." msgstr "" "ВернутьÑÑ Ðº Загрузить файл." #: flask_version/worksheet_listing.py:380 #, python-format msgid "" "Please specify a worksheet to load.\n" "%(backlinks)s" msgstr "ПожалуйÑта, укажите рабочий лиÑÑ‚ Ð´Ð»Ñ Ð·Ð°Ð³Ñ€ÑƒÐ·ÐºÐ¸. %(backlinks)s" #: flask_version/worksheet_listing.py:384 #, python-format msgid "" "Invalid filename.\n" "%(backlinks)s" msgstr "" "Ðеверное Ð¸Ð¼Ñ Ñ„Ð°Ð¹Ð»Ð°.\n" "%(backlinks)s" #: flask_version/worksheet_listing.py:425 #, python-format msgid "" "There was an error uploading the worksheet. It could be an old " "unsupported format or worse. If you desperately need its contents " "contact the sage-" "support group and post a link to your worksheet. Alternatively, an " "sws file is just a bzip2 tarball; take a look inside!\n" "%(backlinks)s" msgstr "" "Возникла ошибка при загружке рабочего лиÑта. Возможно, Ñто Ñтарый " "неподдерживаемый формат или того хуже. ЕÑли вам вÑÑ‘ же очень нужно " "Ñодержание Ñтого файла, напишите в группу sage-" "support и дайте ÑÑылку на ваш рабочий лиÑÑ‚. Как вариант, попробуйте " "взглÑнуть внутрь файла Ñами: sws файл — Ñто проÑто текÑтовой файл в " "tar-архиве, Ñжатом bzip2!\n" "%(backlinks)s" #: flask_version/worksheet_listing.py:436 #, python-format msgid "Error uploading worksheet '%(msg)s'.%(backlinks)s" msgstr "Ошибка при загрузке рабочего лиÑта '%(msg)s'. %(backlinks)s" #: ../sagenb/data/sage/html/base.html:33 ../sagenb/data/sage/html/login.html:35 msgid "The Sage Notebook" msgstr "Sage Notebook" #: ../sagenb/data/sage/html/base.html:35 msgid "Searching for Sage server..." msgstr "ПоиÑк Ñервера Sage..." #: ../sagenb/data/sage/html/base.html:37 msgid "Version" msgstr "ВерÑиÑ" #: ../sagenb/data/sage/html/base_authenticated.html:7 msgid "Please log in to the Sage notebook" msgstr "ПожалуйÑта, войдите в Sage Notebook" #: ../sagenb/data/sage/html/base_authenticated.html:7 msgid "Log in" msgstr "Войти" #: ../sagenb/data/sage/html/base_authenticated.html:9 msgid "Toggle the top bar" msgstr "Переключить верхнюю панель" #: ../sagenb/data/sage/html/base_authenticated.html:9 #: ../sagenb/data/sage/html/test_report.html:123 msgid "Toggle" msgstr "Переключить" #: ../sagenb/data/sage/html/base_authenticated.html:10 msgid "Back to your personal worksheet list" msgstr "ВернутьÑÑ Ðº ÑпиÑку ваших рабочих лиÑтов" #: ../sagenb/data/sage/html/base_authenticated.html:10 msgid "Home" msgstr "Домой" #: ../sagenb/data/sage/html/base_authenticated.html:12 #: ../sagenb/data/sage/html/base_authenticated.html:14 msgid "Published" msgstr "Опубликованные" #: ../sagenb/data/sage/html/base_authenticated.html:14 msgid "Browse the published worksheets" msgstr "ПоÑмотреть опубликованные рабочие лиÑты" #: ../sagenb/data/sage/html/base_authenticated.html:15 msgid "View a log of recent computations" msgstr "ПоÑмотреть иÑторию поÑледних вычиÑлений" #: ../sagenb/data/sage/html/base_authenticated.html:17 msgid "Change account settings including password" msgstr "Изменить наÑтройки аккаунта, Ð²ÐºÐ»ÑŽÑ‡Ð°Ñ Ð¿Ð°Ñ€Ð¾Ð»ÑŒ" #: ../sagenb/data/sage/html/base_authenticated.html:17 msgid "Settings" msgstr "ÐаÑтройки" #: ../sagenb/data/sage/html/base_authenticated.html:18 msgid "Documentation" msgstr "ДокументациÑ" #: ../sagenb/data/sage/html/base_authenticated.html:18 msgid "Help" msgstr "Помощь" #: ../sagenb/data/sage/html/base_authenticated.html:19 msgid "Report a problem or submit a bug to improve Sage" msgstr "Сообщить о проблеме или отправить отчёт об ошибке, Ð´Ð»Ñ ÑƒÐ»ÑƒÑ‡ÑˆÐµÐ½Ð¸Ñ Sage" #: ../sagenb/data/sage/html/base_authenticated.html:19 msgid "Report a Problem" msgstr "Сообщить об ошибке" #: ../sagenb/data/sage/html/base_authenticated.html:20 msgid "Log out of the Sage notebook" msgstr "Выйти из Sage notebook" #: ../sagenb/data/sage/html/base_authenticated.html:20 msgid "Sign out" msgstr "Выйти" #: ../sagenb/data/sage/html/docs.html:3 msgid "Sage Documentation" msgstr "Ð”Ð¾ÐºÑƒÐ¼ÐµÐ½Ñ‚Ð°Ñ†Ð¸Ñ Ð¿Ð¾ Sage" #: ../sagenb/data/sage/html/docs.html:15 msgid "To quickly try out Sage start here" msgstr "Чтобы быÑтро попробовать Sage, начните здеÑÑŒ" #: ../sagenb/data/sage/html/docs.html:15 msgid "Tutorial" msgstr "ПрактичеÑкое руководÑтво" #: ../sagenb/data/sage/html/docs.html:16 msgid "Explore a collection of in-depth tutorials on specific topics" msgstr "ПроÑмотреть коллекцию подробных практичеÑких руководÑтв по отдельным облаÑÑ‚Ñм" #: ../sagenb/data/sage/html/docs.html:16 msgid "Thematic Tutorials" msgstr "ТематичеÑкие практичеÑкое руководÑтва" #: ../sagenb/data/sage/html/docs.html:17 msgid "View a 4000+ page reference manual about Sage" msgstr "ПроÑмотреть 4000+ Ñтраниц руководÑтва Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ Sage" #: ../sagenb/data/sage/html/docs.html:17 msgid "Reference Manual" msgstr "РуководÑтво пользователÑ" #: ../sagenb/data/sage/html/docs.html:18 msgid "Learn to write Sage programs" msgstr "ÐаучитьÑÑ Ð¿Ð¸Ñать программы на Sage" #: ../sagenb/data/sage/html/docs.html:18 msgid "Developer Guide" msgstr "РуководÑтво разработчика" #: ../sagenb/data/sage/html/docs.html:19 msgid "How do I construct ... in Sage?" msgstr "Как мне Ñоздать ... в Sage?" #: ../sagenb/data/sage/html/docs.html:19 msgid "Constructions" msgstr "Программные конÑтрукции" #: ../sagenb/data/sage/html/docs.html:22 msgid "Static version..." msgstr "СтатичеÑÐºÐ°Ñ Ð²ÐµÑ€ÑиÑ..." #: ../sagenb/data/sage/html/docs.html:22 msgid "Fast Static Versions of the Documentation" msgstr "БыÑÑ‚Ñ€Ð°Ñ ÑтатичеÑÐºÐ°Ñ Ð²ÐµÑ€ÑÐ¸Ñ Ð´Ð¾ÐºÑƒÐ¼ÐµÐ½Ñ‚Ð°Ñ†Ð¸Ð¸" #: ../sagenb/data/sage/html/docs.html:23 msgid "Help via Internet Chat (IRC)" msgstr "Помощь на канале IRC (интернет чат)" #: ../sagenb/data/sage/html/docs.html:29 msgid "How to use the Sage Notebook" msgstr "Как иÑпользовать Sage Notebook" #: ../sagenb/data/sage/html/docs.html:31 msgid "A worksheet is an ordered list of Sage calculations with output." msgstr "" "Рабочий лиÑÑ‚ — Ñто упорÑдоченый ÑпиÑок вычиÑлений Sage Ñ " "результатами." #: ../sagenb/data/sage/html/docs.html:32 msgid "A session is a worksheet and a set of variables in some state." msgstr "" "СеÑÑÐ¸Ñ â€” Ñто рабочий лиÑÑ‚ и набор переменных в некотором " "ÑоÑтоÑнии." #: ../sagenb/data/sage/html/docs.html:33 msgid "" "The Sage notebook is a collection of worksheets, saved objects, " "and user information." msgstr "" "Sage notebook — Ñто ÐºÐ¾Ð»Ð»ÐµÐºÑ†Ð¸Ñ Ñ€Ð°Ð±Ð¾Ñ‡Ð¸Ñ… лиÑтов, Ñохранённых " "объектов и пользовательÑкой информации." #: ../sagenb/data/sage/html/docs.html:46 msgid "" "The Sage Notebook was primarily written by William Stein with substantial" " contributions from Tom Boothby, Timothy Clemans, Alex Clemesha, Mike " "Hansen, Bobby Moretti, Yi Qiang, and Dorian Raymer." msgstr "" "Sage Notebook был изначально Ñоздан William Stein, Ñ ÑущеÑтвенным вкладом Tom " "Boothby, Timothy Clemans, Alex Clemesha, Mike Hansen, Bobby Moretti, Yi " "Qiang и Dorian Raymer." #: ../sagenb/data/sage/html/error_message.html:19 msgid "Continue" msgstr "Продолжить" #: ../sagenb/data/sage/html/history.html:3 #, python-format msgid "Sage: History for %(u)s" msgstr "Sage: ИÑÑ‚Ð¾Ñ€Ð¸Ñ Ð´Ð»Ñ %(u)s" #: ../sagenb/data/sage/html/history.html:13 msgid "Click here to turn the above into a Sage worksheet" msgstr "Щёлкните здеÑÑŒ, чтобы открыть Ñту программу как рабочий лиÑÑ‚ Sage" #: ../sagenb/data/sage/html/history.html:13 msgid "" "Create a new Sage worksheet version of the last 100 commands in the above" " log." msgstr "Создать новый рабочий лиÑÑ‚ из поÑледних 100 команд приведённой иÑтории" #: ../sagenb/data/sage/html/login.html:12 msgid "username" msgstr "Ð¸Ð¼Ñ Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ" #: ../sagenb/data/sage/html/login.html:13 msgid "Select an OpenID provider" msgstr "Выберите провайдера OpenID" #: ../sagenb/data/sage/html/login.html:14 msgid "Send" msgstr "Отправить" #: ../sagenb/data/sage/html/login.html:22 #: ../sagenb/data/sage/html/login.html:84 msgid "Sign in" msgstr "Войти" #: ../sagenb/data/sage/html/login.html:28 #, python-format msgid "Congratulations %(u)s! You can now sign into the Sage Notebook." msgstr "ПоздравлÑем %(u)s! Теперь вы можете войти в Sage Notebook." #: ../sagenb/data/sage/html/login.html:32 msgid "Welcome!" msgstr "Добро пожаловать!" #: ../sagenb/data/sage/html/login.html:33 msgid "Sage is a different approach to mathematics software." msgstr "" "Sage — Ñто другой подход к математичеÑкому программному " "обеÑпечению." #: ../sagenb/data/sage/html/login.html:36 msgid "" "With the Sage Notebook anyone can create, collaborate on, and publish " "interactive worksheets. In a worksheet, one can write code using Sage, " "Python, and other software included in Sage." msgstr "" "При помощи Sage Notebook можно Ñоздавать интерактивные рабочие лиÑты, " "ÑовмеÑтно работать над ними и публиковать их. Ð’ рабочем лиÑте можно " "пиÑать код на Sage, Pyhton и других программах, включённых в Sage." #: ../sagenb/data/sage/html/login.html:39 msgid "General and Advanced Pure and Applied Mathematics" msgstr "ПроÑÑ‚Ð°Ñ Ð¸ выÑшаÑ, чиÑÑ‚Ð°Ñ Ð¸ Ð¿Ñ€Ð¸ÐºÐ»Ð°Ð´Ð½Ð°Ñ Ð¼Ð°Ñ‚ÐµÐ¼Ð°Ñ‚Ð¸ÐºÐ°" #: ../sagenb/data/sage/html/login.html:40 msgid "" "Use Sage for studying calculus, elementary to very advanced number " "theory, cryptography, commutative algebra, group theory, graph theory, " "numerical and exact linear algebra, and more." msgstr "" "ИÑпользуйте Sage Ð´Ð»Ñ Ð¸Ð·ÑƒÑ‡ÐµÐ½Ð¸Ñ Ð¼Ð°Ñ‚ÐµÐ¼Ð°Ñ‚Ð¸Ñ‡ÐµÑкого анализа, Ñлементарной и " "продвинутой теории чиÑел, криптографии, коммутативной алгебры, теории " "групп, теории графов, клаÑÑичеÑкой и чиÑленной линейной алгебры и многого" " другого." #: ../sagenb/data/sage/html/login.html:43 msgid "Use an Open Source Alternative" msgstr "ИÑпользуйте Ñвободную альтернативу" #: ../sagenb/data/sage/html/login.html:44 msgid "" "By using Sage you help to support a viable open source alternative to " "Magma, Maple, Mathematica, and MATLAB. Sage includes many high-quality " "open source math packages." msgstr "" "ИÑÐ¿Ð¾Ð»ÑŒÐ·ÑƒÑ Sage, вы помогаете поддерживать жизнеÑпоÑобную альтернативу " "Magma, Maple, Mathematica и MATLAB Ñ Ð¾Ñ‚ÐºÑ€Ñ‹Ñ‚Ñ‹Ð¼ иÑходным кодом. Sage " "включает множеÑтво выÑококачеÑтвенных пакетов математичеÑких программ Ñ " "открытым иÑходным кодом." #: ../sagenb/data/sage/html/login.html:47 msgid "Use Most Mathematics Software from Within Sage" msgstr "ИÑпользуйте большинÑтво математичеÑких программ прÑмо из Sage" #: ../sagenb/data/sage/html/login.html:48 msgid "" "Sage makes it easy for you to use most mathematics software together. " "Sage includes GAP, GP/PARI, Maxima, and Singular, and dozens of other " "open packages." msgstr "" "С помощью Sage очень проÑто иÑпользовать большинÑтво математичеÑких программ " "вмеÑте. Sage включает в ÑÐµÐ±Ñ GAP, GP/PARI, Maxima, Singular и дюжины " "других открытых пакетов программного обеÑпечениÑ." #: ../sagenb/data/sage/html/login.html:51 msgid "Use a Mainstream Programming Language" msgstr "ИÑпользуйте Ñовременный широко " "раÑпроÑтраненный Ñзык программированиÑ" #: ../sagenb/data/sage/html/login.html:52 msgid "" "You work with Sage using the highly regarded scripting language Python. " "You can write programs that combine serious mathematics with anything " "else." msgstr "" "Ð’ Sage вы работаете Ñ Ð¸Ñпользованием хорошо зарекомендовашего ÑÐµÐ±Ñ " "Ñкриптового Ñзыка Python. Ð’Ñ‹ можете пиÑать программы, в которых ÑерьёзнаÑ" " математика Ñовмещена Ñ Ñ‡ÐµÐ¼ угодно." #: ../sagenb/data/sage/html/login.html:55 msgid "Acknowledgement" msgstr "БлагодарноÑти" #: ../sagenb/data/sage/html/login.html:56 msgid "" "The Sage Notebook is based upon work supported by the National Science " "Foundation under grants DMS-0821725, DMS-1020378, DMS-0713225, " "DMS-0555776, DMS-0545904, DMS-0838212, DMS-0757627, DUE-1020378, " "DUE-1022574, DMS-1015114, etc. Any opinions, findings, and conclusions" " or recommendations expressed in this material are those of the author(s)" " and do not necessarily reflect the views of the National Science " "Foundation. See also http://sagemath.org/development-ack.html." msgstr "" "Sage Notebook оÑнован на работе, поддерживаемой National Science " "Foundation в рамках грантов DMS-0821725, DMS-1020378, DMS-0713225, " "DMS-0555776, DMS-0545904, DMS-0838212, DMS-0757627, DUE-1020378, " "DUE-1022574, DMS-1015114, и др. Любые мнениÑ, находки, оценки или " "рекомендации предÑтавленные здеÑÑŒ ÑвлÑÑŽÑ‚ÑÑ Ñ‡Ð°Ñтным мнением автора(ов) и " "могут не Ñовпадать Ñо взглÑдами National Science Foundation. См. также " "http://sagemath.org" "/development-ack.html." #: ../sagenb/data/sage/html/login.html:66 #: ../sagenb/data/sage/html/accounts/account_recovery.html:13 msgid "Username" msgstr "Ð˜Ð¼Ñ Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ" #: ../sagenb/data/sage/html/login.html:69 msgid "Username is not in the system" msgstr "Ð˜Ð¼Ñ Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ Ð½Ðµ найдено в ÑиÑтеме" #: ../sagenb/data/sage/html/login.html:73 #: ../sagenb/data/sage/html/settings/user_management.html:13 msgid "Password" msgstr "Пароль" #: ../sagenb/data/sage/html/login.html:76 msgid "Wrong password" msgstr "Ðеверный пароль" #: ../sagenb/data/sage/html/login.html:80 msgid "Remember me" msgstr "Помнить менÑ" #: ../sagenb/data/sage/html/login.html:89 msgid "Sign up for a new Sage Notebook account" msgstr "ЗарегиÑтрировать новый аккаунт в Sage Notebook" #: ../sagenb/data/sage/html/login.html:93 msgid "Browse published Sage worksheets
    (no login required)" msgstr "ПроÑмотреть опубликованные рабочие лиÑты
    (региÑÑ‚Ñ€Ð°Ñ†Ð¸Ñ Ð½Ðµ требуетÑÑ)" #: ../sagenb/data/sage/html/login.html:97 msgid "Forgot password" msgstr "Забыли пароль" #: ../sagenb/data/sage/html/login.html:104 msgid "Creating new users is disabled by the administrator." msgstr "Ð¡Ð¾Ð·Ð´Ð°Ð½Ð¸Ñ Ð½Ð¾Ð²Ñ‹Ñ… пользователей запрещено админиÑтратором" #: ../sagenb/data/sage/html/login.html:106 msgid "Javascript must be enabled in order to use the Sage Notebook." msgstr "Ð”Ð»Ñ Ñ€Ð°Ð±Ð¾Ñ‚Ñ‹ Sage Notebook должне быть включён Javascript." #: ../sagenb/data/sage/html/source_code.html:3 #: ../sagenb/notebook/tutorial.py:358 msgid "Source Code" msgstr "ИÑходный код" #: ../sagenb/data/sage/html/source_code.html:13 msgid "Sage Source Browser" msgstr "Браузер иÑходного кода" #: ../sagenb/data/sage/html/source_code.html:14 msgid "browse directory" msgstr "проÑмотр директории" #: ../sagenb/data/sage/html/test_report.html:79 msgid "Sage Notebook version" msgstr "ВерÑÐ¸Ñ Sage Notebook" #: ../sagenb/data/sage/html/test_report.html:85 msgid "Sage version" msgstr "ВерÑÐ¸Ñ Sage" #: ../sagenb/data/sage/html/test_report.html:91 msgid "Environment" msgstr "Окружение" #: ../sagenb/data/sage/html/test_report.html:96 msgid "Start" msgstr "Старт" #: ../sagenb/data/sage/html/test_report.html:100 #: ../sagenb/data/sage/html/worksheet_listing.html:127 msgid "Stop" msgstr "Стоп" #: ../sagenb/data/sage/html/test_report.html:104 msgid "Elapsed" msgstr "Затрачено" #: ../sagenb/data/sage/html/test_report.html:108 msgid "Status" msgstr "СтатуÑ" #: ../sagenb/data/sage/html/test_report.html:110 #: ../sagenb/data/sage/html/test_report.html:129 msgid "Pass" msgstr "Пройдено" #: ../sagenb/data/sage/html/test_report.html:111 #: ../sagenb/data/sage/html/test_report.html:130 msgid "Fail" msgstr "Сбой" #: ../sagenb/data/sage/html/test_report.html:113 msgid "Total" msgstr "Ð’Ñего" #: ../sagenb/data/sage/html/test_report.html:121 msgid "Hide" msgstr "Скрыть" #: ../sagenb/data/sage/html/test_report.html:122 msgid "Show" msgstr "Показать" #: ../sagenb/data/sage/html/test_report.html:128 msgid "Cases / Tests" msgstr "ТеÑты" #: ../sagenb/data/sage/html/test_report.html:132 msgid "Count" msgstr "ПодÑчёт" #: ../sagenb/data/sage/html/test_report.html:141 msgid "Totals" msgstr "Итоги" #: ../sagenb/data/sage/html/worksheet_listing.html:9 msgid "Published Worksheets" msgstr "Опубликованные рабочие лиÑты" #: ../sagenb/data/sage/html/worksheet_listing.html:11 msgid "Deleted Worksheets" msgstr "Удалённые рабочие лиÑты" #: ../sagenb/data/sage/html/worksheet_listing.html:13 msgid "Active Worksheets" msgstr "Ðктивные рабочие лиÑты" #: ../sagenb/data/sage/html/worksheet_listing.html:15 msgid "Archived Worksheets" msgstr "Ðрхивированные рабочие лиÑты" #: ../sagenb/data/sage/html/worksheet_listing.html:99 msgid "New Worksheet" msgstr "Ðовый рабочий лиÑÑ‚" #: ../sagenb/data/sage/html/worksheet_listing.html:100 msgid "Upload" msgstr "Импортировать" #: ../sagenb/data/sage/html/worksheet_listing.html:101 msgid "Download All Active" msgstr "Сохранить вÑе выделенные" #: ../sagenb/data/sage/html/worksheet_listing.html:108 msgid "Search Worksheets" msgstr "ПоиÑк рабочих лиÑтов" #: ../sagenb/data/sage/html/worksheet_listing.html:116 msgid "Unarchive selected worksheets so it appears in the default worksheet list" msgstr "" "Разархивировать выбранные рабочие лиÑты, чтобы они поÑвилиÑÑŒ на домашней " "Ñтранице" #: ../sagenb/data/sage/html/worksheet_listing.html:116 msgid "Unarchive" msgstr "Разархивировать" #: ../sagenb/data/sage/html/worksheet_listing.html:118 msgid "" "Archive selected worksheets so they do not appear in the default " "worksheet list" msgstr "" "Ðрхивировать выбранные рабочие лиÑты, чтобы они не поÑвлÑлиÑÑŒ на домашней" " Ñтранице" #: ../sagenb/data/sage/html/worksheet_listing.html:118 msgid "Archive" msgstr "Ðрхивировать" #: ../sagenb/data/sage/html/worksheet_listing.html:122 msgid "Move the selected worksheets to the trash" msgstr "ПеремеÑтить выделенные рабочие лиÑты в корзину" #: ../sagenb/data/sage/html/worksheet_listing.html:122 msgid "Delete" msgstr "Удалить" #: ../sagenb/data/sage/html/worksheet_listing.html:124 msgid "Move the selected worksheets out of the trash" msgstr "ВоÑÑтановить выделенные рабочие лиÑты из корзины" #: ../sagenb/data/sage/html/worksheet_listing.html:124 msgid "Undelete" msgstr "ВоÑÑтановить" #: ../sagenb/data/sage/html/worksheet_listing.html:127 msgid "Stop selected worksheets" msgstr "ОÑтановить выделенные рабочие лиÑты" #: ../sagenb/data/sage/html/worksheet_listing.html:128 msgid "Download selected worksheets" msgstr "Загрузить выделенные рабочие лиÑты" #: ../sagenb/data/sage/html/worksheet_listing.html:128 msgid "Download" msgstr "ЭкÑпортировать" #: ../sagenb/data/sage/html/worksheet_listing.html:131 msgid "Current Folder" msgstr "Ð¢ÐµÐºÑƒÑ‰Ð°Ñ Ð¿Ð°Ð¿ÐºÐ°" #: ../sagenb/data/sage/html/worksheet_listing.html:132 msgid "Active" msgstr "Ðктивные" #: ../sagenb/data/sage/html/worksheet_listing.html:133 msgid "Archived" msgstr "Ðрхивированные" #: ../sagenb/data/sage/html/worksheet_listing.html:134 msgid "Trash" msgstr "Корзина" #: ../sagenb/data/sage/html/worksheet_listing.html:138 msgid "Empty Trash" msgstr "ОчиÑтить корзину" #: ../sagenb/data/sage/html/worksheet_listing.html:153 #: ../sagenb/data/sage/html/worksheet/ratings_info.html:9 msgid "Rating" msgstr "Оценка" #: ../sagenb/data/sage/html/worksheet_listing.html:164 msgid "Owner" msgstr "Владелец" #: ../sagenb/data/sage/html/worksheet_listing.html:164 msgid "Collaborators" msgstr "Соавторы" #: ../sagenb/data/sage/html/worksheet_listing.html:170 #: ../sagenb/data/sage/html/notebook/worksheet_revision_list.html:16 msgid "Last Edited" msgstr "ПоÑледнее изменение" #: ../sagenb/data/sage/html/worksheet_listing.html:180 msgid "There are no published worksheets." msgstr "Ðет опубликованных рабочих лиÑтов" #: ../sagenb/data/sage/html/worksheet_listing.html:186 msgid "" "Welcome to Sage! You can create a new " "worksheet, view published worksheets, or read " "the documentation." msgstr "" "Добро пожаловать в Sage! Ð’Ñ‹ можете Ñоздать " "новый рабочий лиÑÑ‚, проÑмотреть опубликованные " "рабочие лиÑты, или почитать документацию." #: ../sagenb/data/sage/html/worksheet_listing.html:228 msgid "running" msgstr "запущен" #: ../sagenb/data/sage/html/worksheet_listing.html:261 msgid "Add or Delete" msgstr "Добавить или удалить" #: ../sagenb/data/sage/html/worksheet_listing.html:263 msgid "Share now" msgstr "ПоделитьÑÑ" #: ../sagenb/data/sage/html/worksheet_listing.html:268 msgid "published" msgstr "опубликовано" #: ../sagenb/data/sage/html/accounts/account_recovery.html:3 #: ../sagenb/data/sage/html/accounts/account_recovery.html:8 msgid "Account Recovery" msgstr "ВоÑÑтановление паролÑ" #: ../sagenb/data/sage/html/accounts/account_recovery.html:9 msgid "" "A new password will be emailed to the email address connected to your " "account. However if you didn't confirm your email address you will be " "unable to recover your account." msgstr "" "Ðовый пароль будет отправлен на email, указанный в вашем аккаунте. " "Однако, еÑли вы не подтвердили Ð°Ð´Ñ€ÐµÑ Ñлектронной почты, то вы не Ñможете " "воÑÑтановить Ñвой аккаунт." #: ../sagenb/data/sage/html/accounts/account_recovery.html:17 msgid "Submit" msgstr "Отправить" #: ../sagenb/data/sage/html/accounts/account_recovery.html:17 #: ../sagenb/data/sage/html/accounts/registration.html:83 #: ../sagenb/data/sage/html/notebook/download_or_delete_datafile.html:54 #: ../sagenb/data/sage/html/notebook/edit_window.html:12 #: ../sagenb/data/sage/html/settings/account_settings.html:10 #: ../sagenb/data/sage/html/settings/account_settings.html:75 #: ../sagenb/data/sage/html/settings/admin_add_user.html:26 #: ../sagenb/data/sage/html/settings/notebook_settings.html:20 #: ../sagenb/data/sage/html/settings/notebook_settings.html:27 msgid "Cancel" msgstr "Отменить" #: ../sagenb/data/sage/html/accounts/registration.html:3 msgid "Sign up" msgstr "Войти" #: ../sagenb/data/sage/html/accounts/registration.html:9 msgid "Sign up for a Sage Notebook account" msgstr "ЗарегиÑтрировать новую учётную запиÑÑŒ в Sage Notebook" #: ../sagenb/data/sage/html/accounts/registration.html:16 msgid "Create a username" msgstr "Выберите Ð¸Ð¼Ñ Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ" #: ../sagenb/data/sage/html/accounts/registration.html:17 msgid "" "Your username must start with a letter and be between 3 and 64 characters" " long. You may only use letters, numbers, underscores, @, and dots." msgstr "" "Ваше Ð¸Ð¼Ñ Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ Ð´Ð¾Ð»Ð¶Ð½Ð¾ начинатьÑÑ Ñ Ð±ÑƒÐºÐ²Ñ‹ и быть не короче 3 и не " "длиннее 64 Ñимволов. Можно иÑпользовать только буквы, цифры, знаки " "подчёркиваниÑ, @ и точки." #: ../sagenb/data/sage/html/accounts/registration.html:22 msgid "No username given" msgstr "Ð˜Ð¼Ñ Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ Ð½Ðµ указано" #: ../sagenb/data/sage/html/accounts/registration.html:25 msgid "Username already in use" msgstr "Пользователь Ñ Ñ‚Ð°ÐºÐ¸Ð¼ именем уже зарегиÑтрирован" #: ../sagenb/data/sage/html/accounts/registration.html:28 msgid "Bad username" msgstr "ÐеподходÑщее Ð¸Ð¼Ñ Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ" #: ../sagenb/data/sage/html/accounts/registration.html:32 msgid "Create a good password" msgstr "Выберите хороший пароль" #: ../sagenb/data/sage/html/accounts/registration.html:34 msgid "" "Your password must have at least 4 characters. Your password can not " "contain your username or spaces." msgstr "" "Пароль должен быть не короче 4 Ñимволов. Пароль не может " "Ñодержать Ð¸Ð¼Ñ Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ Ð¸ пробелы." #: ../sagenb/data/sage/html/accounts/registration.html:39 msgid "No password given" msgstr "Пароль не был введён" #: ../sagenb/data/sage/html/accounts/registration.html:42 msgid "Bad password" msgstr "ÐеподходÑщий пароль" #: ../sagenb/data/sage/html/accounts/registration.html:46 msgid "Re-type your password" msgstr "Ðаберите пароль ещё раз" #: ../sagenb/data/sage/html/accounts/registration.html:49 msgid "Passwords didn't match" msgstr "Пароли не Ñовпадают" #: ../sagenb/data/sage/html/accounts/registration.html:54 msgid "Enter your email address" msgstr "Введите ваш Ð°Ð´Ñ€ÐµÑ Ñлектронной почты" #: ../sagenb/data/sage/html/accounts/registration.html:56 msgid "" "Your email address is required for account confirmation and recovery. You" " will be emailed a confirmation link right after you successfully sign " "up." msgstr "" "Ваш Ð°Ð´Ñ€ÐµÑ Ñлектронной почты иÑпользуетÑÑ Ð´Ð»Ñ Ð¿Ð¾Ð´Ñ‚Ð²ÐµÑ€Ð¶Ð´ÐµÐ½Ð¸Ñ Ð°ÐºÐºÐ°ÑƒÐ½Ñ‚Ð° и его" " воÑÑÑ‚Ð°Ð½Ð¾Ð²Ð»ÐµÐ½Ð¸Ñ Ð² Ñлучае, еÑли вы забыли пароль. ПоÑле региÑтрации на " "Ñтот Ð°Ð´Ñ€ÐµÑ Ð²Ð°Ð¼ будет отправлена ÑÑылка Ð´Ð»Ñ ÐµÐ³Ð¾ подтверждениÑ." #: ../sagenb/data/sage/html/accounts/registration.html:62 msgid "No email address given" msgstr "ÐÐ´Ñ€ÐµÑ Ñлектронной почты не был введён" #: ../sagenb/data/sage/html/accounts/registration.html:65 msgid "Invalid email address" msgstr "Ðеверный Ð°Ð´Ñ€ÐµÑ Ñлектронной почты" #: ../sagenb/data/sage/html/accounts/registration.html:71 msgid "Answer a challenge" msgstr "Пройдите проверку" #: ../sagenb/data/sage/html/accounts/registration.html:74 msgid "No challenge response given" msgstr "Ð’Ñ‹ не заполнили проверочное поле" #: ../sagenb/data/sage/html/accounts/registration.html:77 msgid "Invalid challenge response" msgstr "Ðеверный ответ в проверочном поле" #: ../sagenb/data/sage/html/accounts/registration.html:82 msgid "Create account" msgstr "Создать учётную запиÑÑŒ" #: ../sagenb/data/sage/html/notebook/afterpublish_window.html:8 #, python-format msgid "" "Worksheet is publicly viewable at %(u)s" msgstr "" "Рабочий лиÑÑ‚ доÑтупен Ð´Ð»Ñ Ð¿Ñ€Ð¾Ñмотра вÑеми желающими по адреÑу %(u)s" #: ../sagenb/data/sage/html/notebook/afterpublish_window.html:9 #, python-format msgid "Published on %(t)s" msgstr "Опубликовано %(t)s" #: ../sagenb/data/sage/html/notebook/afterpublish_window.html:11 msgid "Re-publish worksheet" msgstr "Опубликовать Ñнова" #: ../sagenb/data/sage/html/notebook/afterpublish_window.html:12 msgid "Stop publishing" msgstr "Удалить из опубликованных" #: ../sagenb/data/sage/html/notebook/afterpublish_window.html:14 #: ../sagenb/data/sage/html/notebook/beforepublish_window.html:18 msgid "Automatically re-publish when changes are made" msgstr "ÐвтоматичеÑки обновлÑть опубликованную верÑию, когда внеÑены изменениÑ" #: ../sagenb/data/sage/html/notebook/base.html:78 msgid "Click to rename this worksheet" msgstr "Щёлкните, чтобы переименовать Ñтот рабочий лиÑÑ‚" #: ../sagenb/data/sage/html/notebook/base.html:81 msgid "last edited" msgstr "поÑледнее изменение" #: ../sagenb/data/sage/html/notebook/base.html:83 msgid "Someone else is viewing this worksheet" msgstr "Кто-то ещё проÑматривает Ñтот рабочий лиÑÑ‚" #: ../sagenb/data/sage/html/notebook/base.html:88 #: ../sagenb/data/sage/html/notebook/text_cell.html:48 msgid "Save changes" msgstr "Сохранить изменениÑ" #: ../sagenb/data/sage/html/notebook/base.html:88 #: ../sagenb/data/sage/html/settings/account_settings.html:9 #: ../sagenb/data/sage/html/settings/account_settings.html:74 #: ../sagenb/data/sage/html/settings/notebook_settings.html:19 #: ../sagenb/data/sage/html/settings/notebook_settings.html:26 msgid "Save" msgstr "Сохранить" #: ../sagenb/data/sage/html/notebook/base.html:88 msgid "Save changes and close window" msgstr "Сохранить Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ Ð¸ закрыть окно" #: ../sagenb/data/sage/html/notebook/base.html:88 msgid "Save & quit" msgstr "Сохранить и выйти" #: ../sagenb/data/sage/html/notebook/base.html:88 msgid "Discard changes to this worksheet" msgstr "Отменить Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ Ð² Ñтом рабочем лиÑте" #: ../sagenb/data/sage/html/notebook/base.html:88 msgid "Discard & quit" msgstr "Отменить и выйти" #: ../sagenb/data/sage/html/notebook/base.html:95 msgid "Select a file related function" msgstr "Выберите, что вы хотите Ñделать Ñ Ñ„Ð°Ð¹Ð»Ð¾Ð¼" #: ../sagenb/data/sage/html/notebook/base.html:95 msgid "File..." msgstr "Файл..." #: ../sagenb/data/sage/html/notebook/base.html:96 msgid "Load a new worksheet stored in a file" msgstr "Создать новый рабочий лиÑÑ‚, загрузив его из файла" #: ../sagenb/data/sage/html/notebook/base.html:96 msgid "Load worksheet from a file..." msgstr "Загрузить рабочий лиÑÑ‚ из файла..." #: ../sagenb/data/sage/html/notebook/base.html:97 msgid "Create a new worksheet" msgstr "Создать новый рабочий лиÑÑ‚" #: ../sagenb/data/sage/html/notebook/base.html:97 msgid "New worksheet" msgstr "Ðовый рабочий лиÑÑ‚" #: ../sagenb/data/sage/html/notebook/base.html:98 msgid "Save this worksheet to an sws file" msgstr "Сохранить Ñтот рабочий лиÑÑ‚ как файл sws" #: ../sagenb/data/sage/html/notebook/base.html:98 msgid "Save worksheet to a file..." msgstr "Сохранить рабочий лиÑÑ‚ в файл..." #: ../sagenb/data/sage/html/notebook/base.html:99 #: ../sagenb/data/sage/html/notebook/base.html:148 msgid "Print this worksheet" msgstr "Ðапечатать Ñтот рабочий лиÑÑ‚" #: ../sagenb/data/sage/html/notebook/base.html:99 #: ../sagenb/data/sage/html/notebook/base.html:148 msgid "Print" msgstr "Печать" #: ../sagenb/data/sage/html/notebook/base.html:100 msgid "Rename this worksheet" msgstr "Переименовать текущий рабочий лиÑÑ‚" #: ../sagenb/data/sage/html/notebook/base.html:100 #: ../sagenb/data/sage/js/translated-messages.js:11 msgid "Rename worksheet" msgstr "Переименовать рабочий лиÑÑ‚" #: ../sagenb/data/sage/html/notebook/base.html:101 msgid "Copy this worksheet" msgstr "Скопировать текущий рабочий лиÑÑ‚" #: ../sagenb/data/sage/html/notebook/base.html:101 msgid "Copy worksheet" msgstr "Скопировать рабочий лиÑÑ‚" #: ../sagenb/data/sage/html/notebook/base.html:102 msgid "Move this worksheet to the trash" msgstr "ПеремеÑтить Ñтот рабочий лиÑÑ‚ в корзину" #: ../sagenb/data/sage/html/notebook/base.html:102 msgid "Delete worksheet" msgstr "Удалить рабочий лиÑÑ‚" #: ../sagenb/data/sage/html/notebook/base.html:106 msgid "Select a worksheet function" msgstr "Выберите функцию ÑƒÐ¿Ñ€Ð°Ð²Ð»ÐµÐ½Ð¸Ñ Ñ€Ð°Ð±Ð¾Ñ‡Ð¸Ð¼ лиÑтом" #: ../sagenb/data/sage/html/notebook/base.html:106 msgid "Action..." msgstr "ДейÑтвие..." #: ../sagenb/data/sage/html/notebook/base.html:107 msgid "Interrupt currently running calculations, if possible" msgstr "Прервать выполнÑемые ÑÐµÐ¹Ñ‡Ð°Ñ Ð²Ñ‹Ñ‡Ð¸ÑлениÑ, еÑли возможно" #: ../sagenb/data/sage/html/notebook/base.html:107 msgid "Interrupt" msgstr "Прервать" #: ../sagenb/data/sage/html/notebook/base.html:108 msgid "Restart the worksheet process" msgstr "ПерезапуÑтить процеÑÑ Ñ€Ð°Ð±Ð¾Ñ‡ÐµÐ³Ð¾ лиÑта" #: ../sagenb/data/sage/html/notebook/base.html:108 msgid "Restart worksheet" msgstr "ПерезапуÑтить рабочий лиÑÑ‚" #: ../sagenb/data/sage/html/notebook/base.html:109 msgid "Quit the worksheet process" msgstr "Завершить процеÑÑ Ñ€Ð°Ð±Ð¾Ñ‡ÐµÐ³Ð¾ лиÑта" #: ../sagenb/data/sage/html/notebook/base.html:109 msgid "Save and quit worksheet" msgstr "Сохранить и закрыть рабочий лиÑÑ‚" #: ../sagenb/data/sage/html/notebook/base.html:111 msgid "Evaluate all input cells in the worksheet" msgstr "Выполнить вÑе Ñчейки ввода рабочего лиÑта" #: ../sagenb/data/sage/html/notebook/base.html:111 msgid "Evaluate All" msgstr "Выполнить вÑÑ‘" #: ../sagenb/data/sage/html/notebook/base.html:112 msgid "Hide all output" msgstr "Скрыть вÑе результаты" #: ../sagenb/data/sage/html/notebook/base.html:112 msgid "Hide All Output" msgstr "Скрыть вÑе результаты" #: ../sagenb/data/sage/html/notebook/base.html:113 msgid "Show all output" msgstr "Показать вÑе результаты" #: ../sagenb/data/sage/html/notebook/base.html:113 msgid "Show All Output" msgstr "Показать вÑе результаты" #: ../sagenb/data/sage/html/notebook/base.html:114 msgid "Delete all output" msgstr "Удалить вÑе результаты" #: ../sagenb/data/sage/html/notebook/base.html:114 msgid "Delete All Output" msgstr "Удалить вÑе результаты" #: ../sagenb/data/sage/html/notebook/base.html:116 msgid "Switch to single-cell mode" msgstr "ПереключитьÑÑ Ð² режим одной Ñчейки" #: ../sagenb/data/sage/html/notebook/base.html:116 msgid "One Cell Mode" msgstr "Режим одной Ñчейки" #: ../sagenb/data/sage/html/notebook/base.html:117 msgid "Switch to multi-cell mode" msgstr "ПереключитьÑÑ Ð² режим Ñо многими Ñчейками" #: ../sagenb/data/sage/html/notebook/base.html:117 msgid "Multi Cell Mode" msgstr "Режим многих Ñчеек" #: ../sagenb/data/sage/html/notebook/base.html:120 msgid "Select an attached file" msgstr "Выберите приложенный файл" #: ../sagenb/data/sage/html/notebook/base.html:120 msgid "Data..." msgstr "Данные..." #: ../sagenb/data/sage/html/notebook/base.html:121 msgid "Upload or create a data file in a wide range of formats" msgstr "" "Закачайте или Ñоздайте файл данных в одном из многочиÑленных " "поддерживаемых форматов" #: ../sagenb/data/sage/html/notebook/base.html:121 msgid "Upload or create file..." msgstr "Закачать или Ñоздать файл..." #: ../sagenb/data/sage/html/notebook/base.html:131 #, python-format msgid "Evaluate all input cells using %(i)s" msgstr "ВыполнÑть вÑе Ñчейки ввода, иÑÐ¿Ð¾Ð»ÑŒÐ·ÑƒÑ %(i)s" #: ../sagenb/data/sage/html/notebook/base.html:137 msgid "Enable/disable pretty_printing" msgstr "Разрешить/запретить pretty_printing (автоматичеÑкое форматирование вывода)" #: ../sagenb/data/sage/html/notebook/base.html:149 msgid "Interactively use this worksheet" msgstr "ИÑпользовать Ñтот рабочий лиÑÑ‚ интерактивно" #: ../sagenb/data/sage/html/notebook/base.html:149 msgid "Worksheet" msgstr "Рабочий лиÑÑ‚" #: ../sagenb/data/sage/html/notebook/base.html:150 msgid "Edit text version of this worksheet" msgstr "Редактировать текÑтовую верÑию Ñтого рабочего лиÑта" #: ../sagenb/data/sage/html/notebook/base.html:150 msgid "Edit" msgstr "Правка" #: ../sagenb/data/sage/html/notebook/base.html:151 msgid "View plain text version of this worksheet" msgstr "ПроÑмотреть текÑтовую верÑию Ñтого рабочего лиÑта" #: ../sagenb/data/sage/html/notebook/base.html:151 msgid "Text" msgstr "ТекÑÑ‚" #: ../sagenb/data/sage/html/notebook/base.html:152 msgid "View changes to this worksheet over time" msgstr "ПроÑмотреть Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ Ð² Ñтом рабочем лиÑте" #: ../sagenb/data/sage/html/notebook/base.html:152 msgid "Revisions" msgstr "ВерÑии" #: ../sagenb/data/sage/html/notebook/base.html:153 msgid "Let others edit this worksheet" msgstr "Разрешить другим людÑм редактировать Ñтот рабочий лиÑÑ‚" #: ../sagenb/data/sage/html/notebook/base.html:153 msgid "Share" msgstr "ПоделитьÑÑ" #: ../sagenb/data/sage/html/notebook/base.html:154 msgid "Make this worksheet publicly viewable" msgstr "Разрешить проÑматривать Ñтот лиÑÑ‚ вÑем желающим" #: ../sagenb/data/sage/html/notebook/base.html:154 msgid "Publish" msgstr "Опубликовать" #: ../sagenb/data/sage/html/notebook/base.html:162 msgid "Exit" msgstr "Выход" #: ../sagenb/data/sage/html/notebook/beforepublish_window.html:5 msgid "" "You can publish your worksheet to the Internet, where anyone will be able" " to access and view it online." msgstr "" "Ð’Ñ‹ можете опубликовать ваш рабочий лиÑÑ‚ в Интернет, где любой желающий " "Ñможет увидеть его онлайн." #: ../sagenb/data/sage/html/notebook/beforepublish_window.html:7 msgid "" "Your worksheet will be assigned a unique address (URL) that you can send " "to your friends and colleagues." msgstr "" "Вашему рабочему лиÑту будет приÑвоен уникальный Ð°Ð´Ñ€ÐµÑ (URL), который " "можно отправить друзьÑм или коллегам." #: ../sagenb/data/sage/html/notebook/beforepublish_window.html:9 msgid "Do you want to publish this worksheet?" msgstr "Хотите опубликовать Ñтот рабочий лиÑÑ‚?" #: ../sagenb/data/sage/html/notebook/beforepublish_window.html:14 msgid "Yes" msgstr "Да" #: ../sagenb/data/sage/html/notebook/beforepublish_window.html:15 msgid "No" msgstr "Ðет" #: ../sagenb/data/sage/html/notebook/cell.html:80 msgid "Click here or press shift-return to evaluate" msgstr "Щёлкните здеÑÑŒ или нажмите Shift+Enter, чтобы выполнить" #: ../sagenb/data/sage/html/notebook/cell.html:81 msgid "evaluate" msgstr "выполнить" #: ../sagenb/data/sage/html/notebook/download_or_delete_datafile.html:35 msgid "Data file" msgstr "Файл данных" #: ../sagenb/data/sage/html/notebook/download_or_delete_datafile.html:39 #, python-format msgid "" "You may download %(f)s or create a link to this " "file in worksheet " msgstr "" "Ð’Ñ‹ можете Ñкачать %(f)s или Ñоздать ÑÑылку на " "Ñтот файл в рабочем лиÑте" #: ../sagenb/data/sage/html/notebook/download_or_delete_datafile.html:40 msgid "select worksheet" msgstr "выберите рабочий лиÑÑ‚" #: ../sagenb/data/sage/html/notebook/download_or_delete_datafile.html:44 #, python-format msgid "" "or delete " "%(f)s." msgstr "" "или удалить " "%(f)s." #: ../sagenb/data/sage/html/notebook/download_or_delete_datafile.html:46 #, python-format msgid "" "Access %(f)s in this worksheet by typing DATA+'%(f)s'. Here DATA" " is a special variable that gives the exact path to all data files " "uploaded to this worksheet." msgstr "" "ИÑпользуйте %(f)s в Ñтом рабочем лиÑте, набрав DATA+'%(f)s'. " "ЗдеÑÑŒ DATA — Ñто ÑÐ¿ÐµÑ†Ð¸Ð°Ð»ÑŒÐ½Ð°Ñ Ð¿ÐµÑ€ÐµÐ¼ÐµÐ½Ð½Ð°Ñ, ÐºÐ¾Ñ‚Ð¾Ñ€Ð°Ñ Ñодержит полнуй путь ко " "вÑем файлам, приложенным к рабочему лиÑту." #: ../sagenb/data/sage/html/notebook/download_or_delete_datafile.html:54 #: ../sagenb/data/sage/html/notebook/edit_window.html:11 msgid "Save Changes" msgstr "Сохранить изменениÑ" #: ../sagenb/data/sage/html/notebook/edit_window.html:10 msgid "Edit plain text" msgstr "Редактировать как проÑтой текÑÑ‚" #: ../sagenb/data/sage/html/notebook/guest_worksheet_page.html:20 msgid "Edit this." msgstr "Редактирвоать Ñто." #: ../sagenb/data/sage/html/notebook/guest_worksheet_page.html:23 msgid "Log in to edit a copy." msgstr "Войдите, чтобы отредактировать копию." #: ../sagenb/data/sage/html/notebook/guest_worksheet_page.html:26 msgid "Edit a copy." msgstr "Редактировать копию." #: ../sagenb/data/sage/html/notebook/guest_worksheet_page.html:39 msgid "Download." msgstr "Скачать." #: ../sagenb/data/sage/html/notebook/guest_worksheet_page.html:45 #, python-format msgid "This page is rated %(wr).1f." msgstr "Оценка Ñтой Ñтраницы: %(wr).1f." #: ../sagenb/data/sage/html/notebook/guest_worksheet_page.html:54 msgid "leave a comment" msgstr "оÑтавить комментарий" #: ../sagenb/data/sage/html/notebook/guest_worksheet_page.html:55 msgid "Rerate" msgstr "Изменить оценку" #: ../sagenb/data/sage/html/notebook/guest_worksheet_page.html:55 msgid "Rate" msgstr "Оценить" #: ../sagenb/data/sage/html/notebook/guest_worksheet_page.html:59 msgid "Other published documents..." msgstr "Другие опубликованные документы..." #: ../sagenb/data/sage/html/notebook/plain_text_window.html:4 msgid "View plain text" msgstr "ПроÑмотреть как проÑтой текÑÑ‚" #: ../sagenb/data/sage/html/notebook/specific_revision.html:5 #, python-format msgid "Revision from %(ta)s ago" msgstr "Обновлено %(ta)s дней назад" #: ../sagenb/data/sage/html/notebook/specific_revision.html:5 msgid "Revision List" msgstr "СпиÑок изменений" #: ../sagenb/data/sage/html/notebook/specific_revision.html:12 msgid "Older" msgstr "Раньше" #: ../sagenb/data/sage/html/notebook/specific_revision.html:14 msgid "Oldest" msgstr "Самые ранние" #: ../sagenb/data/sage/html/notebook/specific_revision.html:18 msgid "Newer" msgstr "Ðовее" #: ../sagenb/data/sage/html/notebook/specific_revision.html:20 msgid "Newest" msgstr "ПоÑледние" #: ../sagenb/data/sage/html/notebook/specific_revision.html:23 msgid "Revert to this one" msgstr "Откатить к Ñтой верÑии" #: ../sagenb/data/sage/html/notebook/specific_revision.html:23 msgid "(note that images are not recorded)" msgstr "(обратите внимание, что Ð¸Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð¸Ñ Ð½Ðµ запиÑаны)" #: ../sagenb/data/sage/html/notebook/specific_revision.html:24 msgid "Publish this one" msgstr "Опубликовать Ñту верÑию" #: ../sagenb/data/sage/html/notebook/text_cell.html:49 msgid "Cancel changes" msgstr "Отменить изменениÑ" #: ../sagenb/data/sage/html/notebook/upload_data_window.html:7 #, python-format msgid "Upload or Create Data File to attach to worksheet \"%(wn)s\"" msgstr "" "Закачать или Ñоздать файл данных и приложить его к рабочему лиÑту " "\"%(wn)s\"" #: ../sagenb/data/sage/html/notebook/upload_data_window.html:15 msgid "Browse your computer to select a file to upload:" msgstr "Выберите файл на вашем компьютере Ð´Ð»Ñ Ð·Ð°ÐºÐ°Ñ‡ÐºÐ¸:" #: ../sagenb/data/sage/html/notebook/upload_data_window.html:19 msgid "Or enter the URL of a file on the web:" msgstr "Или введите URL файла из Cети:" #: ../sagenb/data/sage/html/notebook/upload_data_window.html:23 msgid "Or enter the name of a new file, which will be created:" msgstr "Или введите Ð¸Ð¼Ñ Ð½Ð¾Ð²Ð¾Ð³Ð¾ файла, который будет Ñоздан:" #: ../sagenb/data/sage/html/notebook/upload_data_window.html:27 msgid "What do you want to call it? (if different than the original name)" msgstr "Как вы хотите назвать его? (еÑли хотите изменить имÑ, запиÑанное в файле)" #: ../sagenb/data/sage/html/notebook/upload_data_window.html:30 msgid "Upload or Create Data File" msgstr "Закачать или Ñоздать файл данных" #: ../sagenb/data/sage/html/notebook/worksheet_revision_list.html:6 msgid "Revision History -- Previous sessions" msgstr "ИÑÑ‚Ð¾Ñ€Ð¸Ñ Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ð¹ — Предыдущие ÑеÑÑии" #: ../sagenb/data/sage/html/notebook/worksheet_revision_list.html:15 msgid "Revision" msgstr "ВерÑиÑ" #: ../sagenb/data/sage/html/notebook/worksheet_revision_list.html:22 #, python-format msgid "Revision %(lr)s" msgstr "ВерÑÐ¸Ñ %(lr)s" #: ../sagenb/data/sage/html/notebook/worksheet_share.html:10 msgid "Share this document" msgstr "ПоделитьÑÑ Ñтим документом" #: ../sagenb/data/sage/html/notebook/worksheet_share.html:27 msgid "" "Only the owner of a worksheet is allowed to share it. You can do whatever" " you want if you make your own copy." msgstr "" "Только владелец рабочего лиÑта может поделитьÑÑ Ð¸Ð¼. Ð’Ñ‹ можете делать вÑÑ‘," " что захотите, еÑли Ñоздадите ÑобÑтвенную копию." #: ../sagenb/data/sage/html/notebook/worksheet_share.html:29 msgid "" "This Sage Worksheet is currently shared with the people listed in the box" " below." msgstr "" "Этот рабочий лиÑÑ‚ на данный момент разделен Ñ Ð»ÑŽÐ´ÑŒÐ¼Ð¸, " "перечиÑленными в поле ниже." #: ../sagenb/data/sage/html/notebook/worksheet_share.html:30 msgid "You may add or remove collaborators (separate user names by commas)." msgstr "" "Ð’Ñ‹ можете добавить или удалить Ñотрудников (отделÑйте их имена " "пользователей друг от друга запÑтыми)." #: ../sagenb/data/sage/html/notebook/worksheet_share.html:34 msgid "Give access to your worksheet to the above collaborators" msgstr "ПредоÑтавить доÑтуп к вашему рабочему лиÑту перечиÑленным выше Ñотрудникам" #: ../sagenb/data/sage/html/notebook/worksheet_share.html:34 msgid "Invite Collaborators" msgstr "ПриглаÑить Ñотрудников" #: ../sagenb/data/sage/html/notebook/worksheet_share.html:40 msgid "Search results:" msgstr "Результаты поиÑка:" #: ../sagenb/data/sage/html/notebook/worksheet_share.html:46 msgid "sorry, no match found" msgstr "проÑтите, по данному запроÑу ничего не найдено" #: ../sagenb/data/sage/html/notebook/worksheet_share.html:50 msgid "Search Users" msgstr "ПоиÑк пользователей" #: ../sagenb/data/sage/html/notebook/worksheet_share.html:60 msgid "Known Sage Users:" msgstr "ИзвеÑтные пользователи Sage:" #: ../sagenb/data/sage/html/settings/account_settings.html:3 #: ../sagenb/data/sage/html/settings/base.html:13 msgid "Account Settings" msgstr "ÐаÑтройки аккаунта" #: ../sagenb/data/sage/html/settings/account_settings.html:13 msgid "Change Auto-Save Interval" msgstr "Изменить интервал авто-ÑохранениÑ" #: ../sagenb/data/sage/html/settings/account_settings.html:15 msgid "Minutes" msgstr "Минут" #: ../sagenb/data/sage/html/settings/account_settings.html:25 msgid "Change Password" msgstr "Изменить пароль" #: ../sagenb/data/sage/html/settings/account_settings.html:31 msgid "Old password" msgstr "Старый пароль" #: ../sagenb/data/sage/html/settings/account_settings.html:35 msgid "New password" msgstr "Ðовый пароль" #: ../sagenb/data/sage/html/settings/account_settings.html:39 msgid "Retype new password" msgstr "Ðаберить пароль ещё раз" #: ../sagenb/data/sage/html/settings/account_settings.html:48 msgid "Change E-mail Address" msgstr "Изменить e-mail" #: ../sagenb/data/sage/html/settings/account_settings.html:52 msgid "Current e-mail" msgstr "Текущий e-mail" #: ../sagenb/data/sage/html/settings/account_settings.html:56 msgid "New e-mail" msgstr "Ðовый e-mail" #: ../sagenb/data/sage/html/settings/account_settings.html:64 msgid "Your Email" msgstr "Ваш e-mail" #: ../sagenb/data/sage/html/settings/admin_add_user.html:2 #: ../sagenb/data/sage/html/settings/admin_add_user.html:6 msgid "Add New User" msgstr "Добавить нового пользователÑ" #: ../sagenb/data/sage/html/settings/admin_add_user.html:8 msgid "Username Error" msgstr "Ошибка в имени пользователÑ" #: ../sagenb/data/sage/html/settings/admin_add_user.html:12 msgid "Pick a username" msgstr "Выберите Ð¸Ð¼Ñ Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ" #: ../sagenb/data/sage/html/settings/admin_add_user.html:13 msgid "" "The username must start with a letter and be between 4 and 32 characters " "long. It can only consist of letters, numbers, underscores, and one dot " "(.)." msgstr "" "Ð˜Ð¼Ñ Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ Ð´Ð¾Ð»Ð¶Ð½Ð¾ начинатьÑÑ Ñ Ð±ÑƒÐºÐ²Ñ‹ и быть не короче 4 и не " "длиннее 32 Ñимволов. Можно иÑпользовать только буквы, цифры, знаки " "Ð¿Ð¾Ð´Ñ‡Ñ‘Ñ€ÐºÐ¸Ð²Ð°Ð½Ð¸Ñ Ð¸ точки (.)." #: ../sagenb/data/sage/html/settings/admin_add_user.html:17 msgid "Invalid username" msgstr "Ðеверное Ð¸Ð¼Ñ Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ" #: ../sagenb/data/sage/html/settings/admin_add_user.html:19 msgid "Username taken" msgstr "Ð˜Ð¼Ñ Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ Ð¿Ñ€Ð¸Ð½Ñто" #: ../sagenb/data/sage/html/settings/admin_add_user.html:25 msgid "Create Account" msgstr "Создать аккаунт" #: ../sagenb/data/sage/html/settings/base.html:10 msgid "Manage Users" msgstr "УправлÑть пользователÑми" #: ../sagenb/data/sage/html/settings/base.html:11 #: ../sagenb/data/sage/html/settings/notebook_settings.html:2 msgid "Notebook Settings" msgstr "ÐаÑтройки Notebook" #: ../sagenb/data/sage/html/settings/user_management.html:3 #: ../sagenb/data/sage/html/settings/user_management.html:13 msgid "Users" msgstr "Пользователи" #: ../sagenb/data/sage/html/settings/user_management.html:7 msgid "User Management" msgstr "Управление пользователÑми" #: ../sagenb/data/sage/html/settings/user_management.html:8 msgid "Add User" msgstr "Добавить пользователÑ" #: ../sagenb/data/sage/html/settings/user_management.html:10 #, python-format msgid "The password for the user %(u)s has been reset to %(p)s" msgstr "Пароль Ð´Ð»Ñ Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ %(u)s был Ñбарошен на %(p)s" #: ../sagenb/data/sage/html/settings/user_management.html:13 msgid "Suspension" msgstr "Блокировка" #: ../sagenb/data/sage/html/settings/user_management.html:16 msgid "Reset" msgstr "СброÑить" #: ../sagenb/data/sage/html/settings/user_management.html:16 msgid "Unsuspend" msgstr "Разблокировать" #: ../sagenb/data/sage/html/settings/user_management.html:16 msgid "Suspend" msgstr "Заблокировать" #: ../sagenb/data/sage/html/worksheet/ratings_info.html:3 #: ../sagenb/data/sage/html/worksheet/ratings_info.html:6 #, python-format msgid "Ratings for %(wn)s" msgstr "Оценки Ð´Ð»Ñ %(wn)s" #: ../sagenb/data/sage/html/worksheet/ratings_info.html:7 msgid "Go to the worksheet." msgstr "Перейти к рабочему лиÑту." #: ../sagenb/data/sage/html/worksheet/ratings_info.html:9 msgid "User" msgstr "Пользователь" #: ../sagenb/data/sage/html/worksheet/ratings_info.html:9 msgid "Comment" msgstr "Комментарий" #: ../sagenb/data/sage/html/worksheet/time_last_edited.html:6 #, python-format msgid "%(t)s by %(le)s" msgstr "%(t)s назад пользователем %(le)s" #: ../sagenb/data/sage/html/worksheet/time_since_last_edited.html:6 #: ../sagenb/notebook/worksheet.py:2010 #, python-format msgid "%(t)s ago by %(le)s" msgstr "%(t)s назад пользователем %(le)s" #: ../sagenb/data/sage/js/translated-messages.js:4 msgid "Click to download and install tex fonts." msgstr "Щёлкните, чтобы загрузить и уÑтановить шрифты TeX." #: ../sagenb/data/sage/js/translated-messages.js:5 msgid "" "Your browser / OS combination is not supported.\n" "Please use Firefox or Opera under Linux, Windows, or Mac OS X, or Safari." msgstr "" "Ваш браузер, Ð¾Ð¿ÐµÑ€Ð°Ñ†Ð¸Ð¾Ð½Ð½Ð°Ñ ÑиÑтема или их ÐºÐ¾Ð¼Ð±Ð¸Ð½Ð°Ñ†Ð¸Ñ Ð½Ðµ поддерживаетÑÑ.\n" "ПожалуйÑта, воÑпользуйтеÑÑŒ Firefox или Opera в операционных ÑиÑтемах " "Linux или Windows или Mac OS X и Safari." #: ../sagenb/data/sage/js/translated-messages.js:6 msgid "Java Applet Hidden" msgstr "Java апплет Ñкрыт" #: ../sagenb/data/sage/js/translated-messages.js:7 msgid "Click here to pop out" msgstr "Открыть в отдельном окне" #: ../sagenb/data/sage/js/translated-messages.js:8 msgid "Error applying function to worksheet(s)." msgstr "Ðе удалоÑÑŒ применить функцию к рабочему(им) лиÑту(ам)." #: ../sagenb/data/sage/js/translated-messages.js:9 msgid "Title of saved worksheet" msgstr "Ð—Ð°Ð³Ð»Ð°Ð²Ð¸Ñ Ñохранённого рабочего лиÑта" #: ../sagenb/data/sage/js/translated-messages.js:10 msgid "Failed to save worksheet." msgstr "Ðе удалоÑÑŒ Ñохранить рабочий лиÑÑ‚." #: ../sagenb/data/sage/js/translated-messages.js:12 msgid "Please enter a name for this worksheet." msgstr "ПожалуйÑта, назовите Ñтот рабочий лиÑÑ‚." #: ../sagenb/data/sage/js/translated-messages.js:13 msgid "Rename" msgstr "Переименовать" #: ../sagenb/data/sage/js/translated-messages.js:14 msgid "Possible failure deleting worksheet." msgstr "Возможнo, произошла ошибка при удалении рабочего лиÑта." #: ../sagenb/data/sage/js/translated-messages.js:15 msgid "unprinted" msgstr "не напечатано" #: ../sagenb/data/sage/js/translated-messages.js:16 msgid "" "You requested to evaluate a cell that, for some reason, the server is " "unaware of." msgstr "" "Ð’Ñ‹ запроÑили выполнение Ñчейки, котораÑ, по каким-то причинам, не " "извеÑтна Ñерверу." #: ../sagenb/data/sage/js/translated-messages.js:18 msgid "" "This worksheet is read only. Please make a copy or contact the owner to " "change it." msgstr "" "Этот рабочий лиÑÑ‚ доÑтупен только Ð´Ð»Ñ Ñ‡Ñ‚ÐµÐ½Ð¸Ñ. ПожалуйÑта, Ñделайте копию " "или ÑвÑзитеÑÑŒ Ñ Ð²Ð»Ð°Ð´ÐµÐ»ÑŒÑ†ÐµÐ¼, чтобы получить права на изменение." #: ../sagenb/data/sage/js/translated-messages.js:19 msgid "loading..." msgstr "загрузка..." #: ../sagenb/data/sage/js/translated-messages.js:20 msgid "Error updating cell output after " msgstr "Ошибка Ð¾Ð±Ð½Ð¾Ð²Ð»ÐµÐ½Ð¸Ñ Ð²Ñ‹Ð²Ð¾Ð´Ð° Ñчейки поÑле " #: ../sagenb/data/sage/js/translated-messages.js:21 msgid "s (canceling further update checks)." msgstr "s (дальнейшие проверки Ð¾Ð±Ð½Ð¾Ð²Ð»ÐµÐ½Ð¸Ñ Ð¿Ñ€ÐµÐºÑ€Ð°Ñ‰ÐµÐ½Ñ‹)" #: ../sagenb/data/sage/js/translated-messages.js:22 msgid "Problem inserting new input cell after current input cell.\n" msgstr "Возникла проблема при вÑтавке новой Ñчейки поÑле текущей.\n" #: ../sagenb/data/sage/js/translated-messages.js:23 msgid "Worksheet is locked. Cannot insert cells." msgstr "Рабочий лиÑÑ‚ зафикÑирован. ÐÐµÐ»ÑŒÐ·Ñ Ð²ÑтавлÑть Ñчейки." #: ../sagenb/data/sage/js/translated-messages.js:24 msgid "Unable to interrupt calculation." msgstr "Ðе удалоÑÑŒ прервать вычиÑлениÑ." #: ../sagenb/data/sage/js/translated-messages.js:25 msgid "Close this box to stop trying." msgstr "Закройте Ñто Ñообщение, чтобы прекратить попытки." #: ../sagenb/data/sage/js/translated-messages.js:26 msgid "Interrupt attempt" msgstr "Попытка прерываниÑ" #: ../sagenb/data/sage/js/translated-messages.js:27 msgid "Restart, instead?" msgstr "" "Может быть, вмеÑто Ñтого вы хотите перезапуÑтить рабочий лиÑÑ‚?" #: ../sagenb/data/sage/js/translated-messages.js:28 msgid "" "Emptying the trash will permanently delete all items in the trash. " "Continue?" msgstr "ОчиÑтка корзины окончательно удалит вÑе рабочие лиÑты в ней. Продолжить?" #: ../sagenb/data/sage/js/translated-messages.js:29 msgid "Get Image" msgstr "Получить изображание" #: ../sagenb/data/sage/js/translated-messages.js:30 msgid "Jmol Image" msgstr "Изображение Jmol" #: ../sagenb/data/sage/js/translated-messages.js:31 msgid "" "To save this image, you can try right-clicking on the image to copy it or" " save it to a file, or you may be able to just drag the image to your " "desktop." msgstr "" "Чтобы Ñохранить Ñто изображение, вы можете попробовать щёлкнуть по нему " "правой кнопкой и выбрать Копировать или Сохранить. Также, возможно, вы " "можете проÑто перетащить картинку на рабочий Ñтол." #: ../sagenb/data/sage/js/translated-messages.js:32 msgid "Sorry, but you need a browser that supports the <canvas> tag." msgstr "" "ПроÑтите, но требуетÑÑ Ð±Ñ€Ð°ÑƒÐ·ÐµÑ€, который поддерживает HTML Ñ‚Ñг " "<canvas>." #: ../sagenb/data/sage/js/translated-messages.js:33 #, python-format msgid "Trying again in %(num)d second..." msgid_plural "Trying again in %(num)d seconds..." msgstr[0] "ÐžÑ‡ÐµÑ€ÐµÐ´Ð½Ð°Ñ Ð¿Ð¾Ð¿Ñ‹Ñ‚ÐºÐ° через %(num)d Ñекунду..." msgstr[1] "ÐžÑ‡ÐµÑ€ÐµÐ´Ð½Ð°Ñ Ð¿Ð¾Ð¿Ñ‹Ñ‚ÐºÐ° через %(num)d Ñекунды..." msgstr[2] "ÐžÑ‡ÐµÑ€ÐµÐ´Ð½Ð°Ñ Ð¿Ð¾Ð¿Ñ‹Ñ‚ÐºÐ° через %(num)d Ñекунд..." #: ../sagenb/notebook/challenge.py:180 msgid "Please ask the server administrator to configure a challenge!" msgstr "" "ПожалуйÑта, попроÑите админиÑтратора Ñервера наÑтроить ÑредÑтво защиты от" " ботов!" #: ../sagenb/notebook/challenge.py:221 msgid "Is pi > e?" msgstr "Верно ли, что Ï€>e?" #: ../sagenb/notebook/challenge.py:221 msgid "y|yes" msgstr "д|да" #: ../sagenb/notebook/challenge.py:222 msgid "What is 3 times 8?" msgstr "Сколько будет трижды воÑемь?" #: ../sagenb/notebook/challenge.py:222 msgid "24|twenty-four" msgstr "24|двадцать четыре" #: ../sagenb/notebook/challenge.py:223 msgid "What is 2 plus 3?" msgstr "Сколько будет два Ð¿Ð»ÑŽÑ Ñ‚Ñ€Ð¸?" #: ../sagenb/notebook/challenge.py:223 ../sagenb/notebook/challenge.py:225 msgid "5|five" msgstr "5|пÑть" #: ../sagenb/notebook/challenge.py:224 msgid "How many bits are in one byte?" msgstr "Сколько бит в одном байте?" #: ../sagenb/notebook/challenge.py:224 msgid "8|eight" msgstr "8|воÑемь" #: ../sagenb/notebook/challenge.py:225 msgid "What is the largest prime factor of 15?" msgstr "Какой наибольший проÑтой делитель чиÑла 15?" #: ../sagenb/notebook/conf.py:124 msgid "Updated" msgstr "Обновлено" #: ../sagenb/notebook/register.py:19 ../sagenb/notebook/register.py:29 #, python-format msgid "" "Hi %(username)s!\n" "\n" msgstr "" "Привет %(username)s!\n" "\n" #: ../sagenb/notebook/register.py:20 #, python-format msgid "" "Thank you for registering for the Sage notebook. To complete your " "registration, copy and paste the following link into your browser:\n" "\n" "%(url_prefix)s://%(addr)s:%(port)s/confirm?key=%(key)s\n" "\n" "You will be taken to a page which will confirm that you have indeed " "registered." msgstr "" "СпаÑибо за региÑтрацию в Sage Notebook. Чтобы завершить региÑтрацию, " "Ñкопируйте и вÑтавьте Ñледующую ÑÑылку в ваш браузер:\n" "\n" "%(url_prefix)s://%(addr)s:%(port)s/confirm?key=%(key)s\n" "\n" "ОткроетÑÑ Ñтраница, на которой будет Ñообщение, подтверждающее вашу " "уÑпешную региÑтрацию." #: ../sagenb/notebook/register.py:30 #, python-format msgid "" "Your new password is %(key)s\n" "\n" "Sign in at %(url_prefix)s://%(addr)s:%(port)s/\n" "\n" "Make sure to reset your password by going to Settings in the upper right " "bar." msgstr "" "Ваш новый пароль: %(key)s\n" "\n" "Войдите на Ñервер: %(url_prefix)s://%(addr)s:%(port)s/\n" "\n" "ПожалуйÑта, ÑброÑьте ваш пароль, Ð¿ÐµÑ€ÐµÐ¹Ð´Ñ Ð¿Ð¾ ÑÑылке ÐаÑтройки в верхней " "правой панели." #: ../sagenb/notebook/server_conf.py:57 msgid "Appearance" msgstr "Внешний вид" #: ../sagenb/notebook/server_conf.py:58 msgid "Authentication" msgstr "ÐутентификациÑ" #: ../sagenb/notebook/server_conf.py:59 msgid "LDAP" msgstr "LDAP" #: ../sagenb/notebook/server_conf.py:60 msgid "Server" msgstr "Сервер" #: ../sagenb/notebook/server_conf.py:65 msgid "Number of word-wrap columns" msgstr "МакÑÐ¸Ð¼Ð°Ð»ÑŒÐ½Ð°Ñ Ð´Ð»Ð¸Ð½Ð° Ñтроки при переноÑе Ñлов" #: ../sagenb/notebook/server_conf.py:71 msgid "Maximum history length" msgstr "МакÑимальный размер иÑтории" #: ../sagenb/notebook/server_conf.py:77 msgid "Idle timeout (seconds)" msgstr "МакÑимальное Ð¾Ð¶Ð¸Ð´Ð°Ð½Ð¸Ñ (в Ñекундах)" #: ../sagenb/notebook/server_conf.py:83 msgid "Idle check interval (seconds)" msgstr "Интервал между запроÑами (в Ñекундах)" #: ../sagenb/notebook/server_conf.py:89 msgid "Save interval (seconds)" msgstr "Ð’Ñ€ÐµÐ¼Ñ Ð´Ð¾ автоÑÐ¾Ñ…Ñ€Ð°Ð½ÐµÐ½Ð¸Ñ (в Ñекундах)" #: ../sagenb/notebook/server_conf.py:95 msgid "Doc worksheet pool size" msgstr "Размер пула документации рабочего лиÑта" #: ../sagenb/notebook/server_conf.py:101 msgid "Doc worksheet idle timeout (seconds)" msgstr "МакÑимальное Ð¾Ð¶Ð¸Ð´Ð°Ð½Ð¸Ñ (в Ñекундах) рабочего лиÑта" #: ../sagenb/notebook/server_conf.py:107 msgid "Enable published interacts (EXPERIMENTAL; USE AT YOUR OWN RISK)" msgstr "" "Разрешить интерактивные опубликованные рабочие лиÑты (ЭКСПЕРИМЕÐТÐЛЬÐÐЯ " "ФУÐКЦИЯ; ИСПОЛЬЗУЙТЕ ÐРСВОЙ РИСК)" #: ../sagenb/notebook/server_conf.py:113 msgid "Worksheet process users (comma-separated list)" msgstr "Пользователи процеÑÑа рабочего лиÑта (ÑпиÑок, разделённый запÑтыми)" #: ../sagenb/notebook/server_conf.py:119 msgid "Default system" msgstr "СиÑтема по-умолчанию" #: ../sagenb/notebook/server_conf.py:125 msgid "Pretty print (typeset) output" msgstr "Ðвтоформатирование вывода" #: ../sagenb/notebook/server_conf.py:131 msgid "Worksheet process limits" msgstr "ÐžÐ³Ñ€Ð°Ð½Ð¸Ñ‡ÐµÐ½Ð¸Ñ Ð¿Ñ€Ð¾Ñ†ÐµÑÑа рабочего лиÑта" #: ../sagenb/notebook/server_conf.py:138 msgid "Require e-mail for account registration" msgstr "Требовать e-mail Ð´Ð»Ñ Ñ€ÐµÐ³Ð¸Ñтрации аккаунта" #: ../sagenb/notebook/server_conf.py:145 msgid "Enable user registration" msgstr "Разрешить региÑтрацию пользователей" #: ../sagenb/notebook/server_conf.py:152 msgid "Allow OpenID authentication (requires python ssl module)" msgstr "Разрешить аутентификацию через OpenID (требуетÑÑ python модуль ssl)" #: ../sagenb/notebook/server_conf.py:159 msgid "Use a challenge for account registration" msgstr "ИÑпользовать защиту от ботов при региÑтрации аккаунтов" #: ../sagenb/notebook/server_conf.py:166 msgid "Type of challenge" msgstr "Тип защиты" #: ../sagenb/notebook/server_conf.py:173 msgid "reCAPTCHA public key" msgstr "Публичный ключ reCAPTCHA" #: ../sagenb/notebook/server_conf.py:179 msgid "reCAPTCHA private key" msgstr "Закрытый ключ reCAPTCHA" #: ../sagenb/notebook/server_conf.py:185 msgid "Default Language" msgstr "Язык по умолчанию" #: ../sagenb/notebook/server_conf.py:191 msgid "Model Version" msgstr "ВерÑÐ¸Ñ Ð¼Ð¾Ð´ÐµÐ»Ð¸" #: ../sagenb/notebook/server_conf.py:197 msgid "Enable LDAP Authentication" msgstr "Разрешить аутентификацию через LDAP" #: ../sagenb/notebook/server_conf.py:209 msgid "Bind DN" msgstr "ПодключатьÑÑ ÐºÐ°Ðº (Bind DN)" #: ../sagenb/notebook/server_conf.py:215 msgid "Bind Password" msgstr "Пароль подключениÑ" #: ../sagenb/notebook/server_conf.py:221 msgid "Base DN" msgstr "База поиÑка" #: ../sagenb/notebook/server_conf.py:227 msgid "Username Attribute (i.e. cn, uid or userPrincipalName)" msgstr "Ðттрибут имени Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ (например, cn, uid или userPrincipalName)" #: ../sagenb/notebook/server_conf.py:233 msgid "Attributes for user lookup" msgstr "Ðттрибуты Ð´Ð»Ñ Ð¿Ð¾Ð¸Ñка пользователей" #: ../sagenb/notebook/template.py:74 #, python-format msgid "%(num)d second" msgid_plural "%(num)d seconds" msgstr[0] "%(num)d Ñекунда" msgstr[1] "%(num)d Ñекунды" msgstr[2] "%(num)d Ñекунд" #: ../sagenb/notebook/template.py:77 #, python-format msgid "%(num)d minute" msgid_plural "%(num)d minutes" msgstr[0] "%(num)d минута" msgstr[1] "%(num)d минуты" msgstr[2] "%(num)d минут" #: ../sagenb/notebook/template.py:80 #, python-format msgid "%(num)d hour" msgid_plural "%(num)d hours" msgstr[0] "%(num)d чаÑ" msgstr[1] "%(num)d чаÑа" msgstr[2] "%(num)d чаÑов" #: ../sagenb/notebook/template.py:82 #, python-format msgid "%(num)d day" msgid_plural "%(num)d days" msgstr[0] "%(num)d день" msgstr[1] "%(num)d днÑ" msgstr[2] "%(num)d дней" #: ../sagenb/notebook/template.py:141 msgid "Sage Notebook" msgstr "Sage Notebook" #: ../sagenb/notebook/tutorial.py:354 msgid "Find Help and Documentation" msgstr "Ðайти помощь и документацию" #: ../sagenb/notebook/tutorial.py:355 msgid "Get Started with Sage" msgstr "Ðачинаем работу Ñ Sage" #: ../sagenb/notebook/tutorial.py:355 msgid "" "Work through the tutorial " "(if you have trouble with it, view the static version)." msgstr "" "Изучите практичеÑкое руководÑтво (еÑли у ваÑ" " возникают проблемы Ñ ÐµÐ³Ð¾ проÑмотром, попробуйте ÑтатичеÑкую верÑию)." #: ../sagenb/notebook/tutorial.py:356 msgid "Help About" msgstr "КонтекÑÑ‚Ð½Ð°Ñ Ñправка" #: ../sagenb/notebook/tutorial.py:357 msgid "" "Type ? immediately after the object or function and press tab or shift-" "enter (shift-enter overwrites output and saves to worksheet)." msgstr "" "Ðаберите ? Ñразу поÑле объекта или функции и нажмите Tab или Shift-Enter " "(Shift-Enter перезапиÑывает вывод и ÑохранÑет рабочий лиÑÑ‚)." #: ../sagenb/notebook/tutorial.py:359 msgid "" "Put ?? after the object and press tab or shift-enter (shift-enter " "overwrites output and saves to worksheet)." msgstr "" "Ðаберите ?? поÑле объекта и нажмите Tab или Shift-Enter (Shift-Enter " "перезапиÑывает вывод и ÑохранÑет рабочий лиÑÑ‚)." #: ../sagenb/notebook/tutorial.py:360 msgid "Full Text Search of Docs and Source" msgstr "ПолнотекÑтовой поиÑк по документации и иÑходному коду" #: ../sagenb/notebook/tutorial.py:361 msgid "" "Search the SAGE documentation by typing
    search_doc(\"my "
    "query\")
    in an input cell and press shift-enter. Search the source" " code of SAGE by typing
    search_src(\"my query\")
    and pressing " "shift-enter. Arbitrary regular expressions are allowed as queries." msgstr "" "Ð”Ð»Ñ Ð¿Ð¾Ð¸Ñка в документации Sage введите
    search_doc(\"ваш "
    "запроÑ\")
    в Ñчейку ввода и нажмите Shift-Enter. Ðайти иÑходный код " "Sage можно, набрав
    search_src(\"ваш запроÑ\")
    . Ð’ запроÑах можно" " иÑпользовать произвольные регулÑрные выражениÑ." #: ../sagenb/notebook/tutorial.py:365 msgid "Key and Mouse Bindings" msgstr "ГорÑчие клавиши и дейÑÑ‚Ð²Ð¸Ñ Ð¼Ñ‹ÑˆÑŒÑŽ" #: ../sagenb/notebook/tutorial.py:366 msgid "Evaluate Input" msgstr "Выполнить ввод" #: ../sagenb/notebook/tutorial.py:367 msgid "" "Press shift-enter. You can start several calculations " "at once. If you press alt-enter instead, then a new " "cell is created after the current one. If you press ctrl-" "enter then the cell is split and both pieces are evaluated " "separately." msgstr "" "Ðажмите Shift-Enter. Ð’Ñ‹ можете начать неÑколько " "вычиÑлений за раз. ЕÑли же вы нажмёте Alt-Enter, то " "будет Ñоздана Ð½Ð¾Ð²Ð°Ñ Ñчейка Ñразу поÑле текущей. Рнажатие Ctrl-" "Enter разобьёт Ñчейку на две чаÑти, которые будут выполнÑтьÑÑ Ð¿Ð¾" " отдельноÑти." #: ../sagenb/notebook/tutorial.py:368 msgid "Tab Completion" msgstr "Ðвтозавершение по нажатию Tab" #: ../sagenb/notebook/tutorial.py:369 msgid "" "Press tab while the cursor is on an identifier. On some " "web browsers (e.g., Opera) you must use control-space instead of tab." msgstr "" "Ðажмите Tab пока курÑор находитÑÑ Ð½Ð° идентификаторе. Ð’ " "некоторых браузерах (например, в Opera) вмеÑто Tab нужно иÑпользовать " "Control-Пробел." #: ../sagenb/notebook/tutorial.py:370 msgid "Insert New Cell" msgstr "Ð’Ñтавить новую Ñчейку" #: ../sagenb/notebook/tutorial.py:371 msgid "" "Put the mouse between an output and input until the horizontal line " "appears and click. If you press Alt-Enter in a cell, the cell is " "evaluated and a new cell is inserted after it." msgstr "" "Ðаведите указатель мыши на проÑтранÑтво над Ñчейкой ввода или под " "выводом, так, чтобы поÑвилаÑÑŒ Ð³Ð¾Ñ€Ð¸Ð·Ð¾Ð½Ñ‚Ð°Ð»ÑŒÐ½Ð°Ñ Ð»Ð¸Ð½Ð¸Ñ, и щёлкните. ЕÑли вы " "нажмёте Alt-Enter Ñчейка будет выполнена и Ð½Ð¾Ð²Ð°Ñ Ñчейка будет вÑтавлена " "поÑле неё." #: ../sagenb/notebook/tutorial.py:372 msgid "Delete Cell" msgstr "Удалить Ñчейку" #: ../sagenb/notebook/tutorial.py:373 msgid "Delete all cell contents, then press backspace." msgstr "Удалите Ñодержимое Ñчейки и, затем, нажмите Backspace." #: ../sagenb/notebook/tutorial.py:374 msgid "Split and Join Cells" msgstr "Разбить и объединить Ñчейки" #: ../sagenb/notebook/tutorial.py:375 msgid "" "Press ctrl-; in a cell to split it into two cells, and " "ctrl-backspace to join them. Press ctrl-" "enter to split a cell and evaluate both pieces." msgstr "" "Ðажмите Ctrl-; в Ñчейке, чтобы разбить её на две, и " "Ctrl-Backspace, чтобы объединить их. Ðажмите Ctrl-Enter, чтобы разбить Ñчейку на две и выполнить обе чаÑти. " #: ../sagenb/notebook/tutorial.py:376 msgid "Insert New Text Cell" msgstr "Ð’Ñтавить новую текÑтовую Ñчейку" #: ../sagenb/notebook/tutorial.py:377 msgid "" "Move the mouse between cells until a blue bar appears. Shift-" "click on the blue bar to create a new text cell. Double click " "on existing text to edit it. Use $...$ and $$...$$ to include typeset " "math in the text block." msgstr "" "Ðаведите мышь между Ñчейками так, чтобы поÑвилаÑÑŒ ÑинÑÑ Ð¿Ð¾Ð»Ð¾Ñка. " "Shift-щелчок Ñоздат новую текÑтовую Ñчейку. Двойной " "щелчок по ÑущеÑтвующей текÑтовой Ñчейке позволит её отредактировать. Ð”Ð»Ñ " "ввода математичеÑких формул (в LaTeX) наберите $...$ и $$...$$ в " "текÑтовой Ñчейке." #: ../sagenb/notebook/tutorial.py:378 msgid "Hide/Show Output" msgstr "Скрыть/показать вывод (результаты)" #: ../sagenb/notebook/tutorial.py:379 msgid "" "Click on the left side of output to toggle between hidden, shown with " "word wrap, and shown without word wrap." msgstr "" "Кликните Ñлева от вывода, чтобы переключить режим отображениÑ: Ñкрытый, Ñ" " переноÑом Ñлов, без переноÑа Ñлов." #: ../sagenb/notebook/tutorial.py:380 msgid "Indenting Blocks" msgstr "ОтÑтупы в блоках" #: ../sagenb/notebook/tutorial.py:381 msgid "" "Highlight text and press > to indent it all and < to unindent it all " "(works in Safari and Firefox). In Firefox you can also press tab and " "shift-tab." msgstr "" "Выделите текÑÑ‚ и нажмите > Ð´Ð»Ñ Ð¾Ñ‚Ñтупа, < Ð´Ð»Ñ ÑƒÐ´Ð°Ð»ÐµÐ½Ð¸Ñ Ð¾Ñ‚Ñтупа (Ñто " "работает в Safari и Firefox). Ð’ Firefox также можно иÑпользовать tab и " "shift-tab." #: ../sagenb/notebook/tutorial.py:382 msgid "Comment/Uncomment Blocks" msgstr "Комментирование/раÑкомментирование блоков" #: ../sagenb/notebook/tutorial.py:383 msgid "" "Highlight text and press ctrl-. to comment it and " "ctrl-, to uncomment it. Alternatively, use " "ctrl-3 and ctrl-4." msgstr "" "Выделите текÑÑ‚ и нажмите Ctrl-., чтобы закомментировать " "его, и Ctrl-,, чтобы раÑкомментировать. Можно также " "иÑпользовать Ctrl-3 и Ctrl-4." #: ../sagenb/notebook/tutorial.py:384 msgid "Paren matching" msgstr "ПарноÑть Ñкобок" #: ../sagenb/notebook/tutorial.py:384 msgid "" "To fix unmatched or mis-matched parentheses, braces or brackets, press " "ctrl-0. Parentheses before the cursor will be matched, " "minding strings and (Python) comments." msgstr "" "Чтобы иÑправить непарные круглые, квадратные, фигурные Ñкобки, нажмите " "Ctrl-0. Скобки перед курÑором Ñтанут парными, Ñ " "правильной обработкой Ñтрок и комментариев (в Python)." #: ../sagenb/notebook/tutorial.py:388 msgid "Interrupt and Restart Sessions" msgstr "Прерывание и перезапуÑк ÑеÑÑий" #: ../sagenb/notebook/tutorial.py:389 msgid "Interrupt Running Calculations" msgstr "Прерывание текущих вычиÑлений" #: ../sagenb/notebook/tutorial.py:390 msgid "" "Click Interrupt or press escape in any input cell. This will " "(attempt) to interrupt SAGE by sending many interrupt signals." msgstr "" "Щёлкните Прервать или нажмите Escape в любой Ñчейке ввода. Это " "заÑтавит Sage (попытатьÑÑ) прервать текущую задачу, отправив много " "Ñигналов прерываниÑ." #: ../sagenb/notebook/tutorial.py:391 msgid "Restart" msgstr "ПерезапуÑтить" #: ../sagenb/notebook/tutorial.py:392 msgid "" "Type \"restart\" to restart the SAGE interpreter for a given worksheet. " "(You have to interrupt first.)" msgstr "" "Ðаберите \"restart\" Ð´Ð»Ñ Ð¿ÐµÑ€ÐµÐ·Ð°Ð¿ÑƒÑка интерпретатора Sage в текущем " "рабочем лиÑте. (Сначала нужно прервать текущие вычиÑлениÑ.)" #: ../sagenb/notebook/tutorial.py:394 msgid "Special Cell Blocks" msgstr "Специальные блоки в Ñчейках" #: ../sagenb/notebook/tutorial.py:395 msgid "Evaluate Cell using GAP, Singular, etc." msgstr "Выполнить Ñчейку, иÑÐ¿Ð¾Ð»ÑŒÐ·ÑƒÑ GAP, Singular, и др." #: ../sagenb/notebook/tutorial.py:396 #, python-format msgid "" "Put \"%%gap\", \"%%singular\", etc. as the first input line of a cell; " "the rest of the cell is evaluated in that system." msgstr "" "Введите \"%%gap\", \"%%singular\", и др. первой Ñтрочкой Ñчейки ввода; " "оÑÑ‚Ð°Ð»ÑŒÐ½Ð°Ñ Ñ‡Ð°Ñть Ñчейки будет выполнена в выбранной ÑиÑтеме." #: ../sagenb/notebook/tutorial.py:397 msgid "Shell Scripts" msgstr "Скрипты оболочки (shell)" #: ../sagenb/notebook/tutorial.py:398 #, python-format msgid "" "Begin a block with %%sh to have the rest of the block evaluated as a " "shell script. The current working directory is maintained." msgstr "" "Ðаберите первой Ñтрочкой %%sh в Ñчейке ввода, чтобы оÑÑ‚Ð°Ð»ÑŒÐ½Ð°Ñ Ñ‡Ð°Ñть " "Ñчейки была интерпретирована как Ñкрипт оболочки. Изменение рабочей " "директории будет обработана правильно." #: ../sagenb/notebook/tutorial.py:399 msgid "Interactive Dynamic Widgets" msgstr "Интерактивные динамичеÑкие виджеты" #: ../sagenb/notebook/tutorial.py:400 msgid "" "Put @interact on the line before a function definition. Type interact? " "for more details." msgstr "" "Ðаберите @interact на Ñтроке перед определением функции. Ðаберите " "interact? Ð´Ð»Ñ Ð¿Ð¾Ð´Ñ€Ð¾Ð±Ð½Ð¾Ñтей." #: ../sagenb/notebook/tutorial.py:401 msgid "Autoevaluate Cells on Load" msgstr "ÐвтоматичеÑки выполнÑть Ñчейки при загрузке рабочего лиÑта" #: ../sagenb/notebook/tutorial.py:402 msgid "" "Any cells with \"#auto\" in the input is automatically evaluated when the" " worksheet is first opened." msgstr "" "Ð’Ñе Ñчейки Ñо введённым Ñловом \"#auto\" будут автоматичеÑки выполнены, " "когда рабочий лиÑÑ‚ будет открыт." #: ../sagenb/notebook/tutorial.py:403 msgid "Time" msgstr "Ð’Ñ€ÐµÐ¼Ñ Ð²Ñ‹Ð¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ" #: ../sagenb/notebook/tutorial.py:404 #, python-format msgid "Type \"%%time\" at the beginning of the cell." msgstr "Добавьте \"%%time\" в начало Ñчейки." #: ../sagenb/notebook/tutorial.py:406 msgid "Useful Tips" msgstr "Полезные замечаниÑ" #: ../sagenb/notebook/tutorial.py:407 msgid "Input Rules" msgstr "Правила ввода" #: ../sagenb/notebook/tutorial.py:408 msgid "" "Code is evaluated by exec'ing (after preparsing). Only the output of the" " last line of the cell is implicitly printed. If any line starts with " "\"sage:\" or \">>>\" the entire block is assumed to contain text and " "examples, so only lines that begin with a prompt are executed. Thus you" " can paste in complete examples from the docs without any editing, and " "you can write input cells that contains non-evaluated plain text mixed " "with examples by starting the block with \">>>\" or including an example." msgstr "" "Код выполнÑетÑÑ Ð¿Ñ€Ð¸ помощи exec (поÑле препарÑинга). Только вывод " "поÑледней Ñтроки в Ñчейке будет отображён по умолчанию. ЕÑли какаÑ-либо " "Ñтрока начинаетÑÑ Ñ \"sage:\" или \">>>\", то ÑчитаетÑÑ, что вÑÑ Ñчейка " "Ñодержит текÑÑ‚ и примеры, так что будут выполнены только Ñтроки, " "Ñодержащие приглашение. Таким образом, вы можете вÑтавлÑть примеры из " "документации целиком, без каких-либо иÑправлений, а также вы можете " "пиÑать в Ñчейках ввода проÑтой текÑÑ‚, который не будет выполнен, вмеÑте Ñ" " примерами, еÑли начнёте Ñчейку Ñ \">>>\" или вÑтавите пример из " "документации." #: ../sagenb/notebook/tutorial.py:409 msgid "History" msgstr "ИÑториÑ" #: ../sagenb/notebook/tutorial.py:410 msgid "" "Click log commands you have entered in any " "worksheet of this notebook." msgstr "" "Щёлкните иÑториÑ, чтобы увидеть вÑе команды, " "которые вы ввели в любом рабочем лиÑте." #: ../sagenb/notebook/tutorial.py:411 msgid "Typesetting All Output" msgstr "Ðвтоформатирование вÑего вывода" #: ../sagenb/notebook/tutorial.py:412 msgid "" "Type pretty_print_default() in an input cell and press shift-enter. All " "future output will be typeset automatically." msgstr "" "Введите pretty_print_default() в Ñчейке ввода и нажмите Shift-Enter. ВеÑÑŒ" " поÑледующий ввывод будет автоматичеÑки отформатирован." #: ../sagenb/notebook/tutorial.py:414 msgid "Files and Scripts" msgstr "Файлы и Ñкрипты" #: ../sagenb/notebook/tutorial.py:415 msgid "Loading SAGE/Python Scripts" msgstr "Подключение Ñкриптов Sage/Python" #: ../sagenb/notebook/tutorial.py:416 msgid "" "Use \"load filename.sage\" and \"load filename.py\". Load is relative to" " the path you started the notebook in. The .sage files are preparsed and" " .py files are not. You may omit the .sage or .py extension. Files may" " load other files." msgstr "" "ИÑпользуйте \"load filename.sage\" и \"load filename.py\". Путь load " "отноÑителен директории, из которой запущен Sage Notebook. Файлы .sage " "будут обработаны препарÑером, а .py — нет. РаÑширение .sage или .py " "можно опуÑтить. Файлы могут загружать другие файлы." #: ../sagenb/notebook/tutorial.py:417 msgid "Attaching Scripts" msgstr "Прикладывание Ñкриптов к рабочему лиÑту" #: ../sagenb/notebook/tutorial.py:418 msgid "" "Use \"attach filename.sage\" or \"attach filename.py\". Attached files " "are automatically reloaded when the file changes. The file " "$HOME/.sage/init.sage is attached on startup if it exists." msgstr "" "ИÑпользуйте \"attach filename.sage\" или \"attach filename.py\". " "Приложенные файлы автоматичеÑки перезагружаютÑÑ Ð¿Ñ€Ð¸ их изменении. ЕÑли " "ÑущеÑтвует файл $HOME/.sage/init.sage, то он прикладываетÑÑ Ð¿Ñ€Ð¸ запуке." #: ../sagenb/notebook/tutorial.py:419 msgid "Working Directory" msgstr "Рабочий каталог" #: ../sagenb/notebook/tutorial.py:420 msgid "" "Each block of code is run from its own directory. If any images are " "created as a side effect, they will automatically be displayed." msgstr "" "ÐšÐ°Ð¶Ð´Ð°Ñ Ñчейка запуÑкаетÑÑ Ð² ÑобÑтвенном каталоге. ЕÑли во Ð²Ñ€ÐµÐ¼Ñ Ñ€Ð°Ð±Ð¾Ñ‚Ñ‹ " "ÑоздаютÑÑ Ñ„Ð°Ð¹Ð»Ñ‹ изображений, то они будут автоматичеÑки отображены." #: ../sagenb/notebook/tutorial.py:421 msgid "DIR Variable" msgstr "ÐŸÐµÑ€ÐµÐ¼ÐµÐ½Ð½Ð°Ñ DIR" #: ../sagenb/notebook/tutorial.py:422 msgid "" "The variable DIR contains the directory from which you started the SAGE " "notebook. For example, to open a file in that directory, do " "\"open(DIR+'filename')\"." msgstr "" "ÐŸÐµÑ€ÐµÐ¼ÐµÐ½Ð½Ð°Ñ DIR Ñодержит Ð°Ð´Ñ€ÐµÑ ÐºÐ°Ñ‚Ð°Ð»Ð¾Ð³Ð°, из которого запущен Sage " "Notebook. Ðапример, чтобы открыть файл в Ñтом каталоге, наберите " "\"open(DIR+'имÑ_файла')\"." #: ../sagenb/notebook/tutorial.py:423 msgid "DATA Variable" msgstr "ÐŸÐµÑ€ÐµÐ¼ÐµÐ½Ð½Ð°Ñ DATA" #: ../sagenb/notebook/tutorial.py:424 msgid "" "Use the Data menu to upload images and other files, and create new files " "that can be shared between worksheets. The DATA variable contains the " "path to the data files. For example, to open a file in that directory, " "do \"open(DATA+'filename')\". If foo.sage is a Sage file that you " "uploaded, type \"load foo.sage\"; if foo.py is a Python file, you can " "import it by typing \"import foo\"." msgstr "" "ИÑпользуйте меню Данные, чтобы загружать картинки и другие файлы, а также" " Ñоздавать новые файлы, которые могут быть иÑпользованы в разных рабочих " "лиÑтах одновременно. ÐŸÐµÑ€ÐµÐ¼ÐµÐ½Ð½Ð°Ñ DATA Ñодержит путь к Ñтим файлам данных." " Ðапример, чтобы открыть файл в Ñтом каталоге, наберите " "\"open(DATA+'файл')\". ЕÑли вы загрузили Sage файл foo.sage, наберите " "\"load foo.sage\", чтобы выполнить его; еÑли вы загрузили Python файл " "foo.py, вы можете импортировать его Ñ Ð¿Ð¾Ð¼Ð¾Ñ‰ÑŒÑŽ \"import foo\"." #: ../sagenb/notebook/tutorial.py:425 msgid "Loading and Saving Objects" msgstr "Загрузка и Ñохранение объектов" #: ../sagenb/notebook/tutorial.py:426 msgid "" "Use \"save obj1 obj2 ...\" and \"load obj1 obj2 ...\". This allows for " "easy moving of objects from one worksheet to another, and saving of " "objects for later use." msgstr "" "ИÑпользуйте \"save obj1 obj2 ...\" и \"load obj1 obj2 ...\". Так можно " "легко перемещать объекты из одного рабочего лиÑта в другой и ÑохранÑть их" " Ð´Ð»Ñ Ð´Ð°Ð»ÑŒÐ½ÐµÐ¹ÑˆÐµÐ³Ð¾ иÑпользованиÑ." #: ../sagenb/notebook/tutorial.py:427 msgid "Loading and Saving Sessions" msgstr "Загрузка и Ñохранение ÑеÑÑий" #: ../sagenb/notebook/tutorial.py:428 msgid "" "Use \"save_session('name')\" to save all variables to an object. Use " "\"load_session('name')\" to merge in all variables from a saved " "session." msgstr "" "ИÑпользуйте \"save_session('name')\", чтобы Ñохранить вÑе переменные в " "объект. Введите \"load_session('name')\", чтобы объединить " "текущее окружение Ñ Ð¿ÐµÑ€ÐµÐ¼ÐµÐ½Ð½Ñ‹Ð¼Ð¸ из Ñохранённой ÑеÑÑии." #: ../sagenb/notebook/tutorial.py:429 msgid "Customizing the Notebook CSS" msgstr "КаÑÑ‚Ð¾Ð¼Ð¸Ð·Ð°Ñ†Ð¸Ñ CSS Sage Notebook" #: ../sagenb/notebook/tutorial.py:430 msgid "" "If you create a file $HOME/.sage/notebook.css then it will get " "applied when rendering the notebook. See " msgstr "" "ЕÑли вы Ñоздадите файл $HOME/.sage/notebook.css, то он будет " "применён при отображении Sage Notebook. См. " #: ../sagenb/notebook/wiki2html.py:647 #, python-format msgid "Expected \"%(wanted)s\" after \"%(key)s\", got \"%(token)s\"" msgstr "ОжидалоÑÑŒ \"%(wanted)s\" поÑле \"%(key)s\", но получено \"%(token)s\"" #: ../sagenb/notebook/wiki2html.py:653 #, python-format msgid "Expected an integer \"%(key)s\" before \"%(token)s\"" msgstr "ОжидалоÑÑŒ целое чиÑло \"%(key)s\" перед \"%(token)s\"" #: ../sagenb/notebook/wiki2html.py:663 ../sagenb/notebook/wiki2html.py:673 #, python-format msgid "Expected an integer \"%(arg)s\" after \"%(key)s\"" msgstr "ОжидалоÑÑŒ целое чиÑло \"%(arg)s\" поÑле \"%(key)s\"" #: ../sagenb/notebook/wiki2html.py:699 #, python-format msgid "Expected a color value \"%(arg)s\" after \"%(key)s\"" msgstr "ОжидалоÑÑŒ определение цвета \"%(arg)s\" поÑле \"%(key)s\"" #: ../sagenb/notebook/worksheet.py:2015 #, python-format msgid "%(seconds)s ago" msgstr "%(seconds)s назад" #~ msgid "Upload worksheet (an sws or txt file) to the Sage Notebook" #~ msgstr "Загрузить рабочий лиÑÑ‚ (файл sws или txt) в Sage Notebook" #~ msgid "Browse your computer to select a worksheet file to upload:" #~ msgstr "Выбирете Ð´Ð»Ñ Ð·Ð°Ð³Ñ€ÑƒÐ·ÐºÐ¸ файл рабочего лиÑта на вашем комьютере:" #~ msgid "Or enter the URL of a worksheet file on the web:" #~ msgstr "Либо введите URL файла рабочего лиÑта в Ñети:" #~ msgid "Upload Worksheet" #~ msgstr "Импортировать рабочий лиÑÑ‚" #~ msgid "Errors found" #~ msgstr "Ðайдены ошибки" #~ msgid "Error found" #~ msgstr "Ðайдена ошибка" #~ msgid "Undo" #~ msgstr "Отменить" #~ msgid "Revision History" #~ msgstr "ИÑÑ‚Ð¾Ñ€Ð¸Ñ Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ð¹" #~ msgid "last edited on %(t)s by %(le)s" #~ msgstr "отредактировано в поÑледний раз %(t)s пользователем %(le)s" #~ msgid "optional" #~ msgstr "необÑзательно" #~ msgid "" #~ "Hi %s!\n" #~ "\n" #~ msgstr "" #~ "Привет %s!\n" #~ "\n" #~ msgid "There was an error uploading \"%s\" (please recheck the URL).%s" #~ msgstr "Возникла ошибка при загрузке \"%s\" (пожалуйÑта, проверьте URL).%s" #~ msgid "Successfully deleted \"%s\"" #~ msgstr "Файл \"%s\" уÑпешно удалён" #~ msgid "Error in introspection -- invalid cell id." #~ msgstr "Ошибка при Ñамоанализе — неправильный идентификатор Ñчейки." #~ msgid "You must login first in order to edit this worksheet." #~ msgstr "" #~ "Чтобы редактировать Ñтот рабочий лиÑÑ‚, " #~ "вы должны войти." #~ msgid "Old password not given" #~ msgstr "Старый пароль не был введён" #~ msgid "Incorrect password given" #~ msgstr "Введён некорректный пароль" #~ msgid "New password not given" #~ msgstr "Ðовый пароль не был указан" #~ msgid "Please type in new password again." #~ msgstr "ПожалуйÑта, введите новый пароль ещё раз." #~ msgid "The passwords you entered do not match." #~ msgstr "Введённые пароли не Ñовпадают." #~ msgid "Confirmed" #~ msgstr "Подтверждено" #~ msgid "can't evaluate worksheet cells" #~ msgstr "не удаётÑÑ Ð²Ñ‹Ð¿Ð¾Ð»Ð½Ð¸Ñ‚ÑŒ Ñчейки рабочего лиÑта" #~ msgid "You must login first in order to rate this worksheet." #~ msgstr "" #~ "Ð”Ð»Ñ Ñ‚Ð¾Ð³Ð¾, чтобы оценить Ñтот рабочий " #~ "лиÑÑ‚ вы должны Ñначала войти." #~ msgid "Gees -- You can't fool the rating system that easily!" #~ msgstr "Фи! — ÐÐµÐ»ÑŒÐ·Ñ Ð¾Ð±Ð¼Ð°Ð½ÑƒÑ‚ÑŒ ÑиÑтему оценок так проÑто!" #~ msgid "" #~ "Thank you for rating the worksheet " #~ "%s! You can see all ratings of this" #~ " worksheet." #~ msgstr "" #~ "СпаÑибо за оценку рабочего лиÑта " #~ "%s! Ð’Ñ‹ можете поÑмотреть вÑе оценки Ñтого " #~ "лиÑта." #~ msgid "Rating Accepted" #~ msgstr "Оценка учтена" #~ msgid "The worksheet operation \"%s\" is not defined." #~ msgstr "ÐžÐ¿ÐµÑ€Ð°Ñ†Ð¸Ñ \"%s\" не определена Ð´Ð»Ñ Ñ€Ð°Ð±Ð¾Ñ‡ÐµÐ³Ð¾ лиÑта." #~ msgid "The user \"%s\" has no worksheet \"%s\"." #~ msgstr "У Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ \"%s\" нет рабочего лиÑта \"%s\"." #~ msgid "" #~ "There is no published worksheet with " #~ "name \"%s\". Redirecting to the index" #~ " of published worksheets in 10 " #~ "seconds...

    " #~ msgstr "" #~ "Ðет опубликованных рабочих лиÑтов Ñ " #~ "именем \"%s\". Перенаправление на ÑпиÑок " #~ "опубликованных рабочих лиÑтов через 10 " #~ "Ñекунд...

    " #~ msgid "You are not logged in or do not have access to the worksheet \"%s\"." #~ msgstr "" #~ "Ð’Ñ‹ не вошли в ÑиÑтему или не " #~ "имеете прав доÑтупа к рабочему лиÑту " #~ "\"%s\"." #~ msgid "This url can only be accessed through a POST request." #~ msgstr "Этот URL может быть принÑÑ‚ только через Ð·Ð°Ð¿Ñ€Ð¾Ñ POST." #~ msgid "You are not authorized to move \"%s\"" #~ msgstr "Ð’Ñ‹ не авторизованны Ð´Ð»Ñ Ð¿ÐµÑ€ÐµÐ¼ÐµÑ‰ÐµÐ½Ð¸Ñ \"%s\"" #~ msgid "Please request a specific worksheet" #~ msgstr "ПожалуйÑта, укажите рабочий лиÑÑ‚." #~ msgid "Language" #~ msgstr "Язык" #~ msgid "January" #~ msgstr "Январь" #~ msgid "February" #~ msgstr "Февраль" #~ msgid "March" #~ msgstr "Март" #~ msgid "April" #~ msgstr "Ðпрель" #~ msgid "May" #~ msgstr "Май" #~ msgid "June" #~ msgstr "Июнь" #~ msgid "July" #~ msgstr "Июль" #~ msgid "August" #~ msgstr "ÐвгуÑÑ‚" #~ msgid "September" #~ msgstr "СентÑбрь" #~ msgid "October" #~ msgstr "ОктÑбрь" #~ msgid "November" #~ msgstr "ÐоÑбрь" #~ msgid "December" #~ msgstr "Декабрь" sagenb-1.0.1/sagenb/translations/uk_UA/000077500000000000000000000000001311436262400177365ustar00rootroot00000000000000sagenb-1.0.1/sagenb/translations/uk_UA/LC_MESSAGES/000077500000000000000000000000001311436262400215235ustar00rootroot00000000000000sagenb-1.0.1/sagenb/translations/uk_UA/LC_MESSAGES/messages.mo000066400000000000000000002145451311436262400237020ustar00rootroot00000000000000Þ•ðœÂàä ý !7!V!f!z!#Š!®!½!Ä!«Ì!:x"6³"Fê"G1#Iy#«Ã#§o$%(%9% I%S%Z% l%y% ‚%8%É%bÜ% ?&J&OR&¢&«&¿&Ñ&ì&û&.'$E' j' w'„'€Œ' ( (7#([(0{(§¬(T)[) j)x)’)¨)*¸)]ã)‚A*,Ä*ñ*2+m:+(¨+Ñ+ð+ï, ÿ- ..?.. n.|.….™.¨.®.½.NÔ.#/:/L/4[//Ÿ/®/ Ë/ Ù/ æ/ð/ø/ 000 10@=0~00¡0´0Ä0!Ó0&õ0$1A1Y1 r1€1‰11 º1„Ä1I2 N2[2#k2 2š2¢2 ²2L¾2 3?&3f33ž3 ·3Ã3(É3#ò3!4:84:s45®41ä465 M5'Z5‚5)‘5$»5à56å506-M60{6=¬6ê6ï6) 737;7M7i7#y717 Ï7Ù78ï7(8=8 B8M8j8}8‚8’8¢8³³8•g9ý9: :*:I:f:„:s›:; ;,;<;Q; m; Ž;˜;·;Ö;5è;<9<O<o<€< •< <=³< ñ<ü<=%= *=6=S=%r=˜=¶=Ò=í= > >>+>%H> n>{>’> š>ì¨>-•?)Ã? í?@@ '@ 5@ @@ M@[@a@h@k@ ‡@•@¬@¾@Ñ@ã@õ@ AA$A +A€9A&ºA7áAB6BLKLiL"L¤L ÀLÍLßLïLþMN:NVNpNˆNN”NN £N­N ÁNÏNÔNäNôNüNO# O'1O&YOC€O ÄOÐOäOùOÿOPPP-PFPMP UPK`P¬PÆPáPðP õP^RbRtR‡T&JUrqUHäUV-V•„VœW·W"ÊWUíWPCY±”YFZRcZ¶Z»Z¶ÔZ"‹[—®[F\M\`\f\m\Ds\¸\+Á\eí\„S]Ø]uê]`^5w^ ­^ Î^IØ^"_ +_5_>_F_M_:h_7£_Û_ºô_é¯`ž™a‘8b.Êb·ùb%±c(×cd~d žeªe¯e¿e6Èeÿef&fDfSfYf-af!f(±fÚf)êf¹gÎgB×gh,h'?h¹gh!i 3i)=iZgiÂi.Ûi jjgj2…j3¸jDìjV1kQˆk“Úk nlzyl“ôl›ˆme$nŒŠnho€o‘o—oo£o©o²o¸o ÎoÚo êoMõoCp IpSpip~p„p$Œp±pÂpØp Þpèpñpv÷p)nr¿˜s0Xu<‰uBÆuB vLv.av.vN¿v w /w ;w<Hwœ…x{"y‡žyq&zŠ˜zu#{9™|8Ó}: ~ G~ T~^~(m~0–~#Ç~"ë~l#{«Ÿ K€X€•m€ 2NA=Îsëv_‚QÖ‚(ƒ3Fƒzƒîƒ'„#§„~Ë„IJ…`”…lõ…b‡u‡ “‡Ož‡=î‡,ˆjHˆ·³ˆ:k‰F¦Š/íŠe‹ãƒ‹]gŒ]ÅŒW#Ð{L‘a‘Dr‘S·‘) ’5’=J’,ˆ’µ’.Ê’.ù’t(“5“/Ó“.”k2”ž”=¸”*ö”!•3•D• X•(d•.•¼•,Í•ú•c–,x–*¥–*Ж)û– %—[F—L¢—Xï—LH˜<•˜Ò˜ë˜(™?-™m™ü…™‚š —š7¸šYðšJ› _›Gl›´›‡Ð›?XœÇ˜œ@`r¡Fž[žpžižZéžZDŸtŸŸh f} dä iI¡³¡PË¡!¢I>¢Oˆ¢ Ø¢]ã¢UA£I—£Kᣃ-¤±¤?º¤Cú¤ >¥ J¥9k¥¥¥fÀ¥Q'¦%y¦#Ÿ¦†Ã¦2J§}§#ާ@²§ó§¨.%¨.T¨8ƒ¨¼¨%Û©« «+«5I«-«>­«:ì«°'¬ جù¬"­3<­:p­X«­®:®9R®#Œ®c°®G¯?\¯8œ¯-Õ¯)°-°$I°Rn°Á°2Û°)±8±=±8]±S–±fê±>Q²5²BƲ= ³ G³ T³?a³¡³d¿³-$´4R´‡´–´æ°´K—¶Qã¶I5·+·«·$Ë·7ð·(¸$@¸e¸n¸¸?†¸"ƸKé¸ 5¹GV¹2ž¹!ѹWó¹Kº eºpº#…ºã©ºH»^Ö»75¼m¼|¼˜¼ ©¼(¶¼/ß¼œ½U¬½8¾l;¾f¨¾H¿ÐXÀ )Â-3ÃaÃ7tÃl¬ÃÄ*2Ä]Ä2vĩĮÈļwÅ4ÆvÅÆ=<ÈzÈ ‰È–È)±È'ÛÈ+É/ÉNÉEiÉ4¯É,äÉ•Êc§Ê} ˉ˥˴ËEÏË4ÌœJÌ'çÌ-Í =ÍJÍ9^͘Í'®Í ÖÍáÍ ÿÍ Î*(ÎKSΟÏ!±ÏÓÏäÏÐ>Ð^Ð:zÐCµÐCùÐ6=Ñ#tÑ(˜Ñ"ÁѬäÑ!‘ÓG³ÓRûÓ,NÔ*{Ô¦Ô »ÔÈÔáÔöÔ0 Õ)<ÕfÕ,wÕ,¤Õ ÑÕ ÞÕ éÕTöÕTKÖG ÖsèÖ\×8t×8­× æ× ó× Ø!Ø.4ØNcزØÉØàØ~õØMtÙEÂÙ:Ú CÚ¾NÚ¦ Ü ´Ü¦ÂÜÍiß>7àßvàcVáyºá4âCã>DäDƒä¥Èä€nç­ïç0éñÎéÀê@Úê;ëKWì,£ìÐí0åí î#î 4îÆ?î+ï32ïÿfïÞfðEñÉ[ñ@%òWfò;¾òúòó£ó¶óÏóáóòóB ô‘Lô’Þô:qõ9¬õ»æö.¢ø*Ñùzüú—wûwý{‡ý`þüdþa}/’Âeâ3HP|FÍ/D [^hIÇM9_]™M÷E†d%ë3JE–!' I ^c ­Â ?p u° & D ±K Rý aP ™² ¤L |ñ  n7z²ÄR¯[  Î%è,BZm~G‘Ù!ùQ7‰#¶%ÚL/*|Q§%ù; [

    Invalid confirmation key

    You are reporting a confirmation key that has not been assigned by this server. Please register with the server.

    Return to Upload or Create Data File or %(worksheet_name)s.%(num)d day%(num)d days%(num)d hour%(num)d hours%(num)d minute%(num)d minutes%(num)d second%(num)d seconds%(seconds)s ago%(t)s ago by %(le)s%(t)s by %(le)s(note that images are not recorded)24|twenty-four5|five8|eightWork through the tutorial (if you have trouble with it, view the static version).Restart, instead?

    Email address confirmed for user %(username)s

    Sage is a different approach to mathematics software.A session is a worksheet and a set of variables in some state.A worksheet is an ordered list of Sage calculations with output.A new password will be emailed to the email address connected to your account. However if you didn't confirm your email address you will be unable to recover your account.Access %(f)s in this worksheet by typing DATA+'%(f)s'. Here DATA is a special variable that gives the exact path to all data files uploaded to this worksheet.Account RecoveryAccount SettingsAcknowledgementAction...ActiveActive WorksheetsAdd New UserAdd UserAdd or DeleteAllow OpenID authentication (requires python ssl module)Answer a challengeAny cells with "#auto" in the input is automatically evaluated when the worksheet is first opened.AppearanceArchiveArchive selected worksheets so they do not appear in the default worksheet listArchivedArchived WorksheetsAttaching ScriptsAttributes for user lookupAuthenticationAutoevaluate Cells on LoadAutomatically re-publish when changes are madeBack to your personal worksheet listBad passwordBad usernameBase DNBegin a block with %%sh to have the rest of the block evaluated as a shell script. The current working directory is maintained.Bind DNBind PasswordBrowse published Sage worksheets
    (no login required)Browse the published worksheetsBrowse your computer to select a file to upload:By using Sage you help to support a viable open source alternative to Magma, Maple, Mathematica, and MATLAB. Sage includes many high-quality open source math packages.CancelCancel changesCases / TestsChange Auto-Save IntervalChange E-mail AddressChange PasswordChange account settings including passwordClick log commands you have entered in any worksheet of this notebook.Click Interrupt or press escape in any input cell. This will (attempt) to interrupt SAGE by sending many interrupt signals.Click here or press shift-return to evaluateClick here to pop outClick here to turn the above into a Sage worksheetClick on the left side of output to toggle between hidden, shown with word wrap, and shown without word wrap.Click to download and install tex fonts.Click to rename this worksheetClose this box to stop trying.Code is evaluated by exec'ing (after preparsing). Only the output of the last line of the cell is implicitly printed. If any line starts with "sage:" or ">>>" the entire block is assumed to contain text and examples, so only lines that begin with a prompt are executed. Thus you can paste in complete examples from the docs without any editing, and you can write input cells that contains non-evaluated plain text mixed with examples by starting the block with ">>>" or including an example.CollaboratorsCommentComment/Uncomment BlocksCongratulations %(u)s! You can now sign into the Sage Notebook.ConstructionsContinueCopy this worksheetCopy worksheetCountCreate AccountCreate a good passwordCreate a new Sage worksheet version of the last 100 commands in the above log.Create a new worksheetCreate a usernameCreate accountCreating new users is disabled by the administrator.Current FolderCurrent e-mailCustomizing the Notebook CSSDATA VariableDIR VariableData fileData...Default LanguageDefault systemDeleteDelete All OutputDelete CellDelete all cell contents, then press backspace.Delete all outputDelete worksheetDeleted WorksheetsDeveloper GuideDiscard & quitDiscard changes to this worksheetDo you want to publish this worksheet?Doc worksheet idle timeout (seconds)Doc worksheet pool sizeDocument does not exist.DocumentationDownloadDownload All ActiveDownload selected worksheetsDownload.Each block of code is run from its own directory. If any images are created as a side effect, they will automatically be displayed.EditEdit a copy.Edit plain textEdit text version of this worksheetEdit this.ElapsedEmail ConfirmedEmpty TrashEmptying the trash will permanently delete all items in the trash. Continue?Enable LDAP AuthenticationEnable published interacts (EXPERIMENTAL; USE AT YOUR OWN RISK)Enable user registrationEnable/disable pretty_printingEnter your email addressEnvironmentErrorError applying function to worksheet(s).Error displaying worksheet listing.Error updating cell output after Error uploading file (missing %(field)s arg).%(backlinks)sError uploading file (missing field "file"). %(backlinks)sError uploading file (missing filename).%(backlinks)sError uploading worksheet '%(msg)s'.%(backlinks)sError: can't add more than 500 collaborators at a timeEvaluate AllEvaluate Cell using GAP, Singular, etc.Evaluate InputEvaluate all input cells in the worksheetEvaluate all input cells using %(i)sExitExpected "%(wanted)s" after "%(key)s", got "%(token)s"Expected a color value "%(arg)s" after "%(key)s"Expected an integer "%(arg)s" after "%(key)s"Expected an integer "%(key)s" before "%(token)s"Explore a collection of in-depth tutorials on specific topicsFailFailed to save worksheet.Fast Static Versions of the DocumentationFile...Files and ScriptsFind Help and DocumentationForgot passwordFull Text Search of Docs and SourceGeneral and Advanced Pure and Applied MathematicsGet ImageGet Started with SageGive access to your worksheet to the above collaboratorsGo to the worksheet.HelpHelp AboutHelp via Internet Chat (IRC)Hi %(username)s! HideHide All OutputHide all outputHide/Show OutputHighlight text and press ctrl-. to comment it and ctrl-, to uncomment it. Alternatively, use ctrl-3 and ctrl-4.Highlight text and press > to indent it all and < to unindent it all (works in Safari and Firefox). In Firefox you can also press tab and shift-tab.HistoryHomeHow do I construct ... in Sage?How many bits are in one byte?How to use the Sage NotebookIdle check interval (seconds)Idle timeout (seconds)If you create a file $HOME/.sage/notebook.css then it will get applied when rendering the notebook. See Indenting BlocksInput RulesInsert New CellInsert New Text CellInteractive Dynamic WidgetsInteractively use this worksheetInterruptInterrupt Running CalculationsInterrupt and Restart SessionsInterrupt attemptInterrupt currently running calculations, if possibleInvalid challenge responseInvalid email addressInvalid filename. %(backlinks)sInvalid usernameInvite CollaboratorsIs pi > e?Java Applet HiddenJavascript must be enabled in order to use the Sage Notebook.Jmol ImageKey and Mouse BindingsKnown Sage Users:LDAPLast EditedLearn to write Sage programsLet others edit this worksheetLoad a new worksheet stored in a fileLoad worksheet from a file...Loading SAGE/Python ScriptsLoading and Saving ObjectsLoading and Saving SessionsLogLog inLog in to edit a copy.Log out of the Sage notebookMake this worksheet publicly viewableManage UsersMaximum history lengthMinutesModel VersionMove the mouse between cells until a blue bar appears. Shift-click on the blue bar to create a new text cell. Double click on existing text to edit it. Use $...$ and $$...$$ to include typeset math in the text block.Move the selected worksheets out of the trashMove the selected worksheets to the trashMove this worksheet to the trashMulti Cell ModeNew UserNew WorksheetNew e-mailNew passwordNew worksheetNewerNewestNoNo challenge response givenNo data filesNo email address givenNo password givenNo such worksheet.No username givenNotebook SettingsNumber of word-wrap columnsOld passwordOlderOldestOne Cell ModeOnly the owner of a worksheet is allowed to share it. You can do whatever you want if you make your own copy.Or enter the URL of a file on the web:Or enter the name of a new file, which will be created:Other published documents...OwnerParen matchingPassPasswordPasswords didn't matchPick a usernamePlease ask the server administrator to configure a challenge!Please enter a name for this worksheet.Please log in to the Sage notebookPlease specify a worksheet to load. %(backlinks)sPossible failure deleting worksheet.Press ctrl-; in a cell to split it into two cells, and ctrl-backspace to join them. Press ctrl-enter to split a cell and evaluate both pieces.Press shift-enter. You can start several calculations at once. If you press alt-enter instead, then a new cell is created after the current one. If you press ctrl-enter then the cell is split and both pieces are evaluated separately.Press tab while the cursor is on an identifier. On some web browsers (e.g., Opera) you must use control-space instead of tab.Pretty print (typeset) outputPrintPrint this worksheetProblem inserting new input cell after current input cell.\nPublishPublish this onePublishedPublished WorksheetsPublished on %(t)sPut "%%gap", "%%singular", etc. as the first input line of a cell; the rest of the cell is evaluated in that system.Put ?? after the object and press tab or shift-enter (shift-enter overwrites output and saves to worksheet).Put @interact on the line before a function definition. Type interact? for more details.Put the mouse between an output and input until the horizontal line appears and click. If you press Alt-Enter in a cell, the cell is evaluated and a new cell is inserted after it.Quit the worksheet processRateRatingRatings for %(wn)sRe-publish worksheetRe-type your passwordReference ManualRemember meRenameRename this worksheetRename worksheetReport a ProblemReport a problem or submit a bug to improve SageRequested public worksheet does not existRequire e-mail for account registrationRerateResetRestartRestart the worksheet processRestart worksheetReturn to Upload File.Retype new passwordRevert to this oneRevisionRevision %(lr)sRevision History -- Previous sessionsRevision ListRevision from %(ta)s agoRevisionsSage DocumentationSage NotebookSage Notebook versionSage Source BrowserSage makes it easy for you to use most mathematics software together. Sage includes GAP, GP/PARI, Maxima, and Singular, and dozens of other open packages.Sage versionSage: History for %(u)sSaveSave & quitSave ChangesSave and quit worksheetSave changesSave changes and close windowSave interval (seconds)Save this worksheet to an sws fileSave worksheet to a file...Search UsersSearch WorksheetsSearch results:Search the SAGE documentation by typing
    search_doc("my query")
    in an input cell and press shift-enter. Search the source code of SAGE by typing
    search_src("my query")
    and pressing shift-enter. Arbitrary regular expressions are allowed as queries.Searching for Sage server...Select a file related functionSelect a worksheet functionSelect an OpenID providerSelect an attached fileSendServerSettingsShareShare nowShare this documentShell ScriptsShowShow All OutputShow all outputSign inSign outSign upSign up for a Sage Notebook accountSign up for a new Sage Notebook accountSomeone else is viewing this worksheetSorry, but you need a browser that supports the <canvas> tag.Source CodeSpecial Cell BlocksSplit and Join CellsStartStatic version...StatusStopStop publishingStop selected worksheetsSubmitSuspendSuspensionSuspicious filename "%(filename)s" encountered uploading file.%(backlinks)sSwitch to multi-cell modeSwitch to single-cell modeTab CompletionTextThank you for registering for the Sage notebook. To complete your registration, copy and paste the following link into your browser: %(url_prefix)s://%(addr)s:%(port)s/confirm?key=%(key)s You will be taken to a page which will confirm that you have indeed registered.The Sage notebook is a collection of worksheets, saved objects, and user information.The Sage NotebookThe Sage Notebook is based upon work supported by the National Science Foundation under grants DMS-0821725, DMS-1020378, DMS-0713225, DMS-0555776, DMS-0545904, DMS-0838212, DMS-0757627, DUE-1020378, DUE-1022574, DMS-1015114, etc. Any opinions, findings, and conclusions or recommendations expressed in this material are those of the author(s) and do not necessarily reflect the views of the National Science Foundation. See also http://sagemath.org/development-ack.html.The Sage Notebook was primarily written by William Stein with substantial contributions from Tom Boothby, Timothy Clemans, Alex Clemesha, Mike Hansen, Bobby Moretti, Yi Qiang, and Dorian Raymer.The confirmation system is not active.The data filename already exists in other worksheet Delete the file in the other worksheet before creating a link.The password for the user %(u)s has been reset to %(p)sThe temporary password for the new user %(username)s is %(password)sThe username must start with a letter and be between 4 and 32 characters long. It can only consist of letters, numbers, underscores, and one dot (.).The variable DIR contains the directory from which you started the SAGE notebook. For example, to open a file in that directory, do "open(DIR+'filename')".Thematic TutorialsThere are no published worksheets.There was an error uploading the worksheet. It could be an old unsupported format or worse. If you desperately need its contents contact the sage-support group and post a link to your worksheet. Alternatively, an sws file is just a bzip2 tarball; take a look inside! %(backlinks)sThis Sage Worksheet is currently shared with the people listed in the box below.This Sage notebook is not configured to load worksheets from 'https' URLs. Try a different URL or download the worksheet and upload it directly from your computer. %(backlinks)sThis page is rated %(wr).1f.This worksheet is read only. Please make a copy or contact the owner to change it.TimeTitle of saved worksheetTo fix unmatched or mis-matched parentheses, braces or brackets, press ctrl-0. Parentheses before the cursor will be matched, minding strings and (Python) comments.To quickly try out Sage start hereTo save this image, you can try right-clicking on the image to copy it or save it to a file, or you may be able to just drag the image to your desktop.ToggleToggle the top barTotalTotalsTrashTrying again in %(num)d second...Trying again in %(num)d seconds...TutorialType "%%time" at the beginning of the cell.Type "restart" to restart the SAGE interpreter for a given worksheet. (You have to interrupt first.)Type ? immediately after the object or function and press tab or shift-enter (shift-enter overwrites output and saves to worksheet).Type of challengeType pretty_print_default() in an input cell and press shift-enter. All future output will be typeset automatically.Typesetting All OutputURL must start with http, https, or ftp.%(backlinks)sUnable to interrupt calculation.UnarchiveUnarchive selected worksheets so it appears in the default worksheet listUndeleteUnsuspendUntitledUpdatedUploadUpload or Create Data FileUpload or Create Data File to attach to worksheet "%(wn)s"Upload or create a data file in a wide range of formatsUpload or create file...Use "attach filename.sage" or "attach filename.py". Attached files are automatically reloaded when the file changes. The file $HOME/.sage/init.sage is attached on startup if it exists.Use "load filename.sage" and "load filename.py". Load is relative to the path you started the notebook in. The .sage files are preparsed and .py files are not. You may omit the .sage or .py extension. Files may load other files.Use "save obj1 obj2 ..." and "load obj1 obj2 ...". This allows for easy moving of objects from one worksheet to another, and saving of objects for later use.Use "save_session('name')" to save all variables to an object. Use "load_session('name')" to merge in all variables from a saved session.Use Most Mathematics Software from Within SageUse Sage for studying calculus, elementary to very advanced number theory, cryptography, commutative algebra, group theory, graph theory, numerical and exact linear algebra, and more.Use a Mainstream Programming LanguageUse a challenge for account registrationUse an Open Source AlternativeUse the Data menu to upload images and other files, and create new files that can be shared between worksheets. The DATA variable contains the path to the data files. For example, to open a file in that directory, do "open(DATA+'filename')". If foo.sage is a Sage file that you uploaded, type "load foo.sage"; if foo.py is a Python file, you can import it by typing "import foo".Useful TipsUserUser ManagementUsernameUsername Attribute (i.e. cn, uid or userPrincipalName)Username ErrorUsername already in useUsername is not in the systemUsername takenUsersVersionView a 4000+ page reference manual about SageView a log of recent computationsView changes to this worksheet over timeView plain textView plain text version of this worksheetWelcome to Sage! You can create a new worksheet, view published worksheets, or read the documentation.Welcome!What do you want to call it? (if different than the original name)What is 2 plus 3?What is 3 times 8?What is the largest prime factor of 15?With the Sage Notebook anyone can create, collaborate on, and publish interactive worksheets. In a worksheet, one can write code using Sage, Python, and other software included in Sage.Working DirectoryWorksheetWorksheet is locked. Cannot insert cells.Worksheet is publicly viewable at %(u)sWorksheet process limitsWorksheet process users (comma-separated list)Wrong passwordYesYou can publish your worksheet to the Internet, where anyone will be able to access and view it online.You do not have permission to access this locationYou do not have permission to access this worksheetYou may add or remove collaborators (separate user names by commas).You may download %(f)s or create a link to this file in worksheet You requested to evaluate a cell that, for some reason, the server is unaware of.You work with Sage using the highly regarded scripting language Python. You can write programs that combine serious mathematics with anything else.Your EmailYour browser / OS combination is not supported.\nPlease use Firefox or Opera under Linux, Windows, or Mac OS X, or Safari.Your email address is required for account confirmation and recovery. You will be emailed a confirmation link right after you successfully sign up.Your new password is %(key)s Sign in at %(url_prefix)s://%(addr)s:%(port)s/ Make sure to reset your password by going to Settings in the upper right bar.Your password must have at least 4 characters. Your password can not contain your username or spaces.Your username must start with a letter and be between 3 and 64 characters long. You may only use letters, numbers, underscores, @, and dots.Your worksheet will be assigned a unique address (URL) that you can send to your friends and colleagues.browse directorycs_CZde_ATen_USes_ESevaluatefr_FRillegal link attempt!last editedleave a commentloading...or delete %(f)s.pt_BRpublishedreCAPTCHA private keyreCAPTCHA public keyru_RUrunnings (canceling further update checks).select worksheetsorry, no match founduk_UAunprintedusernamey|yesProject-Id-Version: sagenb Report-Msgid-Bugs-To: POT-Creation-Date: 2015-07-16 11:00+0300 PO-Revision-Date: 2015-07-20 15:29+0300 Last-Translator: Olena O. Somenko Language-Team: Olena O. Somenko MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit Generated-By: Babel 1.3

    Ðевірний ключ підтвердженнÑ

    Ви надали ключ підтвердженнÑ, Ñкий не зв'Ñзаний із цим Ñервером. Будь-лаÑка, зареєÑтруйтеÑÑŒ на Ñервері.

    ПовернутиÑÑ Ð´Ð¾ Завантажити або Ñтворити файл даних або %(worksheet_name)s.%(num)d доба%(num)d доби%(num)d діб%(num)d година%(num)d години%(num)d годин%(num)d хвилина%(num)d хвилини%(num)d хвилин%(num)d Ñекунда%(num)d Ñекунди%(num)d Ñекунд%(seconds)s тому%(t)s тому кориÑтувачем %(le)s%(t)s тому кориÑтувачем %(le)s(зверніть увагу, що Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð½Ñ Ð½Ðµ запиÑані)24|двадцÑть чотири5|п'Ñть8|віÑімОзнайомтеÑÑŒ із практичними рекомендаціÑми (Ñкщо у Ð²Ð°Ñ Ð²Ð¸Ð½Ð¸ÐºÐ½ÑƒÑ‚ÑŒ проблеми з Ñ—Ñ… переглÑдом, викориÑтовуйте Ñтатичну верÑÑ–ÑŽ).Можливо, заміÑть цього, ви хочете перезапуÑтити, робочий аркуш?

    ÐдреÑа електронної пошти підтверджена Ð´Ð»Ñ ÐºÐ¾Ñ€Ð¸Ñтувача %(username)s

    Sage — це інший підхід до математичного програмного забезпеченнÑ.СеÑÑ–Ñ â€” це робочий аркуш Ñ– набір змінних у деÑкому Ñтані.Робочий аркуш — це впорÑдкований ÑпиÑок обчиÑлень Sage із результатами.Ðовий пароль буде відправлено за адреÑою електронної пошти, вказаної у вашому обліковому запиÑÑ–. Однак, Ñкщо ви не підтвердили Ñвою адреÑу електронної пошти, ви не зможете відновити Ñвій обліковий запиÑ.ВикориÑтовуйте %(f)s в цьому робочому аркуші, ввівши DATA+'%(f)s'. Тут DATA — це Ñпеціальна змінна, що міÑтить повний шлÑÑ… до уÑÑ–Ñ… файлів, прикріплених до цього робочого аркуша.Ð’Ñ–Ð´Ð½Ð¾Ð²Ð»ÐµÐ½Ð½Ñ Ð¾Ð±Ð»Ñ–ÐºÐ¾Ð²Ð¾Ð³Ð¾ запиÑуÐÐ°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ð¾Ð±Ð»Ñ–ÐºÐ¾Ð²Ð¾Ð³Ð¾ запиÑуПодÑкаДіÑ...ÐктивніÐктивні робочі аркушіДодати нового кориÑтувачаДодати кориÑтувачаДодати чи ВидалитиДозволити аутентифікацію через OpenID (потрібен python модуль ssl)Пройдіть перевіркуУÑÑ– Ð¿Ð¾Ð»Ñ Ñ–Ð· введеним Ñловом "#auto" будуть автоматично виконані, коли відкриєтьÑÑ Ñ€Ð¾Ð±Ð¾Ñ‡Ð¸Ð¹ аркуш.ВиглÑдÐрхівуватиÐрхівувати вибрані робочі аркуші, щоб вони не відображалиÑÑŒ на домашній ÑторінціÐрхівЗаархівовані робочі Ð°Ñ€ÐºÑƒÑˆÑ–ÐŸÑ€Ð¸ÐºÑ€Ñ–Ð¿Ð»ÐµÐ½Ð½Ñ Ñценаріїв до робочого аркушаÐтрибути Ð´Ð»Ñ Ð¿Ð¾ÑˆÑƒÐºÑƒ кориÑтувачівÐутентифікаціÑÐвтоматично виконувати Ð¿Ð¾Ð»Ñ Ð¿Ñ€Ð¸ завантаженні робочого аркуша.Ðвтоматично оновлювати опубліковану верÑÑ–ÑŽ піÑÐ»Ñ Ð²Ð½ÐµÑÐµÐ½Ð½Ñ Ð·Ð¼Ñ–Ð½ÐŸÐ¾Ð²ÐµÑ€Ð½ÑƒÑ‚Ð¸ÑÑ Ð´Ð¾ ÑпиÑку ваших робочих аркушівÐевірний парольÐекоректне ім'Ñ ÐºÐ¾Ñ€Ð¸ÑтувачаБаза пошукуВведіть першим Ñ€Ñдком %%sh у полі вводу, щоб решта Ð¿Ð¾Ð»Ñ Ð±ÑƒÐ»Ð° інтерпретована Ñк Ñценарій оболонки. Поточна Ð´Ð¸Ñ€ÐµÐºÑ‚Ð¾Ñ€Ñ–Ñ Ð¿Ñ–Ð´Ñ‚Ñ€Ð¸Ð¼ÑƒÑ”Ñ‚ÑŒÑÑ.ПідключатиÑÑ Ñк (Bind DN)Пароль підключеннÑПереглÑнути опубліковані робочі аркуші Sage
    (реєÑÑ‚Ñ€Ð°Ñ†Ñ–Ñ Ð½Ðµ потрібна)ПереглÑнути опубліковані робочі аркушіВиберіть файл на вашому комп'ютері Ð´Ð»Ñ Ð·Ð°Ð²Ð°Ð½Ñ‚Ð°Ð¶ÐµÐ½Ð½Ñ:ВикориÑтовуючи Sage, ви допомагаєте підтримувати вільнорозповÑюджувану альтернативу Magma, Maple, Mathematica Ñ– MATLAB. Sage міÑтить велику кількіÑть виÑокоÑкіÑних математичних пакетів із відкритим вихідним кодом.СкаÑуватиСкаÑувати зміниТеÑтиЗмінити інтервал автоматичного збереженнÑЗмінити адреÑу електронної поштиЗмінити парольЗмінити Ð½Ð°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ð¾Ð±Ð»Ñ–ÐºÐ¾Ð²Ð¾Ð³Ð¾ запиÑу, включаючи парольÐатиÑніть log, щоб переглÑнути вÑÑ– команди, Ñкі ви ввели у будь-Ñкому робочому аркуші.ÐатиÑніть Перервати або натиÑніть Escape у будь-Ñкому полі вводу. Це змуÑить Sage (Ñпробувати) перервати поточну задачу, відправивши велику кількіÑть Ñигналів перериваннÑ.ÐатиÑніть тут або Shift+Enter Ð´Ð»Ñ Ð²Ð¸ÐºÐ¾Ð½Ð°Ð½Ð½ÑВідкрити в окремому вікніÐатиÑніть тут, щоб відкрити вибране Ñк робочий аркуш SageÐатиÑніть зліва від результатів, щоб переключити режим відображеннÑ: прихований, з перенеÑеннÑм Ñлів, без перенеÑÐµÐ½Ð½Ñ Ñлів.ÐатиÑніть, щоб завантажити та вÑтановити шрифти TeX.ÐатиÑніть тут, щоб перейменувати цей робочий аркушЗакрийте це повідомленнÑ, щоб припинити Ñпроби.Код виконуєтьÑÑ Ð·Ð° допомогою exec (піÑÐ»Ñ Ð¿Ñ€ÐµÐ¿Ð°Ñ€Ñингу). Тільки вивід оÑтаннього Ñ€Ñдка в полі буде відображатиÑÑ Ð¿Ð¾ замовчуваннÑм. Якщо Ñкий-небудь Ñ€Ñдок починаєтьÑÑ Ð· "sage:" чи ">>>" то вважаєтьÑÑ, що вÑе поле міÑтить текÑÑ‚ Ñ– приклади, тому будуть виконуватиÑÑ Ñ‚Ñ–Ð»ÑŒÐºÐ¸ Ñ€Ñдки, що починаютьÑÑ Ð· підказки. Таким чином, ви можете вÑтавлÑти приклади із документації повніÑтю, без будь-Ñких правок, а також пиÑати у полÑÑ… вводу звичайний текÑÑ‚, що не буде виконуватиÑÑ, разом з прикладами, Ñкщо почнете поле з ">>>" або вÑтавите приклад із документації.СпівавториКоментарКоментуваннÑ/Ð Ð¾Ð·ÐºÐ¾Ð¼ÐµÐ½Ñ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ð±Ð»Ð¾ÐºÑ–Ð²Ð’Ñ–Ñ‚Ð°Ñ”Ð¼Ð¾ %(u)s! Тепер ви можете увійти до Sage Notebook.Програмні конÑтрукціїПродовжитиКопіювати поточний робочий аркушКопіювати робочий аркушПідрахунокСтворити обліковий запиÑСтворіть надійний парольСтворити новий робочий аркуш Sage із оÑтанніх 100 команд з Ñ–Ñторії.Створити новий робочий аркушВиберіть ім'Ñ ÐºÐ¾Ñ€Ð¸ÑтувачаСтворити обліковий запиÑÐ¡Ñ‚Ð²Ð¾Ñ€ÐµÐ½Ð½Ñ Ð½Ð¾Ð²Ð¸Ñ… кориÑтувачів заборонено адмініÑтратором.Поточна папкаПоточна адреÑа електронної поштиКаÑÑ‚Ð¾Ð¼Ñ–Ð·Ð°Ñ†Ñ–Ñ CSS Sage NotebookЗмінна DATAЗмінна DIRФайл данихДані...Мова по замовчуваннÑмСиÑтема за замовчуваннÑмВидалитиВидалити вÑÑ– результатиВидалити полеВидаліть вміÑÑ‚ Ð¿Ð¾Ð»Ñ Ñ–, потім, натиÑніть Backspace.Видалити вÑÑ– результатиВидалити робочий аркушВидалені робочі аркушіІнÑÑ‚Ñ€ÑƒÐºÑ†Ñ–Ñ Ñ€Ð¾Ð·Ñ€Ð¾Ð±Ð½Ð¸ÐºÐ°Ð¡ÐºÐ°Ñувати Ñ– вийтиСкаÑувати зміни, внеÑені до цього робочого аркушаВи хочете опублікувати цей робочий аркуш?Тайм-аут Ð¾Ñ‡Ñ–ÐºÑƒÐ²Ð°Ð½Ð½Ñ (в Ñекундах) робочого аркушаРозмір пула документації робочого аркушаЗапитуваного документу не Ñ–Ñнує.ДокументаціÑЕкÑпортуватиЗберегти вÑÑ– виділеніЗавантажити вибрані робочі аркушіЗавантажити.Кожне поле запуÑкаєтьÑÑ Ñƒ влаÑній директорії. Якщо під Ñ‡Ð°Ñ Ñ€Ð¾Ð±Ð¾Ñ‚Ð¸ ÑтворюютьÑÑ Ñ„Ð°Ð¹Ð»Ð¸ зображень, то вони будуть відображатиÑÑ Ð°Ð²Ñ‚Ð¾Ð¼Ð°Ñ‚Ð¸Ñ‡Ð½Ð¾.РедагуватиРедагувати копію.Редагувати Ñк звичайний текÑтРедагувати текÑтову верÑÑ–ÑŽ цого робочого аркушаРедагуватиМинулоÐдреÑу електронної пошти підтвердженоОчиÑтити ÐºÐ¾ÑˆÐ¸ÐºÐžÑ‡Ð¸Ñ‰ÐµÐ½Ð½Ñ ÐºÐ¾ÑˆÐ¸ÐºÐ° оÑтаточно видалить уÑÑ– робочі аркуші в ньому. Продовжити?Дозволити аутентифікацію через LDAPДозволити інтерактивні опубліковані робочі аркуші (ЕКСПЕРИМЕÐТÐЛЬÐРФУÐКЦІЯ; ВИКОРИСТОВУЙТЕ ÐРСВІЙ РИЗИК)Дозволити реєÑтрацію кориÑтувачівУвімкнути/вимкнути pretty_printing (автоматичне Ñ„Ð¾Ñ€Ð¼Ð°Ñ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ð²Ð¸Ð²Ð¾Ð´Ñƒ)Введіть вашу адреÑу електронної поштиСередовищеПомилкаÐе вдалоÑÑ Ð·Ð°ÑтоÑувати функцію до робочого(их) аркуша(ів).Помилка при відображенні ÑпиÑку робочих аркушів.Помилка Ð¾Ð½Ð¾Ð²Ð»ÐµÐ½Ð½Ñ Ñ€ÐµÐ·ÑƒÐ»ÑŒÑ‚Ð°Ñ‚Ñ–Ð² виводу Ð¿Ð¾Ð»Ñ Ð¿Ñ–ÑÐ»Ñ ÐŸÐ¾Ð¼Ð¸Ð»ÐºÐ° Ð·Ð°Ð²Ð°Ð½Ñ‚Ð°Ð¶ÐµÐ½Ð½Ñ Ñ„Ð°Ð¹Ð»Ñƒ (відÑутній аргумент %(field)s arg).%(backlinks)sПомилка Ð·Ð°Ð²Ð°Ð½Ñ‚Ð°Ð¶ÐµÐ½Ð½Ñ Ñ„Ð°Ð¹Ð»Ñƒ (відÑутнє поле "Файл"). %(backlinks)sПомилка Ð·Ð°Ð²Ð°Ð½Ñ‚Ð°Ð¶ÐµÐ½Ð½Ñ Ñ„Ð°Ð¹Ð»Ñƒ (відÑутнє ім'Ñ Ñ„Ð°Ð¹Ð»Ñƒ).%(backlinks)sПомилка при завантаженні робочого аркуша '%(msg)s'.%(backlinks)sПомилка: не можна додати більше 500 Ñпівавторів за один разВиконати вÑеВиконати поле, викориÑтовуючи GAP, Singular та ін.Виконати введеннÑВиконати уÑÑ– Ð¿Ð¾Ð»Ñ Ð²Ð²Ð¾Ð´Ñƒ робочого аркушаВиконати уÑÑ– Ð¿Ð¾Ð»Ñ Ð²Ð²Ð¾Ð´Ñƒ, викориÑтовуючи %(i)sВихідОчікувалоÑÑŒ "%(wanted)s" піÑÐ»Ñ "%(key)s", але отримано "%(token)s"ОчікувалоÑÑŒ Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ ÐºÐ¾Ð»ÑŒÐ¾Ñ€Ñƒ "%(arg)s" піÑÐ»Ñ "%(key)s"ОчікувалоÑÑŒ ціле чиÑло "%(arg)s" піÑÐ»Ñ "%(key)s"ОчікувалоÑÑŒ ціле чиÑло "%(key)s" перед "%(token)s"ПереглÑнути колекцію підібраних практичних рекомендацій з окремих темЗбійÐе вдалоÑÑ Ð·Ð±ÐµÑ€ÐµÐ³Ñ‚Ð¸ робочий аркуш.Швидка Ñтатична верÑÑ–Ñ Ð´Ð¾ÐºÑƒÐ¼ÐµÐ½Ñ‚Ð°Ñ†Ñ–Ñ—Ð¤Ð°Ð¹Ð»...Файли та ÑценаріїЗнайти довідки та документаціюЗабули пароль?ПовнотекÑтовий пошук по документації та вихідному кодуЗагальна, вища, чиÑта Ñ– прикладна математикаОтримати зображеннÑПочаток роботи з SageÐадати доÑтуп до вашого робочого аркуша перерахованим нижче ÑпівавторамПерейти до робочого аркуша.ДопомогаКонтекÑтна довідкаДопомога на каналі IRC (Інтернет-чат)Вітаємо %(username)s! ПриховатиПриховати вÑÑ– результатиПриховати вÑÑ– результатиПриховати/Показати результатиВиділіть текÑÑ‚ Ñ– натиÑніть Ctrl-., щоб закоментувати його, Ñ–Ctrl-, щоб розкоментувати. Також можна викориÑтовувати Ctrl-3 Ñ– Ctrl-4.Виділіть текÑÑ‚ Ñ– натиÑніть > , щоб зробити відÑтуп та < Ð´Ð»Ñ Ð²Ð¸Ð´Ð°Ð»ÐµÐ½Ð½Ñ Ð²Ñ–Ð´Ñтупу (це працює у браузерах Safari та Firefox). У Firefox ви також можете викориÑтовувати Tab Ñ– Shift+Tab.ІÑторіÑДодомуЯк мені Ñтворити ... в Sage?Скільки бітів в одному байті?Як кориÑтуватиÑÑ Sage NotebookІнтервал між запитами (в Ñекундах)Тайм-аут Ð¾Ñ‡Ñ–ÐºÑƒÐ²Ð°Ð½Ð½Ñ (в Ñекундах)Якщо ви Ñтворите файл $HOME/.sage/notebook.css, то він буде викориÑтаний при відображенні Sage Notebook. Див. ВідÑтупи в блокахПравила введеннÑÐ’Ñтавити нове полеВÑтавити нове текÑтове полеІнтерактивні динамічні віджетиВикориÑтовувати цей робочий аркуш Ñ–Ð½Ñ‚ÐµÑ€Ð°ÐºÑ‚Ð¸Ð²Ð½Ð¾ÐŸÐµÑ€ÐµÑ€Ð²Ð°Ñ‚Ð¸ÐŸÐµÑ€ÐµÑ€Ð¸Ð²Ð°Ð½Ð½Ñ Ð¿Ð¾Ñ‚Ð¾Ñ‡Ð½Ð¸Ñ… обчиÑÐ»ÐµÐ½ÑŒÐŸÐµÑ€ÐµÑ€Ð¸Ð²Ð°Ð½Ð½Ñ Ñ– перезапуÑк ÑеÑійСпроба перериваннÑПерервати поточні активні розрахунки, Ñкщо це можливоÐевірна відповідь у полі Ð´Ð»Ñ Ð¿ÐµÑ€ÐµÐ²Ñ–Ñ€ÐºÐ¸ÐедійÑна адреÑа електронної поштиÐеправильне ім'Ñ Ñ„Ð°Ð¹Ð»Ñƒ. %(backlinks)sÐевірне ім'Ñ ÐºÐ¾Ñ€Ð¸ÑтувачаЗапроÑити ÑпівавторівЧи вірно, що Ï€>e?Java апплет Ð¿Ñ€Ð¸Ñ…Ð¾Ð²Ð°Ð½Ð¾Ð”Ð»Ñ Ñ€Ð¾Ð±Ð¾Ñ‚Ð¸ Sage Notebook має бути увімкнений Javascript.Ð—Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð½Ñ JmolГарÑчі клавіші та дії мишеюВідомі кориÑтувачі Sage:LDAPОÑÑ‚Ð°Ð½Ð½Ñ Ñ€ÐµÐ´Ð°ÐºÑ†Ñ–ÑÐавчитиÑÑ Ð¿Ð¸Ñати програми в SageДозволити іншим редагувати цей робочий аркушСтворити новий робочий аркуш, завантаживши його з файлуЗавантажити робочий аркуш з Ñ„Ð°Ð¹Ð»ÑƒÐŸÑ–Ð´ÐºÐ»ÑŽÑ‡ÐµÐ½Ð½Ñ Ñценаріїв Sage/PythonÐ—Ð°Ð²Ð°Ð½Ñ‚Ð°Ð¶ÐµÐ½Ð½Ñ Ñ‚Ð° Ð·Ð±ÐµÑ€ÐµÐ¶ÐµÐ½Ð½Ñ Ð¾Ð±'Ñ”ÐºÑ‚Ñ–Ð²Ð—Ð°Ð²Ð°Ð½Ñ‚Ð°Ð¶ÐµÐ½Ð½Ñ Ñ‚Ð° Ð·Ð±ÐµÑ€ÐµÐ¶ÐµÐ½Ð½Ñ ÑеÑійЖурналУвійтиУвійдіть, щоб відредагувати копію.Вийти із Sage NotebookДозволити переглÑдати цей робочий аркуш уÑім бажаючимУправлÑти кориÑтувачамиМакÑимальна довжина Ñ–ÑторіїХвилиниВерÑÑ–Ñ Ð¼Ð¾Ð´ÐµÐ»Ñ–Ðаведіть вказівник миші між полÑми так, щоб з'ÑвилаÑÑŒ ÑÐ¸Ð½Ñ Ð»Ñ–Ð½Ñ–Ñ. Shift+Клік на Ñиній лінії Ñтворить нове поле. Подвійний клік по Ñ–Ñнуючому текÑтовому полю дозволÑÑ” його відредагувати. Ð”Ð»Ñ Ð·Ð°Ð¿Ð¸Ñу математичних формул (в LaTeX) введіть $...$ Ñ– $$...$$ у текÑтовому полі.Відновити вибрані робочі аркуші з кошикаПереміÑтити вибрані робочі аркуші до кошикаПереміÑтити цей робочий аркуш до кошикаРежим з багатьма полÑмиÐовий кориÑтувачÐовий робочий аркушÐова адреÑа електронної поштиÐовий парольÐовий робочий аркушÐовіÐайновішіÐіВи не заповнили поле Ð´Ð»Ñ Ð¿ÐµÑ€ÐµÐ²Ñ–Ñ€ÐºÐ¸Ðемає файлів данихÐдреÑа електронної пошти не була введенаПароль не введеноЗапитуваний робочий аркуш не знайдено.Ім'Ñ ÐºÐ¾Ñ€Ð¸Ñтувача не вказаноÐÐ°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ NotebookМакÑимальна довжина Ñ€Ñдка при перенеÑенні ÑлівСтарий парольСтаріÐайÑтарішіРежим з одним полемТільки влаÑник робочого аркуша може поділитиÑÑ Ð½Ð¸Ð¼. Ви можете робити вÑе, що вам потрібно, Ñтворивши влаÑну копію.Ðбо введіть URL-адреÑу файлу в Інтернеті:Ðбо введіть ім'Ñ Ð½Ð¾Ð²Ð¾Ð³Ð¾ файлу, котрий буде Ñтворено:Інші опубліковані документи...ВлаÑникПарніÑть дужокПройденоПарольПаролі не ÑпівпадаютьВиберіть ім'Ñ ÐºÐ¾Ñ€Ð¸ÑтувачаБудь-лаÑка, звернітьÑÑ Ð´Ð¾ адмініÑтратора Ñервера Ð´Ð»Ñ Ð½Ð°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ð·Ð°Ñ…Ð¸Ñту від ботів!Будь-лаÑка, введіть ім'Ñ Ñ†ÑŒÐ¾Ð³Ð¾ робочого аркуша.Будь-лаÑка, увійдіть до Sage NotebookБудь-лаÑка, вкажіть робочий аркуш Ð´Ð»Ñ Ð·Ð°Ð²Ð°Ð½Ñ‚Ð°Ð¶ÐµÐ½Ð½Ñ. %(backlinks)sМожливо, ÑталаÑÑŒ помилка при видаленні робочого аркуша.ÐатиÑніть Ctrl-; в полі, щоб розбити його на два, Ñ– Ctrl+Backspace, щоб об'єднати Ñ—Ñ…. ÐатиÑніть Ctrl+Enter, щоб виконати Ñ€Ð¾Ð·Ð±Ð¸Ñ‚Ñ‚Ñ Ð¿Ð¾Ð»Ñ Ð½Ð° два та виконати обидві чаÑтини.ÐатиÑніть Shift+Enter. Ви можете розпочати декілька обчиÑлень одночаÑно. Якщо ж ви натиÑнете Alt-Enter, то буде Ñтворено нове поле відразу піÑÐ»Ñ Ð¿Ð¾Ñ‚Ð¾Ñ‡Ð½Ð¾Ð³Ð¾. РнатиÑненнÑCtrl+Enter розбиває поле на дві чаÑтини, що будуть виконуватиÑÑ Ð¾ÐºÑ€ÐµÐ¼Ð¾.ÐатиÑніть Tab поки курÑор знаходитьÑÑ Ð½Ð° ідентифікаторі. У деÑких браузерах (наприклад, в Opera) заміÑть Tab треба викориÑтовувати Ctrl+Пробіл.ÐÐ²Ñ‚Ð¾Ñ„Ð¾Ñ€Ð¼Ð°Ñ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ð²Ð¸Ð²Ð¾Ð´ÑƒÐ”Ñ€ÑƒÐºÑƒÐ²Ð°Ñ‚Ð¸Ðадрукувати цей робочий аркушВиникла проблема при вÑтавці нового Ð¿Ð¾Ð»Ñ Ð¿Ñ–ÑÐ»Ñ Ð¿Ð¾Ñ‚Ð¾Ñ‡Ð½Ð¾Ð³Ð¾.\nОпублікуватиОпублікувати цю верÑіюОпублікованіОпубліковані робочі аркушіОпубліковано %(t)sВведіть "%%gap", "%%singular" та ін. першим Ñ€Ñдком Ð¿Ð¾Ð»Ñ Ð²Ð²Ð¾Ð´Ñƒ; решта Ð¿Ð¾Ð»Ñ Ð±ÑƒÐ´Ðµ виконана в обраній ÑиÑтемі.Введіть ?? піÑÐ»Ñ Ð¾Ð±'єкта Ñ– натиÑніть Tab або Shift+Enter (Shift+Enter перезапиÑує Ð²Ð²ÐµÐ´ÐµÐ½Ð½Ñ Ñ– зберігає робочий аркуш).Введіть @interact у Ñ€Ñдку перед визначеннÑм функції. Введіть interact? Ð´Ð»Ñ Ð´ÐµÑ‚Ð°Ð»Ñ–Ð·Ð°Ñ†Ñ–Ñ—.Ðаведіть вказівник миші на міÑце над полем вводу Ñ– виводом таким чином, щоб з'ÑвилаÑÑŒ горизонтальна лініÑ, Ñ– натиÑніть. Якщо ви натиÑнете Alt+Enter, поточне поле буде виконано Ñ– піÑÐ»Ñ Ð½ÑŒÐ¾Ð³Ð¾ буде вÑтавлено нове.Завершити Ð¿Ñ€Ð¾Ñ†ÐµÑ Ñ€Ð¾Ð±Ð¾Ñ‡Ð¾Ð³Ð¾ аркушаОцінитиОцінкаОцінки Ð´Ð»Ñ %(wn)sОпублікувати повторноВведіть пароль ще разІнÑÑ‚Ñ€ÑƒÐºÑ†Ñ–Ñ ÐºÐ¾Ñ€Ð¸ÑтувачаЗапам'Ñтати менеПерейменуватиПерейменувати поточний робочий аркушПерейменувати робочий аркушПовідомити про проблемуПовідомити про проблему або відправити звіт про помилку Ð´Ð»Ñ Ð¿Ð¾ÐºÑ€Ð°Ñ‰ÐµÐ½Ð½Ñ Ñ€Ð¾Ð±Ð¾Ñ‚Ð¸ SageЗапитуваного опублікованого робочого аркуша не Ñ–ÑнуєВимагати адреÑу електронної пошти Ð´Ð»Ñ Ñ€ÐµÑ”Ñтрації облікового запиÑуЗмінити оцінкуСкинутиПерезапуÑтитиПерезапуÑтити Ð¿Ñ€Ð¾Ñ†ÐµÑ Ñ€Ð¾Ð±Ð¾Ñ‡Ð¾Ð³Ð¾ аркушаПерезапуÑтити робочий аркушПовернутиÑÑ Ð´Ð¾ Завантажити файл.Введіть пароль ще разВідновити до цієї верÑіїВерÑÑ–ÑВерÑÑ–Ñ %(lr)sІÑÑ‚Ð¾Ñ€Ñ–Ñ Ð·Ð¼Ñ–Ð½ — Попередні ÑеÑіїСпиÑок змінЗмінено %(ta)s днів Ñ‚Ð¾Ð¼ÑƒÐ—Ð¼Ñ–Ð½Ð¸Ð”Ð¾ÐºÑƒÐ¼ÐµÐ½Ñ‚Ð°Ñ†Ñ–Ñ SageSage NotebookВерÑÑ–Ñ Sage NotebookБраузер вихідного кодуЗа допомогою Sage дуже легко одночаÑно кориÑтуватиÑÑ Ð±Ñ–Ð»ÑŒÑˆÑ–Ñтю математичних програм. Sage включає в Ñебе GAP, GP/PARI, Maxima Ñ– Singular та багато інших відкритих пакетів програмного забезпеченнÑ.ВерÑÑ–Ñ SageSage: ІÑÑ‚Ð¾Ñ€Ñ–Ñ Ð´Ð»Ñ %(u)sЗберегтиЗберегти Ñ– вийтиЗберегти зміниЗавершити Ñ– закрити робочий аркушЗберегти зміниЗберегти зміни та закрити вікноІнтервал Ð°Ð²Ñ‚Ð¾Ð·Ð±ÐµÑ€Ñ–Ð³Ð°Ð½Ð½Ñ (в Ñекундах)Зберегти цей робочий аркуш Ñк файл swsЗберегти робочий аркуш у файлПошук кориÑтувачівПошук робочих аркушівРезультати пошуку:Ð”Ð»Ñ Ð¿Ð¾ÑˆÑƒÐºÑƒ в документації Sage введіть
    search_doc("ваш запит")
    в поле вводу Ñ– натиÑніть Shift+Enter. Знайти вихідний код Sage можна, ввівши
    search_src("ваш запит")
    Ñ– натиÑнувши Shift+Enter. У запитах можна викориÑтовувати довільні регулÑрні вирази.Пошук Ñервера Sage...Виберіть, що ви хочете зробити з файломВиберіть функцію ÑƒÐ¿Ñ€Ð°Ð²Ð»Ñ–Ð½Ð½Ñ Ñ€Ð¾Ð±Ð¾Ñ‡Ð¸Ð¼ аркушемВиберіть провайдера OpenIDВибрати вкладений файлВідправитиСерверÐалаштуваннÑПоділитиÑÑПоділитиÑÑПоділитиÑÑ Ñ†Ð¸Ð¼ документомСценарії оболонки (shell)ПоказатиПоказати вÑÑ– результатиПоказати вÑÑ– результатиУвійтиВийтиУвійтиЗареєÑтрувати новий обліковий Ð·Ð°Ð¿Ð¸Ñ Ð² Sage NotebookЗареєÑтрувати новий обліковий Ð·Ð°Ð¿Ð¸Ñ Ð² Sage NotebookХтоÑÑŒ іще переглÑдає цей робочий аркушВибачте, але потрібен браузер, котрий підтримує HTML тег <canvas>.Вихідний кодСпеціальні блоки в полÑÑ… Ð²Ð²Ð¾Ð´ÑƒÐ Ð¾Ð·Ð´Ñ–Ð»ÐµÐ½Ð½Ñ Ñ‚Ð° об'Ñ”Ð´Ð½Ð°Ð½Ð½Ñ Ð¿Ð¾Ð»Ñ–Ð²ÐŸÐ¾Ñ‡Ð°Ñ‚Ð¸Ð¡Ñ‚Ð°Ñ‚Ð¸Ñ‡Ð½Ð° верÑÑ–Ñ...СтатуÑЗавершитиВидалити з опублікованихЗавершити роботу вибраних робочих аркушівПідтвердитиЗаблокуватиБлокуваннÑПідозріле ім'Ñ Ñ„Ð°Ð¹Ð»Ñƒ "%(filename)s" виÑвлено при завантаженні файлу.%(backlinks)sПереключитиÑÑ Ð´Ð¾ режиму з багатьма полÑмиПереключитиÑÑ Ð´Ð¾ режиму з одним полемÐÐ²Ñ‚Ð¾Ð·Ð°Ð²ÐµÑ€ÑˆÐµÐ½Ð½Ñ Ð¿Ð¾ натиÑненню TabТекÑтДÑкуємо за реєÑтрацію в Sage Notebook. Ð”Ð»Ñ Ð·Ð°Ð²ÐµÑ€ÑˆÐµÐ½Ð½Ñ Ñ€ÐµÑ”Ñтрації Ñкопіюйте Ñ– вÑтавте наÑтупне поÑÐ¸Ð»Ð°Ð½Ð½Ñ Ñƒ ваш браузер: %(url_prefix)s://%(addr)s:%(port)s/confirm?key=%(key)s ВідкриєтьÑÑ Ñторінка, на Ñкій з'ÑвитьÑÑ Ð¿Ð¾Ð²Ñ–Ð´Ð¾Ð¼Ð»ÐµÐ½Ð½Ñ, що підтверджуватиме вашу уÑпішну реєÑтрацію.Sage Notebook — це ÐºÐ¾Ð»ÐµÐºÑ†Ñ–Ñ Ñ€Ð¾Ð±Ð¾Ñ‡Ð¸Ñ… аркушів, збережених об'єктів та інформації кориÑтувача.Sage NotebookSage Notebook базуєтьÑÑ Ð½Ð° роботі, підтримуваній National Science Foundation в рамках грантів DMS-0821725, DMS-1020378, DMS-0713225, DMS-0555776, DMS-0545904, DMS-0838212, DMS-0757627, DUE-1020378, DUE-1022574, DMS-1015114 та ін. Будь-Ñкі думки, знахідки, виÑновки чи рекомендації, предÑтавлені тут, Ñ” оÑобиÑтою позицією автора(ів) Ñ– можуть не Ñпівпадати із поглÑдами National Science Foundation. Див. також http://sagemath.org/development-ack.html.Sage Notebook був Ñпершу Ñтворений William Stein, із Ñуттєвим внеÑком Tom Boothby, Timothy Clemans, Alex Clemesha, Mike Hansen, Bobby Moretti, Yi Qiang, Ñ– Dorian Raymer.СиÑтема Ð¿Ñ–Ð´Ñ‚Ð²ÐµÑ€Ð´Ð¶ÐµÐ½Ð½Ñ Ð½Ðµ активна.Файл з вибраною назвою вже Ñ–Ñнує в іншому робочому аркуші. Видаліть файл в іншому аркуші перед ÑтвореннÑм зв'Ñзаної копії.Пароль Ð´Ð»Ñ ÐºÐ¾Ñ€Ð¸Ñтувача %(u)s було Ñкинуто до%(p)sТимчаÑовий пароль Ð´Ð»Ñ Ð½Ð¾Ð²Ð¾Ð³Ð¾ кориÑтувача %(username)s: %(password)sІм'Ñ ÐºÐ¾Ñ€Ð¸Ñтувача має починатиÑÑ Ð· літери та міÑтити від 4 до 32 Ñимволів. Можна викориÑтовувати лише літери, цифри, знаки підкреÑÐ»ÐµÐ½Ð½Ñ Ñ– одну точку (.).Змінна DIR міÑтить адреÑу директорії, із Ñкої було запущено Sage Notebook. Ðаприклад, щоб відкрити файл у цій директорії, введіть "open(DIR+'ім'Ñ Ñ„Ð°Ð¹Ð»Ñƒ')".Тематичні практичні рекомендаціїÐемає опублікованих робочих аркушів.Виникла помилка при завантаженні робочого аркуша. Це може бути Ñтарий непідтримуваний формат або пошкоджений файл. Якщо вам вÑе ж дуже потрібний вміÑÑ‚ цього файлу, напишіть до sage-support group Ñ– дайте поÑÐ¸Ð»Ð°Ð½Ð½Ñ Ð½Ð° ваш робочий аркуш. Ð’ іншому випадку, Ñпробуйте подивитиÑÑ Ð²Ñередину sws файлу: це текÑтовий файл у tarr-архіві, ÑтиÑнутому bzip2! %(backlinks)sЦей робочий аркуш наразі не Ñ” Ñпільним Ð´Ð»Ñ Ð»ÑŽÐ´ÐµÐ¹, перерахованих нижче.Цей Sage Notebook-Ñервер не налаштований Ð´Ð»Ñ Ð·Ð°Ð²Ð°Ð½Ñ‚Ð°Ð¶ÐµÐ½Ð½Ñ Ñ€Ð¾Ð±Ð¾Ñ‡Ð¸Ñ… аркушів за поÑиланнÑми, що починаютьÑÑ Ð· https. Спробуйте інше поÑÐ¸Ð»Ð°Ð½Ð½Ñ Ð°Ð±Ð¾ завантажте файл робочого аркуша, а потім вивантажте його безпоÑередньо зі Ñвого комп'ютера. %(backlinks)sОцінка цієї Ñторінки %(wr).1f.Цей робочий аркуш доÑтупний лише Ð´Ð»Ñ Ñ‡Ð¸Ñ‚Ð°Ð½Ð½Ñ. Будь-лаÑка, зробіть копію чи зв'ÑжітьÑÑ Ð· автором, щоб отримати права на внеÑÐµÐ½Ð½Ñ Ð·Ð¼Ñ–Ð½.Ð§Ð°Ñ Ð²Ð¸ÐºÐ¾Ð½Ð°Ð½Ð½ÑÐазва збереженого робочого аркуша.Щоб виправити непарні круглі, квадратні, фігурні дужки, натиÑніть Ctrl-0. Дужки перед курÑором Ñтануть парними, з правильним опрацюваннÑм Ñ€Ñдків Ñ– коментарів (в Python).Ð”Ð»Ñ ÑˆÐ²Ð¸Ð´ÐºÐ¾Ð³Ð¾ знайомÑтва з Sage, почніть тутЩоб зберегти це зображеннÑ, натиÑніть на ньому правою кнопкою миші та оберіть Копіювати чи Зберегти. Також ви можете проÑто перетÑгнути Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð½Ñ Ð½Ð° робочий Ñтіл.ПеремкнутиПеремикач верхньої панеліВÑьогоПідÑумкиКошикÐаÑтупна Ñпроба через %(num)d Ñекунду...ÐаÑтупна Ñпроба через %(num)d Ñекунди...ÐаÑтупна Ñпроба через %(num)d Ñекунд...Практичні рекомендаціїВведіть "%%time" у початок полÑ.ÐатиÑніть "restart" Ð´Ð»Ñ Ð¿ÐµÑ€ÐµÐ·Ð°Ð¿ÑƒÑку інтерпретатора Sage у поточному робочому аркуші. (Спочатку треба здійÑнити Ð¿ÐµÑ€ÐµÑ€Ð¸Ð²Ð°Ð½Ð½Ñ Ð¿Ð¾Ñ‚Ð¾Ñ‡Ð½Ð¸Ñ… обчиÑлень.)Введіть ? відразу піÑÐ»Ñ Ð¾Ð±'єкта чи функції Ñ– натиÑніть Tab або Shift+Enter (Shift+Enter перезапиÑує Ð²Ð²ÐµÐ´ÐµÐ½Ð½Ñ Ñ– зберігає робочий аркуш).Тип захиÑтуВведіть pretty_print_default() у полі виводу Ñ– натиÑніть Shift+Enter. УвеÑÑŒ наÑтупний вивід буде автоматично відформатовано.ÐÐ²Ñ‚Ð¾Ñ„Ð¾Ñ€Ð¼Ð°Ñ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ð²ÑÑ–Ñ… результатівПоÑÐ¸Ð»Ð°Ð½Ð½Ñ Ð¼Ð°Ñ” починатиÑÑ Ð· http, https, або ftp.%(backlinks)sÐеможливо перервати обчиÑленнÑ.РозархівуватиРозархівувати вибрані робочі аркуші, щоб вони з'ÑвилиÑÑŒ на домашній ÑторінціВідновитиРозблокуватиБез назвиОновленоІмпортуватиЗавантажити або Ñтворити файл данихЗавантажити або Ñтворити файл даних та прикріпити його до робочого аркуша "%(wn)s"Завантажте або Ñтворіть файл даних в одному із багатьох підтримуваних форматівЗавантажити або Ñтворити файл...ВикориÑтовуйте "attach filename.sage" або "attach filename.py". Прикріплені файли автоматично перезавантажатьÑÑ Ð¿Ñ€Ð¸ Ñ—Ñ… зміні. Якщо Ñ–Ñнує файл $HOME/.sage/init.sage, то він прикріплюєтьÑÑ Ð¿Ñ€Ð¸ запуÑку.ВикориÑтовуйте "load filename.sage" Ñ– "load filename.py". ШлÑÑ… load відноÑитьÑÑ Ð´Ð¾ директорії, із Ñкої було запущено Sage Notebook. Файли .sage будуть опрацьовані препарÑером, а файли .py - ні. Ви можете опуÑтити Ñ€Ð¾Ð·ÑˆÐ¸Ñ€ÐµÐ½Ð½Ñ .sage чи .py. Файли можуть завантажувати інші файли.ВикориÑтовуйте "save obj1 obj2 ..." Ñ– "load obj1 obj2 ...". Таким чином, можна легко переміщувати об'єкти із одного робочого аркуша в інший Ñ– зберігати Ñ—Ñ… Ð´Ð»Ñ Ð¿Ð¾Ð´Ð°Ð»ÑŒÑˆÐ¾Ð³Ð¾ викориÑтаннÑ.ВикориÑтовуйте "save_session('name')", щоб зберегти вÑÑ– змінні в об'єкті. Введіть "load_session('name')" Ð´Ð»Ñ Ñ‚Ð¾Ð³Ð¾, щоб об'єднати поточне Ñередовище із змінними зі збереженої ÑеÑÑ–Ñ—.ВикориÑтовуйте більшіÑть математичних програм безпоÑередньо в SageВикориÑтовуйте Sage Ð´Ð»Ñ Ð²Ð¸Ð²Ñ‡ÐµÐ½Ð½Ñ Ð¼Ð°Ñ‚ÐµÐ¼Ð°Ñ‚Ð¸Ñ‡Ð½Ð¾Ð³Ð¾ аналізу, елементарної та розширеної теорії чиÑел, криптографії, комутативної алгебри, теорії груп, теорії графів, клаÑичної Ñ– чиÑленної лінійної алгебри та багато чого іншого.ВикориÑтовуйте ÑучаÑну широко розповÑюджену мову програмуваннÑВикориÑтовувати захиÑÑ‚ від ботів при реєÑтрації облікового запиÑуВикориÑтовуйте вільнорозповÑюджувану альтернативуВикориÑтовуйте меню Дані, щоб завантажувати картинки та інші файли, а також Ñтворювати нові файли, Ñкі можуть бути викориÑтані у різних робочих аркушах одночаÑно. Змінна DATA міÑтить шлÑÑ… до цих файлів даних. Ðаприклад, щоб відкрити файл у цій директорії, введіть "open(DATA+'ім'Ñ Ñ„Ð°Ð¹Ð»Ñƒ')". Якщо ви завантажили Sage-файл foo.sage, введіть "load foo.sage", щоб виконати його; Ñкщо foo.py Ñ” Python-файл, ви можете імпортувати його за допомогою "import foo".КориÑні порадиКориÑÑ‚ÑƒÐ²Ð°Ñ‡Ð£Ð¿Ñ€Ð°Ð²Ð»Ñ–Ð½Ð½Ñ ÐºÐ¾Ñ€Ð¸ÑтувачамиІм'Ñ ÐºÐ¾Ñ€Ð¸Ñтувача:Ðтрибут імені кориÑтувача (наприклад, cn, uid чи userPrincipalName)Помилка в імені кориÑтувачаКориÑтувач з таким ім'Ñм уже зареєÑтрованийІм'Ñ ÐºÐ¾Ñ€Ð¸Ñтувача не знайдено в ÑиÑтеміІм'Ñ ÐºÐ¾Ñ€Ð¸Ñтувача прийнÑтоКориÑтувачіВерÑÑ–ÑПереглÑнути 4000+ Ñторінок інÑтрукції кориÑтувача SageПереглÑнути Ñ–Ñторію оÑтанніх обчиÑленьПереглÑнути зміни в цьому робочому аркушіПереглÑнути Ñк звичайний текÑтПереглÑнути текÑтову верÑÑ–ÑŽ цього робочого аркушаЛаÑкаво проÑимо до Sage! Ви можете Ñтворити новий робочий аркуш, переглÑнути опубліковані робочі аркуші чи ознайомитиÑÑ Ñ–Ð· документацією.ЛаÑкаво проÑимо!Як ви хочете назвати його? (Ñкщо бажаєте змінити ім'Ñ Ð¾Ñ€Ð¸Ð³Ñ–Ð½Ð°Ð»ÑŒÐ½Ð¾Ð³Ð¾ файлу)Скільки буде 2 Ð¿Ð»ÑŽÑ 3?Скільки буде тричі по віÑім?Який найбільший проÑтий дільник чиÑла 15?За допомогою Sage Notebook можна Ñтворювати інтерактивні робочі аркуші, Ñпільно працювати над ними та публікувати Ñ—Ñ…. У робочому аркуші можна пиÑати код, викориÑтовуючи Sage, Python та інше програмне забезпеченнÑ, Ñке включено до Sage.Робоча директоріÑРобочий аркушРобочий аркуш заблоковано. Ðе можна вÑтавлÑти полÑ.Робочий аркуш доÑтупний вÑім бажаючим Ð´Ð»Ñ Ð¿ÐµÑ€ÐµÐ³Ð»Ñду за адреÑою %(u)sÐžÐ±Ð¼ÐµÐ¶ÐµÐ½Ð½Ñ Ð¿Ñ€Ð¾Ñ†ÐµÑу робочого аркушаКориÑтувачі процеÑу робочого аркуша (ÑпиÑок, розділений комами)Ðевірний парольТакВи можете опублікувати ваш робочий аркуш в Інтернеті, де будь-хто зможе переглÑнути його он-лайн.Ви не маєте прав Ð´Ð»Ñ Ð´Ð¾Ñтупу до цієї ÑторінкиВи не маєте прав Ð´Ð»Ñ Ð´Ð¾Ñтупу до цього робочого аркушаВи можете додати чи видалити Ñпівавторів (відділÑйте Ñ—Ñ… імена кориÑтувачів комами).Ви можете завантажити %(f)s або Ñтворити поÑÐ¸Ð»Ð°Ð½Ð½Ñ Ð½Ð° цей файл у робочому аркуші Ви вказали на Ð²Ð¸ÐºÐ¾Ð½Ð°Ð½Ð½Ñ Ð¿Ð¾Ð»Ñ, Ñке, з деÑких причин, невідоме Ñерверу.Працюючи з Sage, ви викориÑтовуєте виÑоко оцінену Ñкриптову мову Python. Ви можете пиÑати програми, у Ñких Ñерйозна математика поєднуєтьÑÑ Ñ–Ð· будь-чим.Ваша адреÑа електронної поштиВаш браузер, операційна ÑиÑтема чи Ñ—Ñ… ÐºÐ¾Ð¼Ð±Ñ–Ð½Ð°Ñ†Ñ–Ñ Ð½Ðµ підтримуєтьÑÑ.\nБудь-лаÑка, ÑкориÑтайтеÑÑŒ Firefox чи Opera в операційних ÑиÑтемах Linux, Windows чи Mac OS X Ñ– Safari.Ваша адреÑа електронної пошти необхідна Ð´Ð»Ñ Ð¿Ñ–Ð´Ñ‚Ð²ÐµÑ€Ð´Ð¶ÐµÐ½Ð½Ñ Ð¾Ð±Ð»Ñ–ÐºÐ¾Ð²Ð¾Ð³Ð¾ запиÑу та його відновленнÑ, у тому випадку, Ñкщо ви забудете пароль. ПіÑÐ»Ñ Ñ€ÐµÑ”Ñтрації на цю адреÑу вам буде надіÑлано поÑÐ¸Ð»Ð°Ð½Ð½Ñ Ð´Ð»Ñ Ð¿Ñ–Ð´Ñ‚Ð²ÐµÑ€Ð´Ð¶ÐµÐ½Ð½Ñ.Ваш новий пароль: %(key)s Увійдіть на Ñервер: %(url_prefix)s://%(addr)s:%(port)s/ Будь-лаÑка, Ñкиньте ваш пароль, перейшовши в ÐÐ°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ñƒ верхній правій панелі.Ваш пароль повинен бути не коротше 4 Ñимволів. Пароль не може міÑтити ім'Ñ ÐºÐ¾Ñ€Ð¸Ñтувача Ñ– пробіли.Ваше ім'Ñ ÐºÐ¾Ñ€Ð¸Ñтувача має починатиÑÑ Ð· літери та міÑтити від 3 до 64 Ñимволів. Можна викориÑтовувати лише літери, цифри, знаки підкреÑленнÑ, @ Ñ– точки.Вашому робочому аркушеві буде приÑвоєна унікальна адреÑа (URL), Ñку ви зможете відправити Ñвоїм друзÑм та колегам.переглÑд директоріїÄeÅ¡tina (ÄŒeská republika)Deutsch (Österreich)English (United States)español (España)виконатиfrançais (France)Ñпроба доÑтупу за невірним поÑиланнÑм!ОÑÑ‚Ð°Ð½Ð½Ñ Ñ€ÐµÐ´Ð°ÐºÑ†Ñ–Ñзалишити коментарзавантаженнÑ...або delete %(f)s.português (Brasil)опублікованоЗакритий ключ reCAPTCHAВідкритий ключ reCAPTCHAруÑÑкий (РоÑÑиÑ)активнийs (подальші перевірки оновлень припинено).виберіть робочий аркушвибачте, по даному запиту нічого не знайденоукраїнÑька (Україна)не надрукованоІм'Ñ ÐºÐ¾Ñ€Ð¸Ñтувача:Ñ‚|такsagenb-1.0.1/sagenb/translations/uk_UA/LC_MESSAGES/messages.po000066400000000000000000003100361311436262400236750ustar00rootroot00000000000000# Ukrainian (Ukraine) translations for Sage (www.sagemath.org) # This file is distributed under the same license as the Sage project. # Olena O. Somenko , 2015. # msgid "" msgstr "" "Project-Id-Version: sagenb\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2015-07-16 11:00+0300\n" "PO-Revision-Date: 2015-07-20 15:29+0300\n" "Last-Translator: Olena O. Somenko \n" "Language-Team: Olena O. Somenko \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Generated-By: Babel 0.9.6\n" "X-Generator: Poedit 1.8.2\n" "Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n" "%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n" "Language: uk_UA\n" "X-Poedit-SourceCharset: UTF-8\n" msgid "cs_CZ" msgstr "ÄeÅ¡tina (ÄŒeská republika)" msgid "de_AT" msgstr "Deutsch (Österreich)" msgid "en_US" msgstr "English (United States)" msgid "es_ES" msgstr "español (España)" msgid "pt_BR" msgstr "português (Brasil)" msgid "ru_RU" msgstr "руÑÑкий (РоÑÑиÑ)" msgid "fr_FR" msgstr "français (France)" msgid "uk_UA" msgstr "українÑька (Україна)" #: flask_version/admin.py:67 #, python-format msgid "" "The temporary password for the new user %(username)s is " "%(password)s" msgstr "" "ТимчаÑовий пароль Ð´Ð»Ñ Ð½Ð¾Ð²Ð¾Ð³Ð¾ кориÑтувача %(username)s: " "%(password)s" #: flask_version/admin.py:69 msgid "New User" msgstr "Ðовий кориÑтувач" #: flask_version/authentication.py:258 msgid "The confirmation system is not active." msgstr "СиÑтема Ð¿Ñ–Ð´Ñ‚Ð²ÐµÑ€Ð´Ð¶ÐµÐ½Ð½Ñ Ð½Ðµ активна." #: flask_version/authentication.py:261 msgid "" "

    Invalid confirmation key

    \n" "

    You are reporting a confirmation key that has not been assigned by " "this\n" " server. Please register with the server.

    \n" " " msgstr "" "

    Ðевірний ключ підтвердженнÑ

    \n" "

    Ви надали ключ підтвердженнÑ, Ñкий не зв'Ñзаний із цим Ñервером.\n" " Будь-лаÑка, зареєÑтруйтеÑÑŒ на Ñервері.

    \n" " " #: flask_version/authentication.py:272 #, python-format msgid "

    Email address confirmed for user %(username)s

    " msgstr "" "

    ÐдреÑа електронної пошти підтверджена Ð´Ð»Ñ ÐºÐ¾Ñ€Ð¸Ñтувача %(username)s

    " #: flask_version/authentication.py:274 msgid "Email Confirmed" msgstr "ÐдреÑу електронної пошти підтверджено" #: flask_version/base.py:226 sagenb/data/sage/html/base_authenticated.html:15 msgid "Log" msgstr "Журнал" #: flask_version/decorators.py:35 msgid "You do not have permission to access this location" msgstr "Ви не маєте прав Ð´Ð»Ñ Ð´Ð¾Ñтупу до цієї Ñторінки" #: flask_version/worksheet.py:27 flask_version/worksheet.py:36 #: flask_version/worksheet_listing.py:195 msgid "You do not have permission to access this worksheet" msgstr "Ви не маєте прав Ð´Ð»Ñ Ð´Ð¾Ñтупу до цього робочого аркуша" #: flask_version/worksheet.py:75 flask_version/worksheet.py:951 #: sagenb/data/sage/html/notebook/worksheet_page.html:28 #: sagenb/notebook/misc.py:237 ../sagenb/notebook/worksheet.py:703 #: sagenb/notebook/worksheet.py:723 ../sagenb/notebook/worksheet.py:4230 msgid "Untitled" msgstr "Без назви" #: flask_version/worksheet.py:578 msgid "Error: can't add more than 500 collaborators at a time" msgstr "Помилка: не можна додати більше 500 Ñпівавторів за один раз" #: flask_version/worksheet.py:631 sagenb/data/sage/html/error_message.html:4 #: sagenb/data/sage/html/login.html:69 sagenb/data/sage/html/login.html:76 #: sagenb/data/sage/html/login.html:104 sagenb/data/sage/html/login.html:106 #: sagenb/data/sage/html/recaptcha.html:27 #: sagenb/data/sage/html/test_report.html:112 #: sagenb/data/sage/html/test_report.html:131 #: sagenb/data/sage/html/accounts/registration.html:22 #: sagenb/data/sage/html/accounts/registration.html:25 #: sagenb/data/sage/html/accounts/registration.html:28 #: sagenb/data/sage/html/accounts/registration.html:39 #: sagenb/data/sage/html/accounts/registration.html:42 #: sagenb/data/sage/html/accounts/registration.html:49 #: sagenb/data/sage/html/accounts/registration.html:62 #: sagenb/data/sage/html/accounts/registration.html:65 #: sagenb/data/sage/html/accounts/registration.html:74 #: sagenb/data/sage/html/accounts/registration.html:77 #: sagenb/data/sage/html/settings/admin_add_user.html:17 #: sagenb/data/sage/html/settings/admin_add_user.html:19 #: sagenb/data/sage/js/translated-messages.js:17 msgid "Error" msgstr "Помилка" #: flask_version/worksheet.py:661 msgid "No data files" msgstr "Ðемає файлів даних" #: flask_version/worksheet.py:702 msgid "illegal link attempt!" msgstr "Ñпроба доÑтупу за невірним поÑиланнÑм!" #: flask_version/worksheet.py:704 msgid "" "The data filename already exists in other worksheet\n" "Delete the file in the other worksheet before creating a link." msgstr "" "Файл з вибраною назвою вже Ñ–Ñнує в іншому робочому аркуші.\n" "Видаліть файл в іншому аркуші перед ÑтвореннÑм зв'Ñзаної копії." #: flask_version/worksheet.py:720 #, python-format msgid "" " Return to Upload or Create Data File " "or %(worksheet_name)s." msgstr "" " ПовернутиÑÑ Ð´Ð¾ Завантажити або " "Ñтворити файл даних або %(worksheet_name)s." #: flask_version/worksheet.py:724 #, python-format msgid "Error uploading file (missing field \"file\"). %(backlinks)s" msgstr "Помилка Ð·Ð°Ð²Ð°Ð½Ñ‚Ð°Ð¶ÐµÐ½Ð½Ñ Ñ„Ð°Ð¹Ð»Ñƒ (відÑутнє поле \"Файл\"). %(backlinks)s" #: flask_version/worksheet.py:731 #, python-format msgid "Error uploading file (missing %(field)s arg).%(backlinks)s" msgstr "" "Помилка Ð·Ð°Ð²Ð°Ð½Ñ‚Ð°Ð¶ÐµÐ½Ð½Ñ Ñ„Ð°Ð¹Ð»Ñƒ (відÑутній аргумент %(field)s arg).%(backlinks)s" #: flask_version/worksheet.py:744 #, python-format msgid "Error uploading file (missing filename).%(backlinks)s" msgstr "Помилка Ð·Ð°Ð²Ð°Ð½Ñ‚Ð°Ð¶ÐµÐ½Ð½Ñ Ñ„Ð°Ð¹Ð»Ñƒ (відÑутнє ім'Ñ Ñ„Ð°Ð¹Ð»Ñƒ).%(backlinks)s" #: flask_version/worksheet.py:752 #, python-format msgid "URL must start with http, https, or ftp.%(backlinks)s" msgstr "ПоÑÐ¸Ð»Ð°Ð½Ð½Ñ Ð¼Ð°Ñ” починатиÑÑ Ð· http, https, або ftp.%(backlinks)s" #: flask_version/worksheet.py:759 #, python-format msgid "" "Suspicious filename \"%(filename)s\" encountered uploading file.%(backlinks)s" msgstr "" "Підозріле ім'Ñ Ñ„Ð°Ð¹Ð»Ñƒ \"%(filename)s\" виÑвлено при завантаженні файлу." "%(backlinks)s" #: flask_version/worksheet.py:874 msgid "No such worksheet." msgstr "Запитуваний робочий аркуш не знайдено." #: flask_version/worksheet.py:959 msgid "Document does not exist." msgstr "Запитуваного документу не Ñ–Ñнує." #: flask_version/worksheet_listing.py:57 msgid "Error displaying worksheet listing." msgstr "Помилка при відображенні ÑпиÑку робочих аркушів." #: flask_version/worksheet_listing.py:176 msgid "Requested public worksheet does not exist" msgstr "Запитуваного опублікованого робочого аркуша не Ñ–Ñнує" #: flask_version/worksheet_listing.py:295 #, python-format msgid "" "This Sage notebook is not configured to load worksheets from 'https' URLs. " "Try a different URL or download the worksheet and upload it directly from " "your computer.\n" "%(backlinks)s" msgstr "" "Цей Sage Notebook-Ñервер не налаштований Ð´Ð»Ñ Ð·Ð°Ð²Ð°Ð½Ñ‚Ð°Ð¶ÐµÐ½Ð½Ñ Ñ€Ð¾Ð±Ð¾Ñ‡Ð¸Ñ… аркушів за " "поÑиланнÑми, що починаютьÑÑ Ð· https. Спробуйте інше поÑÐ¸Ð»Ð°Ð½Ð½Ñ Ð°Ð±Ð¾ завантажте " "файл робочого аркуша, а потім вивантажте його безпоÑередньо зі Ñвого " "комп'ютера.\n" "%(backlinks)s" #: flask_version/worksheet_listing.py:357 msgid "" "Return to Upload " "File." msgstr "" "ПовернутиÑÑ Ð´Ð¾ Завантажити файл." #: flask_version/worksheet_listing.py:380 #, python-format msgid "" "Please specify a worksheet to load.\n" "%(backlinks)s" msgstr "" "Будь-лаÑка, вкажіть робочий аркуш Ð´Ð»Ñ Ð·Ð°Ð²Ð°Ð½Ñ‚Ð°Ð¶ÐµÐ½Ð½Ñ.\n" "%(backlinks)s" #: flask_version/worksheet_listing.py:384 #, python-format msgid "" "Invalid filename.\n" "%(backlinks)s" msgstr "" "Ðеправильне ім'Ñ Ñ„Ð°Ð¹Ð»Ñƒ.\n" "%(backlinks)s" #: flask_version/worksheet_listing.py:425 #, python-format msgid "" "There was an error uploading the worksheet. It could be an old unsupported " "format or worse. If you desperately need its contents contact the sage-support group and " "post a link to your worksheet. Alternatively, an sws file is just a bzip2 " "tarball; take a look inside!\n" "%(backlinks)s" msgstr "" "Виникла помилка при завантаженні робочого аркуша. Це може бути Ñтарий " "непідтримуваний формат або пошкоджений файл. Якщо вам вÑе ж дуже потрібний " "вміÑÑ‚ цього файлу, напишіть до sage-support group Ñ– дайте поÑÐ¸Ð»Ð°Ð½Ð½Ñ Ð½Ð° ваш робочий аркуш. Ð’ " "іншому випадку, Ñпробуйте подивитиÑÑ Ð²Ñередину sws файлу: це текÑтовий файл " "у tarr-архіві, ÑтиÑнутому bzip2!\n" "%(backlinks)s" #: flask_version/worksheet_listing.py:436 #, python-format msgid "Error uploading worksheet '%(msg)s'.%(backlinks)s" msgstr "Помилка при завантаженні робочого аркуша '%(msg)s'.%(backlinks)s" #: sagenb/data/sage/html/base.html:33 ../sagenb/data/sage/html/login.html:35 msgid "The Sage Notebook" msgstr "Sage Notebook" #: sagenb/data/sage/html/base.html:35 msgid "Searching for Sage server..." msgstr "Пошук Ñервера Sage..." #: sagenb/data/sage/html/base.html:37 msgid "Version" msgstr "ВерÑÑ–Ñ" #: sagenb/data/sage/html/base_authenticated.html:7 msgid "Please log in to the Sage notebook" msgstr "Будь-лаÑка, увійдіть до Sage Notebook" #: sagenb/data/sage/html/base_authenticated.html:7 msgid "Log in" msgstr "Увійти" #: sagenb/data/sage/html/base_authenticated.html:9 msgid "Toggle the top bar" msgstr "Перемикач верхньої панелі" #: sagenb/data/sage/html/base_authenticated.html:9 #: sagenb/data/sage/html/test_report.html:123 msgid "Toggle" msgstr "Перемкнути" #: sagenb/data/sage/html/base_authenticated.html:10 msgid "Back to your personal worksheet list" msgstr "ПовернутиÑÑ Ð´Ð¾ ÑпиÑку ваших робочих аркушів" #: sagenb/data/sage/html/base_authenticated.html:10 msgid "Home" msgstr "Додому" #: sagenb/data/sage/html/base_authenticated.html:12 #: sagenb/data/sage/html/base_authenticated.html:14 msgid "Published" msgstr "Опубліковані" #: sagenb/data/sage/html/base_authenticated.html:14 msgid "Browse the published worksheets" msgstr "ПереглÑнути опубліковані робочі аркуші" #: sagenb/data/sage/html/base_authenticated.html:15 msgid "View a log of recent computations" msgstr "ПереглÑнути Ñ–Ñторію оÑтанніх обчиÑлень" #: sagenb/data/sage/html/base_authenticated.html:17 msgid "Change account settings including password" msgstr "Змінити Ð½Ð°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ð¾Ð±Ð»Ñ–ÐºÐ¾Ð²Ð¾Ð³Ð¾ запиÑу, включаючи пароль" #: sagenb/data/sage/html/base_authenticated.html:17 msgid "Settings" msgstr "ÐалаштуваннÑ" #: sagenb/data/sage/html/base_authenticated.html:18 msgid "Documentation" msgstr "ДокументаціÑ" #: sagenb/data/sage/html/base_authenticated.html:18 msgid "Help" msgstr "Допомога" #: sagenb/data/sage/html/base_authenticated.html:19 msgid "Report a problem or submit a bug to improve Sage" msgstr "" "Повідомити про проблему або відправити звіт про помилку Ð´Ð»Ñ Ð¿Ð¾ÐºÑ€Ð°Ñ‰ÐµÐ½Ð½Ñ " "роботи Sage" #: sagenb/data/sage/html/base_authenticated.html:19 msgid "Report a Problem" msgstr "Повідомити про проблему" #: sagenb/data/sage/html/base_authenticated.html:20 msgid "Log out of the Sage notebook" msgstr "Вийти із Sage Notebook" #: sagenb/data/sage/html/base_authenticated.html:20 msgid "Sign out" msgstr "Вийти" #: sagenb/data/sage/html/docs.html:3 msgid "Sage Documentation" msgstr "Ð”Ð¾ÐºÑƒÐ¼ÐµÐ½Ñ‚Ð°Ñ†Ñ–Ñ Sage" #: sagenb/data/sage/html/docs.html:15 msgid "To quickly try out Sage start here" msgstr "Ð”Ð»Ñ ÑˆÐ²Ð¸Ð´ÐºÐ¾Ð³Ð¾ знайомÑтва з Sage, почніть тут" #: sagenb/data/sage/html/docs.html:15 msgid "Tutorial" msgstr "Практичні рекомендації" #: sagenb/data/sage/html/docs.html:16 msgid "Explore a collection of in-depth tutorials on specific topics" msgstr "ПереглÑнути колекцію підібраних практичних рекомендацій з окремих тем" #: sagenb/data/sage/html/docs.html:16 msgid "Thematic Tutorials" msgstr "Тематичні практичні рекомендації" #: sagenb/data/sage/html/docs.html:17 msgid "View a 4000+ page reference manual about Sage" msgstr "ПереглÑнути 4000+ Ñторінок інÑтрукції кориÑтувача Sage" #: sagenb/data/sage/html/docs.html:17 msgid "Reference Manual" msgstr "ІнÑÑ‚Ñ€ÑƒÐºÑ†Ñ–Ñ ÐºÐ¾Ñ€Ð¸Ñтувача" #: sagenb/data/sage/html/docs.html:18 msgid "Learn to write Sage programs" msgstr "ÐавчитиÑÑ Ð¿Ð¸Ñати програми в Sage" #: sagenb/data/sage/html/docs.html:18 msgid "Developer Guide" msgstr "ІнÑÑ‚Ñ€ÑƒÐºÑ†Ñ–Ñ Ñ€Ð¾Ð·Ñ€Ð¾Ð±Ð½Ð¸ÐºÐ°" #: sagenb/data/sage/html/docs.html:19 msgid "How do I construct ... in Sage?" msgstr "Як мені Ñтворити ... в Sage?" #: sagenb/data/sage/html/docs.html:19 msgid "Constructions" msgstr "Програмні конÑтрукції" #: sagenb/data/sage/html/docs.html:22 msgid "Static version..." msgstr "Статична верÑÑ–Ñ..." #: sagenb/data/sage/html/docs.html:22 msgid "Fast Static Versions of the Documentation" msgstr "Швидка Ñтатична верÑÑ–Ñ Ð´Ð¾ÐºÑƒÐ¼ÐµÐ½Ñ‚Ð°Ñ†Ñ–Ñ—" #: sagenb/data/sage/html/docs.html:23 msgid "Help via Internet Chat (IRC)" msgstr "Допомога на каналі IRC (Інтернет-чат)" #: sagenb/data/sage/html/docs.html:29 msgid "How to use the Sage Notebook" msgstr "Як кориÑтуватиÑÑ Sage Notebook" #: sagenb/data/sage/html/docs.html:31 msgid "" "A worksheet is an ordered list of Sage calculations with output." msgstr "" "Робочий аркуш — це впорÑдкований ÑпиÑок обчиÑлень Sage із " "результатами." #: sagenb/data/sage/html/docs.html:32 msgid "A session is a worksheet and a set of variables in some state." msgstr "СеÑÑ–Ñ â€” це робочий аркуш Ñ– набір змінних у деÑкому Ñтані." #: sagenb/data/sage/html/docs.html:33 msgid "" "The Sage notebook is a collection of worksheets, saved objects, and " "user information." msgstr "" "Sage Notebook — це ÐºÐ¾Ð»ÐµÐºÑ†Ñ–Ñ Ñ€Ð¾Ð±Ð¾Ñ‡Ð¸Ñ… аркушів, збережених об'єктів та " "інформації кориÑтувача." #: sagenb/data/sage/html/docs.html:46 msgid "" "The Sage Notebook was primarily written by William Stein with substantial " "contributions from Tom Boothby, Timothy Clemans, Alex Clemesha, Mike Hansen, " "Bobby Moretti, Yi Qiang, and Dorian Raymer." msgstr "" "Sage Notebook був Ñпершу Ñтворений William Stein, із Ñуттєвим внеÑком Tom " "Boothby, Timothy Clemans, Alex Clemesha, Mike Hansen, Bobby Moretti, Yi " "Qiang, Ñ– Dorian Raymer." #: sagenb/data/sage/html/error_message.html:19 msgid "Continue" msgstr "Продовжити" #: sagenb/data/sage/html/history.html:3 #, python-format msgid "Sage: History for %(u)s" msgstr "Sage: ІÑÑ‚Ð¾Ñ€Ñ–Ñ Ð´Ð»Ñ %(u)s" #: sagenb/data/sage/html/history.html:13 msgid "Click here to turn the above into a Sage worksheet" msgstr "ÐатиÑніть тут, щоб відкрити вибране Ñк робочий аркуш Sage" #: sagenb/data/sage/html/history.html:13 msgid "" "Create a new Sage worksheet version of the last 100 commands in the above " "log." msgstr "Створити новий робочий аркуш Sage із оÑтанніх 100 команд з Ñ–Ñторії." #: sagenb/data/sage/html/login.html:12 msgid "username" msgstr "Ім'Ñ ÐºÐ¾Ñ€Ð¸Ñтувача:" #: sagenb/data/sage/html/login.html:13 msgid "Select an OpenID provider" msgstr "Виберіть провайдера OpenID" #: sagenb/data/sage/html/login.html:14 msgid "Send" msgstr "Відправити" #: sagenb/data/sage/html/login.html:22 sagenb/data/sage/html/login.html:84 msgid "Sign in" msgstr "Увійти" #: sagenb/data/sage/html/login.html:28 #, python-format msgid "Congratulations %(u)s! You can now sign into the Sage Notebook." msgstr "Вітаємо %(u)s! Тепер ви можете увійти до Sage Notebook." #: sagenb/data/sage/html/login.html:32 msgid "Welcome!" msgstr "ЛаÑкаво проÑимо!" #: sagenb/data/sage/html/login.html:33 msgid "Sage is a different approach to mathematics software." msgstr "" "Sage — це інший підхід до математичного програмного " "забезпеченнÑ." #: sagenb/data/sage/html/login.html:36 msgid "" "With the Sage Notebook anyone can create, collaborate on, and publish " "interactive worksheets. In a worksheet, one can write code using Sage, " "Python, and other software included in Sage." msgstr "" "За допомогою Sage Notebook можна Ñтворювати інтерактивні робочі аркуші, " "Ñпільно працювати над ними та публікувати Ñ—Ñ…. У робочому аркуші можна пиÑати " "код, викориÑтовуючи Sage, Python та інше програмне забезпеченнÑ, Ñке " "включено до Sage." #: sagenb/data/sage/html/login.html:39 msgid "General and Advanced Pure and Applied Mathematics" msgstr "Загальна, вища, чиÑта Ñ– прикладна математика" #: sagenb/data/sage/html/login.html:40 msgid "" "Use Sage for studying calculus, elementary to very advanced number theory, " "cryptography, commutative algebra, group theory, graph theory, numerical and " "exact linear algebra, and more." msgstr "" "ВикориÑтовуйте Sage Ð´Ð»Ñ Ð²Ð¸Ð²Ñ‡ÐµÐ½Ð½Ñ Ð¼Ð°Ñ‚ÐµÐ¼Ð°Ñ‚Ð¸Ñ‡Ð½Ð¾Ð³Ð¾ аналізу, елементарної та " "розширеної теорії чиÑел, криптографії, комутативної алгебри, теорії груп, " "теорії графів, клаÑичної Ñ– чиÑленної лінійної алгебри та багато чого іншого." #: sagenb/data/sage/html/login.html:43 msgid "Use an Open Source Alternative" msgstr "ВикориÑтовуйте вільнорозповÑюджувану альтернативу" #: sagenb/data/sage/html/login.html:44 msgid "" "By using Sage you help to support a viable open source alternative to Magma, " "Maple, Mathematica, and MATLAB. Sage includes many high-quality open source " "math packages." msgstr "" "ВикориÑтовуючи Sage, ви допомагаєте підтримувати вільнорозповÑюджувану " "альтернативу Magma, Maple, Mathematica Ñ– MATLAB. Sage міÑтить велику " "кількіÑть виÑокоÑкіÑних математичних пакетів із відкритим вихідним кодом." #: sagenb/data/sage/html/login.html:47 msgid "Use Most Mathematics Software from Within Sage" msgstr "ВикориÑтовуйте більшіÑть математичних програм безпоÑередньо в Sage" #: sagenb/data/sage/html/login.html:48 msgid "" "Sage makes it easy for you to use most mathematics software together. Sage " "includes GAP, GP/PARI, Maxima, and Singular, and dozens of other open " "packages." msgstr "" "За допомогою Sage дуже легко одночаÑно кориÑтуватиÑÑ Ð±Ñ–Ð»ÑŒÑˆÑ–Ñтю математичних " "програм. Sage включає в Ñебе GAP, GP/PARI, Maxima Ñ– Singular та багато інших " "відкритих пакетів програмного забезпеченнÑ." #: sagenb/data/sage/html/login.html:51 msgid "Use a Mainstream Programming Language" msgstr "ВикориÑтовуйте ÑучаÑну широко розповÑюджену мову програмуваннÑ" #: sagenb/data/sage/html/login.html:52 msgid "" "You work with Sage using the highly regarded scripting language Python. You " "can write programs that combine serious mathematics with anything else." msgstr "" "Працюючи з Sage, ви викориÑтовуєте виÑоко оцінену Ñкриптову мову Python. Ви " "можете пиÑати програми, у Ñких Ñерйозна математика поєднуєтьÑÑ Ñ–Ð· будь-чим." #: sagenb/data/sage/html/login.html:55 msgid "Acknowledgement" msgstr "ПодÑка" #: sagenb/data/sage/html/login.html:56 msgid "" "The Sage Notebook is based upon work supported by the National Science " "Foundation under grants DMS-0821725, DMS-1020378, DMS-0713225, DMS-0555776, " "DMS-0545904, DMS-0838212, DMS-0757627, DUE-1020378, DUE-1022574, " "DMS-1015114, etc. Any opinions, findings, and conclusions or " "recommendations expressed in this material are those of the author(s) and do " "not necessarily reflect the views of the National Science Foundation. See " "also http://sagemath." "org/development-ack.html." msgstr "" "Sage Notebook базуєтьÑÑ Ð½Ð° роботі, підтримуваній National Science Foundation " "в рамках грантів DMS-0821725, DMS-1020378, DMS-0713225, DMS-0555776, " "DMS-0545904, DMS-0838212, DMS-0757627, DUE-1020378, DUE-1022574, DMS-1015114 " "та ін. Будь-Ñкі думки, знахідки, виÑновки чи рекомендації, предÑтавлені " "тут, Ñ” оÑобиÑтою позицією автора(ів) Ñ– можуть не Ñпівпадати із поглÑдами " "National Science Foundation. Див. також http://sagemath.org/development-ack.html." #: sagenb/data/sage/html/login.html:66 #: sagenb/data/sage/html/accounts/account_recovery.html:13 msgid "Username" msgstr "Ім'Ñ ÐºÐ¾Ñ€Ð¸Ñтувача:" #: sagenb/data/sage/html/login.html:69 msgid "Username is not in the system" msgstr "Ім'Ñ ÐºÐ¾Ñ€Ð¸Ñтувача не знайдено в ÑиÑтемі" #: sagenb/data/sage/html/login.html:73 #: sagenb/data/sage/html/settings/user_management.html:13 msgid "Password" msgstr "Пароль" #: sagenb/data/sage/html/login.html:76 msgid "Wrong password" msgstr "Ðевірний пароль" #: sagenb/data/sage/html/login.html:80 msgid "Remember me" msgstr "Запам'Ñтати мене" #: sagenb/data/sage/html/login.html:89 msgid "Sign up for a new Sage Notebook account" msgstr "ЗареєÑтрувати новий обліковий Ð·Ð°Ð¿Ð¸Ñ Ð² Sage Notebook" #: sagenb/data/sage/html/login.html:93 msgid "Browse published Sage worksheets
    (no login required)" msgstr "" "ПереглÑнути опубліковані робочі аркуші Sage
    (реєÑÑ‚Ñ€Ð°Ñ†Ñ–Ñ Ð½Ðµ потрібна)" #: sagenb/data/sage/html/login.html:97 msgid "Forgot password" msgstr "Забули пароль?" #: sagenb/data/sage/html/login.html:104 msgid "Creating new users is disabled by the administrator." msgstr "Ð¡Ñ‚Ð²Ð¾Ñ€ÐµÐ½Ð½Ñ Ð½Ð¾Ð²Ð¸Ñ… кориÑтувачів заборонено адмініÑтратором." #: sagenb/data/sage/html/login.html:106 msgid "Javascript must be enabled in order to use the Sage Notebook." msgstr "Ð”Ð»Ñ Ñ€Ð¾Ð±Ð¾Ñ‚Ð¸ Sage Notebook має бути увімкнений Javascript." #: sagenb/data/sage/html/source_code.html:3 sagenb/notebook/tutorial.py:358 msgid "Source Code" msgstr "Вихідний код" #: sagenb/data/sage/html/source_code.html:13 msgid "Sage Source Browser" msgstr "Браузер вихідного коду" #: sagenb/data/sage/html/source_code.html:14 msgid "browse directory" msgstr "переглÑд директорії" #: sagenb/data/sage/html/test_report.html:79 msgid "Sage Notebook version" msgstr "ВерÑÑ–Ñ Sage Notebook" #: sagenb/data/sage/html/test_report.html:85 msgid "Sage version" msgstr "ВерÑÑ–Ñ Sage" #: sagenb/data/sage/html/test_report.html:91 msgid "Environment" msgstr "Середовище" #: sagenb/data/sage/html/test_report.html:96 msgid "Start" msgstr "Почати" #: sagenb/data/sage/html/test_report.html:100 #: sagenb/data/sage/html/worksheet_listing.html:127 msgid "Stop" msgstr "Завершити" #: sagenb/data/sage/html/test_report.html:104 msgid "Elapsed" msgstr "Минуло" #: sagenb/data/sage/html/test_report.html:108 msgid "Status" msgstr "СтатуÑ" #: sagenb/data/sage/html/test_report.html:110 #: sagenb/data/sage/html/test_report.html:129 msgid "Pass" msgstr "Пройдено" #: sagenb/data/sage/html/test_report.html:111 #: sagenb/data/sage/html/test_report.html:130 msgid "Fail" msgstr "Збій" #: sagenb/data/sage/html/test_report.html:113 msgid "Total" msgstr "Ð’Ñього" #: sagenb/data/sage/html/test_report.html:121 msgid "Hide" msgstr "Приховати" #: sagenb/data/sage/html/test_report.html:122 msgid "Show" msgstr "Показати" #: sagenb/data/sage/html/test_report.html:128 msgid "Cases / Tests" msgstr "ТеÑти" #: sagenb/data/sage/html/test_report.html:132 msgid "Count" msgstr "Підрахунок" #: sagenb/data/sage/html/test_report.html:141 msgid "Totals" msgstr "ПідÑумки" #: sagenb/data/sage/html/worksheet_listing.html:9 msgid "Published Worksheets" msgstr "Опубліковані робочі аркуші" #: sagenb/data/sage/html/worksheet_listing.html:11 msgid "Deleted Worksheets" msgstr "Видалені робочі аркуші" #: sagenb/data/sage/html/worksheet_listing.html:13 msgid "Active Worksheets" msgstr "Ðктивні робочі аркуші" #: sagenb/data/sage/html/worksheet_listing.html:15 msgid "Archived Worksheets" msgstr "Заархівовані робочі аркуші" #: sagenb/data/sage/html/worksheet_listing.html:99 msgid "New Worksheet" msgstr "Ðовий робочий аркуш" #: sagenb/data/sage/html/worksheet_listing.html:100 msgid "Upload" msgstr "Імпортувати" #: sagenb/data/sage/html/worksheet_listing.html:101 msgid "Download All Active" msgstr "Зберегти вÑÑ– виділені" #: sagenb/data/sage/html/worksheet_listing.html:108 msgid "Search Worksheets" msgstr "Пошук робочих аркушів" #: sagenb/data/sage/html/worksheet_listing.html:116 msgid "" "Unarchive selected worksheets so it appears in the default worksheet list" msgstr "" "Розархівувати вибрані робочі аркуші, щоб вони з'ÑвилиÑÑŒ на домашній Ñторінці" #: sagenb/data/sage/html/worksheet_listing.html:116 msgid "Unarchive" msgstr "Розархівувати" #: sagenb/data/sage/html/worksheet_listing.html:118 msgid "" "Archive selected worksheets so they do not appear in the default worksheet " "list" msgstr "" "Ðрхівувати вибрані робочі аркуші, щоб вони не відображалиÑÑŒ на домашній " "Ñторінці" #: sagenb/data/sage/html/worksheet_listing.html:118 msgid "Archive" msgstr "Ðрхівувати" #: sagenb/data/sage/html/worksheet_listing.html:122 msgid "Move the selected worksheets to the trash" msgstr "ПереміÑтити вибрані робочі аркуші до кошика" #: sagenb/data/sage/html/worksheet_listing.html:122 msgid "Delete" msgstr "Видалити" #: sagenb/data/sage/html/worksheet_listing.html:124 msgid "Move the selected worksheets out of the trash" msgstr "Відновити вибрані робочі аркуші з кошика" #: sagenb/data/sage/html/worksheet_listing.html:124 msgid "Undelete" msgstr "Відновити" #: sagenb/data/sage/html/worksheet_listing.html:127 msgid "Stop selected worksheets" msgstr "Завершити роботу вибраних робочих аркушів" #: sagenb/data/sage/html/worksheet_listing.html:128 msgid "Download selected worksheets" msgstr "Завантажити вибрані робочі аркуші" #: sagenb/data/sage/html/worksheet_listing.html:128 msgid "Download" msgstr "ЕкÑпортувати" #: sagenb/data/sage/html/worksheet_listing.html:131 msgid "Current Folder" msgstr "Поточна папка" #: sagenb/data/sage/html/worksheet_listing.html:132 msgid "Active" msgstr "Ðктивні" #: sagenb/data/sage/html/worksheet_listing.html:133 msgid "Archived" msgstr "Ðрхів" #: sagenb/data/sage/html/worksheet_listing.html:134 msgid "Trash" msgstr "Кошик" #: sagenb/data/sage/html/worksheet_listing.html:138 msgid "Empty Trash" msgstr "ОчиÑтити кошик" #: sagenb/data/sage/html/worksheet_listing.html:153 #: sagenb/data/sage/html/worksheet/ratings_info.html:9 msgid "Rating" msgstr "Оцінка" #: sagenb/data/sage/html/worksheet_listing.html:164 msgid "Owner" msgstr "ВлаÑник" #: sagenb/data/sage/html/worksheet_listing.html:164 msgid "Collaborators" msgstr "Співавтори" #: sagenb/data/sage/html/worksheet_listing.html:170 #: sagenb/data/sage/html/notebook/worksheet_revision_list.html:16 msgid "Last Edited" msgstr "ОÑÑ‚Ð°Ð½Ð½Ñ Ñ€ÐµÐ´Ð°ÐºÑ†Ñ–Ñ" #: sagenb/data/sage/html/worksheet_listing.html:180 msgid "There are no published worksheets." msgstr "Ðемає опублікованих робочих аркушів." #: sagenb/data/sage/html/worksheet_listing.html:186 msgid "" "Welcome to Sage! You can create a new worksheet, view published worksheets, or read the documentation." msgstr "" "ЛаÑкаво проÑимо до Sage! Ви можете Ñтворити новий " "робочий аркуш, переглÑнути опубліковані робочі аркуші чи ознайомитиÑÑ Ñ–Ð· документацією." #: sagenb/data/sage/html/worksheet_listing.html:228 msgid "running" msgstr "активний" #: sagenb/data/sage/html/worksheet_listing.html:261 msgid "Add or Delete" msgstr "Додати чи Видалити" #: sagenb/data/sage/html/worksheet_listing.html:263 msgid "Share now" msgstr "ПоділитиÑÑ" #: sagenb/data/sage/html/worksheet_listing.html:268 msgid "published" msgstr "опубліковано" #: sagenb/data/sage/html/accounts/account_recovery.html:3 #: sagenb/data/sage/html/accounts/account_recovery.html:8 msgid "Account Recovery" msgstr "Ð’Ñ–Ð´Ð½Ð¾Ð²Ð»ÐµÐ½Ð½Ñ Ð¾Ð±Ð»Ñ–ÐºÐ¾Ð²Ð¾Ð³Ð¾ запиÑу" #: sagenb/data/sage/html/accounts/account_recovery.html:9 msgid "" "A new password will be emailed to the email address connected to your " "account. However if you didn't confirm your email address you will be unable " "to recover your account." msgstr "" "Ðовий пароль буде відправлено за адреÑою електронної пошти, вказаної у " "вашому обліковому запиÑÑ–. Однак, Ñкщо ви не підтвердили Ñвою адреÑу " "електронної пошти, ви не зможете відновити Ñвій обліковий запиÑ." #: sagenb/data/sage/html/accounts/account_recovery.html:17 msgid "Submit" msgstr "Підтвердити" #: sagenb/data/sage/html/accounts/account_recovery.html:17 #: sagenb/data/sage/html/accounts/registration.html:83 #: sagenb/data/sage/html/notebook/download_or_delete_datafile.html:54 #: sagenb/data/sage/html/notebook/edit_window.html:12 #: sagenb/data/sage/html/settings/account_settings.html:10 #: sagenb/data/sage/html/settings/account_settings.html:75 #: sagenb/data/sage/html/settings/admin_add_user.html:26 #: sagenb/data/sage/html/settings/notebook_settings.html:20 #: sagenb/data/sage/html/settings/notebook_settings.html:27 msgid "Cancel" msgstr "СкаÑувати" #: sagenb/data/sage/html/accounts/registration.html:3 msgid "Sign up" msgstr "Увійти" #: sagenb/data/sage/html/accounts/registration.html:9 msgid "Sign up for a Sage Notebook account" msgstr "ЗареєÑтрувати новий обліковий Ð·Ð°Ð¿Ð¸Ñ Ð² Sage Notebook" #: sagenb/data/sage/html/accounts/registration.html:16 msgid "Create a username" msgstr "Виберіть ім'Ñ ÐºÐ¾Ñ€Ð¸Ñтувача" #: sagenb/data/sage/html/accounts/registration.html:17 msgid "" "Your username must start with a letter and be between 3 and 64 characters " "long. You may only use letters, numbers, underscores, @, and dots." msgstr "" "Ваше ім'Ñ ÐºÐ¾Ñ€Ð¸Ñтувача має починатиÑÑ Ð· літери та міÑтити від 3 до 64 " "Ñимволів. Можна викориÑтовувати лише літери, цифри, знаки підкреÑленнÑ, @ Ñ– " "точки." #: sagenb/data/sage/html/accounts/registration.html:22 msgid "No username given" msgstr "Ім'Ñ ÐºÐ¾Ñ€Ð¸Ñтувача не вказано" #: sagenb/data/sage/html/accounts/registration.html:25 msgid "Username already in use" msgstr "КориÑтувач з таким ім'Ñм уже зареєÑтрований" #: sagenb/data/sage/html/accounts/registration.html:28 msgid "Bad username" msgstr "Ðекоректне ім'Ñ ÐºÐ¾Ñ€Ð¸Ñтувача" #: sagenb/data/sage/html/accounts/registration.html:32 msgid "Create a good password" msgstr "Створіть надійний пароль" #: sagenb/data/sage/html/accounts/registration.html:34 msgid "" "Your password must have at least 4 characters. Your password can not contain " "your username or spaces." msgstr "" "Ваш пароль повинен бути не коротше 4 Ñимволів. Пароль не може міÑтити ім'Ñ " "кориÑтувача Ñ– пробіли." #: sagenb/data/sage/html/accounts/registration.html:39 msgid "No password given" msgstr "Пароль не введено" #: sagenb/data/sage/html/accounts/registration.html:42 msgid "Bad password" msgstr "Ðевірний пароль" #: sagenb/data/sage/html/accounts/registration.html:46 msgid "Re-type your password" msgstr "Введіть пароль ще раз" #: sagenb/data/sage/html/accounts/registration.html:49 msgid "Passwords didn't match" msgstr "Паролі не Ñпівпадають" #: sagenb/data/sage/html/accounts/registration.html:54 msgid "Enter your email address" msgstr "Введіть вашу адреÑу електронної пошти" #: sagenb/data/sage/html/accounts/registration.html:56 msgid "" "Your email address is required for account confirmation and recovery. You " "will be emailed a confirmation link right after you successfully sign up." msgstr "" "Ваша адреÑа електронної пошти необхідна Ð´Ð»Ñ Ð¿Ñ–Ð´Ñ‚Ð²ÐµÑ€Ð´Ð¶ÐµÐ½Ð½Ñ Ð¾Ð±Ð»Ñ–ÐºÐ¾Ð²Ð¾Ð³Ð¾ запиÑу " "та його відновленнÑ, у тому випадку, Ñкщо ви забудете пароль. ПіÑÐ»Ñ " "реєÑтрації на цю адреÑу вам буде надіÑлано поÑÐ¸Ð»Ð°Ð½Ð½Ñ Ð´Ð»Ñ Ð¿Ñ–Ð´Ñ‚Ð²ÐµÑ€Ð´Ð¶ÐµÐ½Ð½Ñ." #: sagenb/data/sage/html/accounts/registration.html:62 msgid "No email address given" msgstr "ÐдреÑа електронної пошти не була введена" #: sagenb/data/sage/html/accounts/registration.html:65 msgid "Invalid email address" msgstr "ÐедійÑна адреÑа електронної пошти" #: sagenb/data/sage/html/accounts/registration.html:71 msgid "Answer a challenge" msgstr "Пройдіть перевірку" #: sagenb/data/sage/html/accounts/registration.html:74 msgid "No challenge response given" msgstr "Ви не заповнили поле Ð´Ð»Ñ Ð¿ÐµÑ€ÐµÐ²Ñ–Ñ€ÐºÐ¸" #: sagenb/data/sage/html/accounts/registration.html:77 msgid "Invalid challenge response" msgstr "Ðевірна відповідь у полі Ð´Ð»Ñ Ð¿ÐµÑ€ÐµÐ²Ñ–Ñ€ÐºÐ¸" #: sagenb/data/sage/html/accounts/registration.html:82 msgid "Create account" msgstr "Створити обліковий запиÑ" #: sagenb/data/sage/html/notebook/afterpublish_window.html:8 #, python-format msgid "" "Worksheet is publicly viewable at %(u)s" msgstr "" "Робочий аркуш доÑтупний вÑім бажаючим Ð´Ð»Ñ Ð¿ÐµÑ€ÐµÐ³Ð»Ñду за адреÑою %(u)s" #: sagenb/data/sage/html/notebook/afterpublish_window.html:9 #, python-format msgid "Published on %(t)s" msgstr "Опубліковано %(t)s" #: sagenb/data/sage/html/notebook/afterpublish_window.html:11 msgid "Re-publish worksheet" msgstr "Опублікувати повторно" #: sagenb/data/sage/html/notebook/afterpublish_window.html:12 msgid "Stop publishing" msgstr "Видалити з опублікованих" #: sagenb/data/sage/html/notebook/afterpublish_window.html:14 #: sagenb/data/sage/html/notebook/beforepublish_window.html:18 msgid "Automatically re-publish when changes are made" msgstr "Ðвтоматично оновлювати опубліковану верÑÑ–ÑŽ піÑÐ»Ñ Ð²Ð½ÐµÑÐµÐ½Ð½Ñ Ð·Ð¼Ñ–Ð½" #: sagenb/data/sage/html/notebook/base.html:78 msgid "Click to rename this worksheet" msgstr "ÐатиÑніть тут, щоб перейменувати цей робочий аркуш" #: sagenb/data/sage/html/notebook/base.html:81 msgid "last edited" msgstr "ОÑÑ‚Ð°Ð½Ð½Ñ Ñ€ÐµÐ´Ð°ÐºÑ†Ñ–Ñ" #: sagenb/data/sage/html/notebook/base.html:83 msgid "Someone else is viewing this worksheet" msgstr "ХтоÑÑŒ іще переглÑдає цей робочий аркуш" #: sagenb/data/sage/html/notebook/base.html:88 #: sagenb/data/sage/html/notebook/text_cell.html:48 msgid "Save changes" msgstr "Зберегти зміни" #: sagenb/data/sage/html/notebook/base.html:88 #: sagenb/data/sage/html/settings/account_settings.html:9 #: sagenb/data/sage/html/settings/account_settings.html:74 #: sagenb/data/sage/html/settings/notebook_settings.html:19 #: sagenb/data/sage/html/settings/notebook_settings.html:26 msgid "Save" msgstr "Зберегти" #: sagenb/data/sage/html/notebook/base.html:88 msgid "Save changes and close window" msgstr "Зберегти зміни та закрити вікно" #: sagenb/data/sage/html/notebook/base.html:88 msgid "Save & quit" msgstr "Зберегти Ñ– вийти" #: sagenb/data/sage/html/notebook/base.html:88 msgid "Discard changes to this worksheet" msgstr "СкаÑувати зміни, внеÑені до цього робочого аркуша" #: sagenb/data/sage/html/notebook/base.html:88 msgid "Discard & quit" msgstr "СкаÑувати Ñ– вийти" #: sagenb/data/sage/html/notebook/base.html:95 msgid "Select a file related function" msgstr "Виберіть, що ви хочете зробити з файлом" #: sagenb/data/sage/html/notebook/base.html:95 msgid "File..." msgstr "Файл..." #: sagenb/data/sage/html/notebook/base.html:96 msgid "Load a new worksheet stored in a file" msgstr "Створити новий робочий аркуш, завантаживши його з файлу" #: sagenb/data/sage/html/notebook/base.html:96 msgid "Load worksheet from a file..." msgstr "Завантажити робочий аркуш з файлу" #: sagenb/data/sage/html/notebook/base.html:97 msgid "Create a new worksheet" msgstr "Створити новий робочий аркуш" #: sagenb/data/sage/html/notebook/base.html:97 msgid "New worksheet" msgstr "Ðовий робочий аркуш" #: sagenb/data/sage/html/notebook/base.html:98 msgid "Save this worksheet to an sws file" msgstr "Зберегти цей робочий аркуш Ñк файл sws" #: sagenb/data/sage/html/notebook/base.html:98 msgid "Save worksheet to a file..." msgstr "Зберегти робочий аркуш у файл" #: sagenb/data/sage/html/notebook/base.html:99 #: sagenb/data/sage/html/notebook/base.html:148 msgid "Print this worksheet" msgstr "Ðадрукувати цей робочий аркуш" #: sagenb/data/sage/html/notebook/base.html:99 #: sagenb/data/sage/html/notebook/base.html:148 msgid "Print" msgstr "Друкувати" #: sagenb/data/sage/html/notebook/base.html:100 msgid "Rename this worksheet" msgstr "Перейменувати поточний робочий аркуш" #: sagenb/data/sage/html/notebook/base.html:100 #: sagenb/data/sage/js/translated-messages.js:11 msgid "Rename worksheet" msgstr "Перейменувати робочий аркуш" #: sagenb/data/sage/html/notebook/base.html:101 msgid "Copy this worksheet" msgstr "Копіювати поточний робочий аркуш" #: sagenb/data/sage/html/notebook/base.html:101 msgid "Copy worksheet" msgstr "Копіювати робочий аркуш" #: sagenb/data/sage/html/notebook/base.html:102 msgid "Move this worksheet to the trash" msgstr "ПереміÑтити цей робочий аркуш до кошика" #: sagenb/data/sage/html/notebook/base.html:102 msgid "Delete worksheet" msgstr "Видалити робочий аркуш" #: sagenb/data/sage/html/notebook/base.html:106 msgid "Select a worksheet function" msgstr "Виберіть функцію ÑƒÐ¿Ñ€Ð°Ð²Ð»Ñ–Ð½Ð½Ñ Ñ€Ð¾Ð±Ð¾Ñ‡Ð¸Ð¼ аркушем" #: sagenb/data/sage/html/notebook/base.html:106 msgid "Action..." msgstr "ДіÑ..." #: sagenb/data/sage/html/notebook/base.html:107 msgid "Interrupt currently running calculations, if possible" msgstr "Перервати поточні активні розрахунки, Ñкщо це можливо" #: sagenb/data/sage/html/notebook/base.html:107 msgid "Interrupt" msgstr "Перервати" #: sagenb/data/sage/html/notebook/base.html:108 msgid "Restart the worksheet process" msgstr "ПерезапуÑтити Ð¿Ñ€Ð¾Ñ†ÐµÑ Ñ€Ð¾Ð±Ð¾Ñ‡Ð¾Ð³Ð¾ аркуша" #: sagenb/data/sage/html/notebook/base.html:108 msgid "Restart worksheet" msgstr "ПерезапуÑтити робочий аркуш" #: sagenb/data/sage/html/notebook/base.html:109 msgid "Quit the worksheet process" msgstr "Завершити Ð¿Ñ€Ð¾Ñ†ÐµÑ Ñ€Ð¾Ð±Ð¾Ñ‡Ð¾Ð³Ð¾ аркуша" #: sagenb/data/sage/html/notebook/base.html:109 msgid "Save and quit worksheet" msgstr "Завершити Ñ– закрити робочий аркуш" #: sagenb/data/sage/html/notebook/base.html:111 msgid "Evaluate all input cells in the worksheet" msgstr "Виконати уÑÑ– Ð¿Ð¾Ð»Ñ Ð²Ð²Ð¾Ð´Ñƒ робочого аркуша" #: sagenb/data/sage/html/notebook/base.html:111 msgid "Evaluate All" msgstr "Виконати вÑе" #: sagenb/data/sage/html/notebook/base.html:112 msgid "Hide all output" msgstr "Приховати вÑÑ– результати" #: sagenb/data/sage/html/notebook/base.html:112 msgid "Hide All Output" msgstr "Приховати вÑÑ– результати" #: sagenb/data/sage/html/notebook/base.html:113 msgid "Show all output" msgstr "Показати вÑÑ– результати" #: sagenb/data/sage/html/notebook/base.html:113 msgid "Show All Output" msgstr "Показати вÑÑ– результати" #: sagenb/data/sage/html/notebook/base.html:114 msgid "Delete all output" msgstr "Видалити вÑÑ– результати" #: sagenb/data/sage/html/notebook/base.html:114 msgid "Delete All Output" msgstr "Видалити вÑÑ– результати" #: sagenb/data/sage/html/notebook/base.html:116 msgid "Switch to single-cell mode" msgstr "ПереключитиÑÑ Ð´Ð¾ режиму з одним полем" #: sagenb/data/sage/html/notebook/base.html:116 msgid "One Cell Mode" msgstr "Режим з одним полем" #: sagenb/data/sage/html/notebook/base.html:117 msgid "Switch to multi-cell mode" msgstr "ПереключитиÑÑ Ð´Ð¾ режиму з багатьма полÑми" #: sagenb/data/sage/html/notebook/base.html:117 msgid "Multi Cell Mode" msgstr "Режим з багатьма полÑми" #: sagenb/data/sage/html/notebook/base.html:120 msgid "Select an attached file" msgstr "Вибрати вкладений файл" #: sagenb/data/sage/html/notebook/base.html:120 msgid "Data..." msgstr "Дані..." #: sagenb/data/sage/html/notebook/base.html:121 msgid "Upload or create a data file in a wide range of formats" msgstr "" "Завантажте або Ñтворіть файл даних в одному із багатьох підтримуваних " "форматів" #: sagenb/data/sage/html/notebook/base.html:121 msgid "Upload or create file..." msgstr "Завантажити або Ñтворити файл..." #: sagenb/data/sage/html/notebook/base.html:131 #, python-format msgid "Evaluate all input cells using %(i)s" msgstr "Виконати уÑÑ– Ð¿Ð¾Ð»Ñ Ð²Ð²Ð¾Ð´Ñƒ, викориÑтовуючи %(i)s" #: sagenb/data/sage/html/notebook/base.html:137 msgid "Enable/disable pretty_printing" msgstr "Увімкнути/вимкнути pretty_printing (автоматичне Ñ„Ð¾Ñ€Ð¼Ð°Ñ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ð²Ð¸Ð²Ð¾Ð´Ñƒ)" #: sagenb/data/sage/html/notebook/base.html:149 msgid "Interactively use this worksheet" msgstr "ВикориÑтовувати цей робочий аркуш інтерактивно" #: sagenb/data/sage/html/notebook/base.html:149 msgid "Worksheet" msgstr "Робочий аркуш" #: sagenb/data/sage/html/notebook/base.html:150 msgid "Edit text version of this worksheet" msgstr "Редагувати текÑтову верÑÑ–ÑŽ цого робочого аркуша" #: sagenb/data/sage/html/notebook/base.html:150 msgid "Edit" msgstr "Редагувати" #: sagenb/data/sage/html/notebook/base.html:151 msgid "View plain text version of this worksheet" msgstr "ПереглÑнути текÑтову верÑÑ–ÑŽ цього робочого аркуша" #: sagenb/data/sage/html/notebook/base.html:151 msgid "Text" msgstr "ТекÑÑ‚" #: sagenb/data/sage/html/notebook/base.html:152 msgid "View changes to this worksheet over time" msgstr "ПереглÑнути зміни в цьому робочому аркуші" #: sagenb/data/sage/html/notebook/base.html:152 msgid "Revisions" msgstr "Зміни" #: sagenb/data/sage/html/notebook/base.html:153 msgid "Let others edit this worksheet" msgstr "Дозволити іншим редагувати цей робочий аркуш" #: sagenb/data/sage/html/notebook/base.html:153 msgid "Share" msgstr "ПоділитиÑÑ" #: sagenb/data/sage/html/notebook/base.html:154 msgid "Make this worksheet publicly viewable" msgstr "Дозволити переглÑдати цей робочий аркуш уÑім бажаючим" #: sagenb/data/sage/html/notebook/base.html:154 msgid "Publish" msgstr "Опублікувати" #: sagenb/data/sage/html/notebook/base.html:162 msgid "Exit" msgstr "Вихід" #: sagenb/data/sage/html/notebook/beforepublish_window.html:5 msgid "" "You can publish your worksheet to the Internet, where anyone will be able to " "access and view it online." msgstr "" "Ви можете опублікувати ваш робочий аркуш в Інтернеті, де будь-хто зможе " "переглÑнути його он-лайн." #: sagenb/data/sage/html/notebook/beforepublish_window.html:7 msgid "" "Your worksheet will be assigned a unique address (URL) that you can send to " "your friends and colleagues." msgstr "" "Вашому робочому аркушеві буде приÑвоєна унікальна адреÑа (URL), Ñку ви " "зможете відправити Ñвоїм друзÑм та колегам." #: sagenb/data/sage/html/notebook/beforepublish_window.html:9 msgid "Do you want to publish this worksheet?" msgstr "Ви хочете опублікувати цей робочий аркуш?" #: sagenb/data/sage/html/notebook/beforepublish_window.html:14 msgid "Yes" msgstr "Так" #: sagenb/data/sage/html/notebook/beforepublish_window.html:15 msgid "No" msgstr "ÐÑ–" #: sagenb/data/sage/html/notebook/cell.html:80 msgid "Click here or press shift-return to evaluate" msgstr "ÐатиÑніть тут або Shift+Enter Ð´Ð»Ñ Ð²Ð¸ÐºÐ¾Ð½Ð°Ð½Ð½Ñ" #: sagenb/data/sage/html/notebook/cell.html:81 msgid "evaluate" msgstr "виконати" #: sagenb/data/sage/html/notebook/download_or_delete_datafile.html:35 msgid "Data file" msgstr "Файл даних" #: sagenb/data/sage/html/notebook/download_or_delete_datafile.html:39 #, python-format msgid "" "You may download %(f)s or create a link to this file " "in worksheet " msgstr "" "Ви можете завантажити %(f)s або Ñтворити поÑÐ¸Ð»Ð°Ð½Ð½Ñ Ð½Ð° " "цей файл у робочому аркуші " #: sagenb/data/sage/html/notebook/download_or_delete_datafile.html:40 msgid "select worksheet" msgstr "виберіть робочий аркуш" #: sagenb/data/sage/html/notebook/download_or_delete_datafile.html:44 #, python-format msgid "" "or delete %(f)s." msgstr "" "або delete %(f)s." "" #: sagenb/data/sage/html/notebook/download_or_delete_datafile.html:46 #, python-format msgid "" "Access %(f)s in this worksheet by typing DATA+'%(f)s'. Here DATA is " "a special variable that gives the exact path to all data files uploaded to " "this worksheet." msgstr "" "ВикориÑтовуйте %(f)s в цьому робочому аркуші, ввівши DATA+'%(f)s'. " "Тут DATA — це Ñпеціальна змінна, що міÑтить повний шлÑÑ… до уÑÑ–Ñ… файлів, " "прикріплених до цього робочого аркуша." #: sagenb/data/sage/html/notebook/download_or_delete_datafile.html:54 #: sagenb/data/sage/html/notebook/edit_window.html:11 msgid "Save Changes" msgstr "Зберегти зміни" #: sagenb/data/sage/html/notebook/edit_window.html:10 msgid "Edit plain text" msgstr "Редагувати Ñк звичайний текÑÑ‚" #: sagenb/data/sage/html/notebook/guest_worksheet_page.html:20 msgid "Edit this." msgstr "Редагувати" #: sagenb/data/sage/html/notebook/guest_worksheet_page.html:23 msgid "Log in to edit a copy." msgstr "Увійдіть, щоб відредагувати копію." #: sagenb/data/sage/html/notebook/guest_worksheet_page.html:26 msgid "Edit a copy." msgstr "Редагувати копію." #: sagenb/data/sage/html/notebook/guest_worksheet_page.html:39 msgid "Download." msgstr "Завантажити." #: sagenb/data/sage/html/notebook/guest_worksheet_page.html:45 #, python-format msgid "This page is rated %(wr).1f." msgstr "Оцінка цієї Ñторінки %(wr).1f." #: sagenb/data/sage/html/notebook/guest_worksheet_page.html:54 msgid "leave a comment" msgstr "залишити коментар" #: sagenb/data/sage/html/notebook/guest_worksheet_page.html:55 msgid "Rerate" msgstr "Змінити оцінку" #: sagenb/data/sage/html/notebook/guest_worksheet_page.html:55 msgid "Rate" msgstr "Оцінити" #: sagenb/data/sage/html/notebook/guest_worksheet_page.html:59 msgid "Other published documents..." msgstr "Інші опубліковані документи..." #: sagenb/data/sage/html/notebook/plain_text_window.html:4 msgid "View plain text" msgstr "ПереглÑнути Ñк звичайний текÑÑ‚" #: sagenb/data/sage/html/notebook/specific_revision.html:5 #, python-format msgid "Revision from %(ta)s ago" msgstr "Змінено %(ta)s днів тому" #: sagenb/data/sage/html/notebook/specific_revision.html:5 msgid "Revision List" msgstr "СпиÑок змін" #: sagenb/data/sage/html/notebook/specific_revision.html:12 msgid "Older" msgstr "Старі" #: sagenb/data/sage/html/notebook/specific_revision.html:14 msgid "Oldest" msgstr "ÐайÑтаріші" #: sagenb/data/sage/html/notebook/specific_revision.html:18 msgid "Newer" msgstr "Ðові" #: sagenb/data/sage/html/notebook/specific_revision.html:20 msgid "Newest" msgstr "Ðайновіші" #: sagenb/data/sage/html/notebook/specific_revision.html:23 msgid "Revert to this one" msgstr "Відновити до цієї верÑÑ–Ñ—" #: sagenb/data/sage/html/notebook/specific_revision.html:23 msgid "(note that images are not recorded)" msgstr "(зверніть увагу, що Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð½Ñ Ð½Ðµ запиÑані)" #: sagenb/data/sage/html/notebook/specific_revision.html:24 msgid "Publish this one" msgstr "Опублікувати цю верÑÑ–ÑŽ" #: sagenb/data/sage/html/notebook/text_cell.html:49 msgid "Cancel changes" msgstr "СкаÑувати зміни" #: sagenb/data/sage/html/notebook/upload_data_window.html:7 #, python-format msgid "Upload or Create Data File to attach to worksheet \"%(wn)s\"" msgstr "" "Завантажити або Ñтворити файл даних та прикріпити його до робочого аркуша " "\"%(wn)s\"" #: sagenb/data/sage/html/notebook/upload_data_window.html:15 msgid "Browse your computer to select a file to upload:" msgstr "Виберіть файл на вашому комп'ютері Ð´Ð»Ñ Ð·Ð°Ð²Ð°Ð½Ñ‚Ð°Ð¶ÐµÐ½Ð½Ñ:" #: sagenb/data/sage/html/notebook/upload_data_window.html:19 msgid "Or enter the URL of a file on the web:" msgstr "Ðбо введіть URL-адреÑу файлу в Інтернеті:" #: sagenb/data/sage/html/notebook/upload_data_window.html:23 msgid "Or enter the name of a new file, which will be created:" msgstr "Ðбо введіть ім'Ñ Ð½Ð¾Ð²Ð¾Ð³Ð¾ файлу, котрий буде Ñтворено:" #: sagenb/data/sage/html/notebook/upload_data_window.html:27 msgid "What do you want to call it? (if different than the original name)" msgstr "" "Як ви хочете назвати його? (Ñкщо бажаєте змінити ім'Ñ Ð¾Ñ€Ð¸Ð³Ñ–Ð½Ð°Ð»ÑŒÐ½Ð¾Ð³Ð¾ файлу)" #: sagenb/data/sage/html/notebook/upload_data_window.html:30 msgid "Upload or Create Data File" msgstr "Завантажити або Ñтворити файл даних" #: sagenb/data/sage/html/notebook/worksheet_revision_list.html:6 msgid "Revision History -- Previous sessions" msgstr "ІÑÑ‚Ð¾Ñ€Ñ–Ñ Ð·Ð¼Ñ–Ð½ — Попередні ÑеÑÑ–Ñ—" #: sagenb/data/sage/html/notebook/worksheet_revision_list.html:15 msgid "Revision" msgstr "ВерÑÑ–Ñ" #: sagenb/data/sage/html/notebook/worksheet_revision_list.html:22 #, python-format msgid "Revision %(lr)s" msgstr "ВерÑÑ–Ñ %(lr)s" #: sagenb/data/sage/html/notebook/worksheet_share.html:10 msgid "Share this document" msgstr "ПоділитиÑÑ Ñ†Ð¸Ð¼ документом" #: sagenb/data/sage/html/notebook/worksheet_share.html:27 msgid "" "Only the owner of a worksheet is allowed to share it. You can do whatever " "you want if you make your own copy." msgstr "" "Тільки влаÑник робочого аркуша може поділитиÑÑ Ð½Ð¸Ð¼. Ви можете робити вÑе, що " "вам потрібно, Ñтворивши влаÑну копію." #: sagenb/data/sage/html/notebook/worksheet_share.html:29 msgid "" "This Sage Worksheet is currently shared with the people listed in the box " "below." msgstr "Цей робочий аркуш наразі не Ñ” Ñпільним Ð´Ð»Ñ Ð»ÑŽÐ´ÐµÐ¹, перерахованих нижче." #: sagenb/data/sage/html/notebook/worksheet_share.html:30 msgid "You may add or remove collaborators (separate user names by commas)." msgstr "" "Ви можете додати чи видалити Ñпівавторів (відділÑйте Ñ—Ñ… імена кориÑтувачів " "комами)." #: sagenb/data/sage/html/notebook/worksheet_share.html:34 msgid "Give access to your worksheet to the above collaborators" msgstr "" "Ðадати доÑтуп до вашого робочого аркуша перерахованим нижче Ñпівавторам" #: sagenb/data/sage/html/notebook/worksheet_share.html:34 msgid "Invite Collaborators" msgstr "ЗапроÑити Ñпівавторів" #: sagenb/data/sage/html/notebook/worksheet_share.html:40 msgid "Search results:" msgstr "Результати пошуку:" #: sagenb/data/sage/html/notebook/worksheet_share.html:46 msgid "sorry, no match found" msgstr "вибачте, по даному запиту нічого не знайдено" #: sagenb/data/sage/html/notebook/worksheet_share.html:50 msgid "Search Users" msgstr "Пошук кориÑтувачів" #: sagenb/data/sage/html/notebook/worksheet_share.html:60 msgid "Known Sage Users:" msgstr "Відомі кориÑтувачі Sage:" #: sagenb/data/sage/html/settings/account_settings.html:3 #: sagenb/data/sage/html/settings/base.html:13 msgid "Account Settings" msgstr "ÐÐ°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ð¾Ð±Ð»Ñ–ÐºÐ¾Ð²Ð¾Ð³Ð¾ запиÑу" #: sagenb/data/sage/html/settings/account_settings.html:13 msgid "Change Auto-Save Interval" msgstr "Змінити інтервал автоматичного збереженнÑ" #: sagenb/data/sage/html/settings/account_settings.html:15 msgid "Minutes" msgstr "Хвилини" #: sagenb/data/sage/html/settings/account_settings.html:25 msgid "Change Password" msgstr "Змінити пароль" #: sagenb/data/sage/html/settings/account_settings.html:31 msgid "Old password" msgstr "Старий пароль" #: sagenb/data/sage/html/settings/account_settings.html:35 msgid "New password" msgstr "Ðовий пароль" #: sagenb/data/sage/html/settings/account_settings.html:39 msgid "Retype new password" msgstr "Введіть пароль ще раз" #: sagenb/data/sage/html/settings/account_settings.html:48 msgid "Change E-mail Address" msgstr "Змінити адреÑу електронної пошти" #: sagenb/data/sage/html/settings/account_settings.html:52 msgid "Current e-mail" msgstr "Поточна адреÑа електронної пошти" #: sagenb/data/sage/html/settings/account_settings.html:56 msgid "New e-mail" msgstr "Ðова адреÑа електронної пошти" #: sagenb/data/sage/html/settings/account_settings.html:64 msgid "Your Email" msgstr "Ваша адреÑа електронної пошти" #: sagenb/data/sage/html/settings/admin_add_user.html:2 #: sagenb/data/sage/html/settings/admin_add_user.html:6 msgid "Add New User" msgstr "Додати нового кориÑтувача" #: sagenb/data/sage/html/settings/admin_add_user.html:8 msgid "Username Error" msgstr "Помилка в імені кориÑтувача" #: sagenb/data/sage/html/settings/admin_add_user.html:12 msgid "Pick a username" msgstr "Виберіть ім'Ñ ÐºÐ¾Ñ€Ð¸Ñтувача" #: sagenb/data/sage/html/settings/admin_add_user.html:13 msgid "" "The username must start with a letter and be between 4 and 32 characters " "long. It can only consist of letters, numbers, underscores, and one dot (.)." msgstr "" "Ім'Ñ ÐºÐ¾Ñ€Ð¸Ñтувача має починатиÑÑ Ð· літери та міÑтити від 4 до 32 Ñимволів. " "Можна викориÑтовувати лише літери, цифри, знаки підкреÑÐ»ÐµÐ½Ð½Ñ Ñ– одну точку " "(.)." #: sagenb/data/sage/html/settings/admin_add_user.html:17 msgid "Invalid username" msgstr "Ðевірне ім'Ñ ÐºÐ¾Ñ€Ð¸Ñтувача" #: sagenb/data/sage/html/settings/admin_add_user.html:19 msgid "Username taken" msgstr "Ім'Ñ ÐºÐ¾Ñ€Ð¸Ñтувача прийнÑто" #: sagenb/data/sage/html/settings/admin_add_user.html:25 msgid "Create Account" msgstr "Створити обліковий запиÑ" #: sagenb/data/sage/html/settings/base.html:10 msgid "Manage Users" msgstr "УправлÑти кориÑтувачами" #: sagenb/data/sage/html/settings/base.html:11 #: sagenb/data/sage/html/settings/notebook_settings.html:2 msgid "Notebook Settings" msgstr "ÐÐ°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ Notebook" #: sagenb/data/sage/html/settings/user_management.html:3 #: sagenb/data/sage/html/settings/user_management.html:13 msgid "Users" msgstr "КориÑтувачі" #: sagenb/data/sage/html/settings/user_management.html:7 msgid "User Management" msgstr "Ð£Ð¿Ñ€Ð°Ð²Ð»Ñ–Ð½Ð½Ñ ÐºÐ¾Ñ€Ð¸Ñтувачами" #: sagenb/data/sage/html/settings/user_management.html:8 msgid "Add User" msgstr "Додати кориÑтувача" #: sagenb/data/sage/html/settings/user_management.html:10 #, python-format msgid "" "The password for the user %(u)s has been reset to %(p)s" msgstr "Пароль Ð´Ð»Ñ ÐºÐ¾Ñ€Ð¸Ñтувача %(u)s було Ñкинуто до%(p)s" #: sagenb/data/sage/html/settings/user_management.html:13 msgid "Suspension" msgstr "БлокуваннÑ" #: sagenb/data/sage/html/settings/user_management.html:16 msgid "Reset" msgstr "Скинути" #: sagenb/data/sage/html/settings/user_management.html:16 msgid "Unsuspend" msgstr "Розблокувати" #: sagenb/data/sage/html/settings/user_management.html:16 msgid "Suspend" msgstr "Заблокувати" #: sagenb/data/sage/html/worksheet/ratings_info.html:3 #: sagenb/data/sage/html/worksheet/ratings_info.html:6 #, python-format msgid "Ratings for %(wn)s" msgstr "Оцінки Ð´Ð»Ñ %(wn)s" #: sagenb/data/sage/html/worksheet/ratings_info.html:7 msgid "Go to the worksheet." msgstr "Перейти до робочого аркуша." #: sagenb/data/sage/html/worksheet/ratings_info.html:9 msgid "User" msgstr "КориÑтувач" #: sagenb/data/sage/html/worksheet/ratings_info.html:9 msgid "Comment" msgstr "Коментар" #: sagenb/data/sage/html/worksheet/time_last_edited.html:6 #, python-format msgid "%(t)s by %(le)s" msgstr "%(t)s тому кориÑтувачем %(le)s" #: sagenb/data/sage/html/worksheet/time_since_last_edited.html:6 #: sagenb/notebook/worksheet.py:2010 #, python-format msgid "%(t)s ago by %(le)s" msgstr "%(t)s тому кориÑтувачем %(le)s" #: sagenb/data/sage/js/translated-messages.js:4 msgid "Click to download and install tex fonts." msgstr "ÐатиÑніть, щоб завантажити та вÑтановити шрифти TeX." #: sagenb/data/sage/js/translated-messages.js:5 msgid "" "Your browser / OS combination is not supported.\\nPlease use Firefox or " "Opera under Linux, Windows, or Mac OS X, or Safari." msgstr "" "Ваш браузер, операційна ÑиÑтема чи Ñ—Ñ… ÐºÐ¾Ð¼Ð±Ñ–Ð½Ð°Ñ†Ñ–Ñ Ð½Ðµ підтримуєтьÑÑ.\\nБудь-" "лаÑка, ÑкориÑтайтеÑÑŒ Firefox чи Opera в операційних ÑиÑтемах Linux, Windows " "чи Mac OS X Ñ– Safari." #: sagenb/data/sage/js/translated-messages.js:6 msgid "Java Applet Hidden" msgstr "Java апплет приховано" #: sagenb/data/sage/js/translated-messages.js:7 msgid "Click here to pop out" msgstr "Відкрити в окремому вікні" #: sagenb/data/sage/js/translated-messages.js:8 msgid "Error applying function to worksheet(s)." msgstr "Ðе вдалоÑÑ Ð·Ð°ÑтоÑувати функцію до робочого(их) аркуша(ів)." #: sagenb/data/sage/js/translated-messages.js:9 msgid "Title of saved worksheet" msgstr "Ðазва збереженого робочого аркуша." #: sagenb/data/sage/js/translated-messages.js:10 msgid "Failed to save worksheet." msgstr "Ðе вдалоÑÑ Ð·Ð±ÐµÑ€ÐµÐ³Ñ‚Ð¸ робочий аркуш." #: sagenb/data/sage/js/translated-messages.js:12 msgid "Please enter a name for this worksheet." msgstr "Будь-лаÑка, введіть ім'Ñ Ñ†ÑŒÐ¾Ð³Ð¾ робочого аркуша." #: sagenb/data/sage/js/translated-messages.js:13 msgid "Rename" msgstr "Перейменувати" #: sagenb/data/sage/js/translated-messages.js:14 msgid "Possible failure deleting worksheet." msgstr "Можливо, ÑталаÑÑŒ помилка при видаленні робочого аркуша." #: sagenb/data/sage/js/translated-messages.js:15 msgid "unprinted" msgstr "не надруковано" #: sagenb/data/sage/js/translated-messages.js:16 msgid "" "You requested to evaluate a cell that, for some reason, the server is " "unaware of." msgstr "Ви вказали на Ð²Ð¸ÐºÐ¾Ð½Ð°Ð½Ð½Ñ Ð¿Ð¾Ð»Ñ, Ñке, з деÑких причин, невідоме Ñерверу." #: sagenb/data/sage/js/translated-messages.js:18 msgid "" "This worksheet is read only. Please make a copy or contact the owner to " "change it." msgstr "" "Цей робочий аркуш доÑтупний лише Ð´Ð»Ñ Ñ‡Ð¸Ñ‚Ð°Ð½Ð½Ñ. Будь-лаÑка, зробіть копію чи " "зв'ÑжітьÑÑ Ð· автором, щоб отримати права на внеÑÐµÐ½Ð½Ñ Ð·Ð¼Ñ–Ð½." #: sagenb/data/sage/js/translated-messages.js:19 msgid "loading..." msgstr "завантаженнÑ..." #: sagenb/data/sage/js/translated-messages.js:20 msgid "Error updating cell output after " msgstr "Помилка Ð¾Ð½Ð¾Ð²Ð»ÐµÐ½Ð½Ñ Ñ€ÐµÐ·ÑƒÐ»ÑŒÑ‚Ð°Ñ‚Ñ–Ð² виводу Ð¿Ð¾Ð»Ñ Ð¿Ñ–ÑÐ»Ñ " #: sagenb/data/sage/js/translated-messages.js:21 msgid "s (canceling further update checks)." msgstr "s (подальші перевірки оновлень припинено)." #: sagenb/data/sage/js/translated-messages.js:22 msgid "Problem inserting new input cell after current input cell.\\n" msgstr "Виникла проблема при вÑтавці нового Ð¿Ð¾Ð»Ñ Ð¿Ñ–ÑÐ»Ñ Ð¿Ð¾Ñ‚Ð¾Ñ‡Ð½Ð¾Ð³Ð¾.\\n" #: sagenb/data/sage/js/translated-messages.js:23 msgid "Worksheet is locked. Cannot insert cells." msgstr "Робочий аркуш заблоковано. Ðе можна вÑтавлÑти полÑ." #: sagenb/data/sage/js/translated-messages.js:24 msgid "Unable to interrupt calculation." msgstr "Ðеможливо перервати обчиÑленнÑ." #: sagenb/data/sage/js/translated-messages.js:25 msgid "Close this box to stop trying." msgstr "Закрийте це повідомленнÑ, щоб припинити Ñпроби." #: sagenb/data/sage/js/translated-messages.js:26 msgid "Interrupt attempt" msgstr "Спроба перериваннÑ" #: sagenb/data/sage/js/translated-messages.js:27 msgid "Restart, instead?" msgstr "" "Можливо, заміÑть цього, ви хочете перезапуÑтити, робочий аркуш?" #: sagenb/data/sage/js/translated-messages.js:28 msgid "" "Emptying the trash will permanently delete all items in the trash. Continue?" msgstr "" "ÐžÑ‡Ð¸Ñ‰ÐµÐ½Ð½Ñ ÐºÐ¾ÑˆÐ¸ÐºÐ° оÑтаточно видалить уÑÑ– робочі аркуші в ньому. Продовжити?" #: sagenb/data/sage/js/translated-messages.js:29 msgid "Get Image" msgstr "Отримати зображеннÑ" #: sagenb/data/sage/js/translated-messages.js:30 msgid "Jmol Image" msgstr "Ð—Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð½Ñ Jmol" #: sagenb/data/sage/js/translated-messages.js:31 msgid "" "To save this image, you can try right-clicking on the image to copy it or " "save it to a file, or you may be able to just drag the image to your desktop." msgstr "" "Щоб зберегти це зображеннÑ, натиÑніть на ньому правою кнопкою миші та " "оберіть Копіювати чи Зберегти. Також ви можете проÑто перетÑгнути Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð½Ñ " "на робочий Ñтіл." #: sagenb/data/sage/js/translated-messages.js:32 msgid "Sorry, but you need a browser that supports the <canvas> tag." msgstr "" "Вибачте, але потрібен браузер, котрий підтримує HTML тег <canvas>." #: sagenb/data/sage/js/translated-messages.js:33 #, python-format msgid "Trying again in %(num)d second..." msgid_plural "Trying again in %(num)d seconds..." msgstr[0] "ÐаÑтупна Ñпроба через %(num)d Ñекунду..." msgstr[1] "ÐаÑтупна Ñпроба через %(num)d Ñекунди..." msgstr[2] "ÐаÑтупна Ñпроба через %(num)d Ñекунд..." #: sagenb/notebook/challenge.py:180 msgid "Please ask the server administrator to configure a challenge!" msgstr "" "Будь-лаÑка, звернітьÑÑ Ð´Ð¾ адмініÑтратора Ñервера Ð´Ð»Ñ Ð½Ð°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ð·Ð°Ñ…Ð¸Ñту " "від ботів!" #: sagenb/notebook/challenge.py:221 msgid "Is pi > e?" msgstr "Чи вірно, що Ï€>e?" #: sagenb/notebook/challenge.py:221 msgid "y|yes" msgstr "Ñ‚|так" #: sagenb/notebook/challenge.py:222 msgid "What is 3 times 8?" msgstr "Скільки буде тричі по віÑім?" #: sagenb/notebook/challenge.py:222 msgid "24|twenty-four" msgstr "24|двадцÑть чотири" #: sagenb/notebook/challenge.py:223 msgid "What is 2 plus 3?" msgstr "Скільки буде 2 Ð¿Ð»ÑŽÑ 3?" #: sagenb/notebook/challenge.py:223 ../sagenb/notebook/challenge.py:225 msgid "5|five" msgstr "5|п'Ñть" #: sagenb/notebook/challenge.py:224 msgid "How many bits are in one byte?" msgstr "Скільки бітів в одному байті?" #: sagenb/notebook/challenge.py:224 msgid "8|eight" msgstr "8|віÑім" #: sagenb/notebook/challenge.py:225 msgid "What is the largest prime factor of 15?" msgstr "Який найбільший проÑтий дільник чиÑла 15?" #: sagenb/notebook/conf.py:124 msgid "Updated" msgstr "Оновлено" #: sagenb/notebook/register.py:19 ../sagenb/notebook/register.py:29 #, python-format msgid "" "Hi %(username)s!\n" "\n" msgstr "" "Вітаємо %(username)s!\n" "\n" #: sagenb/notebook/register.py:20 #, python-format msgid "" "Thank you for registering for the Sage notebook. To complete your " "registration, copy and paste the following link into your browser:\n" "\n" "%(url_prefix)s://%(addr)s:%(port)s/confirm?key=%(key)s\n" "\n" "You will be taken to a page which will confirm that you have indeed " "registered." msgstr "" "ДÑкуємо за реєÑтрацію в Sage Notebook. Ð”Ð»Ñ Ð·Ð°Ð²ÐµÑ€ÑˆÐµÐ½Ð½Ñ Ñ€ÐµÑ”Ñтрації Ñкопіюйте Ñ– " "вÑтавте наÑтупне поÑÐ¸Ð»Ð°Ð½Ð½Ñ Ñƒ ваш браузер:\n" "\n" "%(url_prefix)s://%(addr)s:%(port)s/confirm?key=%(key)s\n" "\n" "ВідкриєтьÑÑ Ñторінка, на Ñкій з'ÑвитьÑÑ Ð¿Ð¾Ð²Ñ–Ð´Ð¾Ð¼Ð»ÐµÐ½Ð½Ñ, що підтверджуватиме " "вашу уÑпішну реєÑтрацію." #: sagenb/notebook/register.py:30 #, python-format msgid "" "Your new password is %(key)s\n" "\n" "Sign in at %(url_prefix)s://%(addr)s:%(port)s/\n" "\n" "Make sure to reset your password by going to Settings in the upper right bar." msgstr "" "Ваш новий пароль: %(key)s\n" "\n" "Увійдіть на Ñервер: %(url_prefix)s://%(addr)s:%(port)s/\n" "\n" "Будь-лаÑка, Ñкиньте ваш пароль, перейшовши в ÐÐ°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ñƒ верхній правій " "панелі." #: sagenb/notebook/server_conf.py:57 msgid "Appearance" msgstr "ВиглÑд" #: sagenb/notebook/server_conf.py:58 msgid "Authentication" msgstr "ÐутентифікаціÑ" #: sagenb/notebook/server_conf.py:59 msgid "LDAP" msgstr "LDAP" #: sagenb/notebook/server_conf.py:60 msgid "Server" msgstr "Сервер" #: sagenb/notebook/server_conf.py:65 msgid "Number of word-wrap columns" msgstr "МакÑимальна довжина Ñ€Ñдка при перенеÑенні Ñлів" #: sagenb/notebook/server_conf.py:71 msgid "Maximum history length" msgstr "МакÑимальна довжина Ñ–Ñторії" #: sagenb/notebook/server_conf.py:77 msgid "Idle timeout (seconds)" msgstr "Тайм-аут Ð¾Ñ‡Ñ–ÐºÑƒÐ²Ð°Ð½Ð½Ñ (в Ñекундах)" #: sagenb/notebook/server_conf.py:83 msgid "Idle check interval (seconds)" msgstr "Інтервал між запитами (в Ñекундах)" #: sagenb/notebook/server_conf.py:89 msgid "Save interval (seconds)" msgstr "Інтервал Ð°Ð²Ñ‚Ð¾Ð·Ð±ÐµÑ€Ñ–Ð³Ð°Ð½Ð½Ñ (в Ñекундах)" #: sagenb/notebook/server_conf.py:95 msgid "Doc worksheet pool size" msgstr "Розмір пула документації робочого аркуша" #: sagenb/notebook/server_conf.py:101 msgid "Doc worksheet idle timeout (seconds)" msgstr "Тайм-аут Ð¾Ñ‡Ñ–ÐºÑƒÐ²Ð°Ð½Ð½Ñ (в Ñекундах) робочого аркуша" #: sagenb/notebook/server_conf.py:107 msgid "Enable published interacts (EXPERIMENTAL; USE AT YOUR OWN RISK)" msgstr "" "Дозволити інтерактивні опубліковані робочі аркуші (ЕКСПЕРИМЕÐТÐЛЬÐРФУÐКЦІЯ; " "ВИКОРИСТОВУЙТЕ ÐРСВІЙ РИЗИК)" #: sagenb/notebook/server_conf.py:113 msgid "Worksheet process users (comma-separated list)" msgstr "КориÑтувачі процеÑу робочого аркуша (ÑпиÑок, розділений комами)" #: sagenb/notebook/server_conf.py:119 msgid "Default system" msgstr "СиÑтема за замовчуваннÑм" #: sagenb/notebook/server_conf.py:125 msgid "Pretty print (typeset) output" msgstr "ÐÐ²Ñ‚Ð¾Ñ„Ð¾Ñ€Ð¼Ð°Ñ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ð²Ð¸Ð²Ð¾Ð´Ñƒ" #: sagenb/notebook/server_conf.py:131 msgid "Worksheet process limits" msgstr "ÐžÐ±Ð¼ÐµÐ¶ÐµÐ½Ð½Ñ Ð¿Ñ€Ð¾Ñ†ÐµÑу робочого аркуша" #: sagenb/notebook/server_conf.py:138 msgid "Require e-mail for account registration" msgstr "Вимагати адреÑу електронної пошти Ð´Ð»Ñ Ñ€ÐµÑ”Ñтрації облікового запиÑу" #: sagenb/notebook/server_conf.py:145 msgid "Enable user registration" msgstr "Дозволити реєÑтрацію кориÑтувачів" #: sagenb/notebook/server_conf.py:152 msgid "Allow OpenID authentication (requires python ssl module)" msgstr "Дозволити аутентифікацію через OpenID (потрібен python модуль ssl)" #: sagenb/notebook/server_conf.py:159 msgid "Use a challenge for account registration" msgstr "ВикориÑтовувати захиÑÑ‚ від ботів при реєÑтрації облікового запиÑу" #: sagenb/notebook/server_conf.py:166 msgid "Type of challenge" msgstr "Тип захиÑту" #: sagenb/notebook/server_conf.py:173 msgid "reCAPTCHA public key" msgstr "Відкритий ключ reCAPTCHA" #: sagenb/notebook/server_conf.py:179 msgid "reCAPTCHA private key" msgstr "Закритий ключ reCAPTCHA" #: sagenb/notebook/server_conf.py:185 msgid "Default Language" msgstr "Мова по замовчуваннÑм" #: sagenb/notebook/server_conf.py:191 msgid "Model Version" msgstr "ВерÑÑ–Ñ Ð¼Ð¾Ð´ÐµÐ»Ñ–" #: sagenb/notebook/server_conf.py:197 msgid "Enable LDAP Authentication" msgstr "Дозволити аутентифікацію через LDAP" #: sagenb/notebook/server_conf.py:209 msgid "Bind DN" msgstr "ПідключатиÑÑ Ñк (Bind DN)" #: sagenb/notebook/server_conf.py:215 msgid "Bind Password" msgstr "Пароль підключеннÑ" #: sagenb/notebook/server_conf.py:221 msgid "Base DN" msgstr "База пошуку" #: sagenb/notebook/server_conf.py:227 msgid "Username Attribute (i.e. cn, uid or userPrincipalName)" msgstr "Ðтрибут імені кориÑтувача (наприклад, cn, uid чи userPrincipalName)" #: sagenb/notebook/server_conf.py:233 msgid "Attributes for user lookup" msgstr "Ðтрибути Ð´Ð»Ñ Ð¿Ð¾ÑˆÑƒÐºÑƒ кориÑтувачів" #: sagenb/notebook/template.py:74 #, python-format msgid "%(num)d second" msgid_plural "%(num)d seconds" msgstr[0] "%(num)d Ñекунда" msgstr[1] "%(num)d Ñекунди" msgstr[2] "%(num)d Ñекунд" #: sagenb/notebook/template.py:77 #, python-format msgid "%(num)d minute" msgid_plural "%(num)d minutes" msgstr[0] "%(num)d хвилина" msgstr[1] "%(num)d хвилини" msgstr[2] "%(num)d хвилин" #: sagenb/notebook/template.py:80 #, python-format msgid "%(num)d hour" msgid_plural "%(num)d hours" msgstr[0] "%(num)d година" msgstr[1] "%(num)d години" msgstr[2] "%(num)d годин" #: sagenb/notebook/template.py:82 #, python-format msgid "%(num)d day" msgid_plural "%(num)d days" msgstr[0] "%(num)d доба" msgstr[1] "%(num)d доби" msgstr[2] "%(num)d діб" #: sagenb/notebook/template.py:141 msgid "Sage Notebook" msgstr "Sage Notebook" #: sagenb/notebook/tutorial.py:354 msgid "Find Help and Documentation" msgstr "Знайти довідки та документацію" #: sagenb/notebook/tutorial.py:355 msgid "Get Started with Sage" msgstr "Початок роботи з Sage" #: sagenb/notebook/tutorial.py:355 msgid "" "Work through the tutorial (if " "you have trouble with it, view the static version)." msgstr "" "ОзнайомтеÑÑŒ із практичними " "рекомендаціÑми (Ñкщо у Ð²Ð°Ñ Ð²Ð¸Ð½Ð¸ÐºÐ½ÑƒÑ‚ÑŒ проблеми з Ñ—Ñ… переглÑдом, " "викориÑтовуйте Ñтатичну верÑÑ–ÑŽ)." #: sagenb/notebook/tutorial.py:356 msgid "Help About" msgstr "КонтекÑтна довідка" #: sagenb/notebook/tutorial.py:357 msgid "" "Type ? immediately after the object or function and press tab or shift-enter " "(shift-enter overwrites output and saves to worksheet)." msgstr "" "Введіть ? відразу піÑÐ»Ñ Ð¾Ð±'єкта чи функції Ñ– натиÑніть Tab або Shift+Enter " "(Shift+Enter перезапиÑує Ð²Ð²ÐµÐ´ÐµÐ½Ð½Ñ Ñ– зберігає робочий аркуш)." #: sagenb/notebook/tutorial.py:359 msgid "" "Put ?? after the object and press tab or shift-enter (shift-enter overwrites " "output and saves to worksheet)." msgstr "" "Введіть ?? піÑÐ»Ñ Ð¾Ð±'єкта Ñ– натиÑніть Tab або Shift+Enter (Shift+Enter " "перезапиÑує Ð²Ð²ÐµÐ´ÐµÐ½Ð½Ñ Ñ– зберігає робочий аркуш)." #: sagenb/notebook/tutorial.py:360 msgid "Full Text Search of Docs and Source" msgstr "ПовнотекÑтовий пошук по документації та вихідному коду" #: sagenb/notebook/tutorial.py:361 msgid "" "Search the SAGE documentation by typing
    search_doc(\"my query\")
    " "in an input cell and press shift-enter. Search the source code of SAGE by " "typing
    search_src(\"my query\")
    and pressing shift-enter. " "Arbitrary regular expressions are allowed as queries." msgstr "" "Ð”Ð»Ñ Ð¿Ð¾ÑˆÑƒÐºÑƒ в документації Sage введіть
    search_doc(\"ваш запит\")
    " "в поле вводу Ñ– натиÑніть Shift+Enter. Знайти вихідний код Sage можна, " "ввівши
    search_src(\"ваш запит\")
    Ñ– натиÑнувши Shift+Enter. У " "запитах можна викориÑтовувати довільні регулÑрні вирази." #: sagenb/notebook/tutorial.py:365 msgid "Key and Mouse Bindings" msgstr "ГарÑчі клавіші та дії мишею" #: sagenb/notebook/tutorial.py:366 msgid "Evaluate Input" msgstr "Виконати введеннÑ" #: sagenb/notebook/tutorial.py:367 msgid "" "Press shift-enter. You can start several calculations at " "once. If you press alt-enter instead, then a new cell is " "created after the current one. If you press ctrl-enter " "then the cell is split and both pieces are evaluated separately." msgstr "" "ÐатиÑніть Shift+Enter. Ви можете розпочати декілька " "обчиÑлень одночаÑно. Якщо ж ви натиÑнете Alt-Enter, то " "буде Ñтворено нове поле відразу піÑÐ»Ñ Ð¿Ð¾Ñ‚Ð¾Ñ‡Ð½Ð¾Ð³Ð¾. РнатиÑненнÑCtrl" "+Enter розбиває поле на дві чаÑтини, що будуть виконуватиÑÑ Ð¾ÐºÑ€ÐµÐ¼Ð¾." #: sagenb/notebook/tutorial.py:368 msgid "Tab Completion" msgstr "ÐÐ²Ñ‚Ð¾Ð·Ð°Ð²ÐµÑ€ÑˆÐµÐ½Ð½Ñ Ð¿Ð¾ натиÑненню Tab" #: sagenb/notebook/tutorial.py:369 msgid "" "Press tab while the cursor is on an identifier. On some web " "browsers (e.g., Opera) you must use control-space instead of tab." msgstr "" "ÐатиÑніть Tab поки курÑор знаходитьÑÑ Ð½Ð° ідентифікаторі. У " "деÑких браузерах (наприклад, в Opera) заміÑть Tab треба викориÑтовувати Ctrl" "+Пробіл." #: sagenb/notebook/tutorial.py:370 msgid "Insert New Cell" msgstr "Ð’Ñтавити нове поле" #: sagenb/notebook/tutorial.py:371 msgid "" "Put the mouse between an output and input until the horizontal line appears " "and click. If you press Alt-Enter in a cell, the cell is evaluated and a " "new cell is inserted after it." msgstr "" "Ðаведіть вказівник миші на міÑце над полем вводу Ñ– виводом таким чином, щоб " "з'ÑвилаÑÑŒ горизонтальна лініÑ, Ñ– натиÑніть. Якщо ви натиÑнете Alt+Enter, " "поточне поле буде виконано Ñ– піÑÐ»Ñ Ð½ÑŒÐ¾Ð³Ð¾ буде вÑтавлено нове." #: sagenb/notebook/tutorial.py:372 msgid "Delete Cell" msgstr "Видалити поле" #: sagenb/notebook/tutorial.py:373 msgid "Delete all cell contents, then press backspace." msgstr "Видаліть вміÑÑ‚ Ð¿Ð¾Ð»Ñ Ñ–, потім, натиÑніть Backspace." #: sagenb/notebook/tutorial.py:374 msgid "Split and Join Cells" msgstr "Ð Ð¾Ð·Ð´Ñ–Ð»ÐµÐ½Ð½Ñ Ñ‚Ð° об'Ñ”Ð´Ð½Ð°Ð½Ð½Ñ Ð¿Ð¾Ð»Ñ–Ð²" #: sagenb/notebook/tutorial.py:375 msgid "" "Press ctrl-; in a cell to split it into two cells, and " "ctrl-backspace to join them. Press ctrl-enter to split a cell and evaluate both pieces." msgstr "" "ÐатиÑніть Ctrl-; в полі, щоб розбити його на два, Ñ– " "Ctrl+Backspace, щоб об'єднати Ñ—Ñ…. ÐатиÑніть Ctrl" "+Enter, щоб виконати Ñ€Ð¾Ð·Ð±Ð¸Ñ‚Ñ‚Ñ Ð¿Ð¾Ð»Ñ Ð½Ð° два та виконати обидві " "чаÑтини." #: sagenb/notebook/tutorial.py:376 msgid "Insert New Text Cell" msgstr "Ð’Ñтавити нове текÑтове поле" #: sagenb/notebook/tutorial.py:377 msgid "" "Move the mouse between cells until a blue bar appears. Shift-click on the blue bar to create a new text cell. Double click on existing " "text to edit it. Use $...$ and $$...$$ to include typeset math in the text " "block." msgstr "" "Ðаведіть вказівник миші між полÑми так, щоб з'ÑвилаÑÑŒ ÑÐ¸Ð½Ñ Ð»Ñ–Ð½Ñ–Ñ. " "Shift+Клік на Ñиній лінії Ñтворить нове поле. Подвійний " "клік по Ñ–Ñнуючому текÑтовому полю дозволÑÑ” його відредагувати. Ð”Ð»Ñ Ð·Ð°Ð¿Ð¸Ñу " "математичних формул (в LaTeX) введіть $...$ Ñ– $$...$$ у текÑтовому полі." #: sagenb/notebook/tutorial.py:378 msgid "Hide/Show Output" msgstr "Приховати/Показати результати" #: sagenb/notebook/tutorial.py:379 msgid "" "Click on the left side of output to toggle between hidden, shown with word " "wrap, and shown without word wrap." msgstr "" "ÐатиÑніть зліва від результатів, щоб переключити режим відображеннÑ: " "прихований, з перенеÑеннÑм Ñлів, без перенеÑÐµÐ½Ð½Ñ Ñлів." #: sagenb/notebook/tutorial.py:380 msgid "Indenting Blocks" msgstr "ВідÑтупи в блоках" #: sagenb/notebook/tutorial.py:381 msgid "" "Highlight text and press > to indent it all and < to unindent it all (works " "in Safari and Firefox). In Firefox you can also press tab and shift-tab." msgstr "" "Виділіть текÑÑ‚ Ñ– натиÑніть > , щоб зробити відÑтуп та < Ð´Ð»Ñ Ð²Ð¸Ð´Ð°Ð»ÐµÐ½Ð½Ñ " "відÑтупу (це працює у браузерах Safari та Firefox). У Firefox ви також " "можете викориÑтовувати Tab Ñ– Shift+Tab." #: sagenb/notebook/tutorial.py:382 msgid "Comment/Uncomment Blocks" msgstr "КоментуваннÑ/Ð Ð¾Ð·ÐºÐ¾Ð¼ÐµÐ½Ñ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ð±Ð»Ð¾ÐºÑ–Ð²" #: sagenb/notebook/tutorial.py:383 msgid "" "Highlight text and press ctrl-. to comment it and " "ctrl-, to uncomment it. Alternatively, use ctrl-3 and ctrl-4." msgstr "" "Виділіть текÑÑ‚ Ñ– натиÑніть Ctrl-., щоб закоментувати його, " "Ñ–Ctrl-, щоб розкоментувати. Також можна викориÑтовувати " "Ctrl-3 Ñ– Ctrl-4." #: sagenb/notebook/tutorial.py:384 msgid "Paren matching" msgstr "ПарніÑть дужок" #: sagenb/notebook/tutorial.py:384 msgid "" "To fix unmatched or mis-matched parentheses, braces or brackets, press " "ctrl-0. Parentheses before the cursor will be matched, " "minding strings and (Python) comments." msgstr "" "Щоб виправити непарні круглі, квадратні, фігурні дужки, натиÑніть " "Ctrl-0. Дужки перед курÑором Ñтануть парними, з правильним " "опрацюваннÑм Ñ€Ñдків Ñ– коментарів (в Python)." #: sagenb/notebook/tutorial.py:388 msgid "Interrupt and Restart Sessions" msgstr "ÐŸÐµÑ€ÐµÑ€Ð¸Ð²Ð°Ð½Ð½Ñ Ñ– перезапуÑк ÑеÑій" #: sagenb/notebook/tutorial.py:389 msgid "Interrupt Running Calculations" msgstr "ÐŸÐµÑ€ÐµÑ€Ð¸Ð²Ð°Ð½Ð½Ñ Ð¿Ð¾Ñ‚Ð¾Ñ‡Ð½Ð¸Ñ… обчиÑлень" #: sagenb/notebook/tutorial.py:390 msgid "" "Click Interrupt or press escape in any input cell. This will " "(attempt) to interrupt SAGE by sending many interrupt signals." msgstr "" "ÐатиÑніть Перервати або натиÑніть Escape у будь-Ñкому полі вводу. Це " "змуÑить Sage (Ñпробувати) перервати поточну задачу, відправивши велику " "кількіÑть Ñигналів перериваннÑ." #: sagenb/notebook/tutorial.py:391 msgid "Restart" msgstr "ПерезапуÑтити" #: sagenb/notebook/tutorial.py:392 msgid "" "Type \"restart\" to restart the SAGE interpreter for a given worksheet. " "(You have to interrupt first.)" msgstr "" "ÐатиÑніть \"restart\" Ð´Ð»Ñ Ð¿ÐµÑ€ÐµÐ·Ð°Ð¿ÑƒÑку інтерпретатора Sage у поточному " "робочому аркуші. (Спочатку треба здійÑнити Ð¿ÐµÑ€ÐµÑ€Ð¸Ð²Ð°Ð½Ð½Ñ Ð¿Ð¾Ñ‚Ð¾Ñ‡Ð½Ð¸Ñ… обчиÑлень.)" #: sagenb/notebook/tutorial.py:394 msgid "Special Cell Blocks" msgstr "Спеціальні блоки в полÑÑ… вводу" #: sagenb/notebook/tutorial.py:395 msgid "Evaluate Cell using GAP, Singular, etc." msgstr "Виконати поле, викориÑтовуючи GAP, Singular та ін." #: sagenb/notebook/tutorial.py:396 #, python-format msgid "" "Put \"%%gap\", \"%%singular\", etc. as the first input line of a cell; the " "rest of the cell is evaluated in that system." msgstr "" "Введіть \"%%gap\", \"%%singular\" та ін. першим Ñ€Ñдком Ð¿Ð¾Ð»Ñ Ð²Ð²Ð¾Ð´Ñƒ; решта " "Ð¿Ð¾Ð»Ñ Ð±ÑƒÐ´Ðµ виконана в обраній ÑиÑтемі." #: sagenb/notebook/tutorial.py:397 msgid "Shell Scripts" msgstr "Сценарії оболонки (shell)" #: sagenb/notebook/tutorial.py:398 #, python-format msgid "" "Begin a block with %%sh to have the rest of the block evaluated as a shell " "script. The current working directory is maintained." msgstr "" "Введіть першим Ñ€Ñдком %%sh у полі вводу, щоб решта Ð¿Ð¾Ð»Ñ Ð±ÑƒÐ»Ð° інтерпретована " "Ñк Ñценарій оболонки. Поточна Ð´Ð¸Ñ€ÐµÐºÑ‚Ð¾Ñ€Ñ–Ñ Ð¿Ñ–Ð´Ñ‚Ñ€Ð¸Ð¼ÑƒÑ”Ñ‚ÑŒÑÑ." #: sagenb/notebook/tutorial.py:399 msgid "Interactive Dynamic Widgets" msgstr "Інтерактивні динамічні віджети" #: sagenb/notebook/tutorial.py:400 msgid "" "Put @interact on the line before a function definition. Type interact? for " "more details." msgstr "" "Введіть @interact у Ñ€Ñдку перед визначеннÑм функції. Введіть interact? Ð´Ð»Ñ " "деталізації." #: sagenb/notebook/tutorial.py:401 msgid "Autoevaluate Cells on Load" msgstr "Ðвтоматично виконувати Ð¿Ð¾Ð»Ñ Ð¿Ñ€Ð¸ завантаженні робочого аркуша." #: sagenb/notebook/tutorial.py:402 msgid "" "Any cells with \"#auto\" in the input is automatically evaluated when the " "worksheet is first opened." msgstr "" "УÑÑ– Ð¿Ð¾Ð»Ñ Ñ–Ð· введеним Ñловом \"#auto\" будуть автоматично виконані, коли " "відкриєтьÑÑ Ñ€Ð¾Ð±Ð¾Ñ‡Ð¸Ð¹ аркуш." #: sagenb/notebook/tutorial.py:403 msgid "Time" msgstr "Ð§Ð°Ñ Ð²Ð¸ÐºÐ¾Ð½Ð°Ð½Ð½Ñ" #: sagenb/notebook/tutorial.py:404 #, python-format msgid "Type \"%%time\" at the beginning of the cell." msgstr "Введіть \"%%time\" у початок полÑ." #: sagenb/notebook/tutorial.py:406 msgid "Useful Tips" msgstr "КориÑні поради" #: sagenb/notebook/tutorial.py:407 msgid "Input Rules" msgstr "Правила введеннÑ" #: sagenb/notebook/tutorial.py:408 msgid "" "Code is evaluated by exec'ing (after preparsing). Only the output of the " "last line of the cell is implicitly printed. If any line starts with \"sage:" "\" or \">>>\" the entire block is assumed to contain text and examples, so " "only lines that begin with a prompt are executed. Thus you can paste in " "complete examples from the docs without any editing, and you can write input " "cells that contains non-evaluated plain text mixed with examples by starting " "the block with \">>>\" or including an example." msgstr "" "Код виконуєтьÑÑ Ð·Ð° допомогою exec (піÑÐ»Ñ Ð¿Ñ€ÐµÐ¿Ð°Ñ€Ñингу). Тільки вивід " "оÑтаннього Ñ€Ñдка в полі буде відображатиÑÑ Ð¿Ð¾ замовчуваннÑм. Якщо Ñкий-" "небудь Ñ€Ñдок починаєтьÑÑ Ð· \"sage:\" чи \">>>\" то вважаєтьÑÑ, що вÑе поле " "міÑтить текÑÑ‚ Ñ– приклади, тому будуть виконуватиÑÑ Ñ‚Ñ–Ð»ÑŒÐºÐ¸ Ñ€Ñдки, що " "починаютьÑÑ Ð· підказки. Таким чином, ви можете вÑтавлÑти приклади із " "документації повніÑтю, без будь-Ñких правок, а також пиÑати у полÑÑ… вводу " "звичайний текÑÑ‚, що не буде виконуватиÑÑ, разом з прикладами, Ñкщо почнете " "поле з \">>>\" або вÑтавите приклад із документації." #: sagenb/notebook/tutorial.py:409 msgid "History" msgstr "ІÑторіÑ" #: sagenb/notebook/tutorial.py:410 msgid "" "Click
    log commands you have entered in any " "worksheet of this notebook." msgstr "" "ÐатиÑніть log, щоб переглÑнути вÑÑ– команди, Ñкі ви " "ввели у будь-Ñкому робочому аркуші." #: sagenb/notebook/tutorial.py:411 msgid "Typesetting All Output" msgstr "ÐÐ²Ñ‚Ð¾Ñ„Ð¾Ñ€Ð¼Ð°Ñ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ð²ÑÑ–Ñ… результатів" #: sagenb/notebook/tutorial.py:412 msgid "" "Type pretty_print_default() in an input cell and press shift-enter. All " "future output will be typeset automatically." msgstr "" "Введіть pretty_print_default() у полі виводу Ñ– натиÑніть Shift+Enter. УвеÑÑŒ " "наÑтупний вивід буде автоматично відформатовано." #: sagenb/notebook/tutorial.py:414 msgid "Files and Scripts" msgstr "Файли та Ñценарії" #: sagenb/notebook/tutorial.py:415 msgid "Loading SAGE/Python Scripts" msgstr "ÐŸÑ–Ð´ÐºÐ»ÑŽÑ‡ÐµÐ½Ð½Ñ Ñценаріїв Sage/Python" #: sagenb/notebook/tutorial.py:416 msgid "" "Use \"load filename.sage\" and \"load filename.py\". Load is relative to " "the path you started the notebook in. The .sage files are preparsed and .py " "files are not. You may omit the .sage or .py extension. Files may load " "other files." msgstr "" "ВикориÑтовуйте \"load filename.sage\" Ñ– \"load filename.py\". ШлÑÑ… load " "відноÑитьÑÑ Ð´Ð¾ директорії, із Ñкої було запущено Sage Notebook. Файли .sage " "будуть опрацьовані препарÑером, а файли .py - ні. Ви можете опуÑтити " "Ñ€Ð¾Ð·ÑˆÐ¸Ñ€ÐµÐ½Ð½Ñ .sage чи .py. Файли можуть завантажувати інші файли." #: sagenb/notebook/tutorial.py:417 msgid "Attaching Scripts" msgstr "ÐŸÑ€Ð¸ÐºÑ€Ñ–Ð¿Ð»ÐµÐ½Ð½Ñ Ñценаріїв до робочого аркуша" #: sagenb/notebook/tutorial.py:418 msgid "" "Use \"attach filename.sage\" or \"attach filename.py\". Attached files are " "automatically reloaded when the file changes. The file $HOME/.sage/init." "sage is attached on startup if it exists." msgstr "" "ВикориÑтовуйте \"attach filename.sage\" або \"attach filename.py\". " "Прикріплені файли автоматично перезавантажатьÑÑ Ð¿Ñ€Ð¸ Ñ—Ñ… зміні. Якщо Ñ–Ñнує " "файл $HOME/.sage/init.sage, то він прикріплюєтьÑÑ Ð¿Ñ€Ð¸ запуÑку." #: sagenb/notebook/tutorial.py:419 msgid "Working Directory" msgstr "Робоча директоріÑ" #: sagenb/notebook/tutorial.py:420 msgid "" "Each block of code is run from its own directory. If any images are created " "as a side effect, they will automatically be displayed." msgstr "" "Кожне поле запуÑкаєтьÑÑ Ñƒ влаÑній директорії. Якщо під Ñ‡Ð°Ñ Ñ€Ð¾Ð±Ð¾Ñ‚Ð¸ " "ÑтворюютьÑÑ Ñ„Ð°Ð¹Ð»Ð¸ зображень, то вони будуть відображатиÑÑ Ð°Ð²Ñ‚Ð¾Ð¼Ð°Ñ‚Ð¸Ñ‡Ð½Ð¾." #: sagenb/notebook/tutorial.py:421 msgid "DIR Variable" msgstr "Змінна DIR" #: sagenb/notebook/tutorial.py:422 msgid "" "The variable DIR contains the directory from which you started the SAGE " "notebook. For example, to open a file in that directory, do \"open(DIR" "+'filename')\"." msgstr "" "Змінна DIR міÑтить адреÑу директорії, із Ñкої було запущено Sage Notebook. " "Ðаприклад, щоб відкрити файл у цій директорії, введіть \"open(DIR+'ім'Ñ " "файлу')\"." #: sagenb/notebook/tutorial.py:423 msgid "DATA Variable" msgstr "Змінна DATA" #: sagenb/notebook/tutorial.py:424 msgid "" "Use the Data menu to upload images and other files, and create new files " "that can be shared between worksheets. The DATA variable contains the path " "to the data files. For example, to open a file in that directory, do " "\"open(DATA+'filename')\". If foo.sage is a Sage file that you uploaded, " "type \"load foo.sage\"; if foo.py is a Python file, you can import it by " "typing \"import foo\"." msgstr "" "ВикориÑтовуйте меню Дані, щоб завантажувати картинки та інші файли, а також " "Ñтворювати нові файли, Ñкі можуть бути викориÑтані у різних робочих аркушах " "одночаÑно. Змінна DATA міÑтить шлÑÑ… до цих файлів даних. Ðаприклад, щоб " "відкрити файл у цій директорії, введіть \"open(DATA+'ім'Ñ Ñ„Ð°Ð¹Ð»Ñƒ')\". Якщо " "ви завантажили Sage-файл foo.sage, введіть \"load foo.sage\", щоб виконати " "його; Ñкщо foo.py Ñ” Python-файл, ви можете імпортувати його за допомогою " "\"import foo\"." #: sagenb/notebook/tutorial.py:425 msgid "Loading and Saving Objects" msgstr "Ð—Ð°Ð²Ð°Ð½Ñ‚Ð°Ð¶ÐµÐ½Ð½Ñ Ñ‚Ð° Ð·Ð±ÐµÑ€ÐµÐ¶ÐµÐ½Ð½Ñ Ð¾Ð±'єктів" #: sagenb/notebook/tutorial.py:426 msgid "" "Use \"save obj1 obj2 ...\" and \"load obj1 obj2 ...\". This allows for easy " "moving of objects from one worksheet to another, and saving of objects for " "later use." msgstr "" "ВикориÑтовуйте \"save obj1 obj2 ...\" Ñ– \"load obj1 obj2 ...\". Таким " "чином, можна легко переміщувати об'єкти із одного робочого аркуша в інший Ñ– " "зберігати Ñ—Ñ… Ð´Ð»Ñ Ð¿Ð¾Ð´Ð°Ð»ÑŒÑˆÐ¾Ð³Ð¾ викориÑтаннÑ." #: sagenb/notebook/tutorial.py:427 msgid "Loading and Saving Sessions" msgstr "Ð—Ð°Ð²Ð°Ð½Ñ‚Ð°Ð¶ÐµÐ½Ð½Ñ Ñ‚Ð° Ð·Ð±ÐµÑ€ÐµÐ¶ÐµÐ½Ð½Ñ ÑеÑій" #: sagenb/notebook/tutorial.py:428 msgid "" "Use \"save_session('name')\" to save all variables to an object. Use " "\"load_session('name')\" to merge in all variables from a saved " "session." msgstr "" "ВикориÑтовуйте \"save_session('name')\", щоб зберегти вÑÑ– змінні в об'єкті. " "Введіть \"load_session('name')\" Ð´Ð»Ñ Ñ‚Ð¾Ð³Ð¾, щоб об'єднати поточне " "Ñередовище із змінними зі збереженої ÑеÑÑ–Ñ—." #: sagenb/notebook/tutorial.py:429 msgid "Customizing the Notebook CSS" msgstr "КаÑÑ‚Ð¾Ð¼Ñ–Ð·Ð°Ñ†Ñ–Ñ CSS Sage Notebook" #: sagenb/notebook/tutorial.py:430 msgid "" "If you create a file $HOME/.sage/notebook.css then it will get " "applied when rendering the notebook. See " msgstr "" "Якщо ви Ñтворите файл $HOME/.sage/notebook.css, то він буде " "викориÑтаний при відображенні Sage Notebook. Див. " #: sagenb/notebook/wiki2html.py:647 #, python-format msgid "Expected \"%(wanted)s\" after \"%(key)s\", got \"%(token)s\"" msgstr "" "ОчікувалоÑÑŒ \"%(wanted)s\" піÑÐ»Ñ \"%(key)s\", але отримано \"%(token)s\"" #: sagenb/notebook/wiki2html.py:653 #, python-format msgid "Expected an integer \"%(key)s\" before \"%(token)s\"" msgstr "ОчікувалоÑÑŒ ціле чиÑло \"%(key)s\" перед \"%(token)s\"" #: sagenb/notebook/wiki2html.py:663 ../sagenb/notebook/wiki2html.py:673 #, python-format msgid "Expected an integer \"%(arg)s\" after \"%(key)s\"" msgstr "ОчікувалоÑÑŒ ціле чиÑло \"%(arg)s\" піÑÐ»Ñ \"%(key)s\"" #: sagenb/notebook/wiki2html.py:699 #, python-format msgid "Expected a color value \"%(arg)s\" after \"%(key)s\"" msgstr "ОчікувалоÑÑŒ Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ ÐºÐ¾Ð»ÑŒÐ¾Ñ€Ñƒ \"%(arg)s\" піÑÐ»Ñ \"%(key)s\"" #: sagenb/notebook/worksheet.py:2015 #, python-format msgid "%(seconds)s ago" msgstr "%(seconds)s тому" #~ msgid "January" #~ msgstr "Січень" #~ msgid "February" #~ msgstr "Лютий" #~ msgid "March" #~ msgstr "Березень" #~ msgid "April" #~ msgstr "Квітень" #~ msgid "May" #~ msgstr "Травень" #~ msgid "June" #~ msgstr "Червень" #~ msgid "July" #~ msgstr "Липень" #~ msgid "August" #~ msgstr "Серпень" #~ msgid "September" #~ msgstr "ВереÑень" #~ msgid "October" #~ msgstr "Жовтень" #~ msgid "November" #~ msgstr "ЛиÑтопад" #~ msgid "December" #~ msgstr "Грудень" sagenb-1.0.1/sass/000077500000000000000000000000001311436262400137235ustar00rootroot00000000000000sagenb-1.0.1/sass/config.rb000066400000000000000000000005341311436262400155170ustar00rootroot00000000000000# Require any additional compass plugins here. project_type = :stand_alone # Set this to the root of your project when deployed: http_path = "/" css_dir = "../sagenb/data/sage/css/" sass_dir = "src" images_dir = "images" output_style = :compact # To enable relative paths to assets via compass helper functions. Uncomment: # relative_assets = true sagenb-1.0.1/sass/readme.txt000066400000000000000000000017331311436262400157250ustar00rootroot00000000000000Notes on editing the notebook's stylesheets ============================================ The Sage Notebook uses `Sass `_ and `Compass `_ for its stylesheets. Sass is a styling language that compiles down to CSS, and has support for mixins, nesting, variables, and basic operations. Compass is a CSS meta-framework that uses Sass and incorporates Sass-ified versions of most common CSS frameworks. Installing Sass and Compass ---------------------------- Sass and Compass currently require Ruby 1.8.7 and RubyGems. Installation is simply installing HAML, which includes Sass:: $ gem install haml and then Compass:: $ gem install compass Editing the SASS stylesheets ----------------------------- To edit the SASS stylesheets, simply cd to sass/ and run compass:: $ cd sass $ compass watch This will automatically compile any changes made to the Sass files. The Sass files themselves are included at ``sass/src``. sagenb-1.0.1/sass/src/000077500000000000000000000000001311436262400145125ustar00rootroot00000000000000sagenb-1.0.1/sass/src/_accounts.scss000066400000000000000000000012571311436262400173720ustar00rootroot00000000000000.accounts-page { #wrapper { margin: 0 auto; max-width: 600px; } h1, h2, h3, h4, h5 { font-weight: normal; } h1 { border-bottom: 1px solid #696969; font-size: 2em; padding: 10px 0; } h2 { font-weight: bold; } h1, h2, p, li { margin-bottom: 10px; } .entry { margin-bottom: 10px; border: 1px solid #999999; padding: 3px; width: 200; } li { border-bottom: 1px solid #cccccc; } .error { color: red; } .error_found { color: red; font-size: 1.5em; } button { margin-right: 1em; } form { label { display: block; } div { margin-bottom: 1em; } a { text-decoration: none; } } } sagenb-1.0.1/sass/src/_guest_worksheet.scss000066400000000000000000000001661311436262400207730ustar00rootroot00000000000000#guest-worksheet-page { h1, h2 { text-align: center; } ul.controls { @include horizontal-list(0.5em); } } sagenb-1.0.1/sass/src/_login.scss000066400000000000000000000007341311436262400166620ustar00rootroot00000000000000#login-page { h2 { font-size: 1.5em; margin-bottom: 0.375em; } h1,h2,h3,h4,h5,h6 { line-height: 1em; } p { margin-bottom: 1em; } strong { font-weight: bold; } #desc { float: left; margin-right: 400px; } div { padding: 0.5em 1em; } #sign-in-box { background-color: #efefff; float: left; margin-left: -400px; width: 350px; form { label { display: block; } } a { font-size: 0.875em; } } } sagenb-1.0.1/sass/src/_prettify.scss000066400000000000000000000005511311436262400174150ustar00rootroot00000000000000#source-code-page { .str { color: #008800; } .kwd { color: #000088; } .com { color: #880000; } .typ { color: #660066; } .lit { color: #006666; } .pun { color: #666600; } .pln { color: black; } .tag { color: #000088; } .atn { color: #660066; } .atv { color: #008800; } .dec { color: #660066; } } sagenb-1.0.1/sass/src/_print_worksheet.scss000066400000000000000000000000611311436262400207720ustar00rootroot00000000000000#print-page { h1 { text-align: center; } } sagenb-1.0.1/sass/src/_pygment.scss000066400000000000000000000035461311436262400172410ustar00rootroot00000000000000.hll { background-color: #ffffcc; } .c { color: #408090; font-style: italic; } .err { border: 1px solid red; } .k { color: #007020; font-weight: bold; } .o { color: #666666; } .cm { color: #408090; font-style: italic; } .cp { color: #007020; } .c1 { color: #408090; font-style: italic; } .cs { color: #408090; background-color: #fff0f0; } .gd { color: #a00000; } .ge { font-style: italic; } .gr { color: red; } .gh { color: navy; font-weight: bold; } .gi { color: #00a000; } .go { color: #0000aa; } .gp { color: #c65d09; font-weight: bold; } .gs { font-weight: bold; } .gu { color: purple; font-weight: bold; } .gt { color: #0040d0; } .kc, .kd, .kn { color: #007020; font-weight: bold; } .kp { color: #007020; } .kr { color: #007020; font-weight: bold; } .kt { color: #902000; } .m { color: #208050; } .s, .na { color: #4070a0; } .nb { color: #007020; } .nc { color: #0e84b5; font-weight: bold; } .no { color: #60add5; } .nd { color: #555555; font-weight: bold; } .ni { color: #d55537; font-weight: bold; } .ne { color: #007020; } .nf { color: #06287e; } .nl { color: #002070; font-weight: bold; } .nn { color: #0e84b5; font-weight: bold; } .nt { color: #062873; font-weight: bold; } .nv { color: #bb60d5; } .ow { color: #007020; font-weight: bold; } .w { color: #bbbbbb; } .mf, .mh, .mi, .mo { color: #208050; } .sb, .sc { color: #4070a0; } .sd { color: #4070a0; font-style: italic; } .s2 { color: #4070a0; } .se { color: #4070a0; font-weight: bold; } .sh { color: #4070a0; } .si { color: #70a0d0; font-style: italic; } .sx { color: #c65d09; } .sr { color: #235388; } .s1 { color: #4070a0; } .ss { color: #517918; } .bp { color: #007020; } .vc, .vg, .vi { color: #bb60d5; } .il { color: #208050; } sagenb-1.0.1/sass/src/_settings.scss000066400000000000000000000017711311436262400174140ustar00rootroot00000000000000.settings-page { line-height: 1.4; h1 { font-size: 2em; padding: 0 5px; } label { display: block; } .buttons { padding: 5px; button { margin: 0px 5px; } a { text-decoration: none; } } .buttons-top { border-bottom: 1px solid #cccccc; margin-top: 1em; } h2 { font-size: 1.5em; margin: 0 0 0.75em; } .section { border-bottom: 1px solid #cccccc; padding: 5px; margin: 0.5em 0; div { margin-bottom: 0.5em; } } .error, .error_found { color: red; } .error_found { font-size: 1.2em; } .updated { color: green; } input.c1 { width: 200px; } } #settings-nav { @include horizontal-list(0.5em); li { border-right: 1px solid #cccccc; &:last-child, &.last { border-right: none; } } } #user-management-page { table { border-collapse: collapse; } th, td { border: 1px solid #696969; padding: 0.25em; } th { background: #cccccc; } a:link, a:visited { color: $link_color; } } sagenb-1.0.1/sass/src/_source.scss000066400000000000000000000003771311436262400170550ustar00rootroot00000000000000@import "partials/mixins"; #source-code-page { h1, h2 { text-align: center; } .filename { @include monospace-stack; } code { display: block; border-top: 1px solid #cccccc; border-bottom: 1px solid #cccccc; padding: 1em; } } sagenb-1.0.1/sass/src/_topbar.scss000066400000000000000000000035301311436262400170360ustar00rootroot00000000000000body div#banner { font-size: 1.2em; float: left; margin: 0; max-width: 35%; a.banner { text-decoration: none; border: none; margin-top: 2px; float: left; position: relative; &:visited { color: #1950c8; } img { border: none; } span { margin-left: 0.2em; margin-top: -0.25em; } } #ping { float: left; } div.version { float: left; clear: left; font-size: xx-small; text-indent: 13px; color: black; } } #main-controls { float: right; width: 65%; ul { list-style: none; margin: 0; padding: 0; text-align: right; li { border-right: 1px solid black; color: #112abb; display: inline; font-size: 14px; margin: 0; padding: 0 0.5em; &:last-child { border-right: 0; } } li.username { @include sans-serif-stack; border: 0; color: black; font-weight: bold; padding: 0; } a { text-decoration: underline; white-space: nowrap; &:hover { cursor: pointer; } } #toggle-link { display: none; } } } .active-worksheet { margin-bottom: 80%; #main-controls { ul { #toggle-link { display: inline; } } } } #top-bar { position: relative; padding: 10px 5px; border-bottom: 1px solid #c9d7f1; min-height: 40px; margin-bottom: 0.5em; @include clearfix; } #search-area { float: right; clear: right; } hr.usercontrol { clear: both; float: left; } div { &#user-main-controls { @include clearfix; clear: both; border-bottom: 1px solid #c9d7f1; padding: 10px; } &#worksheet-list-controls { padding: 10px; clear: both; @include clearfix; div { &.action-buttons { float: left; } &.folders { float: left; clear: right; margin-left: 100px; } } } } sagenb-1.0.1/sass/src/_worksheet_aux.scss000066400000000000000000000004641311436262400204420ustar00rootroot00000000000000#before-publish-page { form { a { text-decoration: none; } button { margin-left: 1em; margin-bottom: 0.5em; } input { margin-left: 1em; } } } #after-publish-page { input { margin-top: 1em; } } #edit-page { .sharebar { span { margin-right: 2em; } } } sagenb-1.0.1/sass/src/_worksheet_listing.scss000066400000000000000000000105301311436262400213110ustar00rootroot00000000000000/*********** User Home (Worksheet listing) ************************* */ #worksheet-listing-page { #welcome-message { text-align: center; padding: 1em; } } .ratingmsg { color: #112abb; padding: 0.3em; font-size: 14px; } .pubmsg { @include sans-serif-stack; color: #112abb; padding: 0.3em; font-size: 12px; } #worksheet-list { clear: both; width: 100%; thead { background-color: #e8eef7; } td.checkbox { padding: 4px; } } .controls a, .usercontrol { color: #112abb; font-size: 14px; text-decoration: underline; &:hover { cursor: pointer; } } .controls { span { color: #112abb; padding: 0.3em; font-size: 14px; } } .user-controls a, .boldusercontrol { color: #112abb; font-weight: bold; font-size: 14px; } .user-controls a, .controls a, .controls span { padding: 0.3em; } a { &.control, &.control-select { background-color: #7799bb; @include sans-serif-stack; color: white; padding-top: 0.25em; padding-bottom: 0.25em; padding-left: 0.5em; padding-right: 0.5em; font-size: 15px; font-weight: bold; text-decoration: none; } &.control:hover { cursor: pointer; } &.control-select { background-color: #4477aa; &:hover { cursor: pointer; } } } .sharebar { background-color: #4477aa; @include sans-serif-stack; color: white; padding-top: 0.5em; padding-bottom: 0.5em; padding-left: 2em; font-size: 1.25em; font-weight: bold; } textarea.edit { @include monospace-stack; font-size: 10pt; border: 1px solid #8cacbb; color: black; background-color: white; padding: 3px; overflow: auto; margin-top: 0.5em; } a.listcontrol { padding: 1ex; color: #112abb; font-weight: bold; font-size: 14px; text-decoration: none; } hr { &.usercontrol { border: 0; width: 99%; color: #c9d7f1; background-color: #c9d7f1; height: 1px; } &.greybar hr.negative_greybar { border: 0; width: 99%; color: #aaaaaa; background-color: #aaaaaa; height: 1px; } &.negative_greybar { top: -1em; position: relative; } } span { &.checkcol { position: relative; left: 0%; width: 10%; } &.leftcol { position: relative; left: 10%; width: 20%; } &.middlecol { position: relative; left: 30%; width: 20%; } &.rightcol { position: relative; left: 50%; width: 20%; } } tr.greybox { background-color: #e8eef7; } td.entry { padding: 4px; } div.thinspace { border: 0; height: 2px; } tr.thingreybox { background-color: #aaaaaa; } div.ultrathinspace { border: 0; height: 0px; } .lastedit { @include sans-serif-stack; font-size: 10px; color: #717171; } .revs { @include sans-serif-stack; font-size: 12px; font-weight: bold; color: #333333; } .users { @include sans-serif-stack; font-size: 13px; color: #222222; } a.share { @include sans-serif-stack; font-size: 10px; color: #7777cc; } select { &.worksheet { width: 6em; border: #aaaaaa; border-style: solid; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; } &.worksheet_list, &.worksheet_edit { width: 5em; border: #aaaaaa; border-style: solid; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; } } td { &.worksheet_link { @include sans-serif-stack; font-size: 12px; font-weight: bold; color: black; } &.archived_worksheet_link, &.owner_collab, &.last_edited { @include sans-serif-stack; font-size: 12px; color: black; } } span.addtext { @include sans-serif-stack; font-size: 13px; color: #222222; } textarea.plaintextedit { @include monospace-stack; font-size: 10pt; border: 1px solid #8cacbb; color: black; background-color: white; overflow: auto; width: 99%; height: 60%; } pre.plaintext { overflow: auto; @include monospace-stack; font-size: 10pt; border: 1px solid #8cacbb; color: black; background-color: white; margin-top: 0.5em; } div.docidx { text-align: center; @include sans-serif-stack; font-size: 16px; color: #222222; font-weight: bold; } span { &.ping { display: none; } &.pingdown { @include sans-serif-stack; font-size: 15px; font-weight: bold; color: white; background-color: #990000; margin-left: 1em; } } sagenb-1.0.1/sass/src/jquery-plugins/000077500000000000000000000000001311436262400175105ustar00rootroot00000000000000sagenb-1.0.1/sass/src/jquery-plugins/_ui.achtung.scss000066400000000000000000000347431311436262400226240ustar00rootroot00000000000000/** * achtung 0.3.0 * * Growl-like notifications for jQuery * * Copyright (c) 2009 Josh Varner * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. * * Portions of this file are from the jQuery UI CSS framework. * * @license http://www.opensource.org/licenses/mit-license.php * @author Josh Varner */ /* IE 6 doesn't support position: fixed */ * html { #achtung-overlay { position: absolute; } .achtung { width: 280px; } } /* IE6 includes padding in width */ #achtung-overlay { overflow: hidden; position: fixed; top: 15px; right: 15px; width: 280px; z-index: 50; } .achtung { display: none; margin-bottom: 8px; padding: 15px 15px; background-color: #000; color: white; width: 250px; font-weight: bold; position: relative; overflow: hidden; -moz-box-shadow: #aaa 1px 1px 2px; -webkit-box-shadow: #aaa 1px 1px 2px; box-shadow: #aaa 1px 1px 2px; -moz-border-radius: 4px; -webkit-border-radius: 4px; border-radius: 4px; /* Note that if using show/hide animations, IE will lose this setting */ opacity: .85; filter: Alpha(Opacity = 85); } /** * This section from jQuery UI CSS framework * Copyright (c) 2009 AUTHORS.txt (http://jqueryui.com/about) * Can (and should) be removed if you are already loading the jQuery UI CSS * to reduce payload size. */ .ui-icon { display: block; text-indent: -99999px; overflow: hidden; background-repeat: no-repeat; width: 16px; height: 16px; background-image: url(/javascript/jqueryui/css/sage/images/ui-icons_222222_256x240.png); } .ui-icon-carat-1-n { background-position: 0 0; } .ui-icon-carat-1-ne { background-position: -16px 0; } .ui-icon-carat-1-e { background-position: -32px 0; } .ui-icon-carat-1-se { background-position: -48px 0; } .ui-icon-carat-1-s { background-position: -64px 0; } .ui-icon-carat-1-sw { background-position: -80px 0; } .ui-icon-carat-1-w { background-position: -96px 0; } .ui-icon-carat-1-nw { background-position: -112px 0; } .ui-icon-carat-2-n-s { background-position: -128px 0; } .ui-icon-carat-2-e-w { background-position: -144px 0; } .ui-icon-triangle-1-n { background-position: 0 -16px; } .ui-icon-triangle-1-ne { background-position: -16px -16px; } .ui-icon-triangle-1-e { background-position: -32px -16px; } .ui-icon-triangle-1-se { background-position: -48px -16px; } .ui-icon-triangle-1-s { background-position: -64px -16px; } .ui-icon-triangle-1-sw { background-position: -80px -16px; } .ui-icon-triangle-1-w { background-position: -96px -16px; } .ui-icon-triangle-1-nw { background-position: -112px -16px; } .ui-icon-triangle-2-n-s { background-position: -128px -16px; } .ui-icon-triangle-2-e-w { background-position: -144px -16px; } .ui-icon-arrow-1-n { background-position: 0 -32px; } .ui-icon-arrow-1-ne { background-position: -16px -32px; } .ui-icon-arrow-1-e { background-position: -32px -32px; } .ui-icon-arrow-1-se { background-position: -48px -32px; } .ui-icon-arrow-1-s { background-position: -64px -32px; } .ui-icon-arrow-1-sw { background-position: -80px -32px; } .ui-icon-arrow-1-w { background-position: -96px -32px; } .ui-icon-arrow-1-nw { background-position: -112px -32px; } .ui-icon-arrow-2-n-s { background-position: -128px -32px; } .ui-icon-arrow-2-ne-sw { background-position: -144px -32px; } .ui-icon-arrow-2-e-w { background-position: -160px -32px; } .ui-icon-arrow-2-se-nw { background-position: -176px -32px; } .ui-icon-arrowstop-1-n { background-position: -192px -32px; } .ui-icon-arrowstop-1-e { background-position: -208px -32px; } .ui-icon-arrowstop-1-s { background-position: -224px -32px; } .ui-icon-arrowstop-1-w { background-position: -240px -32px; } .ui-icon-arrowthick-1-n { background-position: 0 -48px; } .ui-icon-arrowthick-1-ne { background-position: -16px -48px; } .ui-icon-arrowthick-1-e { background-position: -32px -48px; } .ui-icon-arrowthick-1-se { background-position: -48px -48px; } .ui-icon-arrowthick-1-s { background-position: -64px -48px; } .ui-icon-arrowthick-1-sw { background-position: -80px -48px; } .ui-icon-arrowthick-1-w { background-position: -96px -48px; } .ui-icon-arrowthick-1-nw { background-position: -112px -48px; } .ui-icon-arrowthick-2-n-s { background-position: -128px -48px; } .ui-icon-arrowthick-2-ne-sw { background-position: -144px -48px; } .ui-icon-arrowthick-2-e-w { background-position: -160px -48px; } .ui-icon-arrowthick-2-se-nw { background-position: -176px -48px; } .ui-icon-arrowthickstop-1-n { background-position: -192px -48px; } .ui-icon-arrowthickstop-1-e { background-position: -208px -48px; } .ui-icon-arrowthickstop-1-s { background-position: -224px -48px; } .ui-icon-arrowthickstop-1-w { background-position: -240px -48px; } .ui-icon-arrowreturnthick-1-w { background-position: 0 -64px; } .ui-icon-arrowreturnthick-1-n { background-position: -16px -64px; } .ui-icon-arrowreturnthick-1-e { background-position: -32px -64px; } .ui-icon-arrowreturnthick-1-s { background-position: -48px -64px; } .ui-icon-arrowreturn-1-w { background-position: -64px -64px; } .ui-icon-arrowreturn-1-n { background-position: -80px -64px; } .ui-icon-arrowreturn-1-e { background-position: -96px -64px; } .ui-icon-arrowreturn-1-s { background-position: -112px -64px; } .ui-icon-arrowrefresh-1-w { background-position: -128px -64px; } .ui-icon-arrowrefresh-1-n { background-position: -144px -64px; } .ui-icon-arrowrefresh-1-e { background-position: -160px -64px; } .ui-icon-arrowrefresh-1-s { background-position: -176px -64px; } .ui-icon-arrow-4 { background-position: 0 -80px; } .ui-icon-arrow-4-diag { background-position: -16px -80px; } .ui-icon-extlink { background-position: -32px -80px; } .ui-icon-newwin { background-position: -48px -80px; } .ui-icon-refresh { background-position: -64px -80px; } .ui-icon-shuffle { background-position: -80px -80px; } .ui-icon-transfer-e-w { background-position: -96px -80px; } .ui-icon-transferthick-e-w { background-position: -112px -80px; } .ui-icon-folder-collapsed { background-position: 0 -96px; } .ui-icon-folder-open { background-position: -16px -96px; } .ui-icon-document { background-position: -32px -96px; } .ui-icon-document-b { background-position: -48px -96px; } .ui-icon-note { background-position: -64px -96px; } .ui-icon-mail-closed { background-position: -80px -96px; } .ui-icon-mail-open { background-position: -96px -96px; } .ui-icon-suitcase { background-position: -112px -96px; } .ui-icon-comment { background-position: -128px -96px; } .ui-icon-person { background-position: -144px -96px; } .ui-icon-print { background-position: -160px -96px; } .ui-icon-trash { background-position: -176px -96px; } .ui-icon-locked { background-position: -192px -96px; } .ui-icon-unlocked { background-position: -208px -96px; } .ui-icon-bookmark { background-position: -224px -96px; } .ui-icon-tag { background-position: -240px -96px; } .ui-icon-home { background-position: 0 -112px; } .ui-icon-flag { background-position: -16px -112px; } .ui-icon-calendar { background-position: -32px -112px; } .ui-icon-cart { background-position: -48px -112px; } .ui-icon-pencil { background-position: -64px -112px; } .ui-icon-clock { background-position: -80px -112px; } .ui-icon-disk { background-position: -96px -112px; } .ui-icon-calculator { background-position: -112px -112px; } .ui-icon-zoomin { background-position: -128px -112px; } .ui-icon-zoomout { background-position: -144px -112px; } .ui-icon-search { background-position: -160px -112px; } .ui-icon-wrench { background-position: -176px -112px; } .ui-icon-gear { background-position: -192px -112px; } .ui-icon-heart { background-position: -208px -112px; } .ui-icon-star { background-position: -224px -112px; } .ui-icon-link { background-position: -240px -112px; } .ui-icon-cancel { background-position: 0 -128px; } .ui-icon-plus { background-position: -16px -128px; } .ui-icon-plusthick { background-position: -32px -128px; } .ui-icon-minus { background-position: -48px -128px; } .ui-icon-minusthick { background-position: -64px -128px; } .ui-icon-close { background-position: -80px -128px; } .ui-icon-closethick { background-position: -96px -128px; } .ui-icon-key { background-position: -112px -128px; } .ui-icon-lightbulb { background-position: -128px -128px; } .ui-icon-scissors { background-position: -144px -128px; } .ui-icon-clipboard { background-position: -160px -128px; } .ui-icon-copy { background-position: -176px -128px; } .ui-icon-contact { background-position: -192px -128px; } .ui-icon-image { background-position: -208px -128px; } .ui-icon-video { background-position: -224px -128px; } .ui-icon-script { background-position: -240px -128px; } .ui-icon-alert { background-position: 0 -144px; } .ui-icon-info { background-position: -16px -144px; } .ui-icon-notice { background-position: -32px -144px; } .ui-icon-help { background-position: -48px -144px; } .ui-icon-check { background-position: -64px -144px; } .ui-icon-bullet { background-position: -80px -144px; } .ui-icon-radio-off { background-position: -96px -144px; } .ui-icon-radio-on { background-position: -112px -144px; } .ui-icon-pin-w { background-position: -128px -144px; } .ui-icon-pin-s { background-position: -144px -144px; } .ui-icon-play { background-position: 0 -160px; } .ui-icon-pause { background-position: -16px -160px; } .ui-icon-seek-next { background-position: -32px -160px; } .ui-icon-seek-prev { background-position: -48px -160px; } .ui-icon-seek-end { background-position: -64px -160px; } .ui-icon-seek-first { background-position: -80px -160px; } .ui-icon-stop { background-position: -96px -160px; } .ui-icon-eject { background-position: -112px -160px; } .ui-icon-volume-off { background-position: -128px -160px; } .ui-icon-volume-on { background-position: -144px -160px; } .ui-icon-power { background-position: 0 -176px; } .ui-icon-signal-diag { background-position: -16px -176px; } .ui-icon-signal { background-position: -32px -176px; } .ui-icon-battery-0 { background-position: -48px -176px; } .ui-icon-battery-1 { background-position: -64px -176px; } .ui-icon-battery-2 { background-position: -80px -176px; } .ui-icon-battery-3 { background-position: -96px -176px; } .ui-icon-circle-plus { background-position: 0 -192px; } .ui-icon-circle-minus { background-position: -16px -192px; } .ui-icon-circle-close { background-position: -32px -192px; } .ui-icon-circle-triangle-e { background-position: -48px -192px; } .ui-icon-circle-triangle-s { background-position: -64px -192px; } .ui-icon-circle-triangle-w { background-position: -80px -192px; } .ui-icon-circle-triangle-n { background-position: -96px -192px; } .ui-icon-circle-arrow-e { background-position: -112px -192px; } .ui-icon-circle-arrow-s { background-position: -128px -192px; } .ui-icon-circle-arrow-w { background-position: -144px -192px; } .ui-icon-circle-arrow-n { background-position: -160px -192px; } .ui-icon-circle-zoomin { background-position: -176px -192px; } .ui-icon-circle-zoomout { background-position: -192px -192px; } .ui-icon-circle-check { background-position: -208px -192px; } .ui-icon-circlesmall-plus { background-position: 0 -208px; } .ui-icon-circlesmall-minus { background-position: -16px -208px; } .ui-icon-circlesmall-close { background-position: -32px -208px; } .ui-icon-squaresmall-plus { background-position: -48px -208px; } .ui-icon-squaresmall-minus { background-position: -64px -208px; } .ui-icon-squaresmall-close { background-position: -80px -208px; } .ui-icon-grip-dotted-vertical { background-position: 0 -224px; } .ui-icon-grip-dotted-horizontal { background-position: -16px -224px; } .ui-icon-grip-solid-vertical { background-position: -32px -224px; } .ui-icon-grip-solid-horizontal { background-position: -48px -224px; } .ui-icon-gripsmall-diagonal-se { background-position: -64px -224px; } .ui-icon-grip-diagonal-se { background-position: -80px -224px; } .achtung { .achtung-message-icon { margin-top: 0px; margin-left: -0.5em; margin-right: .5em; float: left; zoom: 1; } .ui-icon { &.achtung-close-button { overflow: hidden; float: right; position: relative; top: -8px; right: -8px; cursor: pointer; background-image: url(/javascript/jqueryui/css/sage/images/ui-icons_888888_256x240.png); } &.achtung-close-button-hover { background-image: url(/javascript/jqueryui/css/sage/images/ui-icons_ffffff_256x240.png); } } } /* Slightly darker for these colors (readability) */ .achtungSuccess, .achtungFail, .achtungWait { /* Note that if using show/hide animations, IE will lose this setting */ opacity: .93; filter: Alpha(Opacity = 93); } .achtungSuccess { background-color: #4DB559; } .achtungFail { background-color: #D64450; } .achtungWait { background-color: #658093; } .achtungSuccess .ui-icon.achtung-close-button, .achtungFail .ui-icon.achtung-close-button { background-image: url(/javascript/jqueryui/css/sage/images/ui-icons_2e83ff_256x240.png); } .achtungSuccess .ui-icon.achtung-close-button-hover, .achtungFail .ui-icon.achtung-close-button-hover { background-image: url(/javascript/jqueryui/css/sage/images/ui-icons_222222_256x240.png); } .achtung { .wait-icon { background-image: url('/javascript/jqueryui/css/sage/images/wait.gif'); } .achtung-message { display: inline; } } sagenb-1.0.1/sass/src/main.scss000066400000000000000000000513621311436262400163420ustar00rootroot00000000000000// The warning below is for those editing the generated .css files /* Warning: These .css files are automatically generated and will be overwritten */ /* when they are next generated. Please edit the source located at */ /* /src. Kindly refer to the readme for editing */ /* instructions at */ @import "compass/utilities/general"; @import "compass/typography/lists"; @import "partials/base"; @import "partials/mixins"; @import "typography/base"; body { background-color: white; } .hidden { display: none; } div { &.fivepix { height: 5px; } } @import "topbar"; /******* Top Control Bar (Worksheets) ********** */ #worksheet-bar { overflow: hidden; clear: both; a.worksheet_title { text-decoration: none; font-size: 20px; font-weight: bold; color: black; &:hover { background-color: #ffffcc; cursor: pointer; } } div.worksheet_title { float: left; clear: left; padding-left: 1em; background-color: white; color: black; margin-bottom: 0.5em; } #save-discard-buttons { float: right; clear: right; } #worksheet-menu { float: left; clear: left; margin-bottom: 0.25em; } #share-publish-buttons { float: right; clear: right; a.print-link { color: #112abb; text-decoration: underline; margin-right: 0.5em; img { margin-right: 0.3em; } } } } span { &.control_commands { position: fixed; top: 1ex; right: 1ex; text-align: right; color: blue; font-weight: normal; font-size: 12px; } &.worksheet_control_commands { position: relative; top: 0px; right: 0px; text-align: right; color: blue; font-weight: normal; font-size: 12px; padding: 5px; } } div.slide_control_commands { float: right; position: fixed; width: 500px; top: 1ex; right: 45%; text-align: right; color: blue; font-weight: normal; font-size: 12px; } span.vbar { height: 1.5ex; border-left: 1px solid black; width: 1px; } a { &.slide_mode:hover, &.cell_mode:hover, &.slide_arrow:hover { cursor: pointer; } } span.worksheet_control_commands a { color: #0000bb; text-decoration: none; padding: 5px; &:hover { cursor: pointer; } } div { &.slideshow_control { float: right; &:hover { cursor: pointer; } } &.slideshow_progress { float: right; background-color: white; padding: 1px; border: 1px solid #cccccc; width: 20%; } &.slideshow_progress_bar { z-index: 1; position: relative; background-color: #dcdcdc; &:hover { cursor: pointer; } } &.slideshow_progress_text { position: absolute; z-index: 2; top: 2px; text-align: center; color: black; width: 20%; } } .completion_menu_selected { background-color: #8888ff; } div.docstring { background-color: #fafafa; color: black; border: solid 1px black; padding: 8px; margin: 8px; } pre { &.literal-block { background-color: white; color: black; padding: 0 0 0 5px; border-left: 2px solid silver; } &.introspection { @include monospace-stack; font-size: 15px; background-color: #f1f1f1; color: blue; border: solid 1px black; padding: 8px; margin: 8px; } } ul.completion_menu_one { list-style: none; position: absolute; z-index: 2; background-color: #efefef; border: solid 1px black; display: inline; margin: 5px; @include monospace-stack; font-size: 15px; padding: 5px; } li.completion_menu_one { display: inline; position: relative; float: left; margin: 0px; } ul.completion_menu_two { display: inline; position: relative; list-style: none; margin: 0px; } li.completion_menu_two { display: block; position: relative; margin: 3px; padding-left: 3px; padding-right: 3px; &:hover { background-color: #8888bb; cursor: pointer; } } /**** SEARCH / HELP AREA ******************************** */ span.search_doc_topbar { z-index: 12; height: 24px; @include monospace-stack; font-size: 12px; width: 158px; top: 40px; left: 5px; position: fixed; border: 1px solid #387caf; background-color: #73a6ff; } td.menubar { text-decoration: none; font-size: 15px; font-weight: bold; color: white; } a.menubar { text-decoration: none; font-size: 15px; font-weight: bold; color: white; background-color: #73a6ff; } input.search_input { position: fixed; left: 5px; top: 65px; height: 32px; width: 160px; padding: 4px; z-index: 12; @include monospace-stack; font-size: 14px; color: #222222; color: gray; border: 3px solid #387caf; background: white; } span { &.search_doc { z-index: 12; font-size: 12px; overflow: auto; position: fixed; top: 96px; left: 5px; width: 154px; height: 150px; margin: 0px; border: 1px solid #387caf; background-color: white; padding: 2px; } } #docs-main-page { div.control-bar { margin: 0 auto 1em; padding: 1em 0.5em; border-bottom: 1px solid #c9d7f1; text-align: center; } ul.controls { margin: 1em auto; list-style-type: none; text-align: center; li { display: inline; a { background-color: #7799bb; color: white; padding: 0.25em 0.5em; font-size: 15px; font-weight: bold; text-decoration: none; &:hover { cursor: pointer; } } } } div.help_window { background-color: white; border: 3px solid #3d86d0; padding: 2em; width: 90%; margin: 0 auto; } table.help_window { background-color: white; width: 95%; } td { &.help_window_sub { background-color: #f5e0aa; width: 100%; padding: 0.5ex; font-weight: bold; } &.help_window_cmd { background-color: #f5e0aa; width: 30%; padding: 0.5ex; } &.help_window_how { padding: 0.5ex; width: 70%; } } .acknowledgments { font-size: small; text-align: center; } } /*********** INFO PANES ************************* */ span { &.pane { z-index: 30; @include monospace-stack; font-size: 12px; position: fixed; left: 5px; top: 33px; width: 180px; height: 100%; margin: 0px; padding-right: 2px; padding-left: 0px; padding-top: 0px; bottom: 0ex; } &.plusminus { color: black; font-size: 8pt; @include monospace-stack; &:hover { cursor: pointer; } } &.controltoggle { color: blue; font-size: 10pt; text-decoration: underline; &:hover { cursor: pointer; } } } div.left_pane_bar { position: fixed; left: 0px; top: 36px; background-color: white; width: 8px; height: 100%; z-index: 100; &:hover { background-color: #8888fe; } } /*********** VARIABLES ************************* */ span.pane div { &.variables_topbar { color: black; background: url("corner.png") no-repeat top left; background-color: #dcdcdc; text-decoration: none; font-size: 13px; height: 2ex; padding-left: 10px; padding-bottom: 1px; width: 174px; } &.variable_list { font-size: 11px; top: 0ex; height: 20ex; border: 2px solid #dcdcdc; width: 180px; overflow: auto; } } div.variable_name { padding-left: 1ex; border-top: 1px solid #d3e9ff; } span { //&.varname &.vartype { color: #657d6c; } } /*********** ATTACHED ************************* */ span { &.pane div { &.attached_topbar { color: black; height: 2ex; top: 0ex; background: url("corner.png") no-repeat top left; background-color: #dcdcdc; text-decoration: none; font-size: 13px; padding-left: 10px; padding-bottom: 1px; width: 174px; } &.attached_list { font-size: 11px; top: 0ex; height: 20ex; border: 2px solid #dcdcdc; width: 180px; overflow: auto; } } } div.attached_filename { padding-left: 1ex; border-top: 1px solid #d3e9ff; } /*********** WORKSHEETS ************************* */ div.docstring-introspection-dialog-source .ui-dialog-title { font-size: inherit; color: #007020; @include sans-serif-stack; } div.docstring-introspection-dialog-doc .ui-dialog-title { font-size: inherit; color: #0000aa; @include sans-serif-stack; } .docstring { @include sans-serif-stack; .click-message { font-size: 0.75em; float: right; clear: both; } .unprinted-note { float: right; clear: both; font-size: 0.6em; } } .active-worksheet .interrupt-fail-notification { background-color: #b22222; } span.pane div.worksheets_topbar { color: black; height: 3ex; top: 0ex; background: url("/images/corner.png") no-repeat top left; background-color: #cccccc; text-decoration: none; font-size: 15px; padding-left: 10px; padding-top: 10px; width: 174px; } a.left_panel_hide { position: relative; top: 0px; right: -1px; text-align: right; color: blue; font-weight: normal; font-size: 12px; &:hover { cursor: pointer; } } span.X { color: white; @include sans-serif-stack; font-weight: bold; cursor: pointer; } .modal-prompt { form { font-size: 0.9em; } div { &.message, &.field { margin-bottom: 0.25em; } &.button-div { text-align: center; } } } span.pane div.add_new_worksheet_menu { position: relative; color: black; padding-top: 0.5ex; padding-bottom: 0.5ex; left: 0ex; background-color: white; text-decoration: none; font-size: 11px; padding-left: 0px; width: 174px; } input.add_new_worksheet_menu { width: 100%; } button.add_new_worksheet_menu { font-size: 14px; } #upload-worksheet-page, #upload-data-page { h2 { padding-bottom: 0.5em; border-bottom: 1px solid #cccccc; } label { display: block; } div { margin-bottom: 1em; } } #specific-revision-page { #revision-data { padding: 1em 0.5em; border-top: 1px solid #c9d7f1; border-bottom: 1px solid #c9d7f1; } .sharebar a { color: white; border-left: 2px white solid; padding-left: 1em;} } #revision-list-page { #revision-list { width: 100%; } .revision-title { width: 30%; } .edit-time { width: 70%; } } #history-page { pre { border-bottom: 1px solid #c9d7f1; padding: 1em 0.5em; } } span.pane div.delete_worksheet_menu { color: black; top: 0ex; background-color: #cccccc; text-decoration: none; font-size: 11px; padding-left: 10px; width: 174px; display: none; } input.delete_worksheet_menu { width: 50%; } button.delete_worksheet_menu { font-size: 11px; background-color: #ffcccc; } span.pane div.worksheet_list { position: fixed; overflow: scroll; font-size: 12px; top: 25ex; bottom: 2ex; left: 1ex; border: 2px solid #cccccc; width: 180px; } a.new_worksheet { @include sans-serif-stack; font-size: 12pt; text-align: right; color: #0000aa; &:hover { cursor: pointer; } } div { &.worksheet_menu { top: 50px; } } a.worksheet_title { text-decoration: none; font-size: 20px; font-weight: bold; color: black; &:hover { background-color: #ffffcc; cursor: pointer; } } div { &.worksheet_title { padding-left: 1em; background-color: white; color: black; } &.worksheet_print_title { text-decoration: none; font-size: 24px; font-weight: bold; color: black; text-align: center; } &.worksheet_title_under { z-index: 0; padding-top: 3px; padding-left: 1em; background-color: #dcdcdc; font-size: 22px; font-weight: bold; color: black; } &.worksheet_cell_list { padding-left: 0.5ex; } } a { &.delete_worksheet { @include sans-serif-stack; font-size: 8pt; text-decoration: underline; text-align: right; color: #0000aa; &:hover { cursor: pointer; } } &.upload_worksheet:hover { cursor: pointer; } } span.pane a { &.worksheet_current { font-size: 14px; padding-left: 1ex; background-color: #cccccc; text-decoration: none; color: black; } &.worksheet_current_computing { font-size: 14px; padding-left: 1ex; background-color: #ffd1d1; text-decoration: none; color: black; } &.worksheet_other { font-size: 14px; padding-left: 1ex; background-color: white; text-decoration: none; color: black; &:hover { background-color: #cccccc; text-decoration: none; cursor: pointer; } } &.worksheet_other_computing { font-size: 14px; padding-left: 1ex; background-color: #ffd1d1; text-decoration: none; color: black; } } /********** DOC-BROWSER*********************** */ .verbatim { background-color: #fafad2; border-style: solid; border-width: 1px 1px; border-color: black; } /*********** OBJECTS ************************* */ span.pane div { &.objects_topbar { color: black; height: 2ex; top: 0ex; background: url("corner.png") no-repeat top left; background-color: #cccccc; text-decoration: none; font-size: 13px; padding-left: 10px; padding-bottom: 1px; width: 174px; } &.object_list { font-size: 11px; height: 20ex; border: 2px solid #cccccc; width: 180px; overflow: auto; } } a.object_name { padding-left: 1ex; border-top: 1px solid #cccccc; background-color: white; text-decoration: none; color: black; &:hover { background-color: #cccccc; text-decoration: none; color: black; cursor: pointer; } } /*********** CONTROLS ************************* */ div.control_area { vertical-align: top; } span.control { border: 1px solid white; @include monospace-stack; font-size: 14pt; font-weight: bold; a.cs { color: #777777; text-decoration: none; border: 0px solid white; } &:hover a.cs, a:hover.cs { color: black; border: 1px solid #333333; } } /*********** WORKSHEET ************************* */ div { &.worksheet { background-color: white; border: 1px solid #aaaaaa; padding: 0.75em 0.2em; } &.banner { background-color: white; font-size: 18px; text-decoration: none; color: #1950c8; a.banner { text-decoration: none; border: none; margin-top: 2px; } } } a.banner:visited { color: #1950c8; } div.banner a.banner { img { text-decoration: none; border: none; margin-top: 2px; } //&:hover } input.btn { @include monospace-stack; font-size: 13pt; font-weight: bold; color: gray; text-decoration: none; background: white; padding: 0px; margin: 0px; border: 1px solid white; &:hover { color: black; text-decoration: none; background: white; padding: 0px; margin: 0px; border: 1px solid #333333; } } /*********** CELL INPUT ************************* */ div { &.cell_visible { display: block; } &.cell_evaluated { border-left: 1px solid white; padding-left: 3px; } &.cell_not_evaluated { border-left: 1px solid #ff8888; padding-left: 3px; } } td { &.cell_number { font-size: 12pt; @include sans-serif-stack; color: #bbbbbb; text-align: left; border-left: 4px solid white; &:hover { color: #555555; cursor: pointer; } } &.cell_number_running { font-size: 12pt; @include sans-serif-stack; color: #bbbbbb; border-left: 4px solid #aaffaa; text-align: left; &:hover { cursor: wait; } } //&.output_cell } div.cellbox { z-index: 2; background-color: white; padding-left: 0.5em; padding-top: 4em; } textarea.cell_input { color: black; background-color: white; border: 1px solid #a8a8a8; @include monospace-stack; font-size: 12pt; overflow: hidden; padding-bottom: 1px; padding-left: 6px; padding-right: 1px; padding-top: 4px; width: 97%; margin-bottom: 0px; margin-top: 0px; line-height: 1.2em; } pre.cell_input { color: black; background-color: white; border: 1px solid #a8a8a8; @include monospace-stack; font-size: 12pt; padding-bottom: 1px; padding-left: 6px; padding-right: 1px; padding-top: 4px; width: 100%; margin-bottom: 0px; margin-top: 0px; &:hover { cursor: text; } } textarea.cell_input_hide { background-color: white; border: 0px solid white; @include monospace-stack; font-size: 12pt; color: #888888; overflow: hidden; padding-bottom: 2px; padding-left: 7px; padding-right: 2px; padding-top: 5px; height: 1em; margin: 0px; } pre.cell_input_hide { background-color: white; border: 2px solid #e8e8e8; @include monospace-stack; font-size: 12pt; overflow: hidden; padding-bottom: 0px; padding-left: 5px; padding-right: 0px; padding-top: 3px; height: 1em; margin: 0px; &:hover { cursor: text; } } textarea.cell_input_active { background-color: white; border: 2px solid #8888fe; color: black; @include monospace-stack; font-size: 12pt; overflow: hidden; padding-bottom: 0px; padding-left: 5px; padding-right: 0px; padding-top: 3px; margin-top: 0px; margin-bottom: 0px; line-height: 1.2em; width: 97%; } div { &.cell_input_active { background-color: white; border: 2px solid #8888fe; @include monospace-stack; font-size: 12pt; padding-bottom: 0px; padding-left: 5px; padding-right: 0px; padding-top: 3px; margin-top: 0px; margin-bottom: 0px; line-height: 1.2em; width: 97%; z-index: -100; visibility: hidden; position: absolute; } &.cell_input_print { background-color: white; border: 1px solid #a8a8a8; @include monospace-stack; font-size: 12pt; padding-bottom: 1px; padding-left: 6px; padding-right: 1px; padding-top: 4px; margin-top: 0px; margin-bottom: 0px; line-height: 1.2em; width: 97%; white-space: pre-wrap; } } textarea.cell_input:hover { cursor: text; } input { &.eval_button { display: none; } &.eval_button_active { display: block; position: relative; top: 2px; margin: 0px; padding: 0px; font-size: 10pt; } } /*********** CELL OUTPUT ************************* */ div { &.cell_div_output { @include monospace-stack; font-size: 12pt; margin-top: -5px; margin-bottom: 5px; padding-bottom: 5px; } &.cell_output_div { overflow-x: auto; overflow-y: hidden; } } table { &.cell_output_box { margin: 0px; padding: 0px; } &.table_form * { td { padding-top: 5px; padding-bottom: 5px; padding-left: 15px; padding-right: 15px; } th { background: #a6ba4e; height: 29px; padding-left: 15px; padding-right: 15px; padding-top: 5px; padding-bottom: 5px; color: white; text-align: left; } tr { &.row-a { background: #f8f8f8; text-align: left; } &.row-b { background: #efefef; text-align: left; } } } } div { &.cell_div_output_wrap { font-size: 12pt; margin: 0px; padding-left: 0px; color: #0000aa; } &.cell_output_wrap pre.cell_output_print_wrap { font-size: 12pt; margin: 0px; padding: 0px; color: #0000aa; } &.cell_output_print_wrap { font-size: 10pt; } &.cell_output_nowrap, &.cell_output_print_nowrap, &.cell_output_hidden, &.cell_output_nowrap_wrap, &.cell_output_print_nowrap_wrap { display: none; } &.cell_output_nowrap_nowrap { font-size: 12pt; margin: 0px; padding: 0px; color: #0000aa; } &.cell_output_nowrap_hidden { display: none; } &.cell_output_html_wrap, &.cell_output_html_nowrap { @include monospace-stack; font-size: 12pt; } &.cell_output_html_hidden { display: none; } &.cell_div_output_running { @include monospace-stack; font-size: 12pt; margin: 0px; background-color: white; padding: 0px; &:hover { cursor: wait; } } &.cell_div_output_hidden { width: 100%; height: 3px; margin: 0px; border-left: 4em solid #aaaaaa; } } pre { &.shrunk { font-size: 12pt; margin: 0px; } &.cell_output_hidden, &.cell_output_hide { display: none; } } a.file_link { text-decoration: underline; } div { &.insert_new_cell { height: 16px; display: block; margin: 3px; &.wksht-icon_button { display:inline-block;} &:hover {background-color:#8888fe;} &.legacy_insert_new_cell{ height: 13px; width: 95%; display: inline-block; &:hover{background-color:#8888fe;}} a { &.worksheetname { text-decoration: none; font-weight: bold; font-size: 14px; color: #222222; &:visited { color: #222222; } } &.worksheetname_moved { color: #888888; text-decoration: none; font-weight: normal; } } span.worksheet_buttons { position: relative; top: -20ex; right: 0ex; } .thin-right { position: absolute; top: auto; right: 0; width: 70%; } @import "worksheet_listing"; @import "prettify"; @import "source"; @import "print_worksheet"; @import "guest_worksheet"; @import "worksheet_aux"; @import "settings"; @import "accounts"; @import "login"; @import "pygment"; @import "jquery-plugins/ui.achtung"; sagenb-1.0.1/sass/src/partials/000077500000000000000000000000001311436262400163315ustar00rootroot00000000000000sagenb-1.0.1/sass/src/partials/_base.scss000066400000000000000000000000651311436262400203000ustar00rootroot00000000000000$subdued_blue: #112abb; $link_color: $subdued_blue; sagenb-1.0.1/sass/src/partials/_mixins.scss000066400000000000000000000003621311436262400206750ustar00rootroot00000000000000@mixin vcenter($height) { height: $height; position: absolute; top: 50%; margin-top: $height/2; } @mixin sans-serif-stack() { font-family: 'Arial', 'Helvetica', sans-serif; } @mixin monospace-stack() { font-family: monospace; } sagenb-1.0.1/sass/src/test_report.scss000066400000000000000000000051011311436262400177560ustar00rootroot00000000000000// The warning below is for those editing the generated .css files /* Warning: These .css files are automatically generated and will be overwritten */ /* when they are next generated. Please edit the source located at */ /* /src. Kindly refer to the readme for editing */ /* instructions at */ @import "partials/base"; @import "partials/mixins"; body, table { @include sans-serif-stack; background-color: white; color: #111111; -moz-border-radius: 0.25em; -webkit-border-radius: 0.25em; } pre { margin: 0; padding: 0; padding-top: 0.25em; } .heading h2 { color: black; } .description { color: #111111; } .statistics { border: 0; .label { font-style: oblique; padding-left: 2em; padding-right: 1em; text-align: right; } .value { color: black; padding-left: 1em; text-align: left; } } .txt_pass { color: #004123; } .txt_fail { color: #ce2029; } .txt_error { color: #ffbf00; } .txt_total { color: black; } .top_bar { margin-bottom: 0.5em; margin-top: 1.5em; } .top_bar_item { color: navy; display: inline; font-weight: bold; &:hover { color: #00009c; cursor: pointer; } } .pass_header:hover, .fail_header:hover, .error_header:hover, .hide_all:hover, .show_all:hover, .toggle_all:hover { background-color: white; color: #004123; cursor: pointer; } .pass:hover, .fail:hover, .error:hover, .hide:hover, .show:hover, .toggle:hover, .spanner:hover { cursor: pointer; outline: white ridge 2px; } .results { border: 1px solid black; border-collapse: collapse; color: black; width: 100%; } .headers, .totals { background-color: #eeeeee; color: black; font-weight: bold; } .headers { text-align: center; } .totals { text-align: right; } .results td { border: 1px solid black; padding: 0.5em; } td.left { width: 90%; max-width: 1px; } .test_case_total { text-align: center; } .pass, .fail, .error, .count { text-align: right; } .hidden { display: none; } .hide, .show, .toggle, .hide_all, .show_all, .toggle_all { text-align: center; } td.case { padding-left: 0.5em; } .case_pass { background-color: #32cd32; } .case_fail { background-color: #ddbec3; } .case_error { background-color: #ffbf40; } .test_pass { background-color: #52ed52; } .test_fail { background-color: #edced3; } .test_error { background-color: #ffdf60; } td.test { padding-left: 1em; padding-right: 1em; } .spanner { text-align: center; } .out_trace { color: black; display: none; } .highlight { font-size: 100%; overflow: auto; } #ending {} sagenb-1.0.1/sass/src/typography/000077500000000000000000000000001311436262400167205ustar00rootroot00000000000000sagenb-1.0.1/sass/src/typography/_base.scss000066400000000000000000000000361311436262400206650ustar00rootroot00000000000000thead { font-weight: bold } sagenb-1.0.1/setup.py000077500000000000000000000045131311436262400144720ustar00rootroot00000000000000#!/usr/bin/env python ########################################################## # The setup.py for the Sage Notebook ########################################################## import os from setuptools import setup def lremove(string, prefix): while string.startswith(prefix): string = string[len(prefix):] return string def all_files(dir, prefix): """ Return list of all filenames in the given directory, with prefix stripped from the left of the filenames. """ X = [] for F in os.listdir(dir): ab = dir+'/'+F if os.path.isfile(ab): X.append(lremove(ab, prefix)) elif os.path.isdir(ab): X.extend(all_files(ab, prefix)) return X install_requires = [ 'twisted>=11.0.0', 'flask>=0.10.1', 'flask-oldsessions>=0.10', 'flask-openid', 'flask-autoindex', 'flask-babel' ] setup(name='sagenb', version = '1.0.1', description = 'The Sage Notebook', license = 'GNU General Public License (GPL) v3+', author = 'William Stein et al.', author_email= 'sage-notebook@googlegroups.com', url = 'http://github.com/sagemath/sagenb', install_requires = install_requires, dependency_links = [ 'http://github.com/mitsuhiko/flask-oldsessions/tarball/master#egg=flask-oldsessions-0.10' ], test_suite = 'sagenb.testing.run_tests.all_tests', packages = [ 'sagenb' , 'sagenb.flask_version' , 'sagenb.interfaces' , 'sagenb.misc' , 'sagenb.notebook' , 'sagenb.notebook.compress' , 'sagenb.simple' , 'sagenb.storage' , 'sagenb.testing' , 'sagenb.testing.tests' , 'sagenb.testing.selenium' ], scripts = [ 'sagenb/data/sage3d/sage3d', ], package_data = {'sagenb': all_files('sagenb/data', 'sagenb/') + all_files('sagenb/translations', 'sagenb/') }, zip_safe = False, ) sagenb-1.0.1/util/000077500000000000000000000000001311436262400137275ustar00rootroot00000000000000sagenb-1.0.1/util/apply-hg.py000066400000000000000000000015351311436262400160260ustar00rootroot00000000000000#! /usr/bin/python # Original script by Ondrej Certik: http://git.661346.n2.nabble.com/importing-mercurial-patch-td1484627.html import os import sys import re import tempfile def run(cmd): print(cmd) execcode=os.system(cmd) if execcode != 0: raise RuntimeError patch = sys.argv[1] args = ' '.join(sys.argv[2:]) print('p {}'.format(patch)) print('args {}'.format(args)) with open(patch) as f: p = f.read() author = re.search("# User (.+)", p).groups()[0] p = p.split("\n") while not p[0].startswith("# Parent"): del p[0] i = 1 while not p[i].startswith("diff -r "): i += 1 commit_message = "\n".join(p[1:i]) _, filename = tempfile.mkstemp() with open(filename, "w") as f: f.write(commit_message) print(commit_message) run("patch %s < %s" %(args,patch)) run("git commit -a --author='%s' -F %s -s" % (author, filename) ) sagenb-1.0.1/util/quota.py000066400000000000000000000026451311436262400154410ustar00rootroot00000000000000""" This script determines the users that are using more than a certain amount of disk space and makes them "readonly". """ from subprocess import check_output import os import sys SERVERDIR = os.path.abspath(sys.argv[1]) HOMEDIR=os.path.join(SERVERDIR,'home','') # end in / READONLY_FILE=os.path.join(SERVERDIR, 'readonly.txt') LOG_FILE = os.path.join(SERVERDIR, 'log-size.txt') MAX=250 # megabytes s = check_output('du -Lm --max-depth 1 %r'%HOMEDIR, shell=True) readonly={} system_users = set(['_sage_','pub','__store__','','admin']) for line in s.split('\n'): if len(line)0 and size>MAX: user = user_dir[len(HOMEDIR):] if user not in system_users: readonly[user]=size import logging logging.basicConfig(format='%(asctime)s %(message)s',filename=LOG_FILE) logging.warning(sorted(readonly.items(), key=lambda x: x[1], reverse=True)) if os.path.exists(READONLY_FILE): with open(READONLY_FILE) as f: oldnames=set(i.strip() for i in f.readlines()) else: oldnames=None if set(readonly.keys())!=oldnames: logging.warning('writing %r'%READONLY_FILE) with open(READONLY_FILE,'w') as f: f.write('\n'.join(readonly.keys())) # for all people over quota: # - delete all output directories # check size again. If still over by 20%, delete DATA directories. # check size again. sagenb-1.0.1/util/translations.py000077500000000000000000000631621311436262400170350ustar00rootroot00000000000000#!/usr/bin/env python # -*- coding: utf-8 -*- """ The sage notebook translation maintenance utility. When used as a command, this application is intended to extract translatable messages from source and to update the translations of the Sage notebook. This can be used as a module for other project by subclassing `Paths`, `LocalData`, and `TranslationFrontend`, overiding `Paths.get_paths()`, and `LocalData.get_data()` and `TranslationFrontend.parser` and by adding methods and attributes as neccesary to the three classes. :copyright: (c) 2014 by J. Miguel Farto :license: GPL, see http://www.gnu.org/licenses/ """ import os import os.path as pth import shutil import logging import argparse from datetime import datetime from babel.core import Locale, UnknownLocaleError from babel.messages.pofile import read_po, write_po from babel.messages.mofile import write_mo from babel.messages.catalog import Catalog from babel.messages.extract import extract_from_dir def restore(file_path): """Restores a file from a backup file of the same name ended by `~`. :param file_path: the absolute path of the file to restore. """ backup_path = '{}~'.format(file_path) if pth.isfile(backup_path): shutil.copyfile(backup_path, file_path) def clear(file_path): """Clears a backup file. :param file_path: the absolute path of the file whose backup ends by `~`. """ backup_path = '{}~'.format(file_path) if pth.isfile(backup_path): os.remove(backup_path) class Paths(object): """This class stores some paths in the source tree. You can subclass this and override the `get_paths` method accordingly with the source tree of your project. """ def __init__(self): self.get_paths() def get_paths(self): """ Defines some paths in the source tree as attributes for the Sage notebook. It must be overridden if subclassing for another project. Mandatory attributes that must be defined by this method: :attribute command_name: the file name of this script. :attribute src: the base path of the source tree. :attribute trans: the base path where translations are. :attribute pot: the messages template file of the project. """ #: Some paths in the sage notebook source tree. This paths are obtained #: from the location of this file, so it must not be moved or copied #: and executed from other location. Symlinking is fine. self.command_name = pth.basename(__file__) self.src = pth.dirname(pth.dirname(pth.realpath(__file__))) self.trans = pth.join(self.src, 'sagenb', 'translations') self.pot = pth.join(self.src, 'sagenb', 'message.pot') def lang(self, lang_id): """Returns the path of the language `lang_id` in the source tree. :param lang_id: language identifier of the form xx_XX. """ return pth.join(self.trans, lang_id, 'LC_MESSAGES', 'messages.po') class LocalData(object): """Stores information about the sage notebook. You can subclass this and override the `get_data` method accordingly with the source tree of your project. :attribute path: a Path instance. It is available before `get_data()` is called :attribute extract: a dictionary with kwargs for `Pot.extract`. Must be overridden for other projects. Implemented as @property. :attribute to_file: a dictionary with kwargs for `Pot.to_file`. Must be overridden for other projects. Implemented as @property. """ def __init__(self): self.path = Paths() self.get_data() def get_data(self): """ Defines some attributes for the Sage notebook localization system. It must be overridden if subclassing for another project. Mandatory attributes that must be defined by this method: :attribute keywords: the file name of this script. :attribute method_map: files with localizable messages in the sources. (see `babel.messages.extract.extract_from_dir() documentation) :attribute options_map: options for every class of localizable files, (see `babel.messages.extract.extract_from_dir() documentation) :attribute charset: charset for `babel.messages.catalog.Catalog`. :attribute sort_by_file: message ordering for po and pot files. This option keeps changes in po and pot files small when changes in notebook sources are small. :attribute width: max line length for po and pot files. This option contributes to keep changes in po and pot files small when changes in notebook sources are small. :attribute langs: list of identifiers for available localizations in the notebook. :attribute lang_names: localized names of available localizations. """ #: function names surrounding translatable strings self.keywords = { '_': None, 'gettext': None, 'ngettext': (1, 2), 'ugettext': None, 'ungettext': (1, 2), 'dgettext': (2,), 'dngettext': (2, 3), 'N_': None, 'nN_': (1,2), 'pgettext': ((1, 'c'), 2), 'npgettext': ((1, 'c'), 2, 3), 'lazy_gettext': None, 'lazy_pgettext': ((1, 'c'), 2), } #: Source files to extract messages self.method_map = [ ('sagenb/notebook/**.py', 'python'), ('sagenb/flask_version/**.py', 'python'), ('sagenb/data/sage/html/**.html', 'jinja2'), ('sagenb/data/sage/js/**.js', 'jinja2')] #: Some configuration for each type of file self.options_map = { 'sagenb/data/sage/html/**.html': { 'encoding': 'utf-8', 'extensions': 'jinja2.ext.autoescape,jinja2.ext.with_'}, 'sagenb/data/sage/js/**.js': { 'encoding': 'utf-8', 'extensions': 'jinja2.ext.autoescape,jinja2.ext.with_'}, 'sagenb/flask_version/**.py': {}, 'sagenb/notebook/**.py': {}} #: Some defaults for babel package self.charset = 'utf-8' self.sort_by_file = True self.width = 76 #: Available translations in the source tree names = os.listdir(self.path.trans) self.langs = [] self.lang_names = [] for name in names: try: locale = Locale.parse(name) except UnknownLocaleError: pass else: self.langs.append(name) self.lang_names.append(locale.display_name) @property def extract(self): """A dictionary with kwargs for `Pot.extract`. Must be overridden for other projects. """ return { 'src_path': self.path.src, 'method_map': self.method_map, 'options_map': self.options_map, 'keywords': self.keywords, 'charset': self.charset, } @property def to_file(self): """A dictionary with kwargs for `Pot.to_file`. Must be overridden for other projects. """ return { 'width': self.width, 'sort_by_file': self.sort_by_file } class Pot(object): """This class encapsulates file operations and update from sources for a po or pot file. It uses the public API of the `babel` package. :param file_path: if is not `None`, the catalog is read from this file. the catalog in empty in other case. Default is `None`. :attribute catalog: the catalog with the messages of the po/pot object. It is a `babel.messages.catalog.Catalog` :attribute path: contains the path of the file associated if any. It is `None` in other case. """ def __init__(self, file_path=None, **kwargs): self.path = file_path if self.path is not None: self.from_file(self.path, **kwargs) else: self.catalog = Catalog(**kwargs) def extract(self, src_path='.', charset='utf-8', locale=None, **kwargs): """Extracts translatable messages from sources. This function is based on the extract function of the `pybabel` command, which is not part of the public API of `babel`. Only the public API of `babel` is used here. :param src_path: base path of the source tree, default is the current path. :param charset: see the `babel.messages.catalog.Catalog` docs. Default is `utf-8`. :param locale: see the `babel.messages.catalog.Catalog` docs. Default is `None`. Other optional keyword parameters are passed to `babel.messages.extract.extract_from_dir` see `babel` public API docs. """ #: This is the babel.messages.catalog.Catalog to contain the #: extracted messages self.catalog = Catalog(charset=charset, locale=locale) if not pth.isdir(src_path): raise IOError('{} is not a directory'.format(src_path)) #: Extracts the data from source in a low level format. This is #: the only way present in babel's public API. extracted = extract_from_dir(src_path, **kwargs) #: Constructs the catalog from the raw extracted data. #: Based on the source code of pybabel: #: babel.messages.frontend.extract_messages.run for filename, lineno, message, comments, context in extracted: self.catalog.add(message, None, [(filename, lineno)], auto_comments=comments, context=context) def from_file(self, file_path, **kwargs): """Reads the message's catalog from a file :param file_path: a path to a po/pot file. A exception is raised if the file does not exist. The `path` attribute is updated with this value. Other optional keyword parameters are passed to `babel.messages.pofile.read_po()` see `babel` public API docs. """ with open(file_path, 'rt') as f: self.catalog = read_po(f, **kwargs) self.path = file_path def to_file(self, file_path=None, backup=True, warn=False, **kwargs): """Writes the catalog to a file. :param file_path: if the `file_path` attribute is `None`, `path` is taken as the output file and `file_path` parameter is discarded. If `file_path` is not `None`, the output file is `file_path` and `path` is not updated. Default is `None`. :param backup: if `True` and the output file exists, a backup is made prior to overwrite the file. Further backups overwrite the previous. :param warn: if `True` warnings about fuzzy, untranslated and obsolete messages are issued. Other optional keyword parameters are passed to `babel.messages.pofile.write_po()` see `babel` public API docs. """ if file_path is None: file_path = self.path if pth.isfile(file_path) and backup: shutil.copy(file_path, '{}~'.format(file_path)) if warn: logging.basicConfig(level=logging.WARNING) fuzzy = 0 untrans = 0 obsolete = len(self.catalog.obsolete) for message in self.catalog: if message.fuzzy and message.id: fuzzy += 1 if not message.string: untrans += 1 if fuzzy: logging.warning('There are {} fuzzy messages in {}.\n'.format( fuzzy, file_path)) if untrans: logging.warning('There are {} untranslated messages ' 'in {}.\n'.format(untrans, file_path)) if obsolete: logging.warning('There are {} obsolete messages ' 'in {}.\n'.format(obsolete, file_path)) else: logging.basicConfig(level=logging.INFO) with open(file_path, 'wb') as f: write_po(f, self.catalog, **kwargs) def update(self, template_po, *args, **kwargs): """updates the catalog from a pot. :param template_po: a pot with a message template catalog. See `babel.messages.catalog.Catalog()` """ self.catalog.update(template_po.catalog, *args, **kwargs) class Po(Pot): """a class specific for actual localizations, not templates (po files). It is like Pot, but with .mo ouput capabilities. """ def compile(self, file_path=None, backup=True, **kwargs): """ :param file_path: if the `file_path` attribute is `None`, `path` is taken as the output file and `file_path` parameter is discarded. If `file_path` is not `None`, the output file is `file_path` and `path` is not updated. Default is `None`. File extension is supposed to be '.po' and is changed to `.mo` before writing. :param backup: if `True` and the output file exists, a backup is made prior to overwrite the file. Further backups overwrite the previous. Other optional keyword parameters are passed to `babel.messages.mofile.write_mo()` see `babel` public API docs. """ if file_path is None: file_path = self.path if file_path is not None: file_path = file_path[:-2] + 'mo' if pth.isfile(file_path) and backup: shutil.copy(file_path, '{}~'.format(file_path)) with open(file_path, 'wb') as f: write_mo(f, self.catalog, **kwargs) class LangsAction(argparse.Action): """action for the --langs/--nolangs option --langs - add all available langs --langs xx_XX ... - add selected langs --nolangs - remove all langs processing --nolangs xx_XX ... - remove selected langs no language is processed by default Examples: To process only spanish and french: translations.py ACTION --langs es_ES fr_FR To process all but spanish and french' translations.py ACTION --langs --nolangs es_ES fr_FR """ def __call__(self, parser, namespace, values, option_string=None): old_values = getattr(namespace, self.dest) if option_string == '--langs': values = set(values) if values else set(self.choices) values.update(old_values) elif option_string == '--nolangs': values = set(values) if values else set(self.choices) values = old_values.difference(values) else: values = old_values setattr(namespace, self.dest, values) class NoList(list): """A tuned list whichs lies about membership. Used by the parser. """ def __contains__(self, item): return not super(self.__class__, self).__contains__(item) class TranslationFrontend(object): """Frontend for this module when used as a command. Issue `nb_src_path/util/translations.py -h` to obtain detailed help. Examples: `translations.py update --pot --langs` updates message.pot and messages.po for all the localizations from messages from the source tree. obsolete, fuzzy and untranslated messages must be edited by hand in every file. This command makes backups of all the files. `translations.py update --langs es_ES pt_BR` the same, but only for the listed localizations. `translations.py update --langs --nolangs fr_FR --nobackupi --fuzzy` the same, but for all the localizations except french and no backups are done. Fuzzy update is performed. `translations.py update --pot --nowarn` updates only the templates message.pot and no warnings about fuzzy, obsolete and untranslated messages are issued (for a template file all messages are untranslated). `translations.py restore --pot --langs` restores all backups present. `translations.py clear --pot --langs` clears all backups present (including backup for .mo files). `translations.py compile --langs` generate .mo files from .po for all the localizations. `translations.py extract` generates a new template file (message.pot) and backup the existing. `translations.py init zh_CN` creates the mandarin chinese localization infrastructure to start the actual task with the .po file. """ def __init__(self, **kwargs): self.data = LocalData() self.args = self.parser.parse_args() @property def parser(self): """the `argparse` parser """ parser = argparse.ArgumentParser( description='Localization management for sage notebook', epilog='This command does nothing without additional options.\n' 'To see options available for every subcommand, type:\n' ' {} SUBCOMMAND -h'.format(self.data.path.command_name), ) pot_parser = argparse.ArgumentParser(add_help=False) pot_parser.add_argument( '--pot', dest='pot', action='store_true', help='Perform ACTION on sage message.pot file\n', ) langs_parser = argparse.ArgumentParser(add_help=False) langs_parser.add_argument( '--langs', '--nolangs', dest='langs', action=LangsAction, nargs='*', choices=self.data.langs, default=set(), metavar=('xx_XX', 'yy_YY'), help='--langs - add all available langs\n' '--langs xx_XX ... - add selected langs\n' '--nolangs - remove all langs processing\n' '--nolangs xx_XX ... - remove selected langs\n' 'no language is processed by default.\n' 'Examples:\n' ' To process only spanish and french:\n' ' translations.py ACTION --langs es_ES fr_FR\n' ' To process all but spanish and french:\n' ' translations.py ACTION --langs --nolangs es_ES fr_FR\n' ) backup_parser = argparse.ArgumentParser(add_help=False) backup_parser.add_argument( '--nobackup', dest='backup', action='store_false', help='Deactivate backup for processed files\n', ) subparsers = parser.add_subparsers( metavar='SUBCOMMAND', title='subcommands', description='', help='is one of:', ) parser_update = subparsers.add_parser( 'update', parents=(pot_parser, langs_parser, backup_parser), help='update pot and/or po files from sources', description='update pot and/or po files from source tree', epilog='Warning: If backup is active, previous backup files ' 'are overwritten', formatter_class=argparse.RawTextHelpFormatter, ) parser_update.add_argument( '--nowarn', dest='warn', action='store_false', help='Prevent warning about fuzzy, untranslated and\n' 'obsolete messages to be printed', ) parser_update.add_argument( '--fuzzy', dest='nofuzzy', action='store_false', help='Fuzzy matching of message IDs\n', ) parser_update.set_defaults(func=self.update) parser_extract = subparsers.add_parser( 'extract', parents=(backup_parser,), help='extract a new pot file from sources', description='extract a new message.pot template file from sources', epilog='Warning: If backup is active, previous backup files ' 'are overwritten', formatter_class=argparse.RawTextHelpFormatter, ) parser_extract.set_defaults(func=self.extract) parser_restore = subparsers.add_parser( 'restore', parents=(pot_parser, langs_parser), help='restore pot and/or po from backup files', description='restore pot and/or po from backup files if exist', epilog='Warning: If a particular backup file is not present, ' 'the corresponding file\n' ' is not restored', formatter_class=argparse.RawTextHelpFormatter, ) parser_restore.set_defaults(func=self.restore) parser_clear = subparsers.add_parser( 'clear', parents=(pot_parser, langs_parser), help='clear pot and/or po backup files', description='clear pot and/or po backup files', epilog='Warning: Backups for the corresponding mo files are also ' 'cleared', formatter_class=argparse.RawTextHelpFormatter, ) parser_clear.set_defaults(func=self.clear) parser_compile = subparsers.add_parser( 'compile', parents=(langs_parser, backup_parser), help='generate mo files from po files', description='generate mo files from po files', epilog='Warning: Previous mo files are overwritten.\n' ' If backup is active, previous backup files ' 'are overwritten', formatter_class=argparse.RawTextHelpFormatter, ) parser_compile.set_defaults(func=self.compile) parser_init = subparsers.add_parser( 'init', help='generate a new localization from source tree messages', description='generate a new localization from source tree ' 'messages', epilog='Warning: Existing localizations or incorrect identifiers ' 'not allowed', formatter_class=argparse.RawTextHelpFormatter, ) parser_init.add_argument( 'lang', choices=NoList(self.data.langs), help='locale identifier', metavar='xx_XX', ) parser_init.set_defaults(func=self.init) return parser def __call__(self): self.args.func() def update(self): """Action function for the `update` subcommand """ pot_new = Pot() pot_new.extract(**self.data.extract) if self.args.pot: pot_old = Pot(self.data.path.pot) pot_old.update(pot_new, no_fuzzy_matching=self.args.nofuzzy) pot_old.to_file(backup=self.args.backup, warn=self.args.warn, **self.data.to_file) for lang in self.args.langs.difference(('en_US',)): po = Po(self.data.path.lang(lang), locale=lang) po.update(pot_new, no_fuzzy_matching=self.args.nofuzzy) for lang in self.data.langs: po.catalog.obsolete.pop(lang, None) self.complete_update(po) if 'en_US' in self.args.langs: po = Po(self.data.path.lang('en_US'), locale='en_US') self.complete_update(po) def complete_update(self, po): for lang, name in zip(self.data.langs, self.data.lang_names): po.catalog.add(lang, name) po.to_file(backup=self.args.backup, warn=self.args.warn, **self.data.to_file) def extract(self): """Action function for the `extract` subcommand """ pot = Pot() pot.extract(**self.data.extract) pot.path = self.data.path.pot pot.to_file(backup=self.args.backup, warn=False, **self.data.to_file) def restore(self): """Action function for the `restore` subcommand """ if self.args.pot: restore(self.data.path.pot) for lang in self.args.langs: po_path = self.data.path.lang(lang) mo_path = po_path[:-2] + 'mo' restore(po_path) restore(mo_path) def clear(self): """Action function for the `clear` subcommand """ if self.args.pot: clear(self.data.path.pot) for lang in self.args.langs: po_path = self.data.path.lang(lang) mo_path = po_path[:-2] + 'mo' clear(po_path) clear(mo_path) def compile(self): """Action function for the `compile` subcommand """ for lang in self.args.langs: po = Po(self.data.path.lang(lang)) po.compile(backup=self.args.backup) def init(self): """action function for the `init` subcommand """ po = Po() po.extract(locale=self.args.lang, **self.data.extract) po.path = self.data.path.lang(self.args.lang) #: Based on the source code of pybabel: #: babel.messages.frontend po.catalog.revision_date = datetime.now() po.catalog.fuzzy = False os.makedirs(pth.dirname(po.path)) self.args.backup = False self.args.warn = False self.complete_update(po) if __name__ == '__main__': frontend = TranslationFrontend() frontend()