diff --git a/LICENSE b/LICENSE index d6a9326..494e7c4 100644 --- a/LICENSE +++ b/LICENSE @@ -1,340 +1,258 @@ -GNU GENERAL PUBLIC LICENSE - Version 2, June 1991 +# GNU GENERAL PUBLIC LICENSE - Copyright (C) 1989, 1991 Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. +Version 2, June 1991 - Preamble +Copyright (C) 1989, 1991 Free Software Foundation, Inc. +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -License is intended to guarantee your freedom to share and change free -software--to make sure the software is free for all its users. This -General Public License applies to most of the Free Software -Foundation's software and to any other program whose authors commit to -using it. (Some other Free Software Foundation software is covered by -the GNU Lesser General Public License instead.) You can apply it to -your programs, too. +Everyone is permitted to copy and distribute verbatim copies +of this license document, but changing it is not allowed. +Preamble - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -this service if you wish), that you receive source code or can get it -if you want it, that you can change the software or use pieces of it -in new free programs; and that you know you can do these things. +The licenses for most software are designed to take away your freedom to share +and change it. By contrast, the GNU General Public License is intended to guarantee +your freedom to share and change free software--to make sure the software is free +for all its users. This General Public License applies to most of the Free +Software Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by the GNU +Lesser General Public License instead.) You can apply it to your programs, too. - To protect your rights, we need to make restrictions that forbid -anyone to deny you these rights or to ask you to surrender the rights. -These restrictions translate to certain responsibilities for you if you -distribute copies of the software, or if you modify it. +When we speak of free software, we are referring to freedom, not price. Our +General Public Licenses are designed to make sure that you have the freedom to +distribute copies of free software (and charge for this service if you wish), +that you receive source code or can get it if you want it, that you can change +the software or use pieces of it in new free programs; and that you know you +can do these things. - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must give the recipients all the rights that -you have. You must make sure that they, too, receive or can get the -source code. And you must show them these terms so they know their -rights. +To protect your rights, we need to make restrictions that forbid anyone to +deny you these rights or to ask you to surrender the rights. These restrictions +translate to certain responsibilities for you if you distribute copies of the +software, or if you modify it. - We protect your rights with two steps: (1) copyright the software, and -(2) offer you this license which gives you legal permission to copy, -distribute and/or modify the software. +For example, if you distribute copies of such a program, whether gratis or for +a fee, you must give the recipients all the rights that you have. You must make +sure that they, too, receive or can get the source code. And you must show them +these terms so they know their rights. - Also, for each author's protection and ours, we want to make certain -that everyone understands that there is no warranty for this free -software. If the software is modified by someone else and passed on, we -want its recipients to know that what they have is not the original, so -that any problems introduced by others will not reflect on the original -authors' reputations. +We protect your rights with two steps: (1) copyright the software, and (2) +offer you this license which gives you legal permission to copy, distribute +and/or modify the software. - Finally, any free program is threatened constantly by software -patents. We wish to avoid the danger that redistributors of a free -program will individually obtain patent licenses, in effect making the -program proprietary. To prevent this, we have made it clear that any -patent must be licensed for everyone's free use or not licensed at all. +Also, for each author's protection and ours, we want to make certain that +everyone understands that there is no warranty for this free software. If the +software is modified by someone else and passed on, we want its recipients to +know that what they have is not the original, so that any problems introduced +by others will not reflect on the original authors' reputations. - The precise terms and conditions for copying, distribution and -modification follow. +Finally, any free program is threatened constantly by software patents. We wish +to avoid the danger that redistributors of a free program will individually +obtain patent licenses, in effect making the program proprietary. To prevent +this, we have made it clear that any patent must be licensed for everyone's +free use or not licensed at all. - GNU GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION +The precise terms and conditions for copying, distribution and modification follow. - 0. This License applies to any program or other work which contains -a notice placed by the copyright holder saying it may be distributed -under the terms of this General Public License. The "Program", below, -refers to any such program or work, and a "work based on the Program" -means either the Program or any derivative work under copyright law: -that is to say, a work containing the Program or a portion of it, -either verbatim or with modifications and/or translated into another -language. (Hereinafter, translation is included without limitation in -the term "modification".) Each licensee is addressed as "you". +## TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION -Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running the Program is not restricted, and the output from the Program -is covered only if its contents constitute a work based on the -Program (independent of having been made by running the Program). -Whether that is true depends on what the Program does. +0. This License applies to any program or other work which contains a notice + placed by the copyright holder saying it may be distributed under the terms of + this General Public License. The "Program", below, refers to any such program + or work, and a "work based on the Program" means either the Program or any + derivative work under copyright law: that is to say, a work containing the + Program or a portion of it, either verbatim or with modifications and/or + translated into another language. (Hereinafter, translation is included without + limitation in the term "modification".) Each licensee is addressed as "you". + + Activities other than copying, distribution and modification are not covered by + this License; they are outside its scope. The act of running the Program is not + restricted, and the output from the Program is covered only if its contents + constitute a work based on the Program (independent of having been made by + running the Program). Whether that is true depends on what the Program does. - 1. You may copy and distribute verbatim copies of the Program's -source code as you receive it, in any medium, provided that you -conspicuously and appropriately publish on each copy an appropriate -copyright notice and disclaimer of warranty; keep intact all the -notices that refer to this License and to the absence of any warranty; -and give any other recipients of the Program a copy of this License -along with the Program. +1. You may copy and distribute verbatim copies of the Program's source code as + you receive it, in any medium, provided that you conspicuously and appropriately + publish on each copy an appropriate copyright notice and disclaimer of warranty; + keep intact all the notices that refer to this License and to the absence of any + warranty; and give any other recipients of the Program a copy of this License + along with the Program. + + You may charge a fee for the physical act of transferring a copy, and you may at + your option offer warranty protection in exchange for a fee. + +2. You may modify your copy or copies of the Program or any portion of it, thus + forming a work based on the Program, and copy and distribute such modifications + or work under the terms of Section 1 above, provided that you also meet all of + these conditions: + + a) You must cause the modified files to carry prominent notices stating that + you changed the files and the date of any change. + b) You must cause any work that you distribute or publish, that in whole or in + part contains or is derived from the Program or any part thereof, to be + licensed as a whole at no charge to all third parties under the terms of this + License. + c) If the modified program normally reads commands interactively when run, you + must cause it, when started running for such interactive use in the most + ordinary way, to print or display an announcement including an appropriate + copyright notice and a notice that there is no warranty (or else, saying + that you provide a warranty) and that users may redistribute the program + under these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but does not + normally print such an announcement, your work based on the Program is not + required to print an announcement.) + + These requirements apply to the modified work as a whole. If identifiable + sections of that work are not derived from the Program, and can be reasonably + considered independent and separate works in themselves, then this License, + and its terms, do not apply to those sections when you distribute them as + separate works. But when you distribute the same sections as part of a whole + which is a work based on the Program, the distribution of the whole must be on + the terms of this License, whose permissions for other licensees extend to the + entire whole, and thus to each and every part regardless of who wrote it. + + Thus, it is not the intent of this section to claim rights or contest your + rights to work written entirely by you; rather, the intent is to exercise the + right to control the distribution of derivative or collective works based on + the Program. + + In addition, mere aggregation of another work not based on the Program with the + Program (or with a work based on the Program) on a volume of a storage or + distribution medium does not bring the other work under the scope of this + License. + + 3. You may copy and distribute the Program (or a work based on it, under + Section 2) in object code or executable form under the terms of Sections 1 + and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable source code, + which must be distributed under the terms of Sections 1 and 2 above on a + medium customarily used for software interchange; or, + b) Accompany it with a written offer, valid for at least three years, to give + any third party, for a charge no more than your cost of physically + performing source distribution, a complete machine-readable copy of the + corresponding source code, to be distributed under the terms of Sections 1 + and 2 above on a medium customarily used for software interchange; or, + c) Accompany it with the information you received as to the offer to distribute + corresponding source code. (This alternative is allowed only for + noncommercial distribution and only if you received the program in object + code or executable form with such an offer, in accord with Subsection b + above.) + + The source code for a work means the preferred form of the work for making + modifications to it. For an executable work, complete source code means all the + source code for all modules it contains, plus any associated interface + definition files, plus the scripts used to control compilation and installation + of the executable. However, as a special exception, the source code distributed + need not include anything that is normally distributed (in either source or + binary form) with the major components (compiler, kernel, and so on) of the + operating system on which the executable runs, unless that component itself + accompanies the executable. + + If distribution of executable or object code is made by offering access to + copy from a designated place, then offering equivalent access to copy the + source code from the same place counts as distribution of the source code, + even though third parties are not compelled to copy the source along with the + object code. -You may charge a fee for the physical act of transferring a copy, and -you may at your option offer warranty protection in exchange for a fee. +4. You may not copy, modify, sublicense, or distribute the Program except as + expressly provided under this License. Any attempt otherwise to copy, modify, + sublicense or distribute the Program is void, and will automatically + terminate your rights under this License. However, parties who have + received copies, or rights, from you under this License will not have their + licenses terminated so long as such parties remain in full compliance. - 2. You may modify your copy or copies of the Program or any portion -of it, thus forming a work based on the Program, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: +5. You are not required to accept this License, since you have not signed it. + However, nothing else grants you permission to modify or distribute the + Program or its derivative works. These actions are prohibited by law if + you do not accept this License. Therefore, by modifying or distributing + the Program (or any work based on the Program), you indicate your + acceptance of this License to do so, and all its terms and conditions + for copying, distributing or modifying the Program or works based on it. - a) You must cause the modified files to carry prominent notices - stating that you changed the files and the date of any change. +6. Each time you redistribute the Program (or any work based on the Program), + the recipient automatically receives a license from the original licensor + to copy, distribute or modify the Program subject to these terms and + conditions. You may not impose any further restrictions on the recipients' + exercise of the rights granted herein. You are not responsible for enforcing + compliance by third parties to this License. - b) You must cause any work that you distribute or publish, that in - whole or in part contains or is derived from the Program or any - part thereof, to be licensed as a whole at no charge to all third - parties under the terms of this License. +7. If, as a consequence of a court judgment or allegation of patent infringement + or for any other reason (not limited to patent issues), conditions are + imposed on you (whether by court order, agreement or otherwise) that + contradict the conditions of this License, they do not excuse you from the + conditions of this License. If you cannot distribute so as to satisfy + simultaneously your obligations under this License and any other pertinent + obligations, then as a consequence you may not distribute the Program at + all. For example, if a patent license would not permit royalty-free + redistribution of the Program by all those who receive copies directly or + indirectly through you, then the only way you could satisfy both it and + this License would be to refrain entirely from distribution of the Program. - c) If the modified program normally reads commands interactively - when run, you must cause it, when started running for such - interactive use in the most ordinary way, to print or display an - announcement including an appropriate copyright notice and a - notice that there is no warranty (or else, saying that you provide - a warranty) and that users may redistribute the program under - these conditions, and telling the user how to view a copy of this - License. (Exception: if the Program itself is interactive but - does not normally print such an announcement, your work based on - the Program is not required to print an announcement.) + If any portion of this section is held invalid or unenforceable under any + particular circumstance, the balance of the section is intended to apply + and the section as a whole is intended to apply in other circumstances. -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Program, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Program, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote it. + It is not the purpose of this section to induce you to infringe any patents + or other property right claims or to contest validity of any such claims; + this section has the sole purpose of protecting the integrity of the free + software distribution system, which is implemented by public license + practices. Many people have made generous contributions to the wide range + of software distributed through that system in reliance on consistent + application of that system; it is up to the author/donor to decide if he or + she is willing to distribute software through any other system and a + licensee cannot impose that choice. + + This section is intended to make thoroughly clear what is believed to be a + consequence of the rest of this License. + +8. If the distribution and/or use of the Program is restricted in certain + countries either by patents or by copyrighted interfaces, the original + copyright holder who places the Program under this License may add an + explicit geographical distribution limitation excluding those countries, + so that distribution is permitted only in or among countries not thus + excluded. In such case, this License incorporates the limitation as if + written in the body of this License. -Thus, it is not the intent of this section to claim rights or contest -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Program. +9. The Free Software Foundation may publish revised and/or new versions of the + General Public License from time to time. Such new versions will be similar + in spirit to the present version, but may differ in detail to address new + problems or concerns. -In addition, mere aggregation of another work not based on the Program -with the Program (or with a work based on the Program) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. + Each version is given a distinguishing version number. If the Program + specifies a version number of this License which applies to it and + "any later version", you have the option of following the terms and + conditions either of that version or of any later version published + by the Free Software Foundation. If the Program does not specify a version + number of this License, you may choose any version ever published by the + Free Software Foundation. - 3. You may copy and distribute the Program (or a work based on it, -under Section 2) in object code or executable form under the terms of -Sections 1 and 2 above provided that you also do one of the following: +10. If you wish to incorporate parts of the Program into other free programs + whose distribution conditions are different, write to the author to ask for + permission. For software which is copyrighted by the Free Software + Foundation, write to the Free Software Foundation; we sometimes make + exceptions for this. Our decision will be guided by the two goals of + preserving the free status of all derivatives of our free software and of + promoting the sharing and reuse of software generally. - a) Accompany it with the complete corresponding machine-readable - source code, which must be distributed under the terms of Sections - 1 and 2 above on a medium customarily used for software interchange; or, +NO WARRANTY - b) Accompany it with a written offer, valid for at least three - years, to give any third party, for a charge no more than your - cost of physically performing source distribution, a complete - machine-readable copy of the corresponding source code, to be - distributed under the terms of Sections 1 and 2 above on a medium - customarily used for software interchange; or, +11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR + THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN + OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES + PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED + OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO + THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM + PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR + CORRECTION. - c) Accompany it with the information you received as to the offer - to distribute corresponding source code. (This alternative is - allowed only for noncommercial distribution and only if you - received the program in object code or executable form with such - an offer, in accord with Subsection b above.) - -The source code for a work means the preferred form of the work for -making modifications to it. For an executable work, complete source -code means all the source code for all modules it contains, plus any -associated interface definition files, plus the scripts used to -control compilation and installation of the executable. However, as a -special exception, the source code distributed need not include -anything that is normally distributed (in either source or binary -form) with the major components (compiler, kernel, and so on) of the -operating system on which the executable runs, unless that component -itself accompanies the executable. - -If distribution of executable or object code is made by offering -access to copy from a designated place, then offering equivalent -access to copy the source code from the same place counts as -distribution of the source code, even though third parties are not -compelled to copy the source along with the object code. - - 4. You may not copy, modify, sublicense, or distribute the Program -except as expressly provided under this License. Any attempt -otherwise to copy, modify, sublicense or distribute the Program is -void, and will automatically terminate your rights under this License. -However, parties who have received copies, or rights, from you under -this License will not have their licenses terminated so long as such -parties remain in full compliance. - - 5. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Program or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Program (or any work based on the -Program), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Program or works based on it. - - 6. Each time you redistribute the Program (or any work based on the -Program), the recipient automatically receives a license from the -original licensor to copy, distribute or modify the Program subject to -these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties to -this License. - - 7. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Program at all. For example, if a patent -license would not permit royalty-free redistribution of the Program by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Program. - -If any portion of this section is held invalid or unenforceable under -any particular circumstance, the balance of the section is intended to -apply and the section as a whole is intended to apply in other -circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system, which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - - 8. If the distribution and/or use of the Program is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Program under this License -may add an explicit geographical distribution limitation excluding -those countries, so that distribution is permitted only in or among -countries not thus excluded. In such case, this License incorporates -the limitation as if written in the body of this License. - - 9. The Free Software Foundation may publish revised and/or new versions -of the General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - -Each version is given a distinguishing version number. If the Program -specifies a version number of this License which applies to it and "any -later version", you have the option of following the terms and conditions -either of that version or of any later version published by the Free -Software Foundation. If the Program does not specify a version number of -this License, you may choose any version ever published by the Free Software -Foundation. - - 10. If you wish to incorporate parts of the Program into other free -programs whose distribution conditions are different, write to the author -to ask for permission. For software which is copyrighted by the Free -Software Foundation, write to the Free Software Foundation; we sometimes -make exceptions for this. Our decision will be guided by the two goals -of preserving the free status of all derivatives of our free software and -of promoting the sharing and reuse of software generally. - - NO WARRANTY - - 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY -FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN -OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES -PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED -OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS -TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE -PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, -REPAIR OR CORRECTION. - - 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR -REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, -INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING -OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED -TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY -YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER -PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE -POSSIBILITY OF SUCH DAMAGES. - - END OF TERMS AND CONDITIONS - - 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 -convey the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - {description} - Copyright (C) {year} {fullname} - - 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 2 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, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - -Also add information on how to contact you by electronic and paper mail. - -If the program is interactive, make it output a short notice like this -when it starts in an interactive mode: - - Gnomovision version 69, Copyright (C) year name of author - Gnomovision 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, the commands you use may -be called something other than `show w' and `show c'; they could even be -mouse-clicks or menu items--whatever suits your program. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the program, if -necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the program - `Gnomovision' (which makes passes at compilers) written by James Hacker. - - {signature of Ty Coon}, 1 April 1989 - Ty Coon, President of Vice - -This 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. +12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL + ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE + THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY + GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE + USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF + DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD + PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), + EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF + SUCH DAMAGES. +END OF TERMS AND CONDITIONS \ No newline at end of file diff --git a/README.md b/README.md index 01786d2..8611367 100644 --- a/README.md +++ b/README.md @@ -2,17 +2,6 @@ Core cellular automaton engine for MicroWorld. -## Part of the overall MicroWorld system - -While this code works and is interesting on its own, you also need at least -[mw-parser](https://github.com/simon-brooke/mw-parser) and -[mw-ui](https://github.com/simon-brooke/mw-ui). There will be other -modules in due course. - -You can see MicroWorld in action [here](http://www.journeyman.cc/microworld/) - -but please don't be mean to my poor little server. If you want to run big maps -or complex rule-sets, please run it on your own machines. - ## Usage Primary entry points are make-world and run-world, both in mw-engine.core. See @@ -21,19 +10,6 @@ using lein marg -To build the whole system, place all MicroWorld projects in a common directory, -and from that directory run *buildall.sh*. Alternatively, in each MicroWorld -project directory, run - - lein clean - lein compile - lein marg - lein install - -and then from the mw-ui directory, run - - lein ring server - ## License Copyright © 2014 Simon Brooke diff --git a/buildall.sh b/buildall.sh index 0eabd8e..488fea0 100755 --- a/buildall.sh +++ b/buildall.sh @@ -6,7 +6,7 @@ # WARNING: The regexps in this are fair awfy bruckle. Edit with care. -# Simon Broooke +# Simon Broooke # Variable and glag initialisation archive=FALSE @@ -72,11 +72,10 @@ if [ $# -lt 1 ] then cat <<-EOF 1>&2 Usage: - -archive Create a tar archive of the current state of the source. + -archive Create a tar archive of the current state of the source. -build Build all components and commit to master. -email [ADDRESS] Your email address, to be recorded in the build signature. -fullname [NAME] Your full name, to be recorded in the build signature. - -pull Pull from remote git repository -release [LABEL] Build all components, branch for release on old label, then upversion to new LABEL and commit to master. -trial Trial build only, do not commit. @@ -87,8 +86,8 @@ fi while (( "$#" )) do case $1 in - -a|-archive) - archive="TRUE";; + -a|-archive) + archive="TRUE";; -b|-build) # 'build' is the expected normal case. trial="FALSE"; @@ -99,9 +98,6 @@ do -f|-fullname) shift; fullname=$1;; - -p|-pull) - # pull from remote Git origin - git pull origin master;; -r|-release) # release is branch a release and upversion to new label shift; @@ -112,6 +108,9 @@ do echo "Release flagged, but no release tag supplied" 1>&2; exit 1; fi;; + -p|-pull) + # pull from remote Git origin + git pull origin master;; -t|-trial) trial="TRUE";; -w|-webapps) diff --git a/project.clj b/project.clj index a2739ff..99018b6 100644 --- a/project.clj +++ b/project.clj @@ -1,4 +1,4 @@ -(defproject mw-engine "0.1.5-SNAPSHOT" +(defproject mw-engine "0.1.3" :description "Cellular automaton world builder." :url "http://www.journeyman.cc/microworld/" :manifest { @@ -11,11 +11,10 @@ :jvm-opts ["-Xmx4g"] :license {:name "GNU General Public License v2" :url "http://www.gnu.org/licenses/gpl-2.0.html"} - :plugins [[lein-marginalia "0.7.1"]] - :dependencies [[org.clojure/clojure "1.6.0"] + :plugins [[lein-marginalia "0.7.1"] + [lein-gorilla "0.3.2"]] + :dependencies [[org.clojure/clojure "1.5.1"] [org.clojure/math.combinatorics "0.0.7"] [org.clojure/tools.trace "0.7.8"] - [org.clojure/tools.namespace "0.2.4"] - [hiccup "1.0.5"] [net.mikera/imagez "0.3.1"] [fivetonine/collage "0.2.0"]]) diff --git a/src/mw_engine/core.clj b/src/mw_engine/core.clj index 9b95b55..8a0ca95 100644 --- a/src/mw_engine/core.clj +++ b/src/mw_engine/core.clj @@ -23,12 +23,12 @@ ;; that every cell's :x and :y properties reflect its place in the matrix. ;; See `world.clj`. ;; -;; Each time the world is transformed (see `transform-world`, for each cell, +;; Each time the world is transformed (see `transform-world`, for each cell, ;; rules are applied in turn until one matches. Once one rule has matched no ;; further rules can be applied. -(defn apply-rule +(defn apply-rule "Apply a single `rule` to a `cell`. What this is about is that I want to be able, for debugging purposes, to tag a cell with the rule text of the rule which fired (and especially so when an exception is thrown. So a rule may be either @@ -41,7 +41,7 @@ (seq? rule) (let [[afn src] rule] (apply-rule cell world afn src)))) ([cell world rule source] (let [result (apply rule (list cell world))] - (cond + (cond (and result source) (merge result {:rule source}) true result)))) @@ -58,11 +58,11 @@ exception is thrown, cache its message on the cell and set it's state to error" [world cell rules] (try - (merge - (apply-rules world cell rules) - {:generation (+ (get-int-or-zero cell :generation) 1)}) - (catch Exception e - (merge cell {:error + (merge + (apply-rules world cell rules) + {:generation (+ (or (:generation cell) 0) 1)}) + (catch Exception e + (merge cell {:error (format "%s at generation %d when in state %s" (.getMessage e) (:generation cell) @@ -93,10 +93,28 @@ * `generations` an (integer) number of generations. Return the final generation of the world." + [world init-rules rules generations] + (let [state {:world (transform-world world init-rules) :rules rules}] + (:world + (last + (doall + (take generations + (iterate transform-world-state state))))))) + +(defn run-world2 + "Doesn't work yet" [world init-rules rules generations] - (reduce (fn [world _iteration] + (with-local-vars [r (ref (transform-world world init-rules))] + (dotimes [g generations] + (dosync + (ref-set r (transform-world (deref r) rules)))) + (deref r))) + +(defn run-world3 + [world init-rules rules generations] + (reduce (fn [world _iteration] (transform-world world rules)) (transform-world world init-rules) (range generations))) - - + + diff --git a/src/mw_engine/drainage.clj b/src/mw_engine/drainage.clj index 925b1a0..c9d5874 100644 --- a/src/mw_engine/drainage.clj +++ b/src/mw_engine/drainage.clj @@ -3,14 +3,7 @@ (ns mw-engine.drainage (:use mw-engine.utils - mw-engine.world - mw-engine.core) - (:require [mw-engine.heightmap :as heightmap])) - -(def ^:dynamic *sealevel* 10) - -;; forward declaration of flow, to allow for a wee bit of mutual recursion. -(declare flow) + mw-engine.world)) (defn rain-world "Simulate rainfall on this `world`. TODO: Doesn't really work just now - should @@ -20,98 +13,30 @@ (defn flow-contributors "Return a list of the cells in this `world` which are higher than this - `cell` and for which this cell is the lowest neighbour, or which are at the - same altitude and have greater flow" - [cell world] - (filter #(map? %) - (map - (fn [n] - (cond - (= cell (get-least-cell (get-neighbours world n) :altitude)) n - (and (= (:altitude cell) (:altitude n)) - (> (or (:flow n) 0) (or (:flow cell) 0))) n)) - (get-neighbours-with-property-value - world (:x cell) (:y cell) 1 :altitude - (or (:altitude cell) 0) >=)))) - -(defn is-hollow - "Detects point hollows - that is, individual cells all of whose neighbours - are higher. Return true if this `cell` has an altitude lower than any of - its neighbours in this `world`" + `cell` and for which this cell is the lowest neighbour" [world cell] - ;; quicker to count the elements of the list and compare equality of numbers - ;; than recursive equality check on members, I think. But worth benchmarking. - (let [neighbours (get-neighbours world cell) - altitude (get-int-or-zero cell :altitude)] - (= (count neighbours) - (count (get-neighbours-with-property-value - world (:x cell) (:y cell) 1 :altitude altitude >))))) + (remove nil? + (map + (fn [n] + (cond (= cell (get-least-cell (get-neighbours world n) :altitude)) n)) + (get-neighbours-with-property-value world (:x cell) (:y cell) 1 + :altitude + (or (:altitude cell) 0) >)))) -(defn flood-hollow - "Raise the altitude of a copy of this `cell` of this `world` to the altitude - of the lowest of its `neighbours`." - ([world cell neighbours] - (let [lowest (get-least-cell neighbours :altitude)] - (merge cell {:state :water :altitude (:altitude lowest)}))) - ([world cell] - (flood-hollow world cell (get-neighbours world cell)))) - -(defn flood-hollows - "Flood all local hollows in this `world`. At this stage only floods single - cell hollows." - [world] - (map-world world - #(if (is-hollow %1 %2) (flood-hollow %1 %2) %2))) - -(def max-altitude 255) - -(defn flow-nr - "Experimental non recursive flow algorithm, needs to be run on a world as - many times as there are distinct altitude values. This algorithm works only - if applied sequentially from the highest altitude to the lowest, see - `flow-world-nr`." - [cell world] - (if (= (- max-altitude (get-int-or-zero cell :generation)) - (get-int-or-zero cell :altitude)) - (merge cell - {:flow (reduce + - (map - #(+ (get-int-or-zero % :rainfall) - (get-int-or-zero % :flow)) - (flow-contributors cell world)))}))) - -(def flow +(defn flow "Compute the total flow upstream of this `cell` in this `world`, and return a cell identical - to this one but having a value of its flow property set from that computation. The function is - memoised because the consequence of mapping a recursive function across an array is that many - cells will be revisited - potentially many times. + to this one but having a value of its flow property set from that computation. - Flow comes from a higher cell to a lower only if the lower is the lowest neighbour of the higher." - (memoize - (fn [cell world] - (cond - (not (nil? (:flow cell))) cell - (<= (or (:altitude cell) 0) *sealevel*) cell - true + Flow comes from a higher cell to a lower only if the lower is the lowest neighbour of the higher." + [world cell] (merge cell - {:flow (+ (:rainfall cell) - (apply + - (map (fn [neighbour] (:flow (flow neighbour world))) - (flow-contributors cell world))))}))))) - -(defn flow-world-nr - "Experimental non-recursive flow-world algorithm" - [world] - (run-world world nil (list flow-nr) max-altitude)) + {:flow (+ (:rainfall cell) + (apply + + (map (fn [neighbour] (:flow (flow world neighbour))) + (flow-contributors world cell))))})) (defn flow-world "Return a world like this `world`, but with cells tagged with the amount of water flowing through them." [world] (map-world (rain-world world) flow)) - -(defn run-drainage - [hmap] - "Create a world from the heightmap `hmap`, rain on it, and then compute river - flows." - (flow-world (rain-world (flood-hollows (heightmap/apply-heightmap hmap))))) diff --git a/src/mw_engine/heightmap.clj b/src/mw_engine/heightmap.clj index 403cad0..bfcf6af 100644 --- a/src/mw_engine/heightmap.clj +++ b/src/mw_engine/heightmap.clj @@ -6,13 +6,14 @@ (ns mw-engine.heightmap (:import [java.awt.image BufferedImage]) (:use mw-engine.utils - mw-engine.world) + mw-engine.world + mw-engine.drainage) (:require [fivetonine.collage.util :as collage :only [load-image]] [mikera.image.core :as imagez :only [filter-image get-pixels]] [mikera.image.filters :as filters])) -(defn tag-property +(defn- tag-property "Set the value of this `property` of this cell from the corresponding pixel of this `heightmap`. If the heightmap you supply is smaller than the world, this will break. @@ -35,7 +36,7 @@ (get-int cell :x) (get-int cell :y)) 256))))}))) -(defn tag-gradient +(defn- tag-gradient "Set the `gradient` property of this `cell` of this `world` to the difference in altitude between its highest and lowest neghbours." [world cell] @@ -53,7 +54,7 @@ [world] (map-world world tag-gradient)) -(defn tag-altitude +(defn- tag-altitude "Set the altitude of this cell from the corresponding pixel of this heightmap. If the heightmap you supply is smaller than the world, this will break. diff --git a/src/mw_engine/utils.clj b/src/mw_engine/utils.clj index 279ec18..8c6fee5 100644 --- a/src/mw_engine/utils.clj +++ b/src/mw_engine/utils.clj @@ -1,9 +1,8 @@ -;; Utility functions needed by MicroWorld and, specifically, in the -;; interpretation of MicroWorld rule. +;; Utility functions needed by MicroWorld and, specifically, in the interpretation of MicroWorld rule. (ns mw-engine.utils - (:require -;; [clojure.core.reducers :as r] + (:require + [clojure.core.reducers :as r] [clojure.math.combinatorics :as combo])) (defn abs @@ -14,28 +13,12 @@ * `n` a number, on the set of real numbers." [n] - (if (neg? n) (- 0 n) n)) + (cond (neg? n) (- 0 n) true n)) (defn member? "True if elt is a member of col." [elt col] (some #(= elt %) col)) -(defn get-int-or-zero - "Return the value of this `property` from this `map` if it is a integer; - otherwise return zero." - [map property] - (let [value (map property)] - (if (integer? value) value 0))) - -(defn init-generation - "Return a cell like this `cell`, but having a value for :generation, zero if - the cell passed had no integer value for generation, otherwise the value - taken from the cell passed. The `world` argument is present only for - consistency with the rule engine and is ignored." - [world cell] - (merge cell {:generation (get-int-or-zero cell :generation)})) - - (defn in-bounds "True if x, y are in bounds for this world (i.e., there is a cell at x, y) else false. @@ -46,47 +29,17 @@ [world x y] (and (>= x 0)(>= y 0)(< y (count world))(< x (count (first world))))) -(defn map-world-n-n - "Wholly non-parallel map world implementation" - ([world function] - (map-world-n-n world function nil)) - ([world function additional-args] - (into [] - (map (fn [row] - (into [] (map - #(apply function - (cons world (cons % additional-args))) - row))) - world)))) - -(defn map-world-p-p - "Wholly parallel map world implementation" - ([world function] - (map-world-p-p world function nil)) - ([world function additional-args] - (into [] - (pmap (fn [row] - (into [] (pmap - #(apply function - (cons world (cons % additional-args))) - row))) - world)))) - - (defn map-world "Apply this `function` to each cell in this `world` to produce a new world. the arguments to the function will be the world, the cell, and any - `additional-args` supplied. Note that we parallel map over rows but - just map over cells within a row. That's because it isn't worth starting - a new thread for each cell, but there may be efficiency gains in - running rows in parallel." + `additional-args` supplied" ([world function] (map-world world function nil)) ([world function additional-args] - (into [] - (pmap (fn [row] - (into [] (map - #(apply function + (into [] ;; vectors are more efficient for scanning, which we do a lot. + (r/map (fn [row] + (into [] (r/map + #(apply function (cons world (cons % additional-args))) row))) world)))) @@ -123,51 +76,35 @@ [cell species] (get-int cell species)) -(def memo-get-neighbours - "Memoised get neighbours is more efficient when running deeply recursive - algorithms on the same world. But it's less efficient when running the - engine in its normal iterative style, because then we will rarely call - get naighbours on the same cell of the same world twice." - (memoize - (fn [world x y depth] - (remove nil? - (map #(get-cell world (first %) (first (rest %))) - (remove #(= % (list x y)) - (combo/cartesian-product - (range (- x depth) (+ x depth 1)) - (range (- y depth) (+ y depth 1))))))))) (defn get-neighbours - "Get the neighbours to distance depth of a cell in this world. - - Several overloads: - * `world` a world, as described in world.clj; - * `cell` a cell within that world - Gets immediate neighbours of the specified cell. - - * `world` a world, as described in world.clj; - * `cell` a cell within that world - * `depth` an integer representing the depth to search from the - `cell` - Gets neighbours within the specified distance of the cell. + "Get the neighbours to distance depth of the cell at x, y in this world. * `world` a world, as described in world.clj; * `x` an integer representing an x coordinate in that world; * `y` an integer representing an y coordinate in that world; * `depth` an integer representing the distance from [x,y] that - should be searched - Gets the neighbours within the specified distance of the cell at - coordinates [x,y] in this world." + should be searched." ([world x y depth] (remove nil? - (map #(get-cell world (first %) (first (rest %))) - (remove #(= % (list x y)) - (combo/cartesian-product - (range (- x depth) (+ x depth 1)) - (range (- y depth) (+ y depth 1))))))) + (map #(get-cell world (first %) (first (rest %))) + (remove #(= % (list x y)) + (combo/cartesian-product + (range (- x depth) (+ x depth 1)) + (range (- y depth) (+ y depth 1))))))) ([world cell depth] - (memo-get-neighbours world (:x cell) (:y cell) depth)) + "Get the neighbours to distance depth of this cell in this world. + + * `world` a world, as described in world.clj; + * `cell` a cell within that world; + * `depth` an integer representing the distance from [x,y] that + should be searched." + (get-neighbours world (:x cell) (:y cell) depth)) ([world cell] + "Get the immediate neighbours of this cell in this world + + * `world` a world, as described in world.clj; + * `cell` a cell within that world." (get-neighbours world cell 1))) (defn get-neighbours-with-property-value @@ -177,10 +114,10 @@ * `world` a world, as described in `world.clj`; * `cell` a cell within that world; * `depth` an integer representing the distance from [x,y] that - should be searched (optional); + should be searched; * `property` a keyword representing a property of the neighbours; * `value` a value of that property (or, possibly, the name of another); - * `op` a comparator function to use in place of `=` (optional). + * `op` a comparator function to use in place of `=`. It gets messy." ([world x y depth property value op] @@ -258,16 +195,4 @@ row))) world)))) -(defn merge-cell - "Return a world like this `world`, but merge the values from this `cell` with - those from the cell in the world with the same co-ordinates" - [world cell] - (if (in-bounds world (:x cell) (:y cell)) - (map-world world - #(if - (and - (= (:x cell)(:x %2)) - (= (:y cell)(:y %2))) - (merge %2 cell) - %2)) - world)) + diff --git a/test/mw_engine/drainage_test.clj b/test/mw_engine/drainage_test.clj deleted file mode 100644 index ba2c95a..0000000 --- a/test/mw_engine/drainage_test.clj +++ /dev/null @@ -1,48 +0,0 @@ -(ns mw-engine.drainage-test - (:require [clojure.test :refer :all] - [mw-engine.world :as world] - [mw-engine.utils :as utils] - [mw-engine.drainage :refer :all])) - -(deftest is-hollow-test - (testing "detection of hollows" - (let [world (utils/set-property - (utils/map-world - (world/make-world 3 3) - #(merge %2 {:altitude 100})) - 1 1 :altitude 90)] - (is (is-hollow world (utils/get-cell world 1 1)) - "Cell at 1, 1 should be a hollow")))) - -(deftest flood-hollow-test - (testing "Flooding of a single specified cell" - (let [world (utils/set-property - (utils/map-world - (world/make-world 3 3) - #(merge %2 {:altitude 100})) - 1 1 :altitude 90) - cell (flood-hollow world (utils/get-cell world 1 1))] - (is (= (:state cell) :water) - "State should be water") - (is (= (:altitude cell) 100) - "Altitude should be 100")))) - -(deftest flood-hollows-test - (testing "Flooding of hollows" - (let [world (utils/set-property - (utils/map-world - (world/make-world 3 3) - #(merge %2 {:altitude 100})) - 1 1 :altitude 90) - w2 (flood-hollows world)] - (is (= (:state (utils/get-cell world 1 1)) :new) - "State of cell in original world should still be :new") - (is (= (:state (utils/get-cell w2 1 1)) :water) - "State of cell in processed world should still be :water") - (is (= (:altitude (utils/get-cell w2 1 1)) 100) - "Altitude of cell in processed world should still be 100")))) - - - - - \ No newline at end of file diff --git a/test/mw_engine/utils_test.clj b/test/mw_engine/utils_test.clj index 0077ceb..977abbb 100644 --- a/test/mw_engine/utils_test.clj +++ b/test/mw_engine/utils_test.clj @@ -164,18 +164,6 @@ "All cells should have property 'test' set to true") (is (empty? (remove #(= % 8) (map #(:number %) (flatten w3c)))) "All cells should have property 'number' set to 8")))) - -(deftest merge-cell-test - (testing "merge-cell utility function" - (let [w1a (make-world 3 3) - w2b (merge-cell w1a {:x 5 :y 5 :out-of-bounds true}) - w3c (merge-cell w1a {:x 2 :y 2 :test true})] - (is (= w1a w2b) "Out of bound cell makes no difference") - (is (empty? (filter #(:out-of-bounds %) (flatten w2b))) - "No cell has :out-of-bounds set") - (is (= 1 (count (filter #(:test %) (flatten w3c)))) - "Exactly one cell has :test set") - (is (:test (get-cell w3c 2 2)) - "The cell with :test set is at 2, 2")))) - - \ No newline at end of file + + + \ No newline at end of file